Add Glave XGL tracer and replayer tools
diff --git a/tools/glave/CMakeLists.txt b/tools/glave/CMakeLists.txt
new file mode 100644
index 0000000..8749422
--- /dev/null
+++ b/tools/glave/CMakeLists.txt
@@ -0,0 +1,72 @@
+PROJECT(gl5debugger)
+cmake_minimum_required(VERSION 2.8)
+
+set(SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src")
+
+#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SRC_DIR}/cmake/Modules/")
+#set(CMAKE_EXTERNAL_PATH "${SRC_DIR}/../../external")
+
+if (WIN32)
+    # TODO: s/CMAKE_PREFIX_PATH/CMAKE_EXTERNAL_WINDOWS_PATH/g
+#    set(CMAKE_PREFIX_PATH "${CMAKE_EXTERNAL_PATH}/windows")
+    set(WIN32_PTHREADS_PATH "${SRC_DIR}/thirdparty/pthreads.2")
+    set(WIN32_PTHREADS_INCLUDE_PATH "${WIN32_PTHREADS_PATH}/include")
+endif()
+
+find_package(PythonLibs REQUIRED)
+find_package(PythonInterp REQUIRED)
+
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+set(GEN_API "xgl")
+else()
+set(GEN_API "mantle")
+endif()
+
+set(CODE_GEN_DIR "glv_extensions/glave_${GEN_API}_gen")
+
+execute_process(COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/code_gen.py --abs_out_dir ${CMAKE_CURRENT_SOURCE_DIR}/src/${CODE_GEN_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src/thirdparty/${GEN_API}/inc/${GEN_API}.h)
+
+
+message("")
+message("cmake options:")
+message("  -DCMAKE_BUILD_TYPE='${CMAKE_BUILD_TYPE}': Build debug or release. (Debug|Release)")
+message("  -DCMAKE_VERBOSE='${CMAKE_VERBOSE}': Spew cmake project options. (On|Off)")
+message("  -DBUILD_X64='${BUILD_X64}': Build 32 or 64-bit. (On|Off)")
+message("")
+
+#
+#  Components to build
+#
+
+add_subdirectory(src/thirdparty/getopt)
+add_subdirectory(src/glvcommon)
+add_subdirectory(src/glvinception)
+add_subdirectory(src/glvtrace)
+add_subdirectory(src/glvreplay)
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+add_subdirectory(src/thirdparty/mhook/mhook-lib)
+add_subdirectory(src/thirdparty/mhook/disasm-lib)
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+# use macro from stackoverflow (link below) to get all the extensions that are on the current system
+# http://stackoverflow.com/questions/7787823/cmake-how-to-get-the-name-of-all-subdirectories-of-a-directory
+MACRO(SUBDIRLIST result curdir)
+  FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
+  SET(dirlist "")
+  FOREACH(child ${children})
+    IF(IS_DIRECTORY ${curdir}/${child})
+        LIST(APPEND dirlist ${child})
+    ENDIF()
+  ENDFOREACH()
+  SET(${result} ${dirlist})
+ENDMACRO()
+
+# now generate the list and add each of the subdirectories
+SUBDIRLIST(SUBDIRS ${SRC_DIR}/glv_extensions)
+message("Adding extensions: '${SUBDIRS}'")
+FOREACH(subdir ${SUBDIRS})
+    add_subdirectory(${SRC_DIR}/glv_extensions/${subdir})
+ENDFOREACH()
+
+
+
diff --git a/tools/glave/README.md b/tools/glave/README.md
new file mode 100644
index 0000000..7d8e470
--- /dev/null
+++ b/tools/glave/README.md
@@ -0,0 +1,70 @@
+Glave (aka gl5_debugger)
+============
+
+Working towards a tracer / debugger of OpenGL5 applications.
+
+###Obtain code###
+```
+git clone https://github.com/KhronosGroup/GL-Next.git
+```
+
+###External dependencies###
+* XGL
+  XGL headers retrieved in place (tools/glave/../../include) by Cmake
+  XGL library retrieved in place (tools/glave/../../<build_dir>/loader by Cmake
+* Python 3.4  (Ubuntu package python3.4-dev)
+* Qt 5        (Ubuntu package qt5-default) (only needed for glave debugger)
+* Mantle (headers and library from AMD's Mantle SDK which is under NDA)
+  * Place in src/thirdparty/mantle ( ONLY needed if using Mantle API)
+
+###Building on Windows###
+```
+cd tools/glave
+mkdir Win64
+cd Win64
+cmake -G "Visual Studio 10 2010 Win64" ..
+// then open the solution file with Visual Studio 2010
+```
+
+###Building on Linux (make)###
+```
+cd tools/glave
+mkdir glv_build
+cd glv_build
+cmake -DCMAKE_BUILD_TYPE=Debug  ..
+make
+```
+
+###Building on Linux (QtCreator)###
+```
+open tools/glave/CMakeLists.txt with QtCreater
+Cmake options: -DCMAKE_BUILD_TYPE=Debug -DBUILD_X64=On
+Change build directory from the suggested 'gl5-debugger' to 'glv_build' (if you want to maintain consistency with the Windows build)
+```
+
+###Running tracer###
+```
+The Glave tracer program launches the app/game you desire and then traces it.
+cd glv_build
+./glvtrace64 <options>
+Example to trace the spinning cube demo from sample implementation
+export LIBXGL_DRIVERS_PATH=/home/jon/dbuild/icd/intel
+export LD_LIBRARY_PATH=/home/jon/dbuild/loader
+./glvtrace64 -p /home/jon/xgl/dbuild/demos/cube -l0 /home/jon/glave/glv_build/libglvtrace_xgl64.so -o glvtrace_cube.glv -w /home/jon/xgl/dbuild/demos
+Trace file is in "glvtrace_cube.glv".
+
+Rather than giving command line options, can instead put tracer options in a
+settings file: "glvtrace_settings.txt".
+```
+
+###Running replayer###
+```
+The Glave replayer takes  a trace file  and will launch an XGL session based
+on trace file.
+cd glv_build
+./glvreplay64 <options> trace_filename
+Example to replay trace file captured above
+export LIBXGL_DRIVERS_PATH=/home/jon/dbuild/icd/intel
+export LD_LIBRARY_PATH=/home/jon/dbuild/loader
+./glvreplay64 glvtrace_cube.glv
+```
\ No newline at end of file
diff --git a/tools/glave/scripts/code_gen.py b/tools/glave/scripts/code_gen.py
new file mode 100644
index 0000000..6fa0c97
--- /dev/null
+++ b/tools/glave/scripts/code_gen.py
@@ -0,0 +1,827 @@
+import argparse
+import os
+import sys
+
+# code_gen.py overview
+# This script generates code based on input headers
+# Initially it's intended to support Mantle and XGL headers and
+#  generate wrappers functions that can be used to display
+#  structs in a human-readable txt format, as well as utility functions
+#  to print enum values as strings
+
+
+def handle_args():
+    parser = argparse.ArgumentParser(description='Perform analysis of vogl trace.')
+    parser.add_argument('input_file', help='The input header file from which code will be generated.')
+    parser.add_argument('--rel_out_dir', required=False, default='glave_gen', help='Path relative to exec path to write output files. Will be created if needed.')
+    parser.add_argument('--abs_out_dir', required=False, default=None, help='Absolute path to write output files. Will be created if needed.')
+    parser.add_argument('--gen_graphviz', required=False, action='store_true', default=False, help='Enable generation of graphviz dot file.')
+    #parser.add_argument('--test', action='store_true', default=False, help='Run simple test.')
+    return parser.parse_args()
+
+# TODO : Ideally these data structs would be opaque to user and could be wrapped
+#   in their own class(es) to make them friendly for data look-up
+# Dicts for Data storage
+# enum_val_dict[value_name] = dict keys are the string enum value names for all enums
+#    |-------->['type'] = the type of enum class into which the value falls
+#    |-------->['val'] = the value assigned to this particular value_name
+#    '-------->['unique'] = bool designating if this enum 'val' is unique within this enum 'type'
+enum_val_dict = {}
+# enum_type_dict['type'] = the type or class of of enum
+#  '----->['val_name1', 'val_name2'...] = each type references a list of val_names within this type
+enum_type_dict = {}
+# struct_dict['struct_basename'] = the base (non-typedef'd) name of the struct
+#  |->[<member_num>] = members are stored via their integer placement in the struct
+#  |    |->['name'] = string name of this struct member
+# ...   |->['full_type'] = complete type qualifier for this member
+#       |->['type'] = base type for this member
+#       |->['ptr'] = bool indicating if this member is ptr
+#       |->['const'] = bool indicating if this member is const
+#       |->['struct'] = bool indicating if this member is a struct type
+#       |->['array'] = bool indicating if this member is an array
+#       '->['array_size'] = int indicating size of array members (0 by default)
+struct_dict = {}
+# typedef_fwd_dict stores mapping from orig_type_name -> new_type_name
+typedef_fwd_dict = {}
+# typedef_rev_dict stores mapping from new_type_name -> orig_type_name
+typedef_rev_dict = {} # store new_name -> orig_name mapping
+# types_dict['id_name'] = identifier name will map to it's type
+#              '---->'type' = currently either 'struct' or 'enum'
+types_dict = {}   # store orig_name -> type mapping
+
+
+# Class that parses header file and generates data structures that can
+#  Then be used for other tasks
+class HeaderFileParser:
+    def __init__(self, header_file=None):
+        self.header_file = header_file
+        # store header data in various formats, see above for more info
+        self.enum_val_dict = {}
+        self.enum_type_dict = {}
+        self.struct_dict = {}
+        self.typedef_fwd_dict = {}
+        self.typedef_rev_dict = {}
+        self.types_dict = {}
+        
+    def setHeaderFile(self, header_file):
+        self.header_file = header_file
+
+    def get_enum_val_dict(self):
+        return self.enum_val_dict
+
+    def get_enum_type_dict(self):
+        return self.enum_type_dict
+
+    def get_struct_dict(self):
+        return self.struct_dict
+
+    def get_typedef_fwd_dict(self):
+        return self.typedef_fwd_dict
+
+    def get_typedef_rev_dict(self):
+        return self.typedef_rev_dict
+
+    def get_types_dict(self):
+        return self.types_dict
+
+    # Parse header file into data structures
+    def parse(self):
+        # parse through the file, identifying different sections
+        parse_enum = False
+        parse_struct = False
+        member_num = 0
+        # TODO : Comment parsing is very fragile but handles 2 known files
+        block_comment = False
+        with open(self.header_file) as f:
+            for line in f:
+                if block_comment:
+                    if '*/' in line:
+                        block_comment = False
+                    continue
+                if '/*' in line:
+                    block_comment = True
+                elif 0 == len(line.split()):
+                    #print("Skipping empty line")
+                    continue
+                elif line.split()[0].strip().startswith("//"):
+                    #print("Skipping commentted line %s" % line)
+                    continue
+                elif 'typedef enum' in line:
+                    (ty_txt, en_txt, base_type) = line.strip().split(None, 2)
+                    #print("Found ENUM type %s" % base_type)
+                    parse_enum = True
+                    self.types_dict[base_type] = 'enum'
+                elif 'typedef struct' in line:
+                    (ty_txt, st_txt, base_type) = line.strip().split(None, 2)
+                    #print("Found STRUCT type: %s" % base_type)
+                    parse_struct = True
+                    self.types_dict[base_type] = 'struct'
+                elif '}' in line and (parse_enum or parse_struct):
+                    if len(line.split()) > 1: # deals with embedded union in one struct
+                        parse_enum = False
+                        parse_struct = False
+                        member_num = 0
+                        # TODO : Can pull target of typedef here for remapping
+                        (cur_char, targ_type) = line.strip().split(None, 1)
+                        self.typedef_fwd_dict[base_type] = targ_type.strip(';')
+                        self.typedef_rev_dict[targ_type.strip(';')] = base_type
+                elif parse_enum:
+                    if '=' in line:
+                        self._add_enum(line, base_type)
+                elif parse_struct:
+                    if ';' in line:
+                        self._add_struct(line, base_type, member_num)
+                        member_num = member_num + 1
+                #elif '(' in line:
+                    #print("Function: %s" % line)
+    
+    # populate enum dicts based on enum lines
+    def _add_enum(self, line_txt, enum_type):    
+        #print("Parsing enum line %s" % line_txt)
+        (enum_name, eq_char, enum_val) = line_txt.split(None, 2)
+        if '=' != eq_char:
+            print("ERROR: Couldn't parse enum line: %s" % line_txt)
+        self.enum_val_dict[enum_name] = {}
+        self.enum_val_dict[enum_name]['type'] = enum_type
+        # strip comma and comment, then extra split in case of no comma w/ comments
+        enum_val = enum_val.strip().split(',', 1)[0]
+        self.enum_val_dict[enum_name]['val'] = enum_val.split()[0]
+        # TODO : Make this more robust, to verify if enum value is unique
+        #  Currently just try to cast to int which works ok but missed -(HEX) values
+        try:
+            #print("ENUM val:", self.enum_val_dict[enum_name]['val'])
+            int(self.enum_val_dict[enum_name]['val'], 0)
+            self.enum_val_dict[enum_name]['unique'] = True
+            #print("ENUM has num value")
+        except ValueError:
+            self.enum_val_dict[enum_name]['unique'] = False
+            #print("ENUM is not a number value")
+        # Update enum_type_dict as well
+        if not enum_type in self.enum_type_dict:
+            self.enum_type_dict[enum_type] = []
+        self.enum_type_dict[enum_type].append(enum_name)
+    
+    # populate struct dicts based on struct lines
+    # TODO : Handle ":" bitfield, "**" ptr->ptr and "const type*const*"
+    def _add_struct(self, line_txt, struct_type, num):
+        #print("Parsing struct line %s" % line_txt)
+        if not struct_type in self.struct_dict:
+            self.struct_dict[struct_type] = {}
+        members = line_txt.strip().split(';', 1)[0] # first strip semicolon & comments
+        # TODO : Handle bitfields more correctly
+        members = members.strip().split(':', 1)[0] # strip bitfield element
+        (member_type, member_name) = members.rsplit(None, 1)
+        self.struct_dict[struct_type][num] = {}
+        self.struct_dict[struct_type][num]['full_type'] = member_type
+        if '*' in member_type:
+            self.struct_dict[struct_type][num]['ptr'] = True
+            member_type = member_type.strip('*')
+        else:
+            self.struct_dict[struct_type][num]['ptr'] = False
+        if 'const' in member_type:
+            self.struct_dict[struct_type][num]['const'] = True
+            member_type = member_type.strip('const').strip()
+        else:
+            self.struct_dict[struct_type][num]['const'] = False
+        if is_type(member_type, 'struct'):
+            self.struct_dict[struct_type][num]['struct'] = True
+        else:
+            self.struct_dict[struct_type][num]['struct'] = False
+        self.struct_dict[struct_type][num]['type'] = member_type
+        if '[' in member_name:
+            (member_name, array_size) = member_name.split('[', 1)
+            self.struct_dict[struct_type][num]['array'] = True
+            self.struct_dict[struct_type][num]['array_size'] = array_size.strip(']')
+        else:
+            self.struct_dict[struct_type][num]['array'] = False
+            self.struct_dict[struct_type][num]['array_size'] = 0
+        self.struct_dict[struct_type][num]['name'] = member_name
+
+# check if given identifier if of specified type_to_check
+def is_type(identifier, type_to_check):
+    #print("Checking if %s is type %s" % (identifier, type_to_check))
+    if identifier in types_dict and type_to_check == types_dict[identifier]:
+        return True
+    if identifier in typedef_rev_dict:
+        new_id = typedef_rev_dict[identifier]
+        if new_id in types_dict and type_to_check == types_dict[new_id]:
+            return True
+    return False
+
+def recreate_structs():
+    for struct_name in struct_dict:
+        sys.stdout.write("typedef struct %s\n{\n" % struct_name)
+        for mem_num in sorted(struct_dict[struct_name]):
+            sys.stdout.write("    ")
+            if struct_dict[struct_name][mem_num]['const']:
+                sys.stdout.write("const ")
+            #if struct_dict[struct_name][mem_num]['struct']:
+            #    sys.stdout.write("struct ")
+            sys.stdout.write (struct_dict[struct_name][mem_num]['type'])
+            if struct_dict[struct_name][mem_num]['ptr']:
+                sys.stdout.write("*")
+            sys.stdout.write(" ")
+            sys.stdout.write(struct_dict[struct_name][mem_num]['name'])
+            if struct_dict[struct_name][mem_num]['array']:
+                sys.stdout.write("[")
+                sys.stdout.write(struct_dict[struct_name][mem_num]['array_size'])
+                sys.stdout.write("]")
+            sys.stdout.write(";\n")
+        sys.stdout.write("} ")
+        sys.stdout.write(typedef_fwd_dict[struct_name])
+        sys.stdout.write(";\n\n")
+
+# class for writing common file elements
+# Here's how this class lays out a file:
+#  COPYRIGHT
+#  HEADER
+#  BODY
+#  FOOTER
+#
+# For each of these sections, there's a "set*" function
+# The class as a whole has a generate function which will write each section in order
+class CommonFileGen:
+    def __init__(self, filename=None, copyright_txt="", header_txt="", body_txt="", footer_txt=""):
+        self.filename = filename
+        self.contents = {'copyright': copyright_txt, 'header': header_txt, 'body': body_txt, 'footer': footer_txt}
+        # TODO : Set a default copyright & footer at least
+    
+    def setFilename(self, filename):
+        self.filename = filename
+        
+    def setCopyright(self, c):
+        self.contents['copyright'] = c
+        
+    def setHeader(self, h):
+        self.contents['header'] = h
+        
+    def setBody(self, b):
+        self.contents['body'] = b
+        
+    def setFooter(self, f):
+        self.contents['footer'] = f
+        
+    def generate(self):
+        #print("Generate to file %s" % self.filename)
+        with open(self.filename, "w") as f:
+            f.write(self.contents['copyright'])
+            f.write(self.contents['header'])
+            f.write(self.contents['body'])
+            f.write(self.contents['footer'])
+
+# class for writing a wrapper class for structures
+# The wrapper class wraps the structs and includes utility functions for
+#  setting/getting member values and displaying the struct data in various formats
+class StructWrapperGen:
+    def __init__(self, in_struct_dict, prefix, out_dir):
+        self.struct_dict = in_struct_dict
+        self.include_headers = []
+        self.api = prefix
+        self.header_filename = os.path.join(out_dir, self.api+"_struct_wrappers.h")
+        self.class_filename = os.path.join(out_dir, self.api+"_struct_wrappers.cpp")
+        self.string_helper_filename = os.path.join(out_dir, self.api+"_struct_string_helper.h")
+        self.hfg = CommonFileGen(self.header_filename)
+        self.cfg = CommonFileGen(self.class_filename)
+        self.shg = CommonFileGen(self.string_helper_filename)
+        #print(self.header_filename)
+        self.header_txt = ""
+        self.definition_txt = ""
+        
+    def set_include_headers(self, include_headers):
+        self.include_headers = include_headers
+
+    # Return class name for given struct name
+    def get_class_name(self, struct_name):
+        class_name = struct_name.strip('_').lower() + "_struct_wrapper"
+        return class_name
+        
+    def get_file_list(self):
+        return [os.path.basename(self.header_filename), os.path.basename(self.class_filename), os.path.basename(self.string_helper_filename)]
+
+    # Generate class header file        
+    def generateHeader(self):
+        self.hfg.setCopyright(self._generateCopyright())
+        self.hfg.setHeader(self._generateHeader())
+        self.hfg.setBody(self._generateClassDeclaration())
+        self.hfg.setFooter(self._generateFooter())
+        self.hfg.generate()
+    
+    # Generate class definition
+    def generateBody(self):
+        self.cfg.setCopyright(self._generateCopyright())
+        self.cfg.setHeader(self._generateCppHeader())
+        self.cfg.setBody(self._generateClassDefinition())
+        self.cfg.setFooter(self._generateFooter())
+        self.cfg.generate()
+
+    # Generate c-style .h file that contains functions for printing structs
+    def generateStringHelper(self):
+        print("Generating struct string helper")
+        self.shg.setCopyright(self._generateCopyright())
+        self.shg.setHeader(self._generateHeader())
+        self.shg.setBody(self._generateStringHelperFunctions())
+        self.shg.generate()
+
+    def _generateCopyright(self):
+        return "//This is the copyright\n"
+
+    def _generateCppHeader(self):
+        header = []
+        header.append("//#includes, #defines, globals and such...\n")
+        header.append("#include <stdio.h>\n#include <%s>\n#include <%s_string_helper.h>\n" % (os.path.basename(self.header_filename), self.api))
+        return "".join(header)
+        
+    def _generateClassDefinition(self):
+        class_def = []
+        if 'xgl' == self.api: # Mantle doesn't have pNext to worry about
+            class_def.append(self._generateDynamicPrintFunctions())
+        for s in self.struct_dict:
+            class_def.append("\n// %s class definition" % self.get_class_name(s))
+            class_def.append(self._generateConstructorDefinitions(s))
+            class_def.append(self._generateDestructorDefinitions(s))
+            class_def.append(self._generateDisplayDefinitions(s))
+        return "\n".join(class_def)
+        
+    def _generateConstructorDefinitions(self, s):
+        con_defs = []
+        con_defs.append("%s::%s() : m_struct(), m_indent(0), m_dummy_prefix('\\0'), m_origStructAddr(NULL) {}" % (self.get_class_name(s), self.get_class_name(s)))
+        # TODO : This is a shallow copy of ptrs
+        con_defs.append("%s::%s(%s* pInStruct) : m_indent(0), m_dummy_prefix('\\0')\n{\n    m_struct = *pInStruct;\n    m_origStructAddr = pInStruct;\n}" % (self.get_class_name(s), self.get_class_name(s), typedef_fwd_dict[s]))
+        con_defs.append("%s::%s(const %s* pInStruct) : m_indent(0), m_dummy_prefix('\\0')\n{\n    m_struct = *pInStruct;\n    m_origStructAddr = pInStruct;\n}" % (self.get_class_name(s), self.get_class_name(s), typedef_fwd_dict[s]))
+        return "\n".join(con_defs)
+        
+    def _generateDestructorDefinitions(self, s):
+        return "%s::~%s() {}" % (self.get_class_name(s), self.get_class_name(s))
+        
+    def _generateDynamicPrintFunctions(self):
+        dp_funcs = []
+        dp_funcs.append("\nvoid dynamic_display_full_txt(const XGL_VOID* pStruct, uint32_t indent)\n{\n    // Cast to APP_INFO ptr initially just to pull sType off struct")
+        dp_funcs.append("    XGL_STRUCTURE_TYPE sType = ((XGL_APPLICATION_INFO*)pStruct)->sType;    switch (sType)\n    {")
+        for e in enum_type_dict:
+            class_num = 0
+            if "_STRUCTURE_TYPE" in e:
+                for v in sorted(enum_type_dict[e]):
+                    struct_name = v.replace("_STRUCTURE_TYPE", "")
+                    class_name = self.get_class_name(struct_name)
+                    # TODO : Hand-coded fixes for some exceptions
+                    if 'XGL_PIPELINE_CB_STATE_CREATE_INFO' in struct_name:
+                        struct_name = 'XGL_PIPELINE_CB_STATE'
+                    elif 'XGL_SEMAPHORE_CREATE_INFO' in struct_name:
+                        struct_name = 'XGL_QUEUE_SEMAPHORE_CREATE_INFO'
+                        class_name = self.get_class_name(struct_name)
+                    elif 'XGL_SEMAPHORE_OPEN_INFO' in struct_name:
+                        struct_name = 'XGL_QUEUE_SEMAPHORE_OPEN_INFO'
+                        class_name = self.get_class_name(struct_name)
+                    instance_name = "swc%i" % class_num
+                    dp_funcs.append("        case %s:\n        {" % (v))
+                    dp_funcs.append("            %s %s((%s*)pStruct);" % (class_name, instance_name, struct_name))
+                    dp_funcs.append("            %s.set_indent(indent);" % (instance_name))
+                    dp_funcs.append("            %s.display_full_txt();" % (instance_name))
+                    dp_funcs.append("        }")
+                    dp_funcs.append("        break;")
+                    class_num += 1
+                dp_funcs.append("    }")
+        dp_funcs.append("}\n")
+        return "\n".join(dp_funcs)
+
+    def _get_sh_func_name(self, struct):
+        return "%s_print_%s" % (self.api, struct.lower().strip("_"))
+
+    # Return elements to create formatted string for given struct member
+    def _get_struct_print_formatted(self, struct_member, pre_var_name="prefix", postfix = "\\n", struct_var_name="pStruct", struct_ptr=True, print_array=False):
+        struct_op = "->"
+        if not struct_ptr:
+            struct_op = "."
+        member_name = struct_member['name']
+        print_type = "p"
+        cast_type = ""
+        member_post = ""
+        array_index = ""
+        member_print_post = ""
+        if struct_member['array'] and 'CHAR' in struct_member['type']: # just print char array as string
+            print_type = "s"
+            print_array = False
+        elif struct_member['array'] and not print_array:
+            # Just print base address of array when not full print_array
+            cast_type = "(void*)"
+        elif is_type(struct_member['type'], 'enum'):
+            cast_type = "string_%s" % struct_member['type']
+            print_type = "s"
+        elif is_type(struct_member['type'], 'struct'): # print struct address for now
+            cast_type = "(void*)"
+            if not struct_member['ptr']:
+                cast_type = "(void*)&"
+        elif 'BOOL' in struct_member['type']:
+            print_type = "s"
+            member_post = ' ? "TRUE" : "FALSE"'
+        elif 'FLOAT' in struct_member['type']:
+            print_type = "f"
+        elif 'UINT64' in struct_member['type']:
+            print_type = "lu"
+        elif 'UINT8' in struct_member['type']:
+            print_type = "hu"
+        elif True in [ui_str in struct_member['type'] for ui_str in ['UINT', '_SIZE', '_FLAGS', '_SAMPLE_MASK']]:
+            print_type = "u"
+        elif 'INT' in struct_member['type']:
+            print_type = "i"
+        elif struct_member['ptr']:
+            #cast_type = ""
+            pass
+        else:
+            #print("Unhandled struct type: %s" % struct_member['type'])
+            cast_type = "(void*)"
+        if print_array and struct_member['array']:
+            member_print_post = "[%u]"
+            array_index = " i,"
+            member_post = "[i]"
+        print_out = "%%s%s%s = %%%s%s" % (member_name, member_print_post, print_type, postfix) # section of print that goes inside of quotes
+        print_arg = ", %s,%s %s(%s%s%s)%s" % (pre_var_name, array_index, cast_type, struct_var_name, struct_op, member_name, member_post) # section of print passed to portion in quotes
+        return (print_out, print_arg)
+
+    def _generateStringHelperFunctions(self):
+        sh_funcs = []
+        # TODO : Need a nice way to unify all of the different struct type print formatting code
+        for s in self.struct_dict:
+            p_out = ""
+            p_args = ""
+            sh_funcs.append('char* %s(const %s* pStruct, const char* prefix)\n{\n    char* str;\n    str = (char*)malloc(sizeof(char)*1024);\n    sprintf(str, "' % (self._get_sh_func_name(s), typedef_fwd_dict[s]))
+            for m in sorted(self.struct_dict[s]):
+                (p_out1, p_args1) = self._get_struct_print_formatted(self.struct_dict[s][m])
+                p_out += p_out1
+                p_args += p_args1
+            p_out += '"'
+            p_args += ");\n    return str;\n}\n"
+            sh_funcs.append(p_out)
+            sh_funcs.append(p_args)
+        return "".join(sh_funcs)
+                
+        
+    def _genStructMemberPrint(self, member, s, array, struct_array):
+        (p_out, p_arg) = self._get_struct_print_formatted(self.struct_dict[s][member], pre_var_name="&m_dummy_prefix", struct_var_name="m_struct", struct_ptr=False, print_array=True)
+        extra_indent = ""
+        if array:
+            extra_indent = "    "
+        if is_type(self.struct_dict[s][member]['type'], 'struct'): # print struct address for now
+            struct_array.insert(0, self.struct_dict[s][member])
+        elif self.struct_dict[s][member]['ptr']:
+            # Special case for VOID* named "pNext"
+            if "VOID" in self.struct_dict[s][member]['type'] and "pNext" == self.struct_dict[s][member]['name']:
+                struct_array.insert(0, self.struct_dict[s][member])
+        return ('    %sprintf("%%*s    %s", m_indent, ""%s);' % (extra_indent, p_out, p_arg), struct_array)
+
+    def _generateDisplayDefinitions(self, s):
+        disp_def = []
+        struct_array = []
+        # Single-line struct print function
+        disp_def.append("// Output 'structname = struct_address' on a single line")
+        disp_def.append("void %s::display_single_txt()\n{" % self.get_class_name(s))
+        disp_def.append('    printf(" %%*s%s = %%p", m_indent, "", (void*)m_origStructAddr);' % typedef_fwd_dict[s])
+        disp_def.append("}\n")
+        # Private helper function to print struct members
+        disp_def.append("// Private helper function that displays the members of the wrapped struct")
+        disp_def.append("void %s::display_struct_members()\n{" % self.get_class_name(s))
+        i_declared = False
+        for member in sorted(self.struct_dict[s]):
+            # TODO : Need to display each member based on its type
+            # TODO : Need to handle pNext which are structs, but of XGL_VOID* type
+            #   Can grab struct type off of header of struct pointed to
+            # TODO : Handle Arrays
+            if self.struct_dict[s][member]['array']:
+                # Create for loop to print each element of array
+                if not i_declared:
+                    disp_def.append('    uint32_t i;')
+                    i_declared = True
+                disp_def.append('    for (i = 0; i<%s; i++) {' % self.struct_dict[s][member]['array_size'])
+                (return_str, struct_array) = self._genStructMemberPrint(member, s, True, struct_array)
+                disp_def.append(return_str)
+                disp_def.append('    }')
+            else:
+                (return_str, struct_array) = self._genStructMemberPrint(member, s, False, struct_array)
+                disp_def.append(return_str)
+        disp_def.append("}\n")
+        i_declared = False
+        # Basic print function to display struct members
+        disp_def.append("// Output all struct elements, each on their own line")
+        disp_def.append("void %s::display_txt()\n{" % self.get_class_name(s))
+        disp_def.append('    printf("%%*s%s struct contents at %%p:\\n", m_indent, "", (void*)m_origStructAddr);' % typedef_fwd_dict[s])
+        disp_def.append('    this->display_struct_members();')
+        disp_def.append("}\n")
+        # Advanced print function to display current struct and contents of any pointed-to structs
+        disp_def.append("// Output all struct elements, and for any structs pointed to, print complete contents")
+        disp_def.append("void %s::display_full_txt()\n{" % self.get_class_name(s))
+        disp_def.append('    printf("%%*s%s struct contents at %%p:\\n", m_indent, "", (void*)m_origStructAddr);' % typedef_fwd_dict[s])
+        disp_def.append('    this->display_struct_members();')
+        class_num = 0
+        # TODO : Need to handle arrays of structs here
+        for ms in struct_array:
+            swc_name = "class%s" % str(class_num)
+            if ms['array']:
+                if not i_declared:
+                    disp_def.append('    uint32_t i;')
+                    i_declared = True
+                disp_def.append('    for (i = 0; i<%s; i++) {' % ms['array_size'])
+                #disp_def.append("        if (m_struct.%s[i]) {" % (ms['name']))
+                disp_def.append("            %s %s(&(m_struct.%s[i]));" % (self.get_class_name(ms['type']), swc_name, ms['name']))
+                disp_def.append("            %s.set_indent(m_indent + 4);" % (swc_name))
+                disp_def.append("            %s.display_full_txt();" % (swc_name))
+                #disp_def.append('        }')
+                disp_def.append('    }')
+            elif 'pNext' == ms['name']:
+                # Need some code trickery here
+                #  I'm thinking have a generated function that takes pNext ptr value
+                #  then it checks sType and in large switch statement creates appropriate
+                #  wrapper class type and then prints contents
+                disp_def.append("    if (m_struct.%s) {" % (ms['name']))
+                #disp_def.append('        printf("%*s    This is where we would call dynamic print function\\n", m_indent, "");')
+                disp_def.append('        dynamic_display_full_txt(m_struct.%s, m_indent);' % (ms['name']))
+                disp_def.append("    }")
+            else:
+                if ms['ptr']:
+                    disp_def.append("    if (m_struct.%s) {" % (ms['name']))
+                    disp_def.append("        %s %s(m_struct.%s);" % (self.get_class_name(ms['type']), swc_name, ms['name']))
+                else:
+                    disp_def.append("    if (&m_struct.%s) {" % (ms['name']))
+                    disp_def.append("        %s %s(&m_struct.%s);" % (self.get_class_name(ms['type']), swc_name, ms['name']))
+                disp_def.append("        %s.set_indent(m_indent + 4);" % (swc_name))
+                disp_def.append("        %s.display_full_txt();\n    }" % (swc_name))
+            class_num += 1
+        disp_def.append("}\n")
+        return "\n".join(disp_def)
+        
+    def _generateHeader(self):
+        header = []
+        header.append("//#includes, #defines, globals and such...\n")
+        for f in self.include_headers:
+            header.append("#include <%s>\n" % f)
+        return "".join(header)
+    
+    # Declarations
+    def _generateConstructorDeclarations(self, s):
+        constructors = []
+        constructors.append("    %s();\n" % self.get_class_name(s))
+        constructors.append("    %s(%s* pInStruct);\n" % (self.get_class_name(s), typedef_fwd_dict[s]))
+        constructors.append("    %s(const %s* pInStruct);\n" % (self.get_class_name(s), typedef_fwd_dict[s]))
+        return "".join(constructors)
+    
+    def _generateDestructorDeclarations(self, s):
+        return "    virtual ~%s();\n" % self.get_class_name(s)
+        
+    def _generateDisplayDeclarations(self, s):
+        return "    void display_txt();\n    void display_single_txt();\n    void display_full_txt();\n"
+        
+    def _generateGetSetDeclarations(self, s):
+        get_set = []
+        get_set.append("    void set_indent(uint32_t indent) { m_indent = indent; }\n")
+        for member in sorted(self.struct_dict[s]):
+            # TODO : Skipping array set/get funcs for now
+            if self.struct_dict[s][member]['array']:
+                continue
+            get_set.append("    %s get_%s() { return m_struct.%s; }\n" % (self.struct_dict[s][member]['full_type'], self.struct_dict[s][member]['name'], self.struct_dict[s][member]['name']))
+            if not self.struct_dict[s][member]['const']:
+                get_set.append("    void set_%s(%s inValue) { m_struct.%s = inValue; }\n" % (self.struct_dict[s][member]['name'], self.struct_dict[s][member]['full_type'], self.struct_dict[s][member]['name']))
+        return "".join(get_set)
+    
+    def _generatePrivateMembers(self, s):
+        priv = []
+        priv.append("\nprivate:\n")
+        priv.append("    %s m_struct;\n" % typedef_fwd_dict[s])
+        priv.append("    const %s* m_origStructAddr;\n" % typedef_fwd_dict[s])
+        priv.append("    uint32_t m_indent;\n")
+        priv.append("    const char m_dummy_prefix;\n")
+        priv.append("    void display_struct_members();\n")
+        return "".join(priv)
+    
+    def _generateClassDeclaration(self):
+        class_decl = []
+        for s in self.struct_dict:
+            class_decl.append("\n//class declaration")
+            class_decl.append("class %s\n{\npublic:" % self.get_class_name(s))
+            class_decl.append(self._generateConstructorDeclarations(s))
+            class_decl.append(self._generateDestructorDeclarations(s))
+            class_decl.append(self._generateDisplayDeclarations(s))
+            class_decl.append(self._generateGetSetDeclarations(s))
+            class_decl.append(self._generatePrivateMembers(s))
+            class_decl.append("};\n")
+        return "\n".join(class_decl)
+        
+    def _generateFooter(self):
+        return "\n//any footer info for class\n"
+
+class EnumCodeGen:
+    def __init__(self, enum_type_dict=None, enum_val_dict=None, typedef_fwd_dict=None, in_file=None, out_file=None):
+        self.et_dict = enum_type_dict
+        self.ev_dict = enum_val_dict
+        self.tf_dict = typedef_fwd_dict
+        self.in_file = in_file
+        self.out_file = out_file
+        self.efg = CommonFileGen(self.out_file)
+        
+    def generateStringHelper(self):
+        self.efg.setHeader(self._generateSHHeader())
+        self.efg.setBody(self._generateSHBody())
+        self.efg.generate()
+    
+    def _generateSHBody(self):
+        body = []
+#        with open(self.out_file, "a") as hf:
+            # bet == base_enum_type, fet == final_enum_type
+        for bet in self.et_dict:
+            fet = self.tf_dict[bet]
+            body.append("static const char* string_%s(%s input_value)\n{\n    switch ((%s)input_value)\n    {\n" % (fet, fet, fet))
+            for e in sorted(self.et_dict[bet]):
+                if (self.ev_dict[e]['unique']):
+                    body.append('    case %s:\n        return "%s";\n' % (e, e))
+            body.append('    }\n    return "Unhandled %s";\n}\n\n' % fet)
+        return "\n".join(body)
+    
+    def _generateSHHeader(self):
+        return "#pragma once\n\n#include <%s>\n\n" % self.in_file
+        
+
+class CMakeGen:
+    def __init__(self, struct_wrapper=None, out_dir=None):
+        self.sw = struct_wrapper
+        self.add_lib_file_list = self.sw.get_file_list()
+        self.out_dir = out_dir
+        self.out_file = os.path.join(self.out_dir, "CMakeLists.txt")
+        self.cmg = CommonFileGen(self.out_file)
+        
+    def generate(self):
+        self.cmg.setBody(self._generateBody())
+        self.cmg.generate()
+        
+    def _generateBody(self):
+        body = []
+        body.append("project(%s)" % os.path.basename(self.out_dir))
+        body.append("cmake_minimum_required(VERSION 2.8)\n")
+        body.append("add_library(${PROJECT_NAME} %s)\n" % " ".join(self.add_lib_file_list))
+        body.append('set(COMPILE_FLAGS "-fpermissive")')
+        body.append('set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}")\n')
+        body.append("include_directories(${SRC_DIR}/thirdparty/${GEN_API}/inc/)\n")
+        body.append("target_include_directories (%s PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})\n" % os.path.basename(self.out_dir))
+        return "\n".join(body)
+
+class GraphVizGen:
+    def __init__(self, struct_dict=None):
+        self.struc_dict = struct_dict
+        self.out_file = os.path.join(os.getcwd(), "struct_gv.dot")
+        self.gvg = CommonFileGen(self.out_file)
+        
+    def generate(self):
+        self.gvg.setHeader(self._generateHeader())
+        self.gvg.setBody(self._generateBody())
+        self.gvg.setFooter('}')
+        self.gvg.generate()
+        
+    def _generateHeader(self):
+        hdr = []
+        hdr.append('digraph g {\ngraph [\nrankdir = "LR"\n];')
+        hdr.append('node [\nfontsize = "16"\nshape = "plaintext"\n];')
+        hdr.append('edge [\n];\n')
+        return "\n".join(hdr)
+        
+    def _generateBody(self):
+        body = []
+        for s in self.struc_dict:
+            field_num = 1
+            body.append('"%s" [\nlabel = <<TABLE BORDER="0" CELLBORDER="1" CELLSPACING="0"> <TR><TD COLSPAN="2" PORT="f0">%s</TD></TR>' % (s, typedef_fwd_dict[s]))
+            for m in sorted(self.struc_dict[s]):
+                body.append('<TR><TD PORT="f%i">%s</TD><TD PORT="f%i">%s</TD></TR>' % (field_num, self.struc_dict[s][m]['full_type'], field_num+1, self.struc_dict[s][m]['name']))
+                field_num += 2
+            body.append('</TABLE>>\n];\n')
+        return "".join(body)
+                
+
+def main(argv=None):
+    opts = handle_args()
+    # Parse input file and fill out global dicts
+    hfp = HeaderFileParser(opts.input_file)
+    hfp.parse()
+    # TODO : Don't want these to be global, see note at top about wrapper classes
+    global enum_val_dict
+    global enum_type_dict
+    global struct_dict
+    global typedef_fwd_dict
+    global typedef_rev_dict
+    global types_dict
+    enum_val_dict = hfp.get_enum_val_dict()
+    enum_type_dict = hfp.get_enum_type_dict()
+    struct_dict = hfp.get_struct_dict()
+    typedef_fwd_dict = hfp.get_typedef_fwd_dict()
+    typedef_rev_dict = hfp.get_typedef_rev_dict()
+    types_dict = hfp.get_types_dict()
+    #print(enum_val_dict)
+    #print(typedef_dict)
+    #print(struct_dict)
+    if (opts.abs_out_dir is not None):
+        enum_filename = os.path.join(opts.abs_out_dir, os.path.basename(opts.input_file).strip(".h")+"_string_helper.h")
+    else:
+        enum_filename = os.path.join(os.getcwd(), opts.rel_out_dir, os.path.basename(opts.input_file).strip(".h")+"_string_helper.h")
+    enum_filename = os.path.abspath(enum_filename)
+    if not os.path.exists(os.path.dirname(enum_filename)):
+        print("Creating output dir %s" % os.path.dirname(enum_filename))
+        os.mkdir(os.path.dirname(enum_filename))
+    print("Generating enum string helper to %s" % enum_filename)
+    eg = EnumCodeGen(enum_type_dict, enum_val_dict, typedef_fwd_dict, os.path.basename(opts.input_file), enum_filename)
+    eg.generateStringHelper()
+    #for struct in struct_dict:
+    #print(struct)
+    sw = StructWrapperGen(struct_dict, os.path.basename(opts.input_file).strip(".h"), os.path.dirname(enum_filename))
+    #print(sw.get_class_name(struct))
+    sw.set_include_headers([os.path.basename(opts.input_file),os.path.basename(enum_filename),"stdint.h","stdio.h","stdlib.h"])
+    print("Generating struct wrapper header to %s" % sw.header_filename)
+    sw.generateHeader()
+    print("Generating struct wrapper class to %s" % sw.class_filename)
+    sw.generateBody()
+    sw.generateStringHelper()
+    cmg = CMakeGen(sw, os.path.dirname(enum_filename))
+    cmg.generate()
+    print("DONE! Check out the file, but we're still early so assume something's probably not quite right. :)")
+    gv = GraphVizGen(struct_dict)
+    gv.generate()
+    #print(typedef_rev_dict)
+    #print(types_dict)
+    #recreate_structs()
+
+if __name__ == "__main__":
+    sys.exit(main())
+    
+    
+## Example class for GR_APPLICATION_INFO struct
+##include <mantle.h>    
+#    
+#class gr_application_info_struct_wrapper {
+#public:
+#    // Constructors
+#    gr_application_info_struct_wrapper();
+#    gr_application_info_struct_wrapper(GR_APPLICATION_INFO* pInStruct);
+#    // Destructor
+#    virtual ~gr_application_info_struct_wrapper();
+#    
+#    void display_txt()
+#    // get functions    
+#    // set functions for every non-const struct member
+#        
+#private:
+#    GR_APPLICATION_INFO m_struct;
+#};
+#
+#gr_application_info_struct_wrapper::gr_application_info_struct_wrapper() : m_struct() {}
+#
+#// Output struct address on single line
+#gr_application_info_struct_wrapper::display_single_txt()
+#{
+#    printf(" GR_APPLICATION_INFO = %p", &m_struct);
+#}
+#// Output struct in txt format
+#gr_application_info_struct_wrapper::display_txt()
+#{
+#    printf("GR_APPLICATION_INFO struct contents:\n");
+#    printf("    pAppName: %s\n", m_struct.pAppName);
+#    printf("    appVersion: %i\n", m_struct.appVersion);
+#    printf("    pEngineNmae: %s\n", m_struct.pEngineName);
+#    printf("    engineVersion: %i\n", m_struct.engineVersion);
+#    printf("    apiVersion: %i\n", m_struct.apiVersion);
+#}
+#// Output struct including detailed info on pointed-to structs
+#gr_application_info_struct_wrapper::display_full_txt()
+#{
+#    
+#    printf("%*s%GR_APPLICATION_INFO struct contents:\n", indent, "");
+#    printf("    pAppName: %s\n", m_struct.pAppName);
+#    printf("    appVersion: %i\n", m_struct.appVersion);
+#    printf("    pEngineNmae: %s\n", m_struct.pEngineName);
+#    printf("    engineVersion: %i\n", m_struct.engineVersion);
+#    printf("    apiVersion: %i\n", m_struct.apiVersion);
+#}
+
+
+# Example of helper function to pretty-print enum info
+#static const char* string_GR_RESULT_CODE(GR_RESULT result)
+#{
+#    switch ((GR_RESULT_CODE)result)
+#    {
+#    // Return codes for successful operation execution
+#    case GR_SUCCESS:
+#        return "GR_SUCCESS";
+#    case GR_UNSUPPORTED:
+#        return "GR_UNSUPPORTED";
+#    case GR_NOT_READY:
+#        return "GR_NOT_READY";
+#    case GR_TIMEOUT:
+#        return "GR_TIMEOUT";
+#    }
+#    return "Unhandled GR_RESULT_CODE";
+#}
+
+# Dynamic print function
+# void dynamic_display_full_txt(XGL_STRUCTURE_TYPE sType, void* pStruct, uint32_t indent)
+# {
+#     switch (sType)
+#     {
+#         case XGL_STRUCTURE_TYPE_COLOR_BLEND_STATE_CREATE_INFO:
+#             xgl_color_blend_state_create_info_struct_wrapper swc((XGL_COLOR_BLEND_STATE_CREATE_INFO*)pStruct);
+#             swc.set_indent(indent);
+#             swc.display_full_txt();
+#     }
+# }
diff --git a/tools/glave/src/LICENSE b/tools/glave/src/LICENSE
new file mode 100644
index 0000000..4f04ead
--- /dev/null
+++ b/tools/glave/src/LICENSE
@@ -0,0 +1,22 @@
+Copyright 2014 Valve Software
+
+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.
+
diff --git a/tools/glave/src/build_options.cmake b/tools/glave/src/build_options.cmake
new file mode 100644
index 0000000..b258152
--- /dev/null
+++ b/tools/glave/src/build_options.cmake
@@ -0,0 +1,503 @@
+#
+# cmake -DCMAKE_BUILD_TYPE=Debug ..
+#
+#   http://www.cmake.org/Wiki/CMake_FAQ
+#   http://www.cmake.org/Wiki/CMake_Useful_Variables
+#   http://clang.llvm.org/docs/LanguageExtensions.html
+#
+#
+cmake_minimum_required(VERSION 2.8)
+
+set(BUILD_X64 "" CACHE STRING "whether to perform 64-bit build: ON or OFF overrides default detection")
+
+option(CMAKE_VERBOSE "Verbose CMake" FALSE)
+if (CMAKE_VERBOSE)
+    SET(CMAKE_VERBOSE_MAKEFILE ON)
+endif()
+
+# With gcc48: http://indico.cern.ch/getFile.py/access?contribId=1&resId=0&materialId=slides&confId=230762
+
+option(WITH_HARDENING "Enable hardening: Compile-time protection against static sized buffer overflows" OFF)
+
+# Unless user specifies BUILD_X64 explicitly, assume native target
+if (BUILD_X64 STREQUAL "")
+  if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    set(BUILD_X64 "TRUE")
+  else()
+    set(BUILD_X64 "FALSE")
+  endif()
+endif()
+
+# Generate bitness suffix to use, but make sure to include the existing suffix (.exe) 
+# for platforms that need it (ie, Windows)
+if (BUILD_X64)
+    set(CMAKE_EXECUTABLE_SUFFIX "64${CMAKE_EXECUTABLE_SUFFIX}")
+    set(CMAKE_SHARED_LIBRARY_SUFFIX "64${CMAKE_SHARED_LIBRARY_SUFFIX}")
+else()
+    set(CMAKE_EXECUTABLE_SUFFIX "32${CMAKE_EXECUTABLE_SUFFIX}")
+    set(CMAKE_SHARED_LIBRARY_SUFFIX "32${CMAKE_SHARED_LIBRARY_SUFFIX}")
+endif()
+
+# Default to release build
+if (NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE Release)
+endif()
+
+# Make sure we're using 64-bit versions of stat, fopen, etc.
+# Large File Support extensions:
+#   http://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html#Feature-Test-Macros
+add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES)
+
+# support for inttypes.h macros
+add_definitions(-D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS)
+
+if(MSVC)
+    set(CMAKE_CXX_FLAGS_LIST "/W3 /D_CRT_SECURE_NO_WARNINGS=1 /DWIN32 /D_WIN32")
+    set(CMAKE_CXX_FLAGS_RELEASE_LIST "/O2 /DNDEBUG")
+    set(CMAKE_CXX_FLAGS_DEBUG_LIST "/Od /D_DEBUG")
+else()
+    set(CMAKE_CXX_FLAGS_LIST "-g -Wall -Wextra")
+    set(CMAKE_CXX_FLAGS_RELEASE_LIST "-g -O2 -DNDEBUG")
+    set(CMAKE_CXX_FLAGS_DEBUG_LIST "-g -O0 -D_DEBUG")
+endif()
+
+
+if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+
+  # clang doesn't print colored diagnostics when invoked from Ninja
+  if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja")
+      add_definitions ("-fcolor-diagnostics")
+  endif()
+
+  if (CLANG_EVERYTHING)
+      set(CMAKE_CXX_FLAGS_LIST ${CMAKE_CXX_FLAGS_LIST}
+          # "-pedantic"             # Warn on language extensions
+          "-Weverything"            # Enable all warnings
+          "-fdiagnostics-show-category=name"
+          "-Wno-unused-macros"
+          "-Wno-padded"
+          "-Wno-variadic-macros"
+          "-Wno-missing-variable-declarations"
+          "-Wno-missing-prototypes"
+          "-Wno-sign-conversion"
+          "-Wno-conversion"
+          "-Wno-cast-align"
+          "-Wno-exit-time-destructors"
+          "-Wno-documentation-deprecated-sync"
+          "-Wno-documentation-unknown-command"
+
+          # TODO: Would be great to start enabling some of these warnings...
+          "-Wno-undefined-reinterpret-cast"
+          "-Wno-incompatible-pointer-types-discards-qualifiers"
+          "-Wno-float-equal"
+          "-Wno-unreachable-code"
+          "-Wno-weak-vtables"
+          "-Wno-extra-semi"
+          "-Wno-disabled-macro-expansion"
+          "-Wno-format-nonliteral"
+          "-Wno-packed"
+          "-Wno-c++11-long-long"
+          "-Wno-c++11-extensions"
+          "-Wno-gnu-anonymous-struct"
+          "-Wno-gnu-zero-variadic-macro-arguments"
+          "-Wno-nested-anon-types"
+          "-Wno-gnu-redeclared-enum"
+
+          "-Wno-pedantic"
+          "-Wno-header-hygiene"
+          "-Wno-covered-switch-default"
+          "-Wno-duplicate-enum"
+          "-Wno-switch-enum"
+          "-Wno-extra-tokens"
+
+          # Added because SDL2 headers have a ton of Doxygen warnings currently.
+          "-Wno-documentation"
+
+          )
+  endif()
+
+endif()
+
+
+if ((NOT MSVC) AND (NOT BUILD_X64) AND (CMAKE_SIZEOF_VOID_P EQUAL 8))
+    set(CMAKE_CXX_FLAGS_LIST "${CMAKE_CXX_FLAGS_LIST} -m32")
+    set(CMAKE_EXE_LINK_FLAGS_LIST "${CMAKE_EXE_LINK_FLAGS_LIST} -m32")
+    set(CMAKE_SHARED_LINK_FLAGS_LIST "${CMAKE_SHARED_LINK_FLAGS_LIST} -m32")
+
+    set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS OFF)
+    set(CMAKE_SYSTEM_LIBRARY_PATH /lib32 /usr/lib32 /usr/lib/i386-linux-gnu /usr/local/lib32)
+    set(CMAKE_IGNORE_PATH /lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib64 /usr/local/lib)
+endif()
+
+function(add_compiler_flag flag)
+    set(CMAKE_C_FLAGS    "${CMAKE_C_FLAGS}   ${flag}" PARENT_SCOPE)
+    set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE)
+endfunction()
+
+function(add_compiler_flag_debug flag)
+    set(CMAKE_C_FLAGS_DEBUG    "${CMAKE_C_FLAGS_DEBUG}   ${flag}" PARENT_SCOPE)
+    set(CMAKE_CXX_FLAGS_DEBUG  "${CMAKE_CXX_FLAGS_DEBUG} ${flag}" PARENT_SCOPE)
+endfunction()
+
+function(add_compiler_flag_release flag)
+    set(CMAKE_C_FLAGS_RELEASE    "${CMAKE_C_FLAGS_RELEASE}   ${flag}" PARENT_SCOPE)
+    set(CMAKE_CXX_FLAGS_RELEASE  "${CMAKE_CXX_FLAGS_RELEASE} ${flag}" PARENT_SCOPE)
+endfunction()
+
+
+function(add_linker_flag flag)
+    set(CMAKE_EXE_LINKER_FLAGS   "${CMAKE_EXE_LINKER_FLAGS} ${flag}" PARENT_SCOPE)
+endfunction()
+
+function(add_shared_linker_flag flag)
+    set(CMAKE_SHARED_LINKER_FLAGS   "${CMAKE_SHARED_LINKER_FLAGS} ${flag}" PARENT_SCOPE)
+endfunction()
+
+#
+# To show the include files as you're building, do this:
+#    add_compiler_flag("-H")
+# For Visual Studio, it's /showIncludes I believe...
+#
+
+# stack-protector-strong: http://gcc.gnu.org/ml/gcc-patches/2012-06/msg00974.html
+## -fstack-protector-strong
+# Compile with the option "-fstack-usage" and a file .su will be generated with stack
+# information for each function.
+## -fstack-usage
+
+# For more info on -fno-strict-aliasing: "Just Say No to strict aliasing optimizations in C": http://nothings.org/
+# The Linux kernel is compiled with -fno-strict-aliasing: https://lkml.org/lkml/2003/2/26/158 or http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg01647.html
+
+### TODO: see if sse is generated with these instructions and clang:
+## -march=corei7 -msse -mfpmath=sse
+
+set(MARCH_STR "-march=corei7")
+if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+   if ( NOT BUILD_X64 )
+      # Fix startup crash in dlopen_notify_callback (called indirectly from our dlopen() function) when tracing glxspheres on my AMD dev box (x86 release only)
+      # Also fixes tracing Q3 Arena using release tracer
+      # Clang is generating sse2 code even when it shouldn't be:
+      #  http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-March/020310.html
+      set(MARCH_STR "-march=i586")
+   endif()
+endif()
+
+if(MSVC)
+    set(CMAKE_CXX_FLAGS_LIST
+        ${CMAKE_CXX_FLAGS_LIST}
+        "/EHsc" # Need exceptions
+    )
+else()
+    set(CMAKE_CXX_FLAGS_LIST
+        ${CMAKE_CXX_FLAGS_LIST}
+        "-fno-omit-frame-pointer"
+        ${MARCH_STR}
+        # "-msse2 -mfpmath=sse" # To build with SSE instruction sets
+        "-Wno-unused-parameter -Wno-unused-function"
+        "-fno-strict-aliasing" # DO NOT remove this, we have lots of code that will fail in obscure ways otherwise because it was developed with MSVC first.
+        "-fno-math-errno"
+    	  "-fvisibility=hidden"
+        # "-fno-exceptions" # Exceptions are enabled by default for c++ files, disabled for c files.
+    )
+endif()
+
+if (CMAKE_COMPILER_IS_GNUCC)
+    execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
+    string(REGEX MATCHALL "[0-9]+" GCC_VERSION_COMPONENTS ${GCC_VERSION})
+    list(GET GCC_VERSION_COMPONENTS 0 GCC_MAJOR)
+    list(GET GCC_VERSION_COMPONENTS 1 GCC_MINOR)
+    # message(STATUS "Detected GCC v ${GCC_MAJOR} . ${GCC_MINOR}")
+endif()
+
+if (GCC_VERSION VERSION_GREATER 4.8 OR GCC_VERSION VERSION_EQUAL 4.8)
+    set(CMAKE_CXX_FLAGS_LIST ${CMAKE_CXX_FLAGS_LIST}
+        "-Wno-unused-local-typedefs"
+    )
+endif()
+
+if (MSVC)
+else()
+    if (WITH_HARDENING)
+        # http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02055.html
+        add_definitions(-D_FORTIFY_SOURCE=2 -fpic)
+        if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+            # During program load, several ELF memory sections need to be written to by the
+            # linker, but can be turned read-only before turning over control to the
+            # program. This prevents some GOT (and .dtors) overwrite attacks, but at least
+            # the part of the GOT used by the dynamic linker (.got.plt) is still vulnerable.
+            add_definitions(-pie -z now -z relro)
+        endif()
+    endif()
+endif()
+
+if (NOT MSVC)
+    set(CMAKE_EXE_LINK_FLAGS_LIST "-Wl,--no-undefined")
+
+endif()
+
+# Compiler flags
+string(REPLACE ";" " " CMAKE_C_FLAGS              "${CMAKE_CXX_FLAGS_LIST}")
+string(REPLACE ";" " " CMAKE_C_FLAGS_RELEASE      "${CMAKE_CXX_FLAGS_RELEASE_LIST}")
+string(REPLACE ";" " " CMAKE_C_FLAGS_DEBUG        "${CMAKE_CXX_FLAGS_DEBUG_LIST}")
+
+string(REPLACE ";" " " CMAKE_CXX_FLAGS            "${CMAKE_CXX_FLAGS_LIST}")
+string(REPLACE ";" " " CMAKE_CXX_FLAGS_RELEASE    "${CMAKE_CXX_FLAGS_RELEASE_LIST}")
+string(REPLACE ";" " " CMAKE_CXX_FLAGS_DEBUG      "${CMAKE_CXX_FLAGS_DEBUG_LIST}")
+
+# Linker flags (exe)
+string(REPLACE ";" " " CMAKE_EXE_LINKER_FLAGS     "${CMAKE_EXE_LINK_FLAGS_LIST}")
+# Linker flags (shared)
+string(REPLACE ";" " " CMAKE_SHARED_LINKER_FLAGS  "${CMAKE_SHARED_LINK_FLAGS_LIST}")
+
+# If building from inside chroot project, use glv_build there.
+if (EXISTS "${CMAKE_SOURCE_DIR}/../bin/chroot_build.sh")
+    set(RADPROJ_BUILD_DIR ${CMAKE_SOURCE_DIR}/../glv_build)
+else()
+    set(RADPROJ_BUILD_DIR ${CMAKE_SOURCE_DIR}/glv_build)
+endif()
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${RADPROJ_BUILD_DIR})
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${RADPROJ_BUILD_DIR})
+
+function(build_options_finalize)
+    if (CMAKE_VERBOSE)
+        message("  CMAKE_PROJECT_NAME: ${CMAKE_PROJECT_NAME}")
+        message("  PROJECT_NAME: ${PROJECT_NAME}")
+        message("  BUILD_X64: ${BUILD_X64}")
+        message("  BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
+        message("  PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR}")
+        message("  CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
+        message("  PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
+        message("  CMAKE_CURRENT_LIST_FILE: ${CMAKE_CURRENT_LIST_FILE}")
+        message("  CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
+        message("  CXX_FLAGS_RELEASE: ${CMAKE_CXX_FLAGS_RELEASE}")
+        message("  CXX_FLAGS_DEBUG: ${CMAKE_CXX_FLAGS_DEBUG}")
+        message("  EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
+        message("  SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}")
+        message("  SHARED_LIBRARY_C_FLAGS: ${CMAKE_SHARED_LIBRARY_C_FLAGS}")
+        message("  SHARED_LIBRARY_CXX_FLAGS: ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}")
+        message("  SHARED_LIBRARY_LINK_CXX_FLAGS: ${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS}")
+        message("  SHARED_LIBRARY_LINK_C_FLAGS: ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS}")
+        message("  CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
+        message("  CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")
+        message("  CMAKE_C_COMPILER_ID: ${CMAKE_C_COMPILER_ID}")
+        message("  CMAKE_EXECUTABLE_SUFFIX: ${CMAKE_EXECUTABLE_SUFFIX}")
+        message("")
+    endif()
+endfunction()
+
+function(require_pthreads)
+    find_package(Threads)
+    if (NOT CMAKE_USE_PTHREADS_INIT AND NOT WIN32_PTHREADS_INCLUDE_PATH)
+        message(FATAL_ERROR "pthread not found")
+    endif()
+
+    if (MSVC)
+        include_directories("${WIN32_PTHREADS_INCLUDE_PATH}")
+        if (BUILD_X64)
+            set(PTHREAD_SRC_LIB "${WIN32_PTHREADS_PATH}/lib/x64/pthreadVC2.lib" PARENT_SCOPE)
+            set(PTHREAD_SRC_DLL "${WIN32_PTHREADS_PATH}/dll/x64/pthreadVC2.dll" PARENT_SCOPE)
+        else()
+            set(PTHREAD_SRC_LIB "${WIN32_PTHREADS_PATH}/lib/x86/pthreadVC2.lib" PARENT_SCOPE)
+            set(PTHREAD_SRC_DLL "${WIN32_PTHREADS_PATH}/dll/x86/pthreadVC2.dll" PARENT_SCOPE)
+        endif()
+
+    else()
+        # Export the variable to the parent scope so the linker knows where to find the library.
+        set(CMAKE_THREAD_LIBS_INIT ${CMAKE_THREAD_LIBS_INIT} PARENT_SCOPE)
+    endif()
+endfunction()
+
+function(require_libjpegturbo)
+    find_library(LibJpegTurbo_LIBRARY
+        NAMES libturbojpeg.so libturbojpeg.so.0 libturbojpeg.dylib
+        PATHS /opt/libjpeg-turbo/lib 
+    )
+
+    # On platforms that find this, the include files will have also been installed to the system
+    # so we don't need extra include dirs.
+    if (LibJpegTurbo_LIBRARY)
+        set(LibJpegTurbo_INCLUDE "" PARENT_SCOPE)
+    else()
+        if (BUILD_X64)
+            set(BITS_STRING "x64")
+        else()
+            set(BITS_STRING "x86")
+        endif()
+        set(LibJpegTurbo_INCLUDE "${CMAKE_PREFIX_PATH}/libjpeg-turbo-2.1.3/include" PARENT_SCOPE)
+        set(LibJpegTurbo_LIBRARY "${CMAKE_PREFIX_PATH}/libjpeg-turbo-2.1.3/lib_${BITS_STRING}/turbojpeg.lib" PARENT_SCOPE)
+    endif()
+endfunction()
+
+function(require_sdl2)
+    if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+        include(FindPkgConfig)
+        pkg_search_module(PC_SDL2 REQUIRED sdl2)
+
+        find_path(SDL2_INCLUDE SDL.h
+            DOC "SDL2 Include Path"
+	    HINTS ${PC_SDL2_INCLUDEDIR} ${PC_SDL2_INCLUDE_DIRS} )
+
+        find_library(SDL2_LIBRARY SDL2
+            DOC "SDL2 Library"
+	    HINTS ${PC_SDL2_LIBDIR} ${PC_SDL2_LIBRARY_DIRS} )
+    elseif (MSVC)
+        set(SDL2Root "${CMAKE_EXTERNAL_PATH}/SDL")
+
+        set(SDL2_INCLUDE "${SDL2Root}/include" CACHE PATH "SDL2 Include Path")
+        set(SDL2_LIBRARY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/SDL2.lib" CACHE FILEPATH "SDL2 Library")
+
+        # Only want to include this once.
+        # This has to go into properties because it needs to persist across the entire cmake run.
+        get_property(SDL_PROJECT_ALREADY_INCLUDED 
+            GLOBAL 
+            PROPERTY SDL_PROJECT_INCLUDED
+            )
+
+        if (NOT SDL_PROJECT_ALREADY_INCLUDED)
+            INCLUDE_EXTERNAL_MSPROJECT(SDL "${SDL2Root}/VisualC/SDL/SDL_VS2013.vcxproj")
+            set_property(GLOBAL
+                PROPERTY SDL_PROJECT_INCLUDED "TRUE"
+                )
+            message("Including SDL_VS2013.vcxproj for you!")
+        endif()
+
+    else()
+        message(FATAL_ERROR "Need to deal with SDL on non-Windows platforms")
+    endif()
+endfunction()
+
+function(require_m)
+    if (MSVC)
+	set(M_LIBRARY "winmm.lib" PARENT_SCOPE)
+    else()
+	set(M_LIBRARY "m" PARENT_SCOPE)
+    endif()
+endfunction()
+
+function(require_gl)
+    if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+	include(FindPkgConfig)
+	pkg_search_module(PC_GL QUIET gl)
+
+	find_path(GL_INCLUDE GL/gl.h
+	    DOC "OpenGL Include Path"
+	    HINTS ${PC_GL_INCLUDEDIR} ${PC_GL_INCLUDE_DIRS} )
+
+	find_library(GL_LIBRARY GL
+	    DOC "OpenGL Library"
+	    HINTS ${PC_GL_LIBDIR} ${PC_GL_LIBRARY_DIRS} )
+    elseif (MSVC)
+	set(GL_INCLUDE ""	      CACHE PATH "OpenGL Include Path")
+	set(GL_LIBRARY "opengl32.lib" CACHE FILEPATH "OpenGL Library")
+    else()
+	set(GL_INCLUDE ""   CACHE PATH "OpenGL Include Path")
+	set(GL_LIBRARY "GL" CACHE FILEPATH "OpenGL Library")
+    endif()
+endfunction()
+
+function(require_glu)
+    if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+	include(FindPkgConfig)
+	pkg_search_module(PC_GLU QUIET glu)
+
+	find_path(GLU_INCLUDE GL/glu.h
+	    DOC "GLU Include Path"
+	    HINTS ${PC_GLU_INCLUDEDIR} ${PC_GLU_INCLUDE_DIRS} )
+
+	find_library(GLU_LIBRARY GLU
+	    DOC "GLU Library"
+	    HINTS ${PC_GLU_LIBDIR} ${PC_GLU_LIBRARY_DIRS} )
+    elseif (MSVC)
+	set(GLU_INCLUDE ""	    CACHE PATH "GLU Include Path")
+	set(GLU_LIBRARY "glu32.lib" CACHE FILEPATH "GLU Library")
+    else()
+	set(GLU_INCLUDE ""    CACHE PATH "GLU Include Path")
+	set(GLU_LIBRARY "GLU" CACHE FILEPATH "GLU Library")
+    endif()
+endfunction()
+
+function(request_backtrace)
+    if (NOT MSVC)
+        set( LibBackTrace_INCLUDE "${SRC_DIR}/libbacktrace" PARENT_SCOPE )
+        set( LibBackTrace_LIBRARY "backtracevogl" PARENT_SCOPE )
+    else()
+        set( LibBackTrace_INCLUDE "" PARENT_SCOPE )
+        set( LibBackTrace_LIBRARY "" PARENT_SCOPE )
+    endif()
+endfunction()
+
+# What compiler toolchain are we building on?
+if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+    add_compiler_flag("-DCOMPILER_GCC=1")
+    add_compiler_flag("-DCOMPILER_GCCLIKE=1")
+elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "mingw")
+    add_compiler_flag("-DCOMPILER_MINGW=1")
+    add_compiler_flag("-DCOMPILER_GCCLIKE=1")
+elseif (MSVC)
+    add_compiler_flag("-DCOMPILER_MSVC=1")
+elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
+    add_compiler_flag("-DCOMPILER_CLANG=1")
+    add_compiler_flag("-DCOMPILER_GCCLIKE=1")
+else()
+    message("Compiler is ${CMAKE_C_COMPILER_ID}")
+    message(FATAL_ERROR "Compiler unset, build will fail--stopping at CMake time.")
+endif()
+
+# Platform specific libary defines.
+if (WIN32)
+    set( LIBRT "" )
+    set( LIBDL "" )
+
+elseif (UNIX)
+    set( LIBRT rt )
+    set( LIBDL dl )
+else()
+    message(FATAL_ERROR "Need to determine what the library name for 'rt' is for non-windows, non-unix platforms (or if it's even needed).")
+endif()
+
+# What OS will we be running on?
+if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    add_compiler_flag("-DPLATFORM_OSX=1")
+    add_compiler_flag("-DPLATFORM_POSIX=1")
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+    add_compiler_flag("-DPLATFORM_LINUX=1")
+    add_compiler_flag("-DPLATFORM_POSIX=1")
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+    add_compiler_flag("-DPLATFORM_WINDOWS=1")
+else()
+    message(FATAL_ERROR "Platform unset, build will fail--stopping at CMake time.")
+endif()
+
+# What bittedness are we building?
+if (BUILD_X64)
+    add_compiler_flag("-DPLATFORM_64BIT=1")
+else()
+    add_compiler_flag("-DPLATFORM_32BIT=1")
+endif()
+
+# Compiler flags for windows.
+if (MSVC)
+    # Multithreaded compilation is a big time saver.
+    add_compiler_flag("/MP")
+
+    # In debug, we use the DLL debug runtime.
+    add_compiler_flag_debug("/MDd")
+
+    # And in release we use the DLL release runtime
+    add_compiler_flag_release("/MD")
+
+    # x64 doesn't ever support /ZI, only /Zi.
+    if (BUILD_X64)
+      add_compiler_flag("/Zi")
+    else()
+
+      # In debug, get debug information suitable for Edit and Continue
+      add_compiler_flag_debug("/ZI")
+
+      # In release, still generate debug information (because not having it is dumb)
+      add_compiler_flag_release("/Zi")
+    endif()
+
+    # And tell the linker to always generate the file for us.
+    add_linker_flag("/DEBUG")
+endif()
diff --git a/tools/glave/src/glv_extensions/glave_xgl_gen/CMakeLists.txt b/tools/glave/src/glv_extensions/glave_xgl_gen/CMakeLists.txt
new file mode 100644
index 0000000..588a834
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glave_xgl_gen/CMakeLists.txt
@@ -0,0 +1,11 @@
+project(glave_xgl_gen)
+cmake_minimum_required(VERSION 2.8)
+
+add_library(${PROJECT_NAME} xgl_struct_wrappers.h xgl_struct_wrappers.cpp xgl_struct_string_helper.h)
+
+set(COMPILE_FLAGS "-fpermissive")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS}")
+
+include_directories(${SRC_DIR}/thirdparty/${GEN_API}/inc/)
+
+target_include_directories (glave_xgl_gen PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_string_helper.h b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_string_helper.h
new file mode 100644
index 0000000..012eaa9
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_string_helper.h
@@ -0,0 +1,1621 @@
+#pragma once
+
+#include <xgl.h>
+
+static const char* string_XGL_MEMORY_PRIORITY(XGL_MEMORY_PRIORITY input_value)
+{
+    switch ((XGL_MEMORY_PRIORITY)input_value)
+    {
+
+    case XGL_MEMORY_PRIORITY_HIGH:
+        return "XGL_MEMORY_PRIORITY_HIGH";
+
+    case XGL_MEMORY_PRIORITY_LOW:
+        return "XGL_MEMORY_PRIORITY_LOW";
+
+    case XGL_MEMORY_PRIORITY_NORMAL:
+        return "XGL_MEMORY_PRIORITY_NORMAL";
+
+    case XGL_MEMORY_PRIORITY_UNUSED:
+        return "XGL_MEMORY_PRIORITY_UNUSED";
+
+    case XGL_MEMORY_PRIORITY_VERY_HIGH:
+        return "XGL_MEMORY_PRIORITY_VERY_HIGH";
+
+    case XGL_MEMORY_PRIORITY_VERY_LOW:
+        return "XGL_MEMORY_PRIORITY_VERY_LOW";
+
+    }
+    return "Unhandled XGL_MEMORY_PRIORITY";
+}
+
+
+static const char* string_XGL_IMAGE_ASPECT(XGL_IMAGE_ASPECT input_value)
+{
+    switch ((XGL_IMAGE_ASPECT)input_value)
+    {
+
+    case XGL_IMAGE_ASPECT_COLOR:
+        return "XGL_IMAGE_ASPECT_COLOR";
+
+    case XGL_IMAGE_ASPECT_DEPTH:
+        return "XGL_IMAGE_ASPECT_DEPTH";
+
+    case XGL_IMAGE_ASPECT_STENCIL:
+        return "XGL_IMAGE_ASPECT_STENCIL";
+
+    }
+    return "Unhandled XGL_IMAGE_ASPECT";
+}
+
+
+static const char* string_XGL_NUM_FORMAT(XGL_NUM_FORMAT input_value)
+{
+    switch ((XGL_NUM_FORMAT)input_value)
+    {
+
+    case XGL_NUM_FMT_DS:
+        return "XGL_NUM_FMT_DS";
+
+    case XGL_NUM_FMT_FLOAT:
+        return "XGL_NUM_FMT_FLOAT";
+
+    case XGL_NUM_FMT_SINT:
+        return "XGL_NUM_FMT_SINT";
+
+    case XGL_NUM_FMT_SNORM:
+        return "XGL_NUM_FMT_SNORM";
+
+    case XGL_NUM_FMT_SRGB:
+        return "XGL_NUM_FMT_SRGB";
+
+    case XGL_NUM_FMT_UINT:
+        return "XGL_NUM_FMT_UINT";
+
+    case XGL_NUM_FMT_UNDEFINED:
+        return "XGL_NUM_FMT_UNDEFINED";
+
+    case XGL_NUM_FMT_UNORM:
+        return "XGL_NUM_FMT_UNORM";
+
+    }
+    return "Unhandled XGL_NUM_FORMAT";
+}
+
+
+static const char* string_XGL_SUBRESOURCE_INFO_TYPE(XGL_SUBRESOURCE_INFO_TYPE input_value)
+{
+    switch ((XGL_SUBRESOURCE_INFO_TYPE)input_value)
+    {
+
+    case XGL_INFO_TYPE_SUBRESOURCE_LAYOUT:
+        return "XGL_INFO_TYPE_SUBRESOURCE_LAYOUT";
+
+    }
+    return "Unhandled XGL_SUBRESOURCE_INFO_TYPE";
+}
+
+
+static const char* string_XGL_IMAGE_USAGE_FLAGS(XGL_IMAGE_USAGE_FLAGS input_value)
+{
+    switch ((XGL_IMAGE_USAGE_FLAGS)input_value)
+    {
+
+    case XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT:
+        return "XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT";
+
+    case XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT:
+        return "XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT";
+
+    case XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT:
+        return "XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT";
+
+    case XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT:
+        return "XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT";
+
+    }
+    return "Unhandled XGL_IMAGE_USAGE_FLAGS";
+}
+
+
+static const char* string_XGL_TEX_FILTER(XGL_TEX_FILTER input_value)
+{
+    switch ((XGL_TEX_FILTER)input_value)
+    {
+
+    case XGL_TEX_FILTER_LINEAR:
+        return "XGL_TEX_FILTER_LINEAR";
+
+    case XGL_TEX_FILTER_NEAREST:
+        return "XGL_TEX_FILTER_NEAREST";
+
+    }
+    return "Unhandled XGL_TEX_FILTER";
+}
+
+
+static const char* string_XGL_DESCRIPTOR_SET_SLOT_TYPE(XGL_DESCRIPTOR_SET_SLOT_TYPE input_value)
+{
+    switch ((XGL_DESCRIPTOR_SET_SLOT_TYPE)input_value)
+    {
+
+    case XGL_SLOT_NEXT_DESCRIPTOR_SET:
+        return "XGL_SLOT_NEXT_DESCRIPTOR_SET";
+
+    case XGL_SLOT_SHADER_RESOURCE:
+        return "XGL_SLOT_SHADER_RESOURCE";
+
+    case XGL_SLOT_SHADER_SAMPLER:
+        return "XGL_SLOT_SHADER_SAMPLER";
+
+    case XGL_SLOT_SHADER_UAV:
+        return "XGL_SLOT_SHADER_UAV";
+
+    case XGL_SLOT_UNUSED:
+        return "XGL_SLOT_UNUSED";
+
+    }
+    return "Unhandled XGL_DESCRIPTOR_SET_SLOT_TYPE";
+}
+
+
+static const char* string_XGL_TEX_ADDRESS(XGL_TEX_ADDRESS input_value)
+{
+    switch ((XGL_TEX_ADDRESS)input_value)
+    {
+
+    case XGL_TEX_ADDRESS_CLAMP:
+        return "XGL_TEX_ADDRESS_CLAMP";
+
+    case XGL_TEX_ADDRESS_CLAMP_BORDER:
+        return "XGL_TEX_ADDRESS_CLAMP_BORDER";
+
+    case XGL_TEX_ADDRESS_MIRROR:
+        return "XGL_TEX_ADDRESS_MIRROR";
+
+    case XGL_TEX_ADDRESS_MIRROR_ONCE:
+        return "XGL_TEX_ADDRESS_MIRROR_ONCE";
+
+    case XGL_TEX_ADDRESS_WRAP:
+        return "XGL_TEX_ADDRESS_WRAP";
+
+    }
+    return "Unhandled XGL_TEX_ADDRESS";
+}
+
+
+static const char* string_XGL_QUERY_TYPE(XGL_QUERY_TYPE input_value)
+{
+    switch ((XGL_QUERY_TYPE)input_value)
+    {
+
+    case XGL_QUERY_OCCLUSION:
+        return "XGL_QUERY_OCCLUSION";
+
+    case XGL_QUERY_PIPELINE_STATISTICS:
+        return "XGL_QUERY_PIPELINE_STATISTICS";
+
+    }
+    return "Unhandled XGL_QUERY_TYPE";
+}
+
+
+static const char* string_XGL_ATOMIC_OP(XGL_ATOMIC_OP input_value)
+{
+    switch ((XGL_ATOMIC_OP)input_value)
+    {
+
+    case XGL_ATOMIC_ADD_INT32:
+        return "XGL_ATOMIC_ADD_INT32";
+
+    case XGL_ATOMIC_ADD_INT64:
+        return "XGL_ATOMIC_ADD_INT64";
+
+    case XGL_ATOMIC_AND_INT32:
+        return "XGL_ATOMIC_AND_INT32";
+
+    case XGL_ATOMIC_AND_INT64:
+        return "XGL_ATOMIC_AND_INT64";
+
+    case XGL_ATOMIC_DEC_UINT32:
+        return "XGL_ATOMIC_DEC_UINT32";
+
+    case XGL_ATOMIC_DEC_UINT64:
+        return "XGL_ATOMIC_DEC_UINT64";
+
+    case XGL_ATOMIC_INC_UINT32:
+        return "XGL_ATOMIC_INC_UINT32";
+
+    case XGL_ATOMIC_INC_UINT64:
+        return "XGL_ATOMIC_INC_UINT64";
+
+    case XGL_ATOMIC_MAX_SINT32:
+        return "XGL_ATOMIC_MAX_SINT32";
+
+    case XGL_ATOMIC_MAX_SINT64:
+        return "XGL_ATOMIC_MAX_SINT64";
+
+    case XGL_ATOMIC_MAX_UINT32:
+        return "XGL_ATOMIC_MAX_UINT32";
+
+    case XGL_ATOMIC_MAX_UINT64:
+        return "XGL_ATOMIC_MAX_UINT64";
+
+    case XGL_ATOMIC_MIN_SINT32:
+        return "XGL_ATOMIC_MIN_SINT32";
+
+    case XGL_ATOMIC_MIN_SINT64:
+        return "XGL_ATOMIC_MIN_SINT64";
+
+    case XGL_ATOMIC_MIN_UINT32:
+        return "XGL_ATOMIC_MIN_UINT32";
+
+    case XGL_ATOMIC_MIN_UINT64:
+        return "XGL_ATOMIC_MIN_UINT64";
+
+    case XGL_ATOMIC_OR_INT32:
+        return "XGL_ATOMIC_OR_INT32";
+
+    case XGL_ATOMIC_OR_INT64:
+        return "XGL_ATOMIC_OR_INT64";
+
+    case XGL_ATOMIC_SUB_INT32:
+        return "XGL_ATOMIC_SUB_INT32";
+
+    case XGL_ATOMIC_SUB_INT64:
+        return "XGL_ATOMIC_SUB_INT64";
+
+    case XGL_ATOMIC_XOR_INT32:
+        return "XGL_ATOMIC_XOR_INT32";
+
+    case XGL_ATOMIC_XOR_INT64:
+        return "XGL_ATOMIC_XOR_INT64";
+
+    }
+    return "Unhandled XGL_ATOMIC_OP";
+}
+
+
+static const char* string_XGL_PROVOKING_VERTEX_CONVENTION(XGL_PROVOKING_VERTEX_CONVENTION input_value)
+{
+    switch ((XGL_PROVOKING_VERTEX_CONVENTION)input_value)
+    {
+
+    case XGL_PROVOKING_VERTEX_FIRST:
+        return "XGL_PROVOKING_VERTEX_FIRST";
+
+    case XGL_PROVOKING_VERTEX_LAST:
+        return "XGL_PROVOKING_VERTEX_LAST";
+
+    }
+    return "Unhandled XGL_PROVOKING_VERTEX_CONVENTION";
+}
+
+
+static const char* string_XGL_MEMORY_HEAP_INFO_TYPE(XGL_MEMORY_HEAP_INFO_TYPE input_value)
+{
+    switch ((XGL_MEMORY_HEAP_INFO_TYPE)input_value)
+    {
+
+    case XGL_INFO_TYPE_MEMORY_HEAP_PROPERTIES:
+        return "XGL_INFO_TYPE_MEMORY_HEAP_PROPERTIES";
+
+    }
+    return "Unhandled XGL_MEMORY_HEAP_INFO_TYPE";
+}
+
+
+static const char* string_XGL_PRIMITIVE_TOPOLOGY(XGL_PRIMITIVE_TOPOLOGY input_value)
+{
+    switch ((XGL_PRIMITIVE_TOPOLOGY)input_value)
+    {
+
+    case XGL_TOPOLOGY_LINE_LIST:
+        return "XGL_TOPOLOGY_LINE_LIST";
+
+    case XGL_TOPOLOGY_LINE_LIST_ADJ:
+        return "XGL_TOPOLOGY_LINE_LIST_ADJ";
+
+    case XGL_TOPOLOGY_LINE_STRIP:
+        return "XGL_TOPOLOGY_LINE_STRIP";
+
+    case XGL_TOPOLOGY_LINE_STRIP_ADJ:
+        return "XGL_TOPOLOGY_LINE_STRIP_ADJ";
+
+    case XGL_TOPOLOGY_PATCH:
+        return "XGL_TOPOLOGY_PATCH";
+
+    case XGL_TOPOLOGY_POINT_LIST:
+        return "XGL_TOPOLOGY_POINT_LIST";
+
+    case XGL_TOPOLOGY_QUAD_LIST:
+        return "XGL_TOPOLOGY_QUAD_LIST";
+
+    case XGL_TOPOLOGY_QUAD_STRIP:
+        return "XGL_TOPOLOGY_QUAD_STRIP";
+
+    case XGL_TOPOLOGY_RECT_LIST:
+        return "XGL_TOPOLOGY_RECT_LIST";
+
+    case XGL_TOPOLOGY_TRIANGLE_LIST:
+        return "XGL_TOPOLOGY_TRIANGLE_LIST";
+
+    case XGL_TOPOLOGY_TRIANGLE_LIST_ADJ:
+        return "XGL_TOPOLOGY_TRIANGLE_LIST_ADJ";
+
+    case XGL_TOPOLOGY_TRIANGLE_STRIP:
+        return "XGL_TOPOLOGY_TRIANGLE_STRIP";
+
+    case XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ:
+        return "XGL_TOPOLOGY_TRIANGLE_STRIP_ADJ";
+
+    }
+    return "Unhandled XGL_PRIMITIVE_TOPOLOGY";
+}
+
+
+static const char* string_XGL_BLEND_FUNC(XGL_BLEND_FUNC input_value)
+{
+    switch ((XGL_BLEND_FUNC)input_value)
+    {
+
+    case XGL_BLEND_FUNC_ADD:
+        return "XGL_BLEND_FUNC_ADD";
+
+    case XGL_BLEND_FUNC_MAX:
+        return "XGL_BLEND_FUNC_MAX";
+
+    case XGL_BLEND_FUNC_MIN:
+        return "XGL_BLEND_FUNC_MIN";
+
+    case XGL_BLEND_FUNC_REVERSE_SUBTRACT:
+        return "XGL_BLEND_FUNC_REVERSE_SUBTRACT";
+
+    case XGL_BLEND_FUNC_SUBTRACT:
+        return "XGL_BLEND_FUNC_SUBTRACT";
+
+    }
+    return "Unhandled XGL_BLEND_FUNC";
+}
+
+
+static const char* string_XGL_SYSTEM_ALLOC_TYPE(XGL_SYSTEM_ALLOC_TYPE input_value)
+{
+    switch ((XGL_SYSTEM_ALLOC_TYPE)input_value)
+    {
+
+    case XGL_SYSTEM_ALLOC_API_OBJECT:
+        return "XGL_SYSTEM_ALLOC_API_OBJECT";
+
+    case XGL_SYSTEM_ALLOC_DEBUG:
+        return "XGL_SYSTEM_ALLOC_DEBUG";
+
+    case XGL_SYSTEM_ALLOC_INTERNAL:
+        return "XGL_SYSTEM_ALLOC_INTERNAL";
+
+    case XGL_SYSTEM_ALLOC_INTERNAL_SHADER:
+        return "XGL_SYSTEM_ALLOC_INTERNAL_SHADER";
+
+    case XGL_SYSTEM_ALLOC_INTERNAL_TEMP:
+        return "XGL_SYSTEM_ALLOC_INTERNAL_TEMP";
+
+    }
+    return "Unhandled XGL_SYSTEM_ALLOC_TYPE";
+}
+
+
+static const char* string_XGL_MEMORY_STATE(XGL_MEMORY_STATE input_value)
+{
+    switch ((XGL_MEMORY_STATE)input_value)
+    {
+
+    case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_ONLY:
+        return "XGL_MEMORY_STATE_COMPUTE_SHADER_READ_ONLY";
+
+    case XGL_MEMORY_STATE_COMPUTE_SHADER_READ_WRITE:
+        return "XGL_MEMORY_STATE_COMPUTE_SHADER_READ_WRITE";
+
+    case XGL_MEMORY_STATE_COMPUTE_SHADER_WRITE_ONLY:
+        return "XGL_MEMORY_STATE_COMPUTE_SHADER_WRITE_ONLY";
+
+    case XGL_MEMORY_STATE_DATA_TRANSFER:
+        return "XGL_MEMORY_STATE_DATA_TRANSFER";
+
+    case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY:
+        return "XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_ONLY";
+
+    case XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_WRITE:
+        return "XGL_MEMORY_STATE_GRAPHICS_SHADER_READ_WRITE";
+
+    case XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY:
+        return "XGL_MEMORY_STATE_GRAPHICS_SHADER_WRITE_ONLY";
+
+    case XGL_MEMORY_STATE_INDEX_DATA:
+        return "XGL_MEMORY_STATE_INDEX_DATA";
+
+    case XGL_MEMORY_STATE_INDIRECT_ARG:
+        return "XGL_MEMORY_STATE_INDIRECT_ARG";
+
+    case XGL_MEMORY_STATE_MULTI_SHADER_READ_ONLY:
+        return "XGL_MEMORY_STATE_MULTI_SHADER_READ_ONLY";
+
+    case XGL_MEMORY_STATE_QUEUE_ATOMIC:
+        return "XGL_MEMORY_STATE_QUEUE_ATOMIC";
+
+    case XGL_MEMORY_STATE_WRITE_TIMESTAMP:
+        return "XGL_MEMORY_STATE_WRITE_TIMESTAMP";
+
+    }
+    return "Unhandled XGL_MEMORY_STATE";
+}
+
+
+static const char* string_XGL_QUERY_CONTROL_FLAGS(XGL_QUERY_CONTROL_FLAGS input_value)
+{
+    switch ((XGL_QUERY_CONTROL_FLAGS)input_value)
+    {
+
+    case XGL_QUERY_IMPRECISE_DATA_BIT:
+        return "XGL_QUERY_IMPRECISE_DATA_BIT";
+
+    }
+    return "Unhandled XGL_QUERY_CONTROL_FLAGS";
+}
+
+
+static const char* string_XGL_FORMAT_INFO_TYPE(XGL_FORMAT_INFO_TYPE input_value)
+{
+    switch ((XGL_FORMAT_INFO_TYPE)input_value)
+    {
+
+    case XGL_INFO_TYPE_FORMAT_PROPERTIES:
+        return "XGL_INFO_TYPE_FORMAT_PROPERTIES";
+
+    }
+    return "Unhandled XGL_FORMAT_INFO_TYPE";
+}
+
+
+static const char* string_XGL_STATE_BIND_POINT(XGL_STATE_BIND_POINT input_value)
+{
+    switch ((XGL_STATE_BIND_POINT)input_value)
+    {
+
+    case XGL_STATE_BIND_COLOR_BLEND:
+        return "XGL_STATE_BIND_COLOR_BLEND";
+
+    case XGL_STATE_BIND_DEPTH_STENCIL:
+        return "XGL_STATE_BIND_DEPTH_STENCIL";
+
+    case XGL_STATE_BIND_MSAA:
+        return "XGL_STATE_BIND_MSAA";
+
+    case XGL_STATE_BIND_RASTER:
+        return "XGL_STATE_BIND_RASTER";
+
+    case XGL_STATE_BIND_VIEWPORT:
+        return "XGL_STATE_BIND_VIEWPORT";
+
+    }
+    return "Unhandled XGL_STATE_BIND_POINT";
+}
+
+
+static const char* string_XGL_CMD_BUFFER_BUILD_FLAGS(XGL_CMD_BUFFER_BUILD_FLAGS input_value)
+{
+    switch ((XGL_CMD_BUFFER_BUILD_FLAGS)input_value)
+    {
+
+    case XGL_CMD_BUFFER_OPTIMIZE_DESCRIPTOR_SET_SWITCH_BIT:
+        return "XGL_CMD_BUFFER_OPTIMIZE_DESCRIPTOR_SET_SWITCH_BIT";
+
+    case XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT:
+        return "XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT";
+
+    case XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT:
+        return "XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT";
+
+    case XGL_CMD_BUFFER_OPTIMIZE_PIPELINE_SWITCH_BIT:
+        return "XGL_CMD_BUFFER_OPTIMIZE_PIPELINE_SWITCH_BIT";
+
+    }
+    return "Unhandled XGL_CMD_BUFFER_BUILD_FLAGS";
+}
+
+
+static const char* string_XGL_MEMORY_REF_FLAGS(XGL_MEMORY_REF_FLAGS input_value)
+{
+    switch ((XGL_MEMORY_REF_FLAGS)input_value)
+    {
+
+    case XGL_MEMORY_REF_READ_ONLY_BIT:
+        return "XGL_MEMORY_REF_READ_ONLY_BIT";
+
+    }
+    return "Unhandled XGL_MEMORY_REF_FLAGS";
+}
+
+
+static const char* string_XGL_TIMESTAMP_TYPE(XGL_TIMESTAMP_TYPE input_value)
+{
+    switch ((XGL_TIMESTAMP_TYPE)input_value)
+    {
+
+    case XGL_TIMESTAMP_BOTTOM:
+        return "XGL_TIMESTAMP_BOTTOM";
+
+    case XGL_TIMESTAMP_TOP:
+        return "XGL_TIMESTAMP_TOP";
+
+    }
+    return "Unhandled XGL_TIMESTAMP_TYPE";
+}
+
+
+static const char* string_XGL_MEMORY_HEAP_FLAGS(XGL_MEMORY_HEAP_FLAGS input_value)
+{
+    switch ((XGL_MEMORY_HEAP_FLAGS)input_value)
+    {
+
+    case XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT:
+        return "XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT";
+
+    case XGL_MEMORY_HEAP_CPU_UNCACHED_BIT:
+        return "XGL_MEMORY_HEAP_CPU_UNCACHED_BIT";
+
+    case XGL_MEMORY_HEAP_CPU_VISIBLE_BIT:
+        return "XGL_MEMORY_HEAP_CPU_VISIBLE_BIT";
+
+    case XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT:
+        return "XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT";
+
+    case XGL_MEMORY_HEAP_HOLDS_PINNED_BIT:
+        return "XGL_MEMORY_HEAP_HOLDS_PINNED_BIT";
+
+    case XGL_MEMORY_HEAP_SHAREABLE_BIT:
+        return "XGL_MEMORY_HEAP_SHAREABLE_BIT";
+
+    }
+    return "Unhandled XGL_MEMORY_HEAP_FLAGS";
+}
+
+
+static const char* string_XGL_MEMORY_ALLOC_FLAGS(XGL_MEMORY_ALLOC_FLAGS input_value)
+{
+    switch ((XGL_MEMORY_ALLOC_FLAGS)input_value)
+    {
+
+    case XGL_MEMORY_ALLOC_SHAREABLE_BIT:
+        return "XGL_MEMORY_ALLOC_SHAREABLE_BIT";
+
+    case XGL_MEMORY_ALLOC_VIRTUAL_BIT:
+        return "XGL_MEMORY_ALLOC_VIRTUAL_BIT";
+
+    }
+    return "Unhandled XGL_MEMORY_ALLOC_FLAGS";
+}
+
+
+static const char* string_XGL_PHYSICAL_GPU_TYPE(XGL_PHYSICAL_GPU_TYPE input_value)
+{
+    switch ((XGL_PHYSICAL_GPU_TYPE)input_value)
+    {
+
+    case XGL_GPU_TYPE_DISCRETE:
+        return "XGL_GPU_TYPE_DISCRETE";
+
+    case XGL_GPU_TYPE_INTEGRATED:
+        return "XGL_GPU_TYPE_INTEGRATED";
+
+    case XGL_GPU_TYPE_OTHER:
+        return "XGL_GPU_TYPE_OTHER";
+
+    case XGL_GPU_TYPE_VIRTUAL:
+        return "XGL_GPU_TYPE_VIRTUAL";
+
+    }
+    return "Unhandled XGL_PHYSICAL_GPU_TYPE";
+}
+
+
+static const char* string_XGL_BORDER_COLOR_TYPE(XGL_BORDER_COLOR_TYPE input_value)
+{
+    switch ((XGL_BORDER_COLOR_TYPE)input_value)
+    {
+
+    case XGL_BORDER_COLOR_OPAQUE_BLACK:
+        return "XGL_BORDER_COLOR_OPAQUE_BLACK";
+
+    case XGL_BORDER_COLOR_OPAQUE_WHITE:
+        return "XGL_BORDER_COLOR_OPAQUE_WHITE";
+
+    case XGL_BORDER_COLOR_TRANSPARENT_BLACK:
+        return "XGL_BORDER_COLOR_TRANSPARENT_BLACK";
+
+    }
+    return "Unhandled XGL_BORDER_COLOR_TYPE";
+}
+
+
+static const char* string_XGL_IMAGE_STATE(XGL_IMAGE_STATE input_value)
+{
+    switch ((XGL_IMAGE_STATE)input_value)
+    {
+
+    case XGL_IMAGE_STATE_CLEAR:
+        return "XGL_IMAGE_STATE_CLEAR";
+
+    case XGL_IMAGE_STATE_COMPUTE_SHADER_READ_ONLY:
+        return "XGL_IMAGE_STATE_COMPUTE_SHADER_READ_ONLY";
+
+    case XGL_IMAGE_STATE_COMPUTE_SHADER_READ_WRITE:
+        return "XGL_IMAGE_STATE_COMPUTE_SHADER_READ_WRITE";
+
+    case XGL_IMAGE_STATE_COMPUTE_SHADER_WRITE_ONLY:
+        return "XGL_IMAGE_STATE_COMPUTE_SHADER_WRITE_ONLY";
+
+    case XGL_IMAGE_STATE_DATA_TRANSFER:
+        return "XGL_IMAGE_STATE_DATA_TRANSFER";
+
+    case XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_ONLY:
+        return "XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_ONLY";
+
+    case XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_WRITE:
+        return "XGL_IMAGE_STATE_GRAPHICS_SHADER_READ_WRITE";
+
+    case XGL_IMAGE_STATE_GRAPHICS_SHADER_WRITE_ONLY:
+        return "XGL_IMAGE_STATE_GRAPHICS_SHADER_WRITE_ONLY";
+
+    case XGL_IMAGE_STATE_MULTI_SHADER_READ_ONLY:
+        return "XGL_IMAGE_STATE_MULTI_SHADER_READ_ONLY";
+
+    case XGL_IMAGE_STATE_RESOLVE_DESTINATION:
+        return "XGL_IMAGE_STATE_RESOLVE_DESTINATION";
+
+    case XGL_IMAGE_STATE_RESOLVE_SOURCE:
+        return "XGL_IMAGE_STATE_RESOLVE_SOURCE";
+
+    case XGL_IMAGE_STATE_TARGET_AND_SHADER_READ_ONLY:
+        return "XGL_IMAGE_STATE_TARGET_AND_SHADER_READ_ONLY";
+
+    case XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL:
+        return "XGL_IMAGE_STATE_TARGET_RENDER_ACCESS_OPTIMAL";
+
+    case XGL_IMAGE_STATE_TARGET_SHADER_ACCESS_OPTIMAL:
+        return "XGL_IMAGE_STATE_TARGET_SHADER_ACCESS_OPTIMAL";
+
+    case XGL_IMAGE_STATE_UNINITIALIZED_TARGET:
+        return "XGL_IMAGE_STATE_UNINITIALIZED_TARGET";
+
+    }
+    return "Unhandled XGL_IMAGE_STATE";
+}
+
+
+static const char* string_XGL_TEX_MIPMAP_MODE(XGL_TEX_MIPMAP_MODE input_value)
+{
+    switch ((XGL_TEX_MIPMAP_MODE)input_value)
+    {
+
+    case XGL_TEX_MIPMAP_BASE:
+        return "XGL_TEX_MIPMAP_BASE";
+
+    case XGL_TEX_MIPMAP_LINEAR:
+        return "XGL_TEX_MIPMAP_LINEAR";
+
+    case XGL_TEX_MIPMAP_NEAREST:
+        return "XGL_TEX_MIPMAP_NEAREST";
+
+    }
+    return "Unhandled XGL_TEX_MIPMAP_MODE";
+}
+
+
+static const char* string_XGL_LOGIC_OP(XGL_LOGIC_OP input_value)
+{
+    switch ((XGL_LOGIC_OP)input_value)
+    {
+
+    case XGL_LOGIC_OP_AND:
+        return "XGL_LOGIC_OP_AND";
+
+    case XGL_LOGIC_OP_AND_INVERTED:
+        return "XGL_LOGIC_OP_AND_INVERTED";
+
+    case XGL_LOGIC_OP_AND_REVERSE:
+        return "XGL_LOGIC_OP_AND_REVERSE";
+
+    case XGL_LOGIC_OP_CLEAR:
+        return "XGL_LOGIC_OP_CLEAR";
+
+    case XGL_LOGIC_OP_COPY:
+        return "XGL_LOGIC_OP_COPY";
+
+    case XGL_LOGIC_OP_COPY_INVERTED:
+        return "XGL_LOGIC_OP_COPY_INVERTED";
+
+    case XGL_LOGIC_OP_EQUIV:
+        return "XGL_LOGIC_OP_EQUIV";
+
+    case XGL_LOGIC_OP_INVERT:
+        return "XGL_LOGIC_OP_INVERT";
+
+    case XGL_LOGIC_OP_NAND:
+        return "XGL_LOGIC_OP_NAND";
+
+    case XGL_LOGIC_OP_NOOP:
+        return "XGL_LOGIC_OP_NOOP";
+
+    case XGL_LOGIC_OP_NOR:
+        return "XGL_LOGIC_OP_NOR";
+
+    case XGL_LOGIC_OP_OR:
+        return "XGL_LOGIC_OP_OR";
+
+    case XGL_LOGIC_OP_OR_INVERTED:
+        return "XGL_LOGIC_OP_OR_INVERTED";
+
+    case XGL_LOGIC_OP_OR_REVERSE:
+        return "XGL_LOGIC_OP_OR_REVERSE";
+
+    case XGL_LOGIC_OP_SET:
+        return "XGL_LOGIC_OP_SET";
+
+    case XGL_LOGIC_OP_XOR:
+        return "XGL_LOGIC_OP_XOR";
+
+    }
+    return "Unhandled XGL_LOGIC_OP";
+}
+
+
+static const char* string_XGL_FORMAT_FEATURE_FLAGS(XGL_FORMAT_FEATURE_FLAGS input_value)
+{
+    switch ((XGL_FORMAT_FEATURE_FLAGS)input_value)
+    {
+
+    case XGL_FORMAT_COLOR_ATTACHMENT_BLEND_BIT:
+        return "XGL_FORMAT_COLOR_ATTACHMENT_BLEND_BIT";
+
+    case XGL_FORMAT_COLOR_ATTACHMENT_WRITE_BIT:
+        return "XGL_FORMAT_COLOR_ATTACHMENT_WRITE_BIT";
+
+    case XGL_FORMAT_CONVERSION_BIT:
+        return "XGL_FORMAT_CONVERSION_BIT";
+
+    case XGL_FORMAT_DEPTH_ATTACHMENT_BIT:
+        return "XGL_FORMAT_DEPTH_ATTACHMENT_BIT";
+
+    case XGL_FORMAT_IMAGE_COPY_BIT:
+        return "XGL_FORMAT_IMAGE_COPY_BIT";
+
+    case XGL_FORMAT_IMAGE_SHADER_READ_BIT:
+        return "XGL_FORMAT_IMAGE_SHADER_READ_BIT";
+
+    case XGL_FORMAT_IMAGE_SHADER_WRITE_BIT:
+        return "XGL_FORMAT_IMAGE_SHADER_WRITE_BIT";
+
+    case XGL_FORMAT_MEMORY_SHADER_ACCESS_BIT:
+        return "XGL_FORMAT_MEMORY_SHADER_ACCESS_BIT";
+
+    case XGL_FORMAT_MSAA_ATTACHMENT_BIT:
+        return "XGL_FORMAT_MSAA_ATTACHMENT_BIT";
+
+    case XGL_FORMAT_STENCIL_ATTACHMENT_BIT:
+        return "XGL_FORMAT_STENCIL_ATTACHMENT_BIT";
+
+    }
+    return "Unhandled XGL_FORMAT_FEATURE_FLAGS";
+}
+
+
+static const char* string_XGL_VALIDATION_LEVEL(XGL_VALIDATION_LEVEL input_value)
+{
+    switch ((XGL_VALIDATION_LEVEL)input_value)
+    {
+
+    case XGL_VALIDATION_LEVEL_0:
+        return "XGL_VALIDATION_LEVEL_0";
+
+    case XGL_VALIDATION_LEVEL_1:
+        return "XGL_VALIDATION_LEVEL_1";
+
+    case XGL_VALIDATION_LEVEL_2:
+        return "XGL_VALIDATION_LEVEL_2";
+
+    case XGL_VALIDATION_LEVEL_3:
+        return "XGL_VALIDATION_LEVEL_3";
+
+    case XGL_VALIDATION_LEVEL_4:
+        return "XGL_VALIDATION_LEVEL_4";
+
+    }
+    return "Unhandled XGL_VALIDATION_LEVEL";
+}
+
+
+static const char* string_XGL_CULL_MODE(XGL_CULL_MODE input_value)
+{
+    switch ((XGL_CULL_MODE)input_value)
+    {
+
+    case XGL_CULL_BACK:
+        return "XGL_CULL_BACK";
+
+    case XGL_CULL_FRONT:
+        return "XGL_CULL_FRONT";
+
+    case XGL_CULL_FRONT_AND_BACK:
+        return "XGL_CULL_FRONT_AND_BACK";
+
+    case XGL_CULL_NONE:
+        return "XGL_CULL_NONE";
+
+    }
+    return "Unhandled XGL_CULL_MODE";
+}
+
+
+static const char* string_XGL_PIPELINE_SHADER_STAGE(XGL_PIPELINE_SHADER_STAGE input_value)
+{
+    switch ((XGL_PIPELINE_SHADER_STAGE)input_value)
+    {
+
+    case XGL_SHADER_STAGE_COMPUTE:
+        return "XGL_SHADER_STAGE_COMPUTE";
+
+    case XGL_SHADER_STAGE_FRAGMENT:
+        return "XGL_SHADER_STAGE_FRAGMENT";
+
+    case XGL_SHADER_STAGE_GEOMETRY:
+        return "XGL_SHADER_STAGE_GEOMETRY";
+
+    case XGL_SHADER_STAGE_TESS_CONTROL:
+        return "XGL_SHADER_STAGE_TESS_CONTROL";
+
+    case XGL_SHADER_STAGE_TESS_EVALUATION:
+        return "XGL_SHADER_STAGE_TESS_EVALUATION";
+
+    case XGL_SHADER_STAGE_VERTEX:
+        return "XGL_SHADER_STAGE_VERTEX";
+
+    }
+    return "Unhandled XGL_PIPELINE_SHADER_STAGE";
+}
+
+
+static const char* string_XGL_CHANNEL_SWIZZLE(XGL_CHANNEL_SWIZZLE input_value)
+{
+    switch ((XGL_CHANNEL_SWIZZLE)input_value)
+    {
+
+    case XGL_CHANNEL_SWIZZLE_A:
+        return "XGL_CHANNEL_SWIZZLE_A";
+
+    case XGL_CHANNEL_SWIZZLE_B:
+        return "XGL_CHANNEL_SWIZZLE_B";
+
+    case XGL_CHANNEL_SWIZZLE_G:
+        return "XGL_CHANNEL_SWIZZLE_G";
+
+    case XGL_CHANNEL_SWIZZLE_ONE:
+        return "XGL_CHANNEL_SWIZZLE_ONE";
+
+    case XGL_CHANNEL_SWIZZLE_R:
+        return "XGL_CHANNEL_SWIZZLE_R";
+
+    case XGL_CHANNEL_SWIZZLE_ZERO:
+        return "XGL_CHANNEL_SWIZZLE_ZERO";
+
+    }
+    return "Unhandled XGL_CHANNEL_SWIZZLE";
+}
+
+
+static const char* string_XGL_DEVICE_CREATE_FLAGS(XGL_DEVICE_CREATE_FLAGS input_value)
+{
+    switch ((XGL_DEVICE_CREATE_FLAGS)input_value)
+    {
+
+    case XGL_DEVICE_CREATE_MGPU_IQ_MATCH_BIT:
+        return "XGL_DEVICE_CREATE_MGPU_IQ_MATCH_BIT";
+
+    case XGL_DEVICE_CREATE_VALIDATION_BIT:
+        return "XGL_DEVICE_CREATE_VALIDATION_BIT";
+
+    }
+    return "Unhandled XGL_DEVICE_CREATE_FLAGS";
+}
+
+
+static const char* string_XGL_RESULT(XGL_RESULT input_value)
+{
+    switch ((XGL_RESULT)input_value)
+    {
+
+    case XGL_EVENT_RESET:
+        return "XGL_EVENT_RESET";
+
+    case XGL_EVENT_SET:
+        return "XGL_EVENT_SET";
+
+    case XGL_NOT_READY:
+        return "XGL_NOT_READY";
+
+    case XGL_SUCCESS:
+        return "XGL_SUCCESS";
+
+    case XGL_TIMEOUT:
+        return "XGL_TIMEOUT";
+
+    case XGL_UNSUPPORTED:
+        return "XGL_UNSUPPORTED";
+
+    }
+    return "Unhandled XGL_RESULT";
+}
+
+
+static const char* string_XGL_PIPELINE_CREATE_FLAGS(XGL_PIPELINE_CREATE_FLAGS input_value)
+{
+    switch ((XGL_PIPELINE_CREATE_FLAGS)input_value)
+    {
+
+    case XGL_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT:
+        return "XGL_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT";
+
+    }
+    return "Unhandled XGL_PIPELINE_CREATE_FLAGS";
+}
+
+
+static const char* string_XGL_SEMAPHORE_CREATE_FLAGS(XGL_SEMAPHORE_CREATE_FLAGS input_value)
+{
+    switch ((XGL_SEMAPHORE_CREATE_FLAGS)input_value)
+    {
+
+    case XGL_SEMAPHORE_CREATE_SHAREABLE_BIT:
+        return "XGL_SEMAPHORE_CREATE_SHAREABLE_BIT";
+
+    }
+    return "Unhandled XGL_SEMAPHORE_CREATE_FLAGS";
+}
+
+
+static const char* string_XGL_STRUCTURE_TYPE(XGL_STRUCTURE_TYPE input_value)
+{
+    switch ((XGL_STRUCTURE_TYPE)input_value)
+    {
+
+    case XGL_STRUCTURE_TYPE_APPLICATION_INFO:
+        return "XGL_STRUCTURE_TYPE_APPLICATION_INFO";
+
+    case XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_COLOR_BLEND_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_COLOR_BLEND_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO:
+        return "XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO";
+
+    case XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO:
+        return "XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO";
+
+    case XGL_STRUCTURE_TYPE_MEMORY_OPEN_INFO:
+        return "XGL_STRUCTURE_TYPE_MEMORY_OPEN_INFO";
+
+    case XGL_STRUCTURE_TYPE_MEMORY_STATE_TRANSITION:
+        return "XGL_STRUCTURE_TYPE_MEMORY_STATE_TRANSITION";
+
+    case XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO:
+        return "XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO";
+
+    case XGL_STRUCTURE_TYPE_MSAA_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_MSAA_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_PEER_MEMORY_OPEN_INFO:
+        return "XGL_STRUCTURE_TYPE_PEER_MEMORY_OPEN_INFO";
+
+    case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_RASTER_STATE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_RASTER_STATE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO";
+
+    case XGL_STRUCTURE_TYPE_SEMAPHORE_OPEN_INFO:
+        return "XGL_STRUCTURE_TYPE_SEMAPHORE_OPEN_INFO";
+
+    case XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO:
+        return "XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO";
+
+    }
+    return "Unhandled XGL_STRUCTURE_TYPE";
+}
+
+
+static const char* string_XGL_DEPTH_STENCIL_VIEW_CREATE_FLAGS(XGL_DEPTH_STENCIL_VIEW_CREATE_FLAGS input_value)
+{
+    switch ((XGL_DEPTH_STENCIL_VIEW_CREATE_FLAGS)input_value)
+    {
+
+    case XGL_DEPTH_STENCIL_VIEW_CREATE_READ_ONLY_DEPTH_BIT:
+        return "XGL_DEPTH_STENCIL_VIEW_CREATE_READ_ONLY_DEPTH_BIT";
+
+    case XGL_DEPTH_STENCIL_VIEW_CREATE_READ_ONLY_STENCIL_BIT:
+        return "XGL_DEPTH_STENCIL_VIEW_CREATE_READ_ONLY_STENCIL_BIT";
+
+    }
+    return "Unhandled XGL_DEPTH_STENCIL_VIEW_CREATE_FLAGS";
+}
+
+
+static const char* string_XGL_GPU_COMPATIBILITY_FLAGS(XGL_GPU_COMPATIBILITY_FLAGS input_value)
+{
+    switch ((XGL_GPU_COMPATIBILITY_FLAGS)input_value)
+    {
+
+    case XGL_GPU_COMPAT_ASIC_FEATURES_BIT:
+        return "XGL_GPU_COMPAT_ASIC_FEATURES_BIT";
+
+    case XGL_GPU_COMPAT_IQ_MATCH_BIT:
+        return "XGL_GPU_COMPAT_IQ_MATCH_BIT";
+
+    case XGL_GPU_COMPAT_PEER_TRANSFER_BIT:
+        return "XGL_GPU_COMPAT_PEER_TRANSFER_BIT";
+
+    case XGL_GPU_COMPAT_SHARED_GPU0_DISPLAY_BIT:
+        return "XGL_GPU_COMPAT_SHARED_GPU0_DISPLAY_BIT";
+
+    case XGL_GPU_COMPAT_SHARED_GPU1_DISPLAY_BIT:
+        return "XGL_GPU_COMPAT_SHARED_GPU1_DISPLAY_BIT";
+
+    case XGL_GPU_COMPAT_SHARED_MEMORY_BIT:
+        return "XGL_GPU_COMPAT_SHARED_MEMORY_BIT";
+
+    case XGL_GPU_COMPAT_SHARED_SYNC_BIT:
+        return "XGL_GPU_COMPAT_SHARED_SYNC_BIT";
+
+    }
+    return "Unhandled XGL_GPU_COMPATIBILITY_FLAGS";
+}
+
+
+static const char* string_XGL_FILL_MODE(XGL_FILL_MODE input_value)
+{
+    switch ((XGL_FILL_MODE)input_value)
+    {
+
+    case XFL_FILL_POINTS:
+        return "XFL_FILL_POINTS";
+
+    case XGL_FILL_SOLID:
+        return "XGL_FILL_SOLID";
+
+    case XGL_FILL_WIREFRAME:
+        return "XGL_FILL_WIREFRAME";
+
+    }
+    return "Unhandled XGL_FILL_MODE";
+}
+
+
+static const char* string_XGL_IMAGE_VIEW_TYPE(XGL_IMAGE_VIEW_TYPE input_value)
+{
+    switch ((XGL_IMAGE_VIEW_TYPE)input_value)
+    {
+
+    case XGL_IMAGE_VIEW_1D:
+        return "XGL_IMAGE_VIEW_1D";
+
+    case XGL_IMAGE_VIEW_2D:
+        return "XGL_IMAGE_VIEW_2D";
+
+    case XGL_IMAGE_VIEW_3D:
+        return "XGL_IMAGE_VIEW_3D";
+
+    case XGL_IMAGE_VIEW_CUBE:
+        return "XGL_IMAGE_VIEW_CUBE";
+
+    }
+    return "Unhandled XGL_IMAGE_VIEW_TYPE";
+}
+
+
+static const char* string_XGL_IMAGE_TYPE(XGL_IMAGE_TYPE input_value)
+{
+    switch ((XGL_IMAGE_TYPE)input_value)
+    {
+
+    case XGL_IMAGE_1D:
+        return "XGL_IMAGE_1D";
+
+    case XGL_IMAGE_2D:
+        return "XGL_IMAGE_2D";
+
+    case XGL_IMAGE_3D:
+        return "XGL_IMAGE_3D";
+
+    }
+    return "Unhandled XGL_IMAGE_TYPE";
+}
+
+
+static const char* string_XGL_INDEX_TYPE(XGL_INDEX_TYPE input_value)
+{
+    switch ((XGL_INDEX_TYPE)input_value)
+    {
+
+    case XGL_INDEX_16:
+        return "XGL_INDEX_16";
+
+    case XGL_INDEX_32:
+        return "XGL_INDEX_32";
+
+    case XGL_INDEX_8:
+        return "XGL_INDEX_8";
+
+    }
+    return "Unhandled XGL_INDEX_TYPE";
+}
+
+
+static const char* string_XGL_IMAGE_CREATE_FLAGS(XGL_IMAGE_CREATE_FLAGS input_value)
+{
+    switch ((XGL_IMAGE_CREATE_FLAGS)input_value)
+    {
+
+    case XGL_IMAGE_CREATE_CLONEABLE_BIT:
+        return "XGL_IMAGE_CREATE_CLONEABLE_BIT";
+
+    case XGL_IMAGE_CREATE_INVARIANT_DATA_BIT:
+        return "XGL_IMAGE_CREATE_INVARIANT_DATA_BIT";
+
+    case XGL_IMAGE_CREATE_SHAREABLE_BIT:
+        return "XGL_IMAGE_CREATE_SHAREABLE_BIT";
+
+    }
+    return "Unhandled XGL_IMAGE_CREATE_FLAGS";
+}
+
+
+static const char* string_XGL_QUEUE_TYPE(XGL_QUEUE_TYPE input_value)
+{
+    switch ((XGL_QUEUE_TYPE)input_value)
+    {
+
+    case XGL_QUEUE_TYPE_COMPUTE:
+        return "XGL_QUEUE_TYPE_COMPUTE";
+
+    case XGL_QUEUE_TYPE_DMA:
+        return "XGL_QUEUE_TYPE_DMA";
+
+    case XGL_QUEUE_TYPE_GRAPHICS:
+        return "XGL_QUEUE_TYPE_GRAPHICS";
+
+    }
+    return "Unhandled XGL_QUEUE_TYPE";
+}
+
+
+static const char* string_XGL_STENCIL_OP(XGL_STENCIL_OP input_value)
+{
+    switch ((XGL_STENCIL_OP)input_value)
+    {
+
+    case XGL_STENCIL_OP_DEC_CLAMP:
+        return "XGL_STENCIL_OP_DEC_CLAMP";
+
+    case XGL_STENCIL_OP_DEC_WRAP:
+        return "XGL_STENCIL_OP_DEC_WRAP";
+
+    case XGL_STENCIL_OP_INC_CLAMP:
+        return "XGL_STENCIL_OP_INC_CLAMP";
+
+    case XGL_STENCIL_OP_INC_WRAP:
+        return "XGL_STENCIL_OP_INC_WRAP";
+
+    case XGL_STENCIL_OP_INVERT:
+        return "XGL_STENCIL_OP_INVERT";
+
+    case XGL_STENCIL_OP_KEEP:
+        return "XGL_STENCIL_OP_KEEP";
+
+    case XGL_STENCIL_OP_REPLACE:
+        return "XGL_STENCIL_OP_REPLACE";
+
+    case XGL_STENCIL_OP_ZERO:
+        return "XGL_STENCIL_OP_ZERO";
+
+    }
+    return "Unhandled XGL_STENCIL_OP";
+}
+
+
+static const char* string_XGL_CHANNEL_FORMAT(XGL_CHANNEL_FORMAT input_value)
+{
+    switch ((XGL_CHANNEL_FORMAT)input_value)
+    {
+
+    case XGL_CH_FMT_B5G6R5:
+        return "XGL_CH_FMT_B5G6R5";
+
+    case XGL_CH_FMT_B8G8R8A8:
+        return "XGL_CH_FMT_B8G8R8A8";
+
+    case XGL_CH_FMT_BC1:
+        return "XGL_CH_FMT_BC1";
+
+    case XGL_CH_FMT_BC2:
+        return "XGL_CH_FMT_BC2";
+
+    case XGL_CH_FMT_BC3:
+        return "XGL_CH_FMT_BC3";
+
+    case XGL_CH_FMT_BC4:
+        return "XGL_CH_FMT_BC4";
+
+    case XGL_CH_FMT_BC5:
+        return "XGL_CH_FMT_BC5";
+
+    case XGL_CH_FMT_BC6S:
+        return "XGL_CH_FMT_BC6S";
+
+    case XGL_CH_FMT_BC6U:
+        return "XGL_CH_FMT_BC6U";
+
+    case XGL_CH_FMT_BC7:
+        return "XGL_CH_FMT_BC7";
+
+    case XGL_CH_FMT_R10G10B10A2:
+        return "XGL_CH_FMT_R10G10B10A2";
+
+    case XGL_CH_FMT_R10G11B11:
+        return "XGL_CH_FMT_R10G11B11";
+
+    case XGL_CH_FMT_R11G11B10:
+        return "XGL_CH_FMT_R11G11B10";
+
+    case XGL_CH_FMT_R16:
+        return "XGL_CH_FMT_R16";
+
+    case XGL_CH_FMT_R16G16:
+        return "XGL_CH_FMT_R16G16";
+
+    case XGL_CH_FMT_R16G16B16A16:
+        return "XGL_CH_FMT_R16G16B16A16";
+
+    case XGL_CH_FMT_R16G8:
+        return "XGL_CH_FMT_R16G8";
+
+    case XGL_CH_FMT_R32:
+        return "XGL_CH_FMT_R32";
+
+    case XGL_CH_FMT_R32G32:
+        return "XGL_CH_FMT_R32G32";
+
+    case XGL_CH_FMT_R32G32B32:
+        return "XGL_CH_FMT_R32G32B32";
+
+    case XGL_CH_FMT_R32G32B32A32:
+        return "XGL_CH_FMT_R32G32B32A32";
+
+    case XGL_CH_FMT_R32G8:
+        return "XGL_CH_FMT_R32G8";
+
+    case XGL_CH_FMT_R4G4:
+        return "XGL_CH_FMT_R4G4";
+
+    case XGL_CH_FMT_R4G4B4A4:
+        return "XGL_CH_FMT_R4G4B4A4";
+
+    case XGL_CH_FMT_R5G5B5A1:
+        return "XGL_CH_FMT_R5G5B5A1";
+
+    case XGL_CH_FMT_R5G6B5:
+        return "XGL_CH_FMT_R5G6B5";
+
+    case XGL_CH_FMT_R8:
+        return "XGL_CH_FMT_R8";
+
+    case XGL_CH_FMT_R8G8:
+        return "XGL_CH_FMT_R8G8";
+
+    case XGL_CH_FMT_R8G8B8A8:
+        return "XGL_CH_FMT_R8G8B8A8";
+
+    case XGL_CH_FMT_R9G9B9E5:
+        return "XGL_CH_FMT_R9G9B9E5";
+
+    case XGL_CH_FMT_UNDEFINED:
+        return "XGL_CH_FMT_UNDEFINED";
+
+    }
+    return "Unhandled XGL_CHANNEL_FORMAT";
+}
+
+
+static const char* string_XGL_COMPARE_FUNC(XGL_COMPARE_FUNC input_value)
+{
+    switch ((XGL_COMPARE_FUNC)input_value)
+    {
+
+    case XGL_COMPARE_ALWAYS:
+        return "XGL_COMPARE_ALWAYS";
+
+    case XGL_COMPARE_EQUAL:
+        return "XGL_COMPARE_EQUAL";
+
+    case XGL_COMPARE_GREATER:
+        return "XGL_COMPARE_GREATER";
+
+    case XGL_COMPARE_GREATER_EQUAL:
+        return "XGL_COMPARE_GREATER_EQUAL";
+
+    case XGL_COMPARE_LESS:
+        return "XGL_COMPARE_LESS";
+
+    case XGL_COMPARE_LESS_EQUAL:
+        return "XGL_COMPARE_LESS_EQUAL";
+
+    case XGL_COMPARE_NEVER:
+        return "XGL_COMPARE_NEVER";
+
+    case XGL_COMPARE_NOT_EQUAL:
+        return "XGL_COMPARE_NOT_EQUAL";
+
+    }
+    return "Unhandled XGL_COMPARE_FUNC";
+}
+
+
+static const char* string_XGL_HEAP_MEMORY_TYPE(XGL_HEAP_MEMORY_TYPE input_value)
+{
+    switch ((XGL_HEAP_MEMORY_TYPE)input_value)
+    {
+
+    case XGL_HEAP_MEMORY_EMBEDDED:
+        return "XGL_HEAP_MEMORY_EMBEDDED";
+
+    case XGL_HEAP_MEMORY_LOCAL:
+        return "XGL_HEAP_MEMORY_LOCAL";
+
+    case XGL_HEAP_MEMORY_OTHER:
+        return "XGL_HEAP_MEMORY_OTHER";
+
+    case XGL_HEAP_MEMORY_REMOTE:
+        return "XGL_HEAP_MEMORY_REMOTE";
+
+    }
+    return "Unhandled XGL_HEAP_MEMORY_TYPE";
+}
+
+
+static const char* string_XGL_OBJECT_INFO_TYPE(XGL_OBJECT_INFO_TYPE input_value)
+{
+    switch ((XGL_OBJECT_INFO_TYPE)input_value)
+    {
+
+    case XGL_INFO_TYPE_MEMORY_REQUIREMENTS:
+        return "XGL_INFO_TYPE_MEMORY_REQUIREMENTS";
+
+    }
+    return "Unhandled XGL_OBJECT_INFO_TYPE";
+}
+
+
+static const char* string_XGL_IMAGE_TILING(XGL_IMAGE_TILING input_value)
+{
+    switch ((XGL_IMAGE_TILING)input_value)
+    {
+
+    case XGL_LINEAR_TILING:
+        return "XGL_LINEAR_TILING";
+
+    case XGL_OPTIMAL_TILING:
+        return "XGL_OPTIMAL_TILING";
+
+    }
+    return "Unhandled XGL_IMAGE_TILING";
+}
+
+
+static const char* string_XGL_PHYSICAL_GPU_INFO_TYPE(XGL_PHYSICAL_GPU_INFO_TYPE input_value)
+{
+    switch ((XGL_PHYSICAL_GPU_INFO_TYPE)input_value)
+    {
+
+    case XGL_INFO_TYPE_PHYSICAL_GPU_MEMORY_PROPERTIES:
+        return "XGL_INFO_TYPE_PHYSICAL_GPU_MEMORY_PROPERTIES";
+
+    case XGL_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE:
+        return "XGL_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE";
+
+    case XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES:
+        return "XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES";
+
+    case XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES:
+        return "XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES";
+
+    }
+    return "Unhandled XGL_PHYSICAL_GPU_INFO_TYPE";
+}
+
+
+static const char* string_XGL_FACE_ORIENTATION(XGL_FACE_ORIENTATION input_value)
+{
+    switch ((XGL_FACE_ORIENTATION)input_value)
+    {
+
+    case XGL_FRONT_FACE_CCW:
+        return "XGL_FRONT_FACE_CCW";
+
+    case XGL_FRONT_FACE_CW:
+        return "XGL_FRONT_FACE_CW";
+
+    }
+    return "Unhandled XGL_FACE_ORIENTATION";
+}
+
+
+static const char* string_XGL_QUEUE_FLAGS(XGL_QUEUE_FLAGS input_value)
+{
+    switch ((XGL_QUEUE_FLAGS)input_value)
+    {
+
+    case XGL_QUEUE_COMPUTE_BIT:
+        return "XGL_QUEUE_COMPUTE_BIT";
+
+    case XGL_QUEUE_DMA_BIT:
+        return "XGL_QUEUE_DMA_BIT";
+
+    case XGL_QUEUE_EXTENDED_BIT:
+        return "XGL_QUEUE_EXTENDED_BIT";
+
+    case XGL_QUEUE_GRAPHICS_BIT:
+        return "XGL_QUEUE_GRAPHICS_BIT";
+
+    }
+    return "Unhandled XGL_QUEUE_FLAGS";
+}
+
+
+static const char* string_XGL_PIPELINE_BIND_POINT(XGL_PIPELINE_BIND_POINT input_value)
+{
+    switch ((XGL_PIPELINE_BIND_POINT)input_value)
+    {
+
+    case XGL_PIPELINE_BIND_POINT_COMPUTE:
+        return "XGL_PIPELINE_BIND_POINT_COMPUTE";
+
+    case XGL_PIPELINE_BIND_POINT_GRAPHICS:
+        return "XGL_PIPELINE_BIND_POINT_GRAPHICS";
+
+    }
+    return "Unhandled XGL_PIPELINE_BIND_POINT";
+}
+
+
+static const char* string_XGL_BLEND(XGL_BLEND input_value)
+{
+    switch ((XGL_BLEND)input_value)
+    {
+
+    case XGL_BLEND_CONSTANT_ALPHA:
+        return "XGL_BLEND_CONSTANT_ALPHA";
+
+    case XGL_BLEND_CONSTANT_COLOR:
+        return "XGL_BLEND_CONSTANT_COLOR";
+
+    case XGL_BLEND_DEST_ALPHA:
+        return "XGL_BLEND_DEST_ALPHA";
+
+    case XGL_BLEND_DEST_COLOR:
+        return "XGL_BLEND_DEST_COLOR";
+
+    case XGL_BLEND_ONE:
+        return "XGL_BLEND_ONE";
+
+    case XGL_BLEND_ONE_MINUS_CONSTANT_ALPHA:
+        return "XGL_BLEND_ONE_MINUS_CONSTANT_ALPHA";
+
+    case XGL_BLEND_ONE_MINUS_CONSTANT_COLOR:
+        return "XGL_BLEND_ONE_MINUS_CONSTANT_COLOR";
+
+    case XGL_BLEND_ONE_MINUS_DEST_ALPHA:
+        return "XGL_BLEND_ONE_MINUS_DEST_ALPHA";
+
+    case XGL_BLEND_ONE_MINUS_DEST_COLOR:
+        return "XGL_BLEND_ONE_MINUS_DEST_COLOR";
+
+    case XGL_BLEND_ONE_MINUS_SRC1_ALPHA:
+        return "XGL_BLEND_ONE_MINUS_SRC1_ALPHA";
+
+    case XGL_BLEND_ONE_MINUS_SRC1_COLOR:
+        return "XGL_BLEND_ONE_MINUS_SRC1_COLOR";
+
+    case XGL_BLEND_ONE_MINUS_SRC_ALPHA:
+        return "XGL_BLEND_ONE_MINUS_SRC_ALPHA";
+
+    case XGL_BLEND_ONE_MINUS_SRC_COLOR:
+        return "XGL_BLEND_ONE_MINUS_SRC_COLOR";
+
+    case XGL_BLEND_SRC1_ALPHA:
+        return "XGL_BLEND_SRC1_ALPHA";
+
+    case XGL_BLEND_SRC1_COLOR:
+        return "XGL_BLEND_SRC1_COLOR";
+
+    case XGL_BLEND_SRC_ALPHA:
+        return "XGL_BLEND_SRC_ALPHA";
+
+    case XGL_BLEND_SRC_ALPHA_SATURATE:
+        return "XGL_BLEND_SRC_ALPHA_SATURATE";
+
+    case XGL_BLEND_SRC_COLOR:
+        return "XGL_BLEND_SRC_COLOR";
+
+    case XGL_BLEND_ZERO:
+        return "XGL_BLEND_ZERO";
+
+    }
+    return "Unhandled XGL_BLEND";
+}
+
diff --git a/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_string_helper.h b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_string_helper.h
new file mode 100644
index 0000000..833c840
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_string_helper.h
@@ -0,0 +1,553 @@
+//This is the copyright
+//#includes, #defines, globals and such...
+#include <xgl.h>
+#include <xgl_string_helper.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+char* xgl_print_xgl_raster_state_create_info(const XGL_RASTER_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sfillMode = %s\n%scullMode = %s\n%sfrontFace = %s\n%sdepthBias = %i\n%sdepthBiasClamp = %f\n%sslopeScaledDepthBias = %f\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, string_XGL_FILL_MODE(pStruct->fillMode), prefix, string_XGL_CULL_MODE(pStruct->cullMode), prefix, string_XGL_FACE_ORIENTATION(pStruct->frontFace), prefix, (pStruct->depthBias), prefix, (pStruct->depthBiasClamp), prefix, (pStruct->slopeScaledDepthBias));
+    return str;
+}
+char* xgl_print_xgl_gpu_compatibility_info(const XGL_GPU_COMPATIBILITY_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%scompatibilityFlags = %u\n", prefix, (pStruct->compatibilityFlags));
+    return str;
+}
+char* xgl_print_xgl_image_view_create_info(const XGL_IMAGE_VIEW_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%simage = %p\n%sviewType = %s\n%sformat = %p\n%schannels = %p\n%ssubresourceRange = %p\n%sminLod = %f\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->image), prefix, string_XGL_IMAGE_VIEW_TYPE(pStruct->viewType), prefix, (void*)&(pStruct->format), prefix, (void*)&(pStruct->channels), prefix, (void*)&(pStruct->subresourceRange), prefix, (pStruct->minLod));
+    return str;
+}
+char* xgl_print_xgl_memory_open_info(const XGL_MEMORY_OPEN_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%ssharedMem = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->sharedMem));
+    return str;
+}
+char* xgl_print_xgl_memory_heap_properties(const XGL_MEMORY_HEAP_PROPERTIES* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sstructSize = %u\n%sheapMemoryType = %s\n%sheapSize = %u\n%spageSize = %u\n%sflags = %u\n%sgpuReadPerfRating = %f\n%sgpuWritePerfRating = %f\n%scpuReadPerfRating = %f\n%scpuWritePerfRating = %f\n", prefix, (pStruct->structSize), prefix, string_XGL_HEAP_MEMORY_TYPE(pStruct->heapMemoryType), prefix, (pStruct->heapSize), prefix, (pStruct->pageSize), prefix, (pStruct->flags), prefix, (pStruct->gpuReadPerfRating), prefix, (pStruct->gpuWritePerfRating), prefix, (pStruct->cpuReadPerfRating), prefix, (pStruct->cpuWritePerfRating));
+    return str;
+}
+char* xgl_print_xgl_image_subresource(const XGL_IMAGE_SUBRESOURCE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%saspect = %s\n%smipLevel = %u\n%sarraySlice = %u\n", prefix, string_XGL_IMAGE_ASPECT(pStruct->aspect), prefix, (pStruct->mipLevel), prefix, (pStruct->arraySlice));
+    return str;
+}
+char* xgl_print_xgl_physical_gpu_performance(const XGL_PHYSICAL_GPU_PERFORMANCE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%smaxGpuClock = %f\n%saluPerClock = %f\n%stexPerClock = %f\n%sprimsPerClock = %f\n%spixelsPerClock = %f\n", prefix, (pStruct->maxGpuClock), prefix, (pStruct->aluPerClock), prefix, (pStruct->texPerClock), prefix, (pStruct->primsPerClock), prefix, (pStruct->pixelsPerClock));
+    return str;
+}
+char* xgl_print_xgl_physical_gpu_memory_properties(const XGL_PHYSICAL_GPU_MEMORY_PROPERTIES* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sstructSize = %u\n%ssupportsMigration = %s\n%ssupportsVirtualMemoryRemapping = %s\n%ssupportsPinning = %s\n", prefix, (pStruct->structSize), prefix, (pStruct->supportsMigration) ? "TRUE" : "FALSE", prefix, (pStruct->supportsVirtualMemoryRemapping) ? "TRUE" : "FALSE", prefix, (pStruct->supportsPinning) ? "TRUE" : "FALSE");
+    return str;
+}
+char* xgl_print_xgl_pipeline_shader(const XGL_PIPELINE_SHADER* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sstage = %s\n%sshader = %p\n%sdescriptorSetMapping = %p\n%slinkConstBufferCount = %u\n%spLinkConstBufferInfo = %p\n%sdynamicMemoryViewMapping = %p\n", prefix, string_XGL_PIPELINE_SHADER_STAGE(pStruct->stage), prefix, (void*)(pStruct->shader), prefix, (void*)(pStruct->descriptorSetMapping), prefix, (pStruct->linkConstBufferCount), prefix, (void*)(pStruct->pLinkConstBufferInfo), prefix, (void*)&(pStruct->dynamicMemoryViewMapping));
+    return str;
+}
+char* xgl_print_xgl_fence_create_info(const XGL_FENCE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_pipeline_cb_attachment_state(const XGL_PIPELINE_CB_ATTACHMENT_STATE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sblendEnable = %s\n%sformat = %p\n%schannelWriteMask = %hu\n", prefix, (pStruct->blendEnable) ? "TRUE" : "FALSE", prefix, (void*)&(pStruct->format), prefix, (pStruct->channelWriteMask));
+    return str;
+}
+char* xgl_print_xgl_alloc_callbacks(const XGL_ALLOC_CALLBACKS* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%spUserData = %p\n%spfnAlloc = %p\n%spfnFree = %p\n", prefix, (pStruct->pUserData), prefix, (void*)(pStruct->pfnAlloc), prefix, (void*)(pStruct->pfnFree));
+    return str;
+}
+char* xgl_print_xgl_color_attachment_view_create_info(const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%simage = %p\n%sformat = %p\n%smipLevel = %u\n%sbaseArraySlice = %u\n%sarraySize = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->image), prefix, (void*)&(pStruct->format), prefix, (pStruct->mipLevel), prefix, (pStruct->baseArraySlice), prefix, (pStruct->arraySize));
+    return str;
+}
+char* xgl_print_xgl_image_copy(const XGL_IMAGE_COPY* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssrcSubresource = %p\n%ssrcOffset = %p\n%sdestSubresource = %p\n%sdestOffset = %p\n%sextent = %p\n", prefix, (void*)&(pStruct->srcSubresource), prefix, (void*)&(pStruct->srcOffset), prefix, (void*)&(pStruct->destSubresource), prefix, (void*)&(pStruct->destOffset), prefix, (void*)&(pStruct->extent));
+    return str;
+}
+char* xgl_print_xgl_msaa_state_create_info(const XGL_MSAA_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%ssamples = %u\n%ssampleMask = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->samples), prefix, (pStruct->sampleMask));
+    return str;
+}
+char* xgl_print_xgl_descriptor_set_create_info(const XGL_DESCRIPTOR_SET_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sslots = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->slots));
+    return str;
+}
+char* xgl_print_xgl_color_attachment_bind_info(const XGL_COLOR_ATTACHMENT_BIND_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sview = %p\n%scolorAttachmentState = %s\n", prefix, (void*)(pStruct->view), prefix, string_XGL_IMAGE_STATE(pStruct->colorAttachmentState));
+    return str;
+}
+char* xgl_print_xgl_event_create_info(const XGL_EVENT_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_memory_requirements(const XGL_MEMORY_REQUIREMENTS* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssize = %u\n%salignment = %u\n%sheapCount = %u\n%sheaps = %p\n", prefix, (pStruct->size), prefix, (pStruct->alignment), prefix, (pStruct->heapCount), prefix, (void*)(pStruct->heaps));
+    return str;
+}
+char* xgl_print_xgl_queue_semaphore_open_info(const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%ssharedSemaphore = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->sharedSemaphore));
+    return str;
+}
+char* xgl_print_xgl_image_resolve(const XGL_IMAGE_RESOLVE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssrcSubresource = %p\n%ssrcOffset = %p\n%sdestSubresource = %p\n%sdestOffset = %p\n%sextent = %p\n", prefix, (void*)&(pStruct->srcSubresource), prefix, (void*)&(pStruct->srcOffset), prefix, (void*)&(pStruct->destSubresource), prefix, (void*)&(pStruct->destOffset), prefix, (void*)&(pStruct->extent));
+    return str;
+}
+char* xgl_print_xgl_draw_indexed_indirect_cmd(const XGL_DRAW_INDEXED_INDIRECT_CMD* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sindexCount = %u\n%sinstanceCount = %u\n%sfirstIndex = %u\n%svertexOffset = %i\n%sfirstInstance = %u\n", prefix, (pStruct->indexCount), prefix, (pStruct->instanceCount), prefix, (pStruct->firstIndex), prefix, (pStruct->vertexOffset), prefix, (pStruct->firstInstance));
+    return str;
+}
+char* xgl_print_xgl_compute_pipeline_create_info(const XGL_COMPUTE_PIPELINE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%scs = %p\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)&(pStruct->cs), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_peer_image_open_info(const XGL_PEER_IMAGE_OPEN_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%soriginalImage = %p\n", prefix, (void*)(pStruct->originalImage));
+    return str;
+}
+char* xgl_print_xgl_physical_gpu_queue_properties(const XGL_PHYSICAL_GPU_QUEUE_PROPERTIES* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sstructSize = %u\n%squeueFlags = %u\n%squeueCount = %u\n%smaxAtomicCounters = %u\n%ssupportsTimestamps = %s\n", prefix, (pStruct->structSize), prefix, (pStruct->queueFlags), prefix, (pStruct->queueCount), prefix, (pStruct->maxAtomicCounters), prefix, (pStruct->supportsTimestamps) ? "TRUE" : "FALSE");
+    return str;
+}
+char* xgl_print_xgl_pipeline_statistics_data(const XGL_PIPELINE_STATISTICS_DATA* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sfsInvocations = %lu\n%scPrimitives = %lu\n%scInvocations = %lu\n%svsInvocations = %lu\n%sgsInvocations = %lu\n%sgsPrimitives = %lu\n%siaPrimitives = %lu\n%siaVertices = %lu\n%stcsInvocations = %lu\n%stesInvocations = %lu\n%scsInvocations = %lu\n", prefix, (pStruct->fsInvocations), prefix, (pStruct->cPrimitives), prefix, (pStruct->cInvocations), prefix, (pStruct->vsInvocations), prefix, (pStruct->gsInvocations), prefix, (pStruct->gsPrimitives), prefix, (pStruct->iaPrimitives), prefix, (pStruct->iaVertices), prefix, (pStruct->tcsInvocations), prefix, (pStruct->tesInvocations), prefix, (pStruct->csInvocations));
+    return str;
+}
+char* xgl_print_xgl_device_queue_create_info(const XGL_DEVICE_QUEUE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%squeueNodeIndex = %u\n%squeueCount = %u\n", prefix, (pStruct->queueNodeIndex), prefix, (pStruct->queueCount));
+    return str;
+}
+char* xgl_print_xgl_sampler_create_info(const XGL_SAMPLER_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%smagFilter = %s\n%sminFilter = %s\n%smipMode = %s\n%saddressU = %s\n%saddressV = %s\n%saddressW = %s\n%smipLodBias = %f\n%smaxAnisotropy = %u\n%scompareFunc = %s\n%sminLod = %f\n%smaxLod = %f\n%sborderColorType = %s\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, string_XGL_TEX_FILTER(pStruct->magFilter), prefix, string_XGL_TEX_FILTER(pStruct->minFilter), prefix, string_XGL_TEX_MIPMAP_MODE(pStruct->mipMode), prefix, string_XGL_TEX_ADDRESS(pStruct->addressU), prefix, string_XGL_TEX_ADDRESS(pStruct->addressV), prefix, string_XGL_TEX_ADDRESS(pStruct->addressW), prefix, (pStruct->mipLodBias), prefix, (pStruct->maxAnisotropy), prefix, string_XGL_COMPARE_FUNC(pStruct->compareFunc), prefix, (pStruct->minLod), prefix, (pStruct->maxLod), prefix, string_XGL_BORDER_COLOR_TYPE(pStruct->borderColorType));
+    return str;
+}
+char* xgl_print_xgl_queue_semaphore_create_info(const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sinitialCount = %u\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->initialCount), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_format(const XGL_FORMAT* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%schannelFormat = %s\n%snumericFormat = %s\n", prefix, string_XGL_CHANNEL_FORMAT(pStruct->channelFormat), prefix, string_XGL_NUM_FORMAT(pStruct->numericFormat));
+    return str;
+}
+char* xgl_print_xgl_memory_state_transition(const XGL_MEMORY_STATE_TRANSITION* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%smem = %p\n%soldState = %s\n%snewState = %s\n%soffset = %u\n%sregionSize = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->mem), prefix, string_XGL_MEMORY_STATE(pStruct->oldState), prefix, string_XGL_MEMORY_STATE(pStruct->newState), prefix, (pStruct->offset), prefix, (pStruct->regionSize));
+    return str;
+}
+char* xgl_print_xgl_extent3d(const XGL_EXTENT3D* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%swidth = %i\n%sheight = %i\n%sdepth = %i\n", prefix, (pStruct->width), prefix, (pStruct->height), prefix, (pStruct->depth));
+    return str;
+}
+char* xgl_print_xgl_dynamic_memory_view_slot_info(const XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sslotObjectType = %s\n%sshaderEntityIndex = %u\n", prefix, string_XGL_DESCRIPTOR_SET_SLOT_TYPE(pStruct->slotObjectType), prefix, (pStruct->shaderEntityIndex));
+    return str;
+}
+char* xgl_print_xgl_image_view_attach_info(const XGL_IMAGE_VIEW_ATTACH_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sview = %p\n%sstate = %s\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->view), prefix, string_XGL_IMAGE_STATE(pStruct->state));
+    return str;
+}
+char* xgl_print_xgl_image_subresource_range(const XGL_IMAGE_SUBRESOURCE_RANGE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%saspect = %s\n%sbaseMipLevel = %u\n%smipLevels = %u\n%sbaseArraySlice = %u\n%sarraySize = %u\n", prefix, string_XGL_IMAGE_ASPECT(pStruct->aspect), prefix, (pStruct->baseMipLevel), prefix, (pStruct->mipLevels), prefix, (pStruct->baseArraySlice), prefix, (pStruct->arraySize));
+    return str;
+}
+char* xgl_print_xgl_pipeline_db_state_create_info(const XGL_PIPELINE_DB_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sformat = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)&(pStruct->format));
+    return str;
+}
+char* xgl_print_xgl_application_info(const XGL_APPLICATION_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%spAppName = %p\n%sappVersion = %u\n%spEngineName = %p\n%sengineVersion = %u\n%sapiVersion = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->pAppName), prefix, (pStruct->appVersion), prefix, (pStruct->pEngineName), prefix, (pStruct->engineVersion), prefix, (pStruct->apiVersion));
+    return str;
+}
+char* xgl_print_xgl_offset2d(const XGL_OFFSET2D* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sx = %i\n%sy = %i\n", prefix, (pStruct->x), prefix, (pStruct->y));
+    return str;
+}
+char* xgl_print_xgl_viewport_state_create_info(const XGL_VIEWPORT_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sviewportCount = %u\n%sscissorEnable = %s\n%sviewports = %p\n%sscissors = %p\n", prefix, (pStruct->viewportCount), prefix, (pStruct->scissorEnable) ? "TRUE" : "FALSE", prefix, (void*)(pStruct->viewports), prefix, (void*)(pStruct->scissors));
+    return str;
+}
+char* xgl_print_xgl_image_state_transition(const XGL_IMAGE_STATE_TRANSITION* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%simage = %p\n%soldState = %s\n%snewState = %s\n%ssubresourceRange = %p\n", prefix, (void*)(pStruct->image), prefix, string_XGL_IMAGE_STATE(pStruct->oldState), prefix, string_XGL_IMAGE_STATE(pStruct->newState), prefix, (void*)&(pStruct->subresourceRange));
+    return str;
+}
+char* xgl_print_xgl_device_create_info(const XGL_DEVICE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%squeueRecordCount = %u\n%spRequestedQueues = %p\n%sextensionCount = %u\n%sppEnabledExtensionNames = %p\n%smaxValidationLevel = %s\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->queueRecordCount), prefix, (void*)(pStruct->pRequestedQueues), prefix, (pStruct->extensionCount), prefix, (pStruct->ppEnabledExtensionNames), prefix, string_XGL_VALIDATION_LEVEL(pStruct->maxValidationLevel), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_image_create_info(const XGL_IMAGE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%simageType = %s\n%sformat = %p\n%sextent = %p\n%smipLevels = %u\n%sarraySize = %u\n%ssamples = %u\n%stiling = %s\n%susage = %u\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, string_XGL_IMAGE_TYPE(pStruct->imageType), prefix, (void*)&(pStruct->format), prefix, (void*)&(pStruct->extent), prefix, (pStruct->mipLevels), prefix, (pStruct->arraySize), prefix, (pStruct->samples), prefix, string_XGL_IMAGE_TILING(pStruct->tiling), prefix, (pStruct->usage), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_rect(const XGL_RECT* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%soffset = %p\n%sextent = %p\n", prefix, (void*)&(pStruct->offset), prefix, (void*)&(pStruct->extent));
+    return str;
+}
+char* xgl_print_xgl_memory_copy(const XGL_MEMORY_COPY* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssrcOffset = %u\n%sdestOffset = %u\n%scopySize = %u\n", prefix, (pStruct->srcOffset), prefix, (pStruct->destOffset), prefix, (pStruct->copySize));
+    return str;
+}
+char* xgl_print_xgl_descriptor_slot_info(const XGL_DESCRIPTOR_SLOT_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sslotObjectType = %s\n%sshaderEntityIndex = %u\n%spNextLevelSet = %p\n", prefix, string_XGL_DESCRIPTOR_SET_SLOT_TYPE(pStruct->slotObjectType), prefix, (pStruct->shaderEntityIndex), prefix, (pStruct->pNextLevelSet));
+    return str;
+}
+char* xgl_print_xgl_link_const_buffer(const XGL_LINK_CONST_BUFFER* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sbufferId = %u\n%sbufferSize = %u\n%spBufferData = %p\n", prefix, (pStruct->bufferId), prefix, (pStruct->bufferSize), prefix, (pStruct->pBufferData));
+    return str;
+}
+char* xgl_print_xgl_memory_image_copy(const XGL_MEMORY_IMAGE_COPY* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%smemOffset = %u\n%simageSubresource = %p\n%simageOffset = %p\n%simageExtent = %p\n", prefix, (pStruct->memOffset), prefix, (void*)&(pStruct->imageSubresource), prefix, (void*)&(pStruct->imageOffset), prefix, (void*)&(pStruct->imageExtent));
+    return str;
+}
+char* xgl_print_xgl_depth_stencil_state_create_info(const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sdepthTestEnable = %s\n%sdepthWriteEnable = %s\n%sdepthFunc = %s\n%sdepthBoundsEnable = %s\n%sminDepth = %f\n%smaxDepth = %f\n%sstencilTestEnable = %s\n%sstencilReadMask = %u\n%sstencilWriteMask = %u\n%sfront = %p\n%sback = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->depthTestEnable) ? "TRUE" : "FALSE", prefix, (pStruct->depthWriteEnable) ? "TRUE" : "FALSE", prefix, string_XGL_COMPARE_FUNC(pStruct->depthFunc), prefix, (pStruct->depthBoundsEnable) ? "TRUE" : "FALSE", prefix, (pStruct->minDepth), prefix, (pStruct->maxDepth), prefix, (pStruct->stencilTestEnable) ? "TRUE" : "FALSE", prefix, (pStruct->stencilReadMask), prefix, (pStruct->stencilWriteMask), prefix, (void*)&(pStruct->front), prefix, (void*)&(pStruct->back));
+    return str;
+}
+char* xgl_print_xgl_viewport(const XGL_VIEWPORT* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%soriginX = %f\n%soriginY = %f\n%swidth = %f\n%sheight = %f\n%sminDepth = %f\n%smaxDepth = %f\n", prefix, (pStruct->originX), prefix, (pStruct->originY), prefix, (pStruct->width), prefix, (pStruct->height), prefix, (pStruct->minDepth), prefix, (pStruct->maxDepth));
+    return str;
+}
+char* xgl_print_xgl_descriptor_set_mapping(const XGL_DESCRIPTOR_SET_MAPPING* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sdescriptorCount = %u\n%spDescriptorInfo = %p\n", prefix, (pStruct->descriptorCount), prefix, (void*)(pStruct->pDescriptorInfo));
+    return str;
+}
+char* xgl_print_xgl_peer_memory_open_info(const XGL_PEER_MEMORY_OPEN_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%soriginalMem = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->originalMem));
+    return str;
+}
+char* xgl_print_xgl_subresource_layout(const XGL_SUBRESOURCE_LAYOUT* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%soffset = %u\n%ssize = %u\n%srowPitch = %u\n%sdepthPitch = %u\n", prefix, (pStruct->offset), prefix, (pStruct->size), prefix, (pStruct->rowPitch), prefix, (pStruct->depthPitch));
+    return str;
+}
+char* xgl_print_xgl_descriptor_set_attach_info(const XGL_DESCRIPTOR_SET_ATTACH_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sdescriptorSet = %p\n%sslotOffset = %u\n", prefix, (void*)(pStruct->descriptorSet), prefix, (pStruct->slotOffset));
+    return str;
+}
+char* xgl_print_xgl_pipeline_tess_state_create_info(const XGL_PIPELINE_TESS_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%spatchControlPoints = %u\n%soptimalTessFactor = %f\n%sfixedTessFactor = %f\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->patchControlPoints), prefix, (pStruct->optimalTessFactor), prefix, (pStruct->fixedTessFactor));
+    return str;
+}
+char* xgl_print_xgl_pipeline_rs_state_create_info(const XGL_PIPELINE_RS_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sdepthClipEnable = %s\n%srasterizerDiscardEnable = %s\n%spointSize = %f\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->depthClipEnable) ? "TRUE" : "FALSE", prefix, (pStruct->rasterizerDiscardEnable) ? "TRUE" : "FALSE", prefix, (pStruct->pointSize));
+    return str;
+}
+char* xgl_print_xgl_stencil_op_state(const XGL_STENCIL_OP_STATE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sstencilFailOp = %s\n%sstencilPassOp = %s\n%sstencilDepthFailOp = %s\n%sstencilFunc = %s\n%sstencilRef = %u\n", prefix, string_XGL_STENCIL_OP(pStruct->stencilFailOp), prefix, string_XGL_STENCIL_OP(pStruct->stencilPassOp), prefix, string_XGL_STENCIL_OP(pStruct->stencilDepthFailOp), prefix, string_XGL_COMPARE_FUNC(pStruct->stencilFunc), prefix, (pStruct->stencilRef));
+    return str;
+}
+char* xgl_print_xgl_shader_create_info(const XGL_SHADER_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%scodeSize = %u\n%spCode = %p\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->codeSize), prefix, (pStruct->pCode), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_color_blend_state_create_info(const XGL_COLOR_BLEND_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sattachment = %p\n%sblendConst = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->attachment), prefix, (void*)(pStruct->blendConst));
+    return str;
+}
+char* xgl_print_xgl_pipeline_cb_state_create_info(const XGL_PIPELINE_CB_STATE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%salphaToCoverageEnable = %s\n%sdualSourceBlendEnable = %s\n%slogicOp = %s\n%sattachment = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->alphaToCoverageEnable) ? "TRUE" : "FALSE", prefix, (pStruct->dualSourceBlendEnable) ? "TRUE" : "FALSE", prefix, string_XGL_LOGIC_OP(pStruct->logicOp), prefix, (void*)(pStruct->attachment));
+    return str;
+}
+char* xgl_print_xgl_channel_mapping(const XGL_CHANNEL_MAPPING* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sr = %s\n%sg = %s\n%sb = %s\n%sa = %s\n", prefix, string_XGL_CHANNEL_SWIZZLE(pStruct->r), prefix, string_XGL_CHANNEL_SWIZZLE(pStruct->g), prefix, string_XGL_CHANNEL_SWIZZLE(pStruct->b), prefix, string_XGL_CHANNEL_SWIZZLE(pStruct->a));
+    return str;
+}
+char* xgl_print_xgl_depth_stencil_view_create_info(const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%simage = %p\n%smipLevel = %u\n%sbaseArraySlice = %u\n%sarraySize = %u\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->image), prefix, (pStruct->mipLevel), prefix, (pStruct->baseArraySlice), prefix, (pStruct->arraySize), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_virtual_memory_remap_range(const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%svirtualMem = %p\n%svirtualStartPage = %u\n%srealMem = %p\n%srealStartPage = %u\n%spageCount = %u\n", prefix, (void*)(pStruct->virtualMem), prefix, (pStruct->virtualStartPage), prefix, (void*)(pStruct->realMem), prefix, (pStruct->realStartPage), prefix, (pStruct->pageCount));
+    return str;
+}
+char* xgl_print_xgl_cmd_buffer_create_info(const XGL_CMD_BUFFER_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%squeueType = %s\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, string_XGL_QUEUE_TYPE(pStruct->queueType), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_format_properties(const XGL_FORMAT_PROPERTIES* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%slinearTilingFeatures = %u\n%soptimalTilingFeatures = %u\n", prefix, (pStruct->linearTilingFeatures), prefix, (pStruct->optimalTilingFeatures));
+    return str;
+}
+char* xgl_print_xgl_physical_gpu_properties(const XGL_PHYSICAL_GPU_PROPERTIES* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sstructSize = %u\n%sapiVersion = %u\n%sdriverVersion = %u\n%svendorId = %u\n%sdeviceId = %u\n%sgpuType = %s\n%sgpuName = %s\n%smaxMemRefsPerSubmission = %u\n%svirtualMemPageSize = %u\n%smaxInlineMemoryUpdateSize = %u\n%smaxBoundDescriptorSets = %u\n%smaxThreadGroupSize = %u\n%stimestampFrequency = %lu\n%smultiColorAttachmentClears = %s\n", prefix, (pStruct->structSize), prefix, (pStruct->apiVersion), prefix, (pStruct->driverVersion), prefix, (pStruct->vendorId), prefix, (pStruct->deviceId), prefix, string_XGL_PHYSICAL_GPU_TYPE(pStruct->gpuType), prefix, (pStruct->gpuName), prefix, (pStruct->maxMemRefsPerSubmission), prefix, (pStruct->virtualMemPageSize), prefix, (pStruct->maxInlineMemoryUpdateSize), prefix, (pStruct->maxBoundDescriptorSets), prefix, (pStruct->maxThreadGroupSize), prefix, (pStruct->timestampFrequency), prefix, (pStruct->multiColorAttachmentClears) ? "TRUE" : "FALSE");
+    return str;
+}
+char* xgl_print_xgl_depth_stencil_bind_info(const XGL_DEPTH_STENCIL_BIND_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sview = %p\n%sdepthState = %s\n%sstencilState = %s\n", prefix, (void*)(pStruct->view), prefix, string_XGL_IMAGE_STATE(pStruct->depthState), prefix, string_XGL_IMAGE_STATE(pStruct->stencilState));
+    return str;
+}
+char* xgl_print_xgl_draw_indirect_cmd(const XGL_DRAW_INDIRECT_CMD* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%svertexCount = %u\n%sinstanceCount = %u\n%sfirstVertex = %u\n%sfirstInstance = %u\n", prefix, (pStruct->vertexCount), prefix, (pStruct->instanceCount), prefix, (pStruct->firstVertex), prefix, (pStruct->firstInstance));
+    return str;
+}
+char* xgl_print_xgl_graphics_pipeline_create_info(const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sflags = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_pipeline_ia_state_create_info(const XGL_PIPELINE_IA_STATE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%stopology = %s\n%sdisableVertexReuse = %s\n%sprovokingVertex = %s\n%sprimitiveRestartEnable = %s\n%sprimitiveRestartIndex = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, string_XGL_PRIMITIVE_TOPOLOGY(pStruct->topology), prefix, (pStruct->disableVertexReuse) ? "TRUE" : "FALSE", prefix, string_XGL_PROVOKING_VERTEX_CONVENTION(pStruct->provokingVertex), prefix, (pStruct->primitiveRestartEnable) ? "TRUE" : "FALSE", prefix, (pStruct->primitiveRestartIndex));
+    return str;
+}
+char* xgl_print_xgl_color_attachment_blend_state(const XGL_COLOR_ATTACHMENT_BLEND_STATE* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sblendEnable = %s\n%ssrcBlendColor = %s\n%sdestBlendColor = %s\n%sblendFuncColor = %s\n%ssrcBlendAlpha = %s\n%sdestBlendAlpha = %s\n%sblendFuncAlpha = %s\n", prefix, (pStruct->blendEnable) ? "TRUE" : "FALSE", prefix, string_XGL_BLEND(pStruct->srcBlendColor), prefix, string_XGL_BLEND(pStruct->destBlendColor), prefix, string_XGL_BLEND_FUNC(pStruct->blendFuncColor), prefix, string_XGL_BLEND(pStruct->srcBlendAlpha), prefix, string_XGL_BLEND(pStruct->destBlendAlpha), prefix, string_XGL_BLEND_FUNC(pStruct->blendFuncAlpha));
+    return str;
+}
+char* xgl_print_xgl_extent2d(const XGL_EXTENT2D* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%swidth = %i\n%sheight = %i\n", prefix, (pStruct->width), prefix, (pStruct->height));
+    return str;
+}
+char* xgl_print_xgl_memory_alloc_info(const XGL_MEMORY_ALLOC_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sallocationSize = %u\n%salignment = %u\n%sflags = %u\n%sheapCount = %u\n%sheaps = %p\n%smemPriority = %s\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (pStruct->allocationSize), prefix, (pStruct->alignment), prefix, (pStruct->flags), prefix, (pStruct->heapCount), prefix, (void*)(pStruct->heaps), prefix, string_XGL_MEMORY_PRIORITY(pStruct->memPriority));
+    return str;
+}
+char* xgl_print_xgl_memory_ref(const XGL_MEMORY_REF* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%smem = %p\n%sflags = %u\n", prefix, (void*)(pStruct->mem), prefix, (pStruct->flags));
+    return str;
+}
+char* xgl_print_xgl_query_pool_create_info(const XGL_QUERY_POOL_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%squeryType = %s\n%sslots = %u\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, string_XGL_QUERY_TYPE(pStruct->queryType), prefix, (pStruct->slots));
+    return str;
+}
+char* xgl_print_xgl_offset3d(const XGL_OFFSET3D* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sx = %i\n%sy = %i\n%sz = %i\n", prefix, (pStruct->x), prefix, (pStruct->y), prefix, (pStruct->z));
+    return str;
+}
+char* xgl_print_xgl_pipeline_shader_stage_create_info(const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%sshader = %p\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)&(pStruct->shader));
+    return str;
+}
+char* xgl_print_xgl_memory_view_attach_info(const XGL_MEMORY_VIEW_ATTACH_INFO* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%ssType = %s\n%spNext = %p\n%smem = %p\n%soffset = %u\n%srange = %u\n%sstride = %u\n%sformat = %p\n%sstate = %s\n", prefix, string_XGL_STRUCTURE_TYPE(pStruct->sType), prefix, (pStruct->pNext), prefix, (void*)(pStruct->mem), prefix, (pStruct->offset), prefix, (pStruct->range), prefix, (pStruct->stride), prefix, (void*)&(pStruct->format), prefix, string_XGL_MEMORY_STATE(pStruct->state));
+    return str;
+}
+char* xgl_print_xgl_dispatch_indirect_cmd(const XGL_DISPATCH_INDIRECT_CMD* pStruct, const char* prefix)
+{
+    char* str;
+    str = (char*)malloc(sizeof(char)*1024);
+    sprintf(str, "%sx = %u\n%sy = %u\n%sz = %u\n", prefix, (pStruct->x), prefix, (pStruct->y), prefix, (pStruct->z));
+    return str;
+}
diff --git a/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_wrappers.cpp b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_wrappers.cpp
new file mode 100644
index 0000000..3bf712b
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_wrappers.cpp
@@ -0,0 +1,3974 @@
+//This is the copyright
+//#includes, #defines, globals and such...
+#include <stdio.h>
+#include <xgl_struct_wrappers.h>
+#include <xgl_string_helper.h>
+
+void dynamic_display_full_txt(const XGL_VOID* pStruct, uint32_t indent)
+{
+    // Cast to APP_INFO ptr initially just to pull sType off struct
+    XGL_STRUCTURE_TYPE sType = ((XGL_APPLICATION_INFO*)pStruct)->sType;    switch (sType)
+    {
+        case XGL_STRUCTURE_TYPE_APPLICATION_INFO:
+        {
+            xgl_application_info_struct_wrapper swc0((XGL_APPLICATION_INFO*)pStruct);
+            swc0.set_indent(indent);
+            swc0.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO:
+        {
+            xgl_cmd_buffer_create_info_struct_wrapper swc1((XGL_CMD_BUFFER_CREATE_INFO*)pStruct);
+            swc1.set_indent(indent);
+            swc1.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO:
+        {
+            xgl_color_attachment_view_create_info_struct_wrapper swc2((XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO*)pStruct);
+            swc2.set_indent(indent);
+            swc2.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_COLOR_BLEND_STATE_CREATE_INFO:
+        {
+            xgl_color_blend_state_create_info_struct_wrapper swc3((XGL_COLOR_BLEND_STATE_CREATE_INFO*)pStruct);
+            swc3.set_indent(indent);
+            swc3.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
+        {
+            xgl_compute_pipeline_create_info_struct_wrapper swc4((XGL_COMPUTE_PIPELINE_CREATE_INFO*)pStruct);
+            swc4.set_indent(indent);
+            swc4.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_DEPTH_STENCIL_STATE_CREATE_INFO:
+        {
+            xgl_depth_stencil_state_create_info_struct_wrapper swc5((XGL_DEPTH_STENCIL_STATE_CREATE_INFO*)pStruct);
+            swc5.set_indent(indent);
+            swc5.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO:
+        {
+            xgl_depth_stencil_view_create_info_struct_wrapper swc6((XGL_DEPTH_STENCIL_VIEW_CREATE_INFO*)pStruct);
+            swc6.set_indent(indent);
+            swc6.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_CREATE_INFO:
+        {
+            xgl_descriptor_set_create_info_struct_wrapper swc7((XGL_DESCRIPTOR_SET_CREATE_INFO*)pStruct);
+            swc7.set_indent(indent);
+            swc7.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO:
+        {
+            xgl_device_create_info_struct_wrapper swc8((XGL_DEVICE_CREATE_INFO*)pStruct);
+            swc8.set_indent(indent);
+            swc8.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO:
+        {
+            xgl_event_create_info_struct_wrapper swc9((XGL_EVENT_CREATE_INFO*)pStruct);
+            swc9.set_indent(indent);
+            swc9.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO:
+        {
+            xgl_fence_create_info_struct_wrapper swc10((XGL_FENCE_CREATE_INFO*)pStruct);
+            swc10.set_indent(indent);
+            swc10.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
+        {
+            xgl_graphics_pipeline_create_info_struct_wrapper swc11((XGL_GRAPHICS_PIPELINE_CREATE_INFO*)pStruct);
+            swc11.set_indent(indent);
+            swc11.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO:
+        {
+            xgl_image_create_info_struct_wrapper swc12((XGL_IMAGE_CREATE_INFO*)pStruct);
+            swc12.set_indent(indent);
+            swc12.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO:
+        {
+            xgl_image_view_attach_info_struct_wrapper swc13((XGL_IMAGE_VIEW_ATTACH_INFO*)pStruct);
+            swc13.set_indent(indent);
+            swc13.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO:
+        {
+            xgl_image_view_create_info_struct_wrapper swc14((XGL_IMAGE_VIEW_CREATE_INFO*)pStruct);
+            swc14.set_indent(indent);
+            swc14.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO:
+        {
+            xgl_memory_alloc_info_struct_wrapper swc15((XGL_MEMORY_ALLOC_INFO*)pStruct);
+            swc15.set_indent(indent);
+            swc15.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_MEMORY_OPEN_INFO:
+        {
+            xgl_memory_open_info_struct_wrapper swc16((XGL_MEMORY_OPEN_INFO*)pStruct);
+            swc16.set_indent(indent);
+            swc16.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_MEMORY_STATE_TRANSITION:
+        {
+            xgl_memory_state_transition_struct_wrapper swc17((XGL_MEMORY_STATE_TRANSITION*)pStruct);
+            swc17.set_indent(indent);
+            swc17.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_MEMORY_VIEW_ATTACH_INFO:
+        {
+            xgl_memory_view_attach_info_struct_wrapper swc18((XGL_MEMORY_VIEW_ATTACH_INFO*)pStruct);
+            swc18.set_indent(indent);
+            swc18.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_MSAA_STATE_CREATE_INFO:
+        {
+            xgl_msaa_state_create_info_struct_wrapper swc19((XGL_MSAA_STATE_CREATE_INFO*)pStruct);
+            swc19.set_indent(indent);
+            swc19.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PEER_MEMORY_OPEN_INFO:
+        {
+            xgl_peer_memory_open_info_struct_wrapper swc20((XGL_PEER_MEMORY_OPEN_INFO*)pStruct);
+            swc20.set_indent(indent);
+            swc20.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
+        {
+            xgl_pipeline_cb_state_create_info_struct_wrapper swc21((XGL_PIPELINE_CB_STATE*)pStruct);
+            swc21.set_indent(indent);
+            swc21.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
+        {
+            xgl_pipeline_db_state_create_info_struct_wrapper swc22((XGL_PIPELINE_DB_STATE_CREATE_INFO*)pStruct);
+            swc22.set_indent(indent);
+            swc22.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
+        {
+            xgl_pipeline_ia_state_create_info_struct_wrapper swc23((XGL_PIPELINE_IA_STATE_CREATE_INFO*)pStruct);
+            swc23.set_indent(indent);
+            swc23.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
+        {
+            xgl_pipeline_rs_state_create_info_struct_wrapper swc24((XGL_PIPELINE_RS_STATE_CREATE_INFO*)pStruct);
+            swc24.set_indent(indent);
+            swc24.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
+        {
+            xgl_pipeline_shader_stage_create_info_struct_wrapper swc25((XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pStruct);
+            swc25.set_indent(indent);
+            swc25.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
+        {
+            xgl_pipeline_tess_state_create_info_struct_wrapper swc26((XGL_PIPELINE_TESS_STATE_CREATE_INFO*)pStruct);
+            swc26.set_indent(indent);
+            swc26.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO:
+        {
+            xgl_query_pool_create_info_struct_wrapper swc27((XGL_QUERY_POOL_CREATE_INFO*)pStruct);
+            swc27.set_indent(indent);
+            swc27.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_RASTER_STATE_CREATE_INFO:
+        {
+            xgl_raster_state_create_info_struct_wrapper swc28((XGL_RASTER_STATE_CREATE_INFO*)pStruct);
+            swc28.set_indent(indent);
+            swc28.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO:
+        {
+            xgl_sampler_create_info_struct_wrapper swc29((XGL_SAMPLER_CREATE_INFO*)pStruct);
+            swc29.set_indent(indent);
+            swc29.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO:
+        {
+            xgl_queue_semaphore_create_info_struct_wrapper swc30((XGL_QUEUE_SEMAPHORE_CREATE_INFO*)pStruct);
+            swc30.set_indent(indent);
+            swc30.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_SEMAPHORE_OPEN_INFO:
+        {
+            xgl_queue_semaphore_open_info_struct_wrapper swc31((XGL_QUEUE_SEMAPHORE_OPEN_INFO*)pStruct);
+            swc31.set_indent(indent);
+            swc31.display_full_txt();
+        }
+        break;
+        case XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO:
+        {
+            xgl_shader_create_info_struct_wrapper swc32((XGL_SHADER_CREATE_INFO*)pStruct);
+            swc32.set_indent(indent);
+            swc32.display_full_txt();
+        }
+        break;
+    }
+}
+
+
+// xgl_raster_state_create_info_struct_wrapper class definition
+xgl_raster_state_create_info_struct_wrapper::xgl_raster_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_raster_state_create_info_struct_wrapper::xgl_raster_state_create_info_struct_wrapper(XGL_RASTER_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_raster_state_create_info_struct_wrapper::xgl_raster_state_create_info_struct_wrapper(const XGL_RASTER_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_raster_state_create_info_struct_wrapper::~xgl_raster_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_raster_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_RASTER_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_raster_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sfillMode = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_FILL_MODE(m_struct.fillMode));
+    printf("%*s    %scullMode = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_CULL_MODE(m_struct.cullMode));
+    printf("%*s    %sfrontFace = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_FACE_ORIENTATION(m_struct.frontFace));
+    printf("%*s    %sdepthBias = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.depthBias));
+    printf("%*s    %sdepthBiasClamp = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.depthBiasClamp));
+    printf("%*s    %sslopeScaledDepthBias = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.slopeScaledDepthBias));
+}
+
+// Output all struct elements, each on their own line
+void xgl_raster_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_RASTER_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_raster_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_RASTER_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_gpu_compatibility_info_struct_wrapper class definition
+xgl_gpu_compatibility_info_struct_wrapper::xgl_gpu_compatibility_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_gpu_compatibility_info_struct_wrapper::xgl_gpu_compatibility_info_struct_wrapper(XGL_GPU_COMPATIBILITY_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_gpu_compatibility_info_struct_wrapper::xgl_gpu_compatibility_info_struct_wrapper(const XGL_GPU_COMPATIBILITY_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_gpu_compatibility_info_struct_wrapper::~xgl_gpu_compatibility_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_gpu_compatibility_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_GPU_COMPATIBILITY_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_gpu_compatibility_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %scompatibilityFlags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.compatibilityFlags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_gpu_compatibility_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_GPU_COMPATIBILITY_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_gpu_compatibility_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_GPU_COMPATIBILITY_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_image_view_create_info_struct_wrapper class definition
+xgl_image_view_create_info_struct_wrapper::xgl_image_view_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_view_create_info_struct_wrapper::xgl_image_view_create_info_struct_wrapper(XGL_IMAGE_VIEW_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_view_create_info_struct_wrapper::xgl_image_view_create_info_struct_wrapper(const XGL_IMAGE_VIEW_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_view_create_info_struct_wrapper::~xgl_image_view_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_view_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_VIEW_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_view_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %simage = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.image));
+    printf("%*s    %sviewType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_VIEW_TYPE(m_struct.viewType));
+    printf("%*s    %sformat = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.format));
+    printf("%*s    %schannels = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.channels));
+    printf("%*s    %ssubresourceRange = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.subresourceRange));
+    printf("%*s    %sminLod = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.minLod));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_view_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_VIEW_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_view_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_VIEW_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.subresourceRange) {
+        xgl_image_subresource_range_struct_wrapper class0(&m_struct.subresourceRange);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.channels) {
+        xgl_channel_mapping_struct_wrapper class1(&m_struct.channels);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    if (&m_struct.format) {
+        xgl_format_struct_wrapper class2(&m_struct.format);
+        class2.set_indent(m_indent + 4);
+        class2.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_memory_open_info_struct_wrapper class definition
+xgl_memory_open_info_struct_wrapper::xgl_memory_open_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_open_info_struct_wrapper::xgl_memory_open_info_struct_wrapper(XGL_MEMORY_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_open_info_struct_wrapper::xgl_memory_open_info_struct_wrapper(const XGL_MEMORY_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_open_info_struct_wrapper::~xgl_memory_open_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_open_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_OPEN_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_open_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %ssharedMem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.sharedMem));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_open_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_open_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_memory_heap_properties_struct_wrapper class definition
+xgl_memory_heap_properties_struct_wrapper::xgl_memory_heap_properties_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_heap_properties_struct_wrapper::xgl_memory_heap_properties_struct_wrapper(XGL_MEMORY_HEAP_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_heap_properties_struct_wrapper::xgl_memory_heap_properties_struct_wrapper(const XGL_MEMORY_HEAP_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_heap_properties_struct_wrapper::~xgl_memory_heap_properties_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_heap_properties_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_HEAP_PROPERTIES = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_heap_properties_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sstructSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.structSize));
+    printf("%*s    %sheapMemoryType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_HEAP_MEMORY_TYPE(m_struct.heapMemoryType));
+    printf("%*s    %sheapSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.heapSize));
+    printf("%*s    %spageSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.pageSize));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+    printf("%*s    %sgpuReadPerfRating = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.gpuReadPerfRating));
+    printf("%*s    %sgpuWritePerfRating = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.gpuWritePerfRating));
+    printf("%*s    %scpuReadPerfRating = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.cpuReadPerfRating));
+    printf("%*s    %scpuWritePerfRating = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.cpuWritePerfRating));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_heap_properties_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_HEAP_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_heap_properties_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_HEAP_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_image_subresource_struct_wrapper class definition
+xgl_image_subresource_struct_wrapper::xgl_image_subresource_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_subresource_struct_wrapper::xgl_image_subresource_struct_wrapper(XGL_IMAGE_SUBRESOURCE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_subresource_struct_wrapper::xgl_image_subresource_struct_wrapper(const XGL_IMAGE_SUBRESOURCE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_subresource_struct_wrapper::~xgl_image_subresource_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_subresource_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_SUBRESOURCE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_subresource_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %saspect = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_ASPECT(m_struct.aspect));
+    printf("%*s    %smipLevel = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.mipLevel));
+    printf("%*s    %sarraySlice = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.arraySlice));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_subresource_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_SUBRESOURCE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_subresource_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_SUBRESOURCE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_physical_gpu_performance_struct_wrapper class definition
+xgl_physical_gpu_performance_struct_wrapper::xgl_physical_gpu_performance_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_physical_gpu_performance_struct_wrapper::xgl_physical_gpu_performance_struct_wrapper(XGL_PHYSICAL_GPU_PERFORMANCE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_performance_struct_wrapper::xgl_physical_gpu_performance_struct_wrapper(const XGL_PHYSICAL_GPU_PERFORMANCE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_performance_struct_wrapper::~xgl_physical_gpu_performance_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_physical_gpu_performance_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PHYSICAL_GPU_PERFORMANCE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_physical_gpu_performance_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %smaxGpuClock = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.maxGpuClock));
+    printf("%*s    %saluPerClock = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.aluPerClock));
+    printf("%*s    %stexPerClock = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.texPerClock));
+    printf("%*s    %sprimsPerClock = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.primsPerClock));
+    printf("%*s    %spixelsPerClock = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.pixelsPerClock));
+}
+
+// Output all struct elements, each on their own line
+void xgl_physical_gpu_performance_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_PERFORMANCE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_physical_gpu_performance_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_PERFORMANCE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_physical_gpu_memory_properties_struct_wrapper class definition
+xgl_physical_gpu_memory_properties_struct_wrapper::xgl_physical_gpu_memory_properties_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_physical_gpu_memory_properties_struct_wrapper::xgl_physical_gpu_memory_properties_struct_wrapper(XGL_PHYSICAL_GPU_MEMORY_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_memory_properties_struct_wrapper::xgl_physical_gpu_memory_properties_struct_wrapper(const XGL_PHYSICAL_GPU_MEMORY_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_memory_properties_struct_wrapper::~xgl_physical_gpu_memory_properties_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_physical_gpu_memory_properties_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PHYSICAL_GPU_MEMORY_PROPERTIES = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_physical_gpu_memory_properties_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sstructSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.structSize));
+    printf("%*s    %ssupportsMigration = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.supportsMigration) ? "TRUE" : "FALSE");
+    printf("%*s    %ssupportsVirtualMemoryRemapping = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.supportsVirtualMemoryRemapping) ? "TRUE" : "FALSE");
+    printf("%*s    %ssupportsPinning = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.supportsPinning) ? "TRUE" : "FALSE");
+}
+
+// Output all struct elements, each on their own line
+void xgl_physical_gpu_memory_properties_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_MEMORY_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_physical_gpu_memory_properties_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_MEMORY_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_pipeline_shader_struct_wrapper class definition
+xgl_pipeline_shader_struct_wrapper::xgl_pipeline_shader_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_shader_struct_wrapper::xgl_pipeline_shader_struct_wrapper(XGL_PIPELINE_SHADER* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_shader_struct_wrapper::xgl_pipeline_shader_struct_wrapper(const XGL_PIPELINE_SHADER* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_shader_struct_wrapper::~xgl_pipeline_shader_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_shader_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_SHADER = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_shader_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sstage = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_PIPELINE_SHADER_STAGE(m_struct.stage));
+    printf("%*s    %sshader = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.shader));
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_DESCRIPTOR_SETS; i++) {
+        printf("%*s    %sdescriptorSetMapping[%u] = %p\n", m_indent, "", &m_dummy_prefix, i, (void*)&(m_struct.descriptorSetMapping)[i]);
+    }
+    printf("%*s    %slinkConstBufferCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.linkConstBufferCount));
+    printf("%*s    %spLinkConstBufferInfo = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.pLinkConstBufferInfo));
+    printf("%*s    %sdynamicMemoryViewMapping = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.dynamicMemoryViewMapping));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_shader_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_SHADER struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_shader_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_SHADER struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.dynamicMemoryViewMapping) {
+        xgl_dynamic_memory_view_slot_info_struct_wrapper class0(&m_struct.dynamicMemoryViewMapping);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pLinkConstBufferInfo) {
+        xgl_link_const_buffer_struct_wrapper class1(m_struct.pLinkConstBufferInfo);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_DESCRIPTOR_SETS; i++) {
+            xgl_descriptor_set_mapping_struct_wrapper class2(&(m_struct.descriptorSetMapping[i]));
+            class2.set_indent(m_indent + 4);
+            class2.display_full_txt();
+    }
+}
+
+
+// xgl_fence_create_info_struct_wrapper class definition
+xgl_fence_create_info_struct_wrapper::xgl_fence_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_fence_create_info_struct_wrapper::xgl_fence_create_info_struct_wrapper(XGL_FENCE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_fence_create_info_struct_wrapper::xgl_fence_create_info_struct_wrapper(const XGL_FENCE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_fence_create_info_struct_wrapper::~xgl_fence_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_fence_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_FENCE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_fence_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_fence_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_FENCE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_fence_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_FENCE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_pipeline_cb_attachment_state_struct_wrapper class definition
+xgl_pipeline_cb_attachment_state_struct_wrapper::xgl_pipeline_cb_attachment_state_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_cb_attachment_state_struct_wrapper::xgl_pipeline_cb_attachment_state_struct_wrapper(XGL_PIPELINE_CB_ATTACHMENT_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_cb_attachment_state_struct_wrapper::xgl_pipeline_cb_attachment_state_struct_wrapper(const XGL_PIPELINE_CB_ATTACHMENT_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_cb_attachment_state_struct_wrapper::~xgl_pipeline_cb_attachment_state_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_cb_attachment_state_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_CB_ATTACHMENT_STATE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_cb_attachment_state_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sblendEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.blendEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sformat = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.format));
+    printf("%*s    %schannelWriteMask = %hu\n", m_indent, "", &m_dummy_prefix, (m_struct.channelWriteMask));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_cb_attachment_state_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_CB_ATTACHMENT_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_cb_attachment_state_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_CB_ATTACHMENT_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.format) {
+        xgl_format_struct_wrapper class0(&m_struct.format);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+}
+
+
+// xgl_alloc_callbacks_struct_wrapper class definition
+xgl_alloc_callbacks_struct_wrapper::xgl_alloc_callbacks_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_alloc_callbacks_struct_wrapper::xgl_alloc_callbacks_struct_wrapper(XGL_ALLOC_CALLBACKS* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_alloc_callbacks_struct_wrapper::xgl_alloc_callbacks_struct_wrapper(const XGL_ALLOC_CALLBACKS* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_alloc_callbacks_struct_wrapper::~xgl_alloc_callbacks_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_alloc_callbacks_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_ALLOC_CALLBACKS = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_alloc_callbacks_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %spUserData = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pUserData));
+    printf("%*s    %spfnAlloc = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.pfnAlloc));
+    printf("%*s    %spfnFree = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.pfnFree));
+}
+
+// Output all struct elements, each on their own line
+void xgl_alloc_callbacks_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_ALLOC_CALLBACKS struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_alloc_callbacks_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_ALLOC_CALLBACKS struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_color_attachment_view_create_info_struct_wrapper class definition
+xgl_color_attachment_view_create_info_struct_wrapper::xgl_color_attachment_view_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_color_attachment_view_create_info_struct_wrapper::xgl_color_attachment_view_create_info_struct_wrapper(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_attachment_view_create_info_struct_wrapper::xgl_color_attachment_view_create_info_struct_wrapper(const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_attachment_view_create_info_struct_wrapper::~xgl_color_attachment_view_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_color_attachment_view_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_color_attachment_view_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %simage = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.image));
+    printf("%*s    %sformat = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.format));
+    printf("%*s    %smipLevel = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.mipLevel));
+    printf("%*s    %sbaseArraySlice = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.baseArraySlice));
+    printf("%*s    %sarraySize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.arraySize));
+}
+
+// Output all struct elements, each on their own line
+void xgl_color_attachment_view_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_color_attachment_view_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.format) {
+        xgl_format_struct_wrapper class0(&m_struct.format);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_image_copy_struct_wrapper class definition
+xgl_image_copy_struct_wrapper::xgl_image_copy_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_copy_struct_wrapper::xgl_image_copy_struct_wrapper(XGL_IMAGE_COPY* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_copy_struct_wrapper::xgl_image_copy_struct_wrapper(const XGL_IMAGE_COPY* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_copy_struct_wrapper::~xgl_image_copy_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_copy_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_COPY = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_copy_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssrcSubresource = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.srcSubresource));
+    printf("%*s    %ssrcOffset = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.srcOffset));
+    printf("%*s    %sdestSubresource = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.destSubresource));
+    printf("%*s    %sdestOffset = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.destOffset));
+    printf("%*s    %sextent = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.extent));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_copy_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_COPY struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_copy_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_COPY struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.extent) {
+        xgl_extent3d_struct_wrapper class0(&m_struct.extent);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.destOffset) {
+        xgl_offset3d_struct_wrapper class1(&m_struct.destOffset);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    if (&m_struct.destSubresource) {
+        xgl_image_subresource_struct_wrapper class2(&m_struct.destSubresource);
+        class2.set_indent(m_indent + 4);
+        class2.display_full_txt();
+    }
+    if (&m_struct.srcOffset) {
+        xgl_offset3d_struct_wrapper class3(&m_struct.srcOffset);
+        class3.set_indent(m_indent + 4);
+        class3.display_full_txt();
+    }
+    if (&m_struct.srcSubresource) {
+        xgl_image_subresource_struct_wrapper class4(&m_struct.srcSubresource);
+        class4.set_indent(m_indent + 4);
+        class4.display_full_txt();
+    }
+}
+
+
+// xgl_msaa_state_create_info_struct_wrapper class definition
+xgl_msaa_state_create_info_struct_wrapper::xgl_msaa_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_msaa_state_create_info_struct_wrapper::xgl_msaa_state_create_info_struct_wrapper(XGL_MSAA_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_msaa_state_create_info_struct_wrapper::xgl_msaa_state_create_info_struct_wrapper(const XGL_MSAA_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_msaa_state_create_info_struct_wrapper::~xgl_msaa_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_msaa_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MSAA_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_msaa_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %ssamples = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.samples));
+    printf("%*s    %ssampleMask = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.sampleMask));
+}
+
+// Output all struct elements, each on their own line
+void xgl_msaa_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MSAA_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_msaa_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MSAA_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_descriptor_set_create_info_struct_wrapper class definition
+xgl_descriptor_set_create_info_struct_wrapper::xgl_descriptor_set_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_descriptor_set_create_info_struct_wrapper::xgl_descriptor_set_create_info_struct_wrapper(XGL_DESCRIPTOR_SET_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_set_create_info_struct_wrapper::xgl_descriptor_set_create_info_struct_wrapper(const XGL_DESCRIPTOR_SET_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_set_create_info_struct_wrapper::~xgl_descriptor_set_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_descriptor_set_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DESCRIPTOR_SET_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_descriptor_set_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sslots = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.slots));
+}
+
+// Output all struct elements, each on their own line
+void xgl_descriptor_set_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SET_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_descriptor_set_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SET_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_color_attachment_bind_info_struct_wrapper class definition
+xgl_color_attachment_bind_info_struct_wrapper::xgl_color_attachment_bind_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_color_attachment_bind_info_struct_wrapper::xgl_color_attachment_bind_info_struct_wrapper(XGL_COLOR_ATTACHMENT_BIND_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_attachment_bind_info_struct_wrapper::xgl_color_attachment_bind_info_struct_wrapper(const XGL_COLOR_ATTACHMENT_BIND_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_attachment_bind_info_struct_wrapper::~xgl_color_attachment_bind_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_color_attachment_bind_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_COLOR_ATTACHMENT_BIND_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_color_attachment_bind_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sview = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.view));
+    printf("%*s    %scolorAttachmentState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_STATE(m_struct.colorAttachmentState));
+}
+
+// Output all struct elements, each on their own line
+void xgl_color_attachment_bind_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_COLOR_ATTACHMENT_BIND_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_color_attachment_bind_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_COLOR_ATTACHMENT_BIND_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_event_create_info_struct_wrapper class definition
+xgl_event_create_info_struct_wrapper::xgl_event_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_event_create_info_struct_wrapper::xgl_event_create_info_struct_wrapper(XGL_EVENT_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_event_create_info_struct_wrapper::xgl_event_create_info_struct_wrapper(const XGL_EVENT_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_event_create_info_struct_wrapper::~xgl_event_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_event_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_EVENT_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_event_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_event_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_EVENT_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_event_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_EVENT_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_memory_requirements_struct_wrapper class definition
+xgl_memory_requirements_struct_wrapper::xgl_memory_requirements_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_requirements_struct_wrapper::xgl_memory_requirements_struct_wrapper(XGL_MEMORY_REQUIREMENTS* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_requirements_struct_wrapper::xgl_memory_requirements_struct_wrapper(const XGL_MEMORY_REQUIREMENTS* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_requirements_struct_wrapper::~xgl_memory_requirements_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_requirements_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_REQUIREMENTS = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_requirements_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.size));
+    printf("%*s    %salignment = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.alignment));
+    printf("%*s    %sheapCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.heapCount));
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_MEMORY_HEAPS; i++) {
+        printf("%*s    %sheaps[%u] = %u\n", m_indent, "", &m_dummy_prefix, i, (m_struct.heaps)[i]);
+    }
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_requirements_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_REQUIREMENTS struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_requirements_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_REQUIREMENTS struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_queue_semaphore_open_info_struct_wrapper class definition
+xgl_queue_semaphore_open_info_struct_wrapper::xgl_queue_semaphore_open_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_queue_semaphore_open_info_struct_wrapper::xgl_queue_semaphore_open_info_struct_wrapper(XGL_QUEUE_SEMAPHORE_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_queue_semaphore_open_info_struct_wrapper::xgl_queue_semaphore_open_info_struct_wrapper(const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_queue_semaphore_open_info_struct_wrapper::~xgl_queue_semaphore_open_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_queue_semaphore_open_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_QUEUE_SEMAPHORE_OPEN_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_queue_semaphore_open_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %ssharedSemaphore = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.sharedSemaphore));
+}
+
+// Output all struct elements, each on their own line
+void xgl_queue_semaphore_open_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_QUEUE_SEMAPHORE_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_queue_semaphore_open_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_QUEUE_SEMAPHORE_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_image_resolve_struct_wrapper class definition
+xgl_image_resolve_struct_wrapper::xgl_image_resolve_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_resolve_struct_wrapper::xgl_image_resolve_struct_wrapper(XGL_IMAGE_RESOLVE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_resolve_struct_wrapper::xgl_image_resolve_struct_wrapper(const XGL_IMAGE_RESOLVE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_resolve_struct_wrapper::~xgl_image_resolve_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_resolve_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_RESOLVE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_resolve_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssrcSubresource = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.srcSubresource));
+    printf("%*s    %ssrcOffset = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.srcOffset));
+    printf("%*s    %sdestSubresource = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.destSubresource));
+    printf("%*s    %sdestOffset = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.destOffset));
+    printf("%*s    %sextent = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.extent));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_resolve_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_RESOLVE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_resolve_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_RESOLVE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.extent) {
+        xgl_extent2d_struct_wrapper class0(&m_struct.extent);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.destOffset) {
+        xgl_offset2d_struct_wrapper class1(&m_struct.destOffset);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    if (&m_struct.destSubresource) {
+        xgl_image_subresource_struct_wrapper class2(&m_struct.destSubresource);
+        class2.set_indent(m_indent + 4);
+        class2.display_full_txt();
+    }
+    if (&m_struct.srcOffset) {
+        xgl_offset2d_struct_wrapper class3(&m_struct.srcOffset);
+        class3.set_indent(m_indent + 4);
+        class3.display_full_txt();
+    }
+    if (&m_struct.srcSubresource) {
+        xgl_image_subresource_struct_wrapper class4(&m_struct.srcSubresource);
+        class4.set_indent(m_indent + 4);
+        class4.display_full_txt();
+    }
+}
+
+
+// xgl_draw_indexed_indirect_cmd_struct_wrapper class definition
+xgl_draw_indexed_indirect_cmd_struct_wrapper::xgl_draw_indexed_indirect_cmd_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_draw_indexed_indirect_cmd_struct_wrapper::xgl_draw_indexed_indirect_cmd_struct_wrapper(XGL_DRAW_INDEXED_INDIRECT_CMD* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_draw_indexed_indirect_cmd_struct_wrapper::xgl_draw_indexed_indirect_cmd_struct_wrapper(const XGL_DRAW_INDEXED_INDIRECT_CMD* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_draw_indexed_indirect_cmd_struct_wrapper::~xgl_draw_indexed_indirect_cmd_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_draw_indexed_indirect_cmd_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DRAW_INDEXED_INDIRECT_CMD = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_draw_indexed_indirect_cmd_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sindexCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.indexCount));
+    printf("%*s    %sinstanceCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.instanceCount));
+    printf("%*s    %sfirstIndex = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.firstIndex));
+    printf("%*s    %svertexOffset = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.vertexOffset));
+    printf("%*s    %sfirstInstance = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.firstInstance));
+}
+
+// Output all struct elements, each on their own line
+void xgl_draw_indexed_indirect_cmd_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DRAW_INDEXED_INDIRECT_CMD struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_draw_indexed_indirect_cmd_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DRAW_INDEXED_INDIRECT_CMD struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_compute_pipeline_create_info_struct_wrapper class definition
+xgl_compute_pipeline_create_info_struct_wrapper::xgl_compute_pipeline_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_compute_pipeline_create_info_struct_wrapper::xgl_compute_pipeline_create_info_struct_wrapper(XGL_COMPUTE_PIPELINE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_compute_pipeline_create_info_struct_wrapper::xgl_compute_pipeline_create_info_struct_wrapper(const XGL_COMPUTE_PIPELINE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_compute_pipeline_create_info_struct_wrapper::~xgl_compute_pipeline_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_compute_pipeline_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_COMPUTE_PIPELINE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_compute_pipeline_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %scs = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.cs));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_compute_pipeline_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_COMPUTE_PIPELINE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_compute_pipeline_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_COMPUTE_PIPELINE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.cs) {
+        xgl_pipeline_shader_struct_wrapper class0(&m_struct.cs);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_peer_image_open_info_struct_wrapper class definition
+xgl_peer_image_open_info_struct_wrapper::xgl_peer_image_open_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_peer_image_open_info_struct_wrapper::xgl_peer_image_open_info_struct_wrapper(XGL_PEER_IMAGE_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_peer_image_open_info_struct_wrapper::xgl_peer_image_open_info_struct_wrapper(const XGL_PEER_IMAGE_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_peer_image_open_info_struct_wrapper::~xgl_peer_image_open_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_peer_image_open_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PEER_IMAGE_OPEN_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_peer_image_open_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %soriginalImage = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.originalImage));
+}
+
+// Output all struct elements, each on their own line
+void xgl_peer_image_open_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PEER_IMAGE_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_peer_image_open_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PEER_IMAGE_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_physical_gpu_queue_properties_struct_wrapper class definition
+xgl_physical_gpu_queue_properties_struct_wrapper::xgl_physical_gpu_queue_properties_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_physical_gpu_queue_properties_struct_wrapper::xgl_physical_gpu_queue_properties_struct_wrapper(XGL_PHYSICAL_GPU_QUEUE_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_queue_properties_struct_wrapper::xgl_physical_gpu_queue_properties_struct_wrapper(const XGL_PHYSICAL_GPU_QUEUE_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_queue_properties_struct_wrapper::~xgl_physical_gpu_queue_properties_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_physical_gpu_queue_properties_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PHYSICAL_GPU_QUEUE_PROPERTIES = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_physical_gpu_queue_properties_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sstructSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.structSize));
+    printf("%*s    %squeueFlags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.queueFlags));
+    printf("%*s    %squeueCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.queueCount));
+    printf("%*s    %smaxAtomicCounters = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.maxAtomicCounters));
+    printf("%*s    %ssupportsTimestamps = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.supportsTimestamps) ? "TRUE" : "FALSE");
+}
+
+// Output all struct elements, each on their own line
+void xgl_physical_gpu_queue_properties_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_QUEUE_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_physical_gpu_queue_properties_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_QUEUE_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_pipeline_statistics_data_struct_wrapper class definition
+xgl_pipeline_statistics_data_struct_wrapper::xgl_pipeline_statistics_data_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_statistics_data_struct_wrapper::xgl_pipeline_statistics_data_struct_wrapper(XGL_PIPELINE_STATISTICS_DATA* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_statistics_data_struct_wrapper::xgl_pipeline_statistics_data_struct_wrapper(const XGL_PIPELINE_STATISTICS_DATA* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_statistics_data_struct_wrapper::~xgl_pipeline_statistics_data_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_statistics_data_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_STATISTICS_DATA = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_statistics_data_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sfsInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.fsInvocations));
+    printf("%*s    %scPrimitives = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.cPrimitives));
+    printf("%*s    %scInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.cInvocations));
+    printf("%*s    %svsInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.vsInvocations));
+    printf("%*s    %sgsInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.gsInvocations));
+    printf("%*s    %sgsPrimitives = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.gsPrimitives));
+    printf("%*s    %siaPrimitives = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.iaPrimitives));
+    printf("%*s    %siaVertices = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.iaVertices));
+    printf("%*s    %stcsInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.tcsInvocations));
+    printf("%*s    %stesInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.tesInvocations));
+    printf("%*s    %scsInvocations = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.csInvocations));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_statistics_data_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_STATISTICS_DATA struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_statistics_data_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_STATISTICS_DATA struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_device_queue_create_info_struct_wrapper class definition
+xgl_device_queue_create_info_struct_wrapper::xgl_device_queue_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_device_queue_create_info_struct_wrapper::xgl_device_queue_create_info_struct_wrapper(XGL_DEVICE_QUEUE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_device_queue_create_info_struct_wrapper::xgl_device_queue_create_info_struct_wrapper(const XGL_DEVICE_QUEUE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_device_queue_create_info_struct_wrapper::~xgl_device_queue_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_device_queue_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DEVICE_QUEUE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_device_queue_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %squeueNodeIndex = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.queueNodeIndex));
+    printf("%*s    %squeueCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.queueCount));
+}
+
+// Output all struct elements, each on their own line
+void xgl_device_queue_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DEVICE_QUEUE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_device_queue_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DEVICE_QUEUE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_sampler_create_info_struct_wrapper class definition
+xgl_sampler_create_info_struct_wrapper::xgl_sampler_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_sampler_create_info_struct_wrapper::xgl_sampler_create_info_struct_wrapper(XGL_SAMPLER_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_sampler_create_info_struct_wrapper::xgl_sampler_create_info_struct_wrapper(const XGL_SAMPLER_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_sampler_create_info_struct_wrapper::~xgl_sampler_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_sampler_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_SAMPLER_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_sampler_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %smagFilter = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_TEX_FILTER(m_struct.magFilter));
+    printf("%*s    %sminFilter = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_TEX_FILTER(m_struct.minFilter));
+    printf("%*s    %smipMode = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_TEX_MIPMAP_MODE(m_struct.mipMode));
+    printf("%*s    %saddressU = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_TEX_ADDRESS(m_struct.addressU));
+    printf("%*s    %saddressV = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_TEX_ADDRESS(m_struct.addressV));
+    printf("%*s    %saddressW = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_TEX_ADDRESS(m_struct.addressW));
+    printf("%*s    %smipLodBias = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.mipLodBias));
+    printf("%*s    %smaxAnisotropy = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.maxAnisotropy));
+    printf("%*s    %scompareFunc = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_COMPARE_FUNC(m_struct.compareFunc));
+    printf("%*s    %sminLod = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.minLod));
+    printf("%*s    %smaxLod = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.maxLod));
+    printf("%*s    %sborderColorType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BORDER_COLOR_TYPE(m_struct.borderColorType));
+}
+
+// Output all struct elements, each on their own line
+void xgl_sampler_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_SAMPLER_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_sampler_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_SAMPLER_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_queue_semaphore_create_info_struct_wrapper class definition
+xgl_queue_semaphore_create_info_struct_wrapper::xgl_queue_semaphore_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_queue_semaphore_create_info_struct_wrapper::xgl_queue_semaphore_create_info_struct_wrapper(XGL_QUEUE_SEMAPHORE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_queue_semaphore_create_info_struct_wrapper::xgl_queue_semaphore_create_info_struct_wrapper(const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_queue_semaphore_create_info_struct_wrapper::~xgl_queue_semaphore_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_queue_semaphore_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_QUEUE_SEMAPHORE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_queue_semaphore_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sinitialCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.initialCount));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_queue_semaphore_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_QUEUE_SEMAPHORE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_queue_semaphore_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_QUEUE_SEMAPHORE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_format_struct_wrapper class definition
+xgl_format_struct_wrapper::xgl_format_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_format_struct_wrapper::xgl_format_struct_wrapper(XGL_FORMAT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_format_struct_wrapper::xgl_format_struct_wrapper(const XGL_FORMAT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_format_struct_wrapper::~xgl_format_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_format_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_FORMAT = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_format_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %schannelFormat = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_CHANNEL_FORMAT(m_struct.channelFormat));
+    printf("%*s    %snumericFormat = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_NUM_FORMAT(m_struct.numericFormat));
+}
+
+// Output all struct elements, each on their own line
+void xgl_format_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_FORMAT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_format_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_FORMAT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_memory_state_transition_struct_wrapper class definition
+xgl_memory_state_transition_struct_wrapper::xgl_memory_state_transition_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_state_transition_struct_wrapper::xgl_memory_state_transition_struct_wrapper(XGL_MEMORY_STATE_TRANSITION* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_state_transition_struct_wrapper::xgl_memory_state_transition_struct_wrapper(const XGL_MEMORY_STATE_TRANSITION* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_state_transition_struct_wrapper::~xgl_memory_state_transition_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_state_transition_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_STATE_TRANSITION = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_state_transition_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %smem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.mem));
+    printf("%*s    %soldState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_MEMORY_STATE(m_struct.oldState));
+    printf("%*s    %snewState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_MEMORY_STATE(m_struct.newState));
+    printf("%*s    %soffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.offset));
+    printf("%*s    %sregionSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.regionSize));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_state_transition_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_STATE_TRANSITION struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_state_transition_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_STATE_TRANSITION struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_extent3d_struct_wrapper class definition
+xgl_extent3d_struct_wrapper::xgl_extent3d_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_extent3d_struct_wrapper::xgl_extent3d_struct_wrapper(XGL_EXTENT3D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_extent3d_struct_wrapper::xgl_extent3d_struct_wrapper(const XGL_EXTENT3D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_extent3d_struct_wrapper::~xgl_extent3d_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_extent3d_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_EXTENT3D = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_extent3d_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %swidth = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.width));
+    printf("%*s    %sheight = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.height));
+    printf("%*s    %sdepth = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.depth));
+}
+
+// Output all struct elements, each on their own line
+void xgl_extent3d_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_EXTENT3D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_extent3d_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_EXTENT3D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_dynamic_memory_view_slot_info_struct_wrapper class definition
+xgl_dynamic_memory_view_slot_info_struct_wrapper::xgl_dynamic_memory_view_slot_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_dynamic_memory_view_slot_info_struct_wrapper::xgl_dynamic_memory_view_slot_info_struct_wrapper(XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_dynamic_memory_view_slot_info_struct_wrapper::xgl_dynamic_memory_view_slot_info_struct_wrapper(const XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_dynamic_memory_view_slot_info_struct_wrapper::~xgl_dynamic_memory_view_slot_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_dynamic_memory_view_slot_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_dynamic_memory_view_slot_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sslotObjectType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_DESCRIPTOR_SET_SLOT_TYPE(m_struct.slotObjectType));
+    printf("%*s    %sshaderEntityIndex = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.shaderEntityIndex));
+}
+
+// Output all struct elements, each on their own line
+void xgl_dynamic_memory_view_slot_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_dynamic_memory_view_slot_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_image_view_attach_info_struct_wrapper class definition
+xgl_image_view_attach_info_struct_wrapper::xgl_image_view_attach_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_view_attach_info_struct_wrapper::xgl_image_view_attach_info_struct_wrapper(XGL_IMAGE_VIEW_ATTACH_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_view_attach_info_struct_wrapper::xgl_image_view_attach_info_struct_wrapper(const XGL_IMAGE_VIEW_ATTACH_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_view_attach_info_struct_wrapper::~xgl_image_view_attach_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_view_attach_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_VIEW_ATTACH_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_view_attach_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sview = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.view));
+    printf("%*s    %sstate = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_STATE(m_struct.state));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_view_attach_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_VIEW_ATTACH_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_view_attach_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_VIEW_ATTACH_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_image_subresource_range_struct_wrapper class definition
+xgl_image_subresource_range_struct_wrapper::xgl_image_subresource_range_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_subresource_range_struct_wrapper::xgl_image_subresource_range_struct_wrapper(XGL_IMAGE_SUBRESOURCE_RANGE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_subresource_range_struct_wrapper::xgl_image_subresource_range_struct_wrapper(const XGL_IMAGE_SUBRESOURCE_RANGE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_subresource_range_struct_wrapper::~xgl_image_subresource_range_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_subresource_range_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_SUBRESOURCE_RANGE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_subresource_range_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %saspect = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_ASPECT(m_struct.aspect));
+    printf("%*s    %sbaseMipLevel = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.baseMipLevel));
+    printf("%*s    %smipLevels = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.mipLevels));
+    printf("%*s    %sbaseArraySlice = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.baseArraySlice));
+    printf("%*s    %sarraySize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.arraySize));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_subresource_range_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_SUBRESOURCE_RANGE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_subresource_range_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_SUBRESOURCE_RANGE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_pipeline_db_state_create_info_struct_wrapper class definition
+xgl_pipeline_db_state_create_info_struct_wrapper::xgl_pipeline_db_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_db_state_create_info_struct_wrapper::xgl_pipeline_db_state_create_info_struct_wrapper(XGL_PIPELINE_DB_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_db_state_create_info_struct_wrapper::xgl_pipeline_db_state_create_info_struct_wrapper(const XGL_PIPELINE_DB_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_db_state_create_info_struct_wrapper::~xgl_pipeline_db_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_db_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_DB_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_db_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sformat = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.format));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_db_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_DB_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_db_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_DB_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.format) {
+        xgl_format_struct_wrapper class0(&m_struct.format);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_application_info_struct_wrapper class definition
+xgl_application_info_struct_wrapper::xgl_application_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_application_info_struct_wrapper::xgl_application_info_struct_wrapper(XGL_APPLICATION_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_application_info_struct_wrapper::xgl_application_info_struct_wrapper(const XGL_APPLICATION_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_application_info_struct_wrapper::~xgl_application_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_application_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_APPLICATION_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_application_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %spAppName = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pAppName));
+    printf("%*s    %sappVersion = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.appVersion));
+    printf("%*s    %spEngineName = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pEngineName));
+    printf("%*s    %sengineVersion = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.engineVersion));
+    printf("%*s    %sapiVersion = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.apiVersion));
+}
+
+// Output all struct elements, each on their own line
+void xgl_application_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_APPLICATION_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_application_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_APPLICATION_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_offset2d_struct_wrapper class definition
+xgl_offset2d_struct_wrapper::xgl_offset2d_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_offset2d_struct_wrapper::xgl_offset2d_struct_wrapper(XGL_OFFSET2D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_offset2d_struct_wrapper::xgl_offset2d_struct_wrapper(const XGL_OFFSET2D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_offset2d_struct_wrapper::~xgl_offset2d_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_offset2d_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_OFFSET2D = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_offset2d_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sx = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.x));
+    printf("%*s    %sy = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.y));
+}
+
+// Output all struct elements, each on their own line
+void xgl_offset2d_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_OFFSET2D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_offset2d_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_OFFSET2D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_viewport_state_create_info_struct_wrapper class definition
+xgl_viewport_state_create_info_struct_wrapper::xgl_viewport_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_viewport_state_create_info_struct_wrapper::xgl_viewport_state_create_info_struct_wrapper(XGL_VIEWPORT_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_viewport_state_create_info_struct_wrapper::xgl_viewport_state_create_info_struct_wrapper(const XGL_VIEWPORT_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_viewport_state_create_info_struct_wrapper::~xgl_viewport_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_viewport_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_VIEWPORT_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_viewport_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sviewportCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.viewportCount));
+    printf("%*s    %sscissorEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.scissorEnable) ? "TRUE" : "FALSE");
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_VIEWPORTS; i++) {
+        printf("%*s    %sviewports[%u] = %p\n", m_indent, "", &m_dummy_prefix, i, (void*)&(m_struct.viewports)[i]);
+    }
+    for (i = 0; i<XGL_MAX_VIEWPORTS; i++) {
+        printf("%*s    %sscissors[%u] = %p\n", m_indent, "", &m_dummy_prefix, i, (void*)&(m_struct.scissors)[i]);
+    }
+}
+
+// Output all struct elements, each on their own line
+void xgl_viewport_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_VIEWPORT_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_viewport_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_VIEWPORT_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_VIEWPORTS; i++) {
+            xgl_rect_struct_wrapper class0(&(m_struct.scissors[i]));
+            class0.set_indent(m_indent + 4);
+            class0.display_full_txt();
+    }
+    for (i = 0; i<XGL_MAX_VIEWPORTS; i++) {
+            xgl_viewport_struct_wrapper class1(&(m_struct.viewports[i]));
+            class1.set_indent(m_indent + 4);
+            class1.display_full_txt();
+    }
+}
+
+
+// xgl_image_state_transition_struct_wrapper class definition
+xgl_image_state_transition_struct_wrapper::xgl_image_state_transition_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_state_transition_struct_wrapper::xgl_image_state_transition_struct_wrapper(XGL_IMAGE_STATE_TRANSITION* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_state_transition_struct_wrapper::xgl_image_state_transition_struct_wrapper(const XGL_IMAGE_STATE_TRANSITION* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_state_transition_struct_wrapper::~xgl_image_state_transition_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_state_transition_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_STATE_TRANSITION = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_state_transition_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %simage = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.image));
+    printf("%*s    %soldState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_STATE(m_struct.oldState));
+    printf("%*s    %snewState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_STATE(m_struct.newState));
+    printf("%*s    %ssubresourceRange = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.subresourceRange));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_state_transition_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_STATE_TRANSITION struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_state_transition_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_STATE_TRANSITION struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.subresourceRange) {
+        xgl_image_subresource_range_struct_wrapper class0(&m_struct.subresourceRange);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+}
+
+
+// xgl_device_create_info_struct_wrapper class definition
+xgl_device_create_info_struct_wrapper::xgl_device_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_device_create_info_struct_wrapper::xgl_device_create_info_struct_wrapper(XGL_DEVICE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_device_create_info_struct_wrapper::xgl_device_create_info_struct_wrapper(const XGL_DEVICE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_device_create_info_struct_wrapper::~xgl_device_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_device_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DEVICE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_device_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %squeueRecordCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.queueRecordCount));
+    printf("%*s    %spRequestedQueues = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.pRequestedQueues));
+    printf("%*s    %sextensionCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.extensionCount));
+    printf("%*s    %sppEnabledExtensionNames = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.ppEnabledExtensionNames));
+    printf("%*s    %smaxValidationLevel = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_VALIDATION_LEVEL(m_struct.maxValidationLevel));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_device_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DEVICE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_device_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DEVICE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pRequestedQueues) {
+        xgl_device_queue_create_info_struct_wrapper class0(m_struct.pRequestedQueues);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_image_create_info_struct_wrapper class definition
+xgl_image_create_info_struct_wrapper::xgl_image_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_image_create_info_struct_wrapper::xgl_image_create_info_struct_wrapper(XGL_IMAGE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_create_info_struct_wrapper::xgl_image_create_info_struct_wrapper(const XGL_IMAGE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_image_create_info_struct_wrapper::~xgl_image_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_image_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_IMAGE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_image_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %simageType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_TYPE(m_struct.imageType));
+    printf("%*s    %sformat = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.format));
+    printf("%*s    %sextent = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.extent));
+    printf("%*s    %smipLevels = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.mipLevels));
+    printf("%*s    %sarraySize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.arraySize));
+    printf("%*s    %ssamples = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.samples));
+    printf("%*s    %stiling = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_TILING(m_struct.tiling));
+    printf("%*s    %susage = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.usage));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_image_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_IMAGE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_image_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_IMAGE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.extent) {
+        xgl_extent3d_struct_wrapper class0(&m_struct.extent);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.format) {
+        xgl_format_struct_wrapper class1(&m_struct.format);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_rect_struct_wrapper class definition
+xgl_rect_struct_wrapper::xgl_rect_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_rect_struct_wrapper::xgl_rect_struct_wrapper(XGL_RECT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_rect_struct_wrapper::xgl_rect_struct_wrapper(const XGL_RECT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_rect_struct_wrapper::~xgl_rect_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_rect_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_RECT = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_rect_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %soffset = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.offset));
+    printf("%*s    %sextent = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.extent));
+}
+
+// Output all struct elements, each on their own line
+void xgl_rect_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_RECT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_rect_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_RECT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.extent) {
+        xgl_extent2d_struct_wrapper class0(&m_struct.extent);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.offset) {
+        xgl_offset2d_struct_wrapper class1(&m_struct.offset);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+}
+
+
+// xgl_memory_copy_struct_wrapper class definition
+xgl_memory_copy_struct_wrapper::xgl_memory_copy_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_copy_struct_wrapper::xgl_memory_copy_struct_wrapper(XGL_MEMORY_COPY* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_copy_struct_wrapper::xgl_memory_copy_struct_wrapper(const XGL_MEMORY_COPY* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_copy_struct_wrapper::~xgl_memory_copy_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_copy_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_COPY = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_copy_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssrcOffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.srcOffset));
+    printf("%*s    %sdestOffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.destOffset));
+    printf("%*s    %scopySize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.copySize));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_copy_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_COPY struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_copy_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_COPY struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_descriptor_slot_info_struct_wrapper class definition
+xgl_descriptor_slot_info_struct_wrapper::xgl_descriptor_slot_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_descriptor_slot_info_struct_wrapper::xgl_descriptor_slot_info_struct_wrapper(XGL_DESCRIPTOR_SLOT_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_slot_info_struct_wrapper::xgl_descriptor_slot_info_struct_wrapper(const XGL_DESCRIPTOR_SLOT_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_slot_info_struct_wrapper::~xgl_descriptor_slot_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_descriptor_slot_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DESCRIPTOR_SLOT_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_descriptor_slot_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sslotObjectType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_DESCRIPTOR_SET_SLOT_TYPE(m_struct.slotObjectType));
+    printf("%*s    %sshaderEntityIndex = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.shaderEntityIndex));
+    printf("%*s    %spNextLevelSet = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNextLevelSet));
+}
+
+// Output all struct elements, each on their own line
+void xgl_descriptor_slot_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SLOT_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_descriptor_slot_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SLOT_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_link_const_buffer_struct_wrapper class definition
+xgl_link_const_buffer_struct_wrapper::xgl_link_const_buffer_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_link_const_buffer_struct_wrapper::xgl_link_const_buffer_struct_wrapper(XGL_LINK_CONST_BUFFER* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_link_const_buffer_struct_wrapper::xgl_link_const_buffer_struct_wrapper(const XGL_LINK_CONST_BUFFER* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_link_const_buffer_struct_wrapper::~xgl_link_const_buffer_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_link_const_buffer_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_LINK_CONST_BUFFER = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_link_const_buffer_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sbufferId = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.bufferId));
+    printf("%*s    %sbufferSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.bufferSize));
+    printf("%*s    %spBufferData = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pBufferData));
+}
+
+// Output all struct elements, each on their own line
+void xgl_link_const_buffer_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_LINK_CONST_BUFFER struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_link_const_buffer_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_LINK_CONST_BUFFER struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_memory_image_copy_struct_wrapper class definition
+xgl_memory_image_copy_struct_wrapper::xgl_memory_image_copy_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_image_copy_struct_wrapper::xgl_memory_image_copy_struct_wrapper(XGL_MEMORY_IMAGE_COPY* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_image_copy_struct_wrapper::xgl_memory_image_copy_struct_wrapper(const XGL_MEMORY_IMAGE_COPY* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_image_copy_struct_wrapper::~xgl_memory_image_copy_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_image_copy_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_IMAGE_COPY = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_image_copy_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %smemOffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.memOffset));
+    printf("%*s    %simageSubresource = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.imageSubresource));
+    printf("%*s    %simageOffset = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.imageOffset));
+    printf("%*s    %simageExtent = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.imageExtent));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_image_copy_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_IMAGE_COPY struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_image_copy_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_IMAGE_COPY struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.imageExtent) {
+        xgl_extent3d_struct_wrapper class0(&m_struct.imageExtent);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.imageOffset) {
+        xgl_offset3d_struct_wrapper class1(&m_struct.imageOffset);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    if (&m_struct.imageSubresource) {
+        xgl_image_subresource_struct_wrapper class2(&m_struct.imageSubresource);
+        class2.set_indent(m_indent + 4);
+        class2.display_full_txt();
+    }
+}
+
+
+// xgl_depth_stencil_state_create_info_struct_wrapper class definition
+xgl_depth_stencil_state_create_info_struct_wrapper::xgl_depth_stencil_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_depth_stencil_state_create_info_struct_wrapper::xgl_depth_stencil_state_create_info_struct_wrapper(XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_depth_stencil_state_create_info_struct_wrapper::xgl_depth_stencil_state_create_info_struct_wrapper(const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_depth_stencil_state_create_info_struct_wrapper::~xgl_depth_stencil_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_depth_stencil_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DEPTH_STENCIL_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_depth_stencil_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sdepthTestEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.depthTestEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sdepthWriteEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.depthWriteEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sdepthFunc = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_COMPARE_FUNC(m_struct.depthFunc));
+    printf("%*s    %sdepthBoundsEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.depthBoundsEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sminDepth = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.minDepth));
+    printf("%*s    %smaxDepth = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.maxDepth));
+    printf("%*s    %sstencilTestEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.stencilTestEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sstencilReadMask = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.stencilReadMask));
+    printf("%*s    %sstencilWriteMask = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.stencilWriteMask));
+    printf("%*s    %sfront = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.front));
+    printf("%*s    %sback = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.back));
+}
+
+// Output all struct elements, each on their own line
+void xgl_depth_stencil_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DEPTH_STENCIL_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_depth_stencil_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DEPTH_STENCIL_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.back) {
+        xgl_stencil_op_state_struct_wrapper class0(&m_struct.back);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (&m_struct.front) {
+        xgl_stencil_op_state_struct_wrapper class1(&m_struct.front);
+        class1.set_indent(m_indent + 4);
+        class1.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_viewport_struct_wrapper class definition
+xgl_viewport_struct_wrapper::xgl_viewport_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_viewport_struct_wrapper::xgl_viewport_struct_wrapper(XGL_VIEWPORT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_viewport_struct_wrapper::xgl_viewport_struct_wrapper(const XGL_VIEWPORT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_viewport_struct_wrapper::~xgl_viewport_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_viewport_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_VIEWPORT = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_viewport_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %soriginX = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.originX));
+    printf("%*s    %soriginY = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.originY));
+    printf("%*s    %swidth = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.width));
+    printf("%*s    %sheight = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.height));
+    printf("%*s    %sminDepth = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.minDepth));
+    printf("%*s    %smaxDepth = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.maxDepth));
+}
+
+// Output all struct elements, each on their own line
+void xgl_viewport_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_VIEWPORT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_viewport_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_VIEWPORT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_descriptor_set_mapping_struct_wrapper class definition
+xgl_descriptor_set_mapping_struct_wrapper::xgl_descriptor_set_mapping_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_descriptor_set_mapping_struct_wrapper::xgl_descriptor_set_mapping_struct_wrapper(XGL_DESCRIPTOR_SET_MAPPING* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_set_mapping_struct_wrapper::xgl_descriptor_set_mapping_struct_wrapper(const XGL_DESCRIPTOR_SET_MAPPING* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_set_mapping_struct_wrapper::~xgl_descriptor_set_mapping_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_descriptor_set_mapping_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DESCRIPTOR_SET_MAPPING = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_descriptor_set_mapping_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sdescriptorCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.descriptorCount));
+    printf("%*s    %spDescriptorInfo = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.pDescriptorInfo));
+}
+
+// Output all struct elements, each on their own line
+void xgl_descriptor_set_mapping_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SET_MAPPING struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_descriptor_set_mapping_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SET_MAPPING struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pDescriptorInfo) {
+        xgl_descriptor_slot_info_struct_wrapper class0(m_struct.pDescriptorInfo);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+}
+
+
+// xgl_peer_memory_open_info_struct_wrapper class definition
+xgl_peer_memory_open_info_struct_wrapper::xgl_peer_memory_open_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_peer_memory_open_info_struct_wrapper::xgl_peer_memory_open_info_struct_wrapper(XGL_PEER_MEMORY_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_peer_memory_open_info_struct_wrapper::xgl_peer_memory_open_info_struct_wrapper(const XGL_PEER_MEMORY_OPEN_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_peer_memory_open_info_struct_wrapper::~xgl_peer_memory_open_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_peer_memory_open_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PEER_MEMORY_OPEN_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_peer_memory_open_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %soriginalMem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.originalMem));
+}
+
+// Output all struct elements, each on their own line
+void xgl_peer_memory_open_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PEER_MEMORY_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_peer_memory_open_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PEER_MEMORY_OPEN_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_subresource_layout_struct_wrapper class definition
+xgl_subresource_layout_struct_wrapper::xgl_subresource_layout_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_subresource_layout_struct_wrapper::xgl_subresource_layout_struct_wrapper(XGL_SUBRESOURCE_LAYOUT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_subresource_layout_struct_wrapper::xgl_subresource_layout_struct_wrapper(const XGL_SUBRESOURCE_LAYOUT* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_subresource_layout_struct_wrapper::~xgl_subresource_layout_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_subresource_layout_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_SUBRESOURCE_LAYOUT = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_subresource_layout_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %soffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.offset));
+    printf("%*s    %ssize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.size));
+    printf("%*s    %srowPitch = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.rowPitch));
+    printf("%*s    %sdepthPitch = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.depthPitch));
+}
+
+// Output all struct elements, each on their own line
+void xgl_subresource_layout_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_SUBRESOURCE_LAYOUT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_subresource_layout_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_SUBRESOURCE_LAYOUT struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_descriptor_set_attach_info_struct_wrapper class definition
+xgl_descriptor_set_attach_info_struct_wrapper::xgl_descriptor_set_attach_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_descriptor_set_attach_info_struct_wrapper::xgl_descriptor_set_attach_info_struct_wrapper(XGL_DESCRIPTOR_SET_ATTACH_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_set_attach_info_struct_wrapper::xgl_descriptor_set_attach_info_struct_wrapper(const XGL_DESCRIPTOR_SET_ATTACH_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_descriptor_set_attach_info_struct_wrapper::~xgl_descriptor_set_attach_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_descriptor_set_attach_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DESCRIPTOR_SET_ATTACH_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_descriptor_set_attach_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sdescriptorSet = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.descriptorSet));
+    printf("%*s    %sslotOffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.slotOffset));
+}
+
+// Output all struct elements, each on their own line
+void xgl_descriptor_set_attach_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SET_ATTACH_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_descriptor_set_attach_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DESCRIPTOR_SET_ATTACH_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_pipeline_tess_state_create_info_struct_wrapper class definition
+xgl_pipeline_tess_state_create_info_struct_wrapper::xgl_pipeline_tess_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_tess_state_create_info_struct_wrapper::xgl_pipeline_tess_state_create_info_struct_wrapper(XGL_PIPELINE_TESS_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_tess_state_create_info_struct_wrapper::xgl_pipeline_tess_state_create_info_struct_wrapper(const XGL_PIPELINE_TESS_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_tess_state_create_info_struct_wrapper::~xgl_pipeline_tess_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_tess_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_TESS_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_tess_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %spatchControlPoints = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.patchControlPoints));
+    printf("%*s    %soptimalTessFactor = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.optimalTessFactor));
+    printf("%*s    %sfixedTessFactor = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.fixedTessFactor));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_tess_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_TESS_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_tess_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_TESS_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_pipeline_rs_state_create_info_struct_wrapper class definition
+xgl_pipeline_rs_state_create_info_struct_wrapper::xgl_pipeline_rs_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_rs_state_create_info_struct_wrapper::xgl_pipeline_rs_state_create_info_struct_wrapper(XGL_PIPELINE_RS_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_rs_state_create_info_struct_wrapper::xgl_pipeline_rs_state_create_info_struct_wrapper(const XGL_PIPELINE_RS_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_rs_state_create_info_struct_wrapper::~xgl_pipeline_rs_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_rs_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_RS_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_rs_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sdepthClipEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.depthClipEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %srasterizerDiscardEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.rasterizerDiscardEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %spointSize = %f\n", m_indent, "", &m_dummy_prefix, (m_struct.pointSize));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_rs_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_RS_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_rs_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_RS_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_stencil_op_state_struct_wrapper class definition
+xgl_stencil_op_state_struct_wrapper::xgl_stencil_op_state_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_stencil_op_state_struct_wrapper::xgl_stencil_op_state_struct_wrapper(XGL_STENCIL_OP_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_stencil_op_state_struct_wrapper::xgl_stencil_op_state_struct_wrapper(const XGL_STENCIL_OP_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_stencil_op_state_struct_wrapper::~xgl_stencil_op_state_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_stencil_op_state_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_STENCIL_OP_STATE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_stencil_op_state_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sstencilFailOp = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STENCIL_OP(m_struct.stencilFailOp));
+    printf("%*s    %sstencilPassOp = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STENCIL_OP(m_struct.stencilPassOp));
+    printf("%*s    %sstencilDepthFailOp = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STENCIL_OP(m_struct.stencilDepthFailOp));
+    printf("%*s    %sstencilFunc = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_COMPARE_FUNC(m_struct.stencilFunc));
+    printf("%*s    %sstencilRef = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.stencilRef));
+}
+
+// Output all struct elements, each on their own line
+void xgl_stencil_op_state_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_STENCIL_OP_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_stencil_op_state_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_STENCIL_OP_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_shader_create_info_struct_wrapper class definition
+xgl_shader_create_info_struct_wrapper::xgl_shader_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_shader_create_info_struct_wrapper::xgl_shader_create_info_struct_wrapper(XGL_SHADER_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_shader_create_info_struct_wrapper::xgl_shader_create_info_struct_wrapper(const XGL_SHADER_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_shader_create_info_struct_wrapper::~xgl_shader_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_shader_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_SHADER_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_shader_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %scodeSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.codeSize));
+    printf("%*s    %spCode = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pCode));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_shader_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_SHADER_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_shader_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_SHADER_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_color_blend_state_create_info_struct_wrapper class definition
+xgl_color_blend_state_create_info_struct_wrapper::xgl_color_blend_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_color_blend_state_create_info_struct_wrapper::xgl_color_blend_state_create_info_struct_wrapper(XGL_COLOR_BLEND_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_blend_state_create_info_struct_wrapper::xgl_color_blend_state_create_info_struct_wrapper(const XGL_COLOR_BLEND_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_blend_state_create_info_struct_wrapper::~xgl_color_blend_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_color_blend_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_COLOR_BLEND_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_color_blend_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_COLOR_ATTACHMENTS; i++) {
+        printf("%*s    %sattachment[%u] = %p\n", m_indent, "", &m_dummy_prefix, i, (void*)&(m_struct.attachment)[i]);
+    }
+    for (i = 0; i<4; i++) {
+        printf("%*s    %sblendConst[%u] = %f\n", m_indent, "", &m_dummy_prefix, i, (m_struct.blendConst)[i]);
+    }
+}
+
+// Output all struct elements, each on their own line
+void xgl_color_blend_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_COLOR_BLEND_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_color_blend_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_COLOR_BLEND_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_COLOR_ATTACHMENTS; i++) {
+            xgl_color_attachment_blend_state_struct_wrapper class0(&(m_struct.attachment[i]));
+            class0.set_indent(m_indent + 4);
+            class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_pipeline_cb_state_create_info_struct_wrapper class definition
+xgl_pipeline_cb_state_create_info_struct_wrapper::xgl_pipeline_cb_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_cb_state_create_info_struct_wrapper::xgl_pipeline_cb_state_create_info_struct_wrapper(XGL_PIPELINE_CB_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_cb_state_create_info_struct_wrapper::xgl_pipeline_cb_state_create_info_struct_wrapper(const XGL_PIPELINE_CB_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_cb_state_create_info_struct_wrapper::~xgl_pipeline_cb_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_cb_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_CB_STATE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_cb_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %salphaToCoverageEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.alphaToCoverageEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sdualSourceBlendEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.dualSourceBlendEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %slogicOp = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_LOGIC_OP(m_struct.logicOp));
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_COLOR_ATTACHMENTS; i++) {
+        printf("%*s    %sattachment[%u] = %p\n", m_indent, "", &m_dummy_prefix, i, (void*)&(m_struct.attachment)[i]);
+    }
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_cb_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_CB_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_cb_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_CB_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_COLOR_ATTACHMENTS; i++) {
+            xgl_pipeline_cb_attachment_state_struct_wrapper class0(&(m_struct.attachment[i]));
+            class0.set_indent(m_indent + 4);
+            class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_channel_mapping_struct_wrapper class definition
+xgl_channel_mapping_struct_wrapper::xgl_channel_mapping_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_channel_mapping_struct_wrapper::xgl_channel_mapping_struct_wrapper(XGL_CHANNEL_MAPPING* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_channel_mapping_struct_wrapper::xgl_channel_mapping_struct_wrapper(const XGL_CHANNEL_MAPPING* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_channel_mapping_struct_wrapper::~xgl_channel_mapping_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_channel_mapping_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_CHANNEL_MAPPING = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_channel_mapping_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sr = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_CHANNEL_SWIZZLE(m_struct.r));
+    printf("%*s    %sg = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_CHANNEL_SWIZZLE(m_struct.g));
+    printf("%*s    %sb = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_CHANNEL_SWIZZLE(m_struct.b));
+    printf("%*s    %sa = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_CHANNEL_SWIZZLE(m_struct.a));
+}
+
+// Output all struct elements, each on their own line
+void xgl_channel_mapping_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_CHANNEL_MAPPING struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_channel_mapping_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_CHANNEL_MAPPING struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_depth_stencil_view_create_info_struct_wrapper class definition
+xgl_depth_stencil_view_create_info_struct_wrapper::xgl_depth_stencil_view_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_depth_stencil_view_create_info_struct_wrapper::xgl_depth_stencil_view_create_info_struct_wrapper(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_depth_stencil_view_create_info_struct_wrapper::xgl_depth_stencil_view_create_info_struct_wrapper(const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_depth_stencil_view_create_info_struct_wrapper::~xgl_depth_stencil_view_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_depth_stencil_view_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DEPTH_STENCIL_VIEW_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_depth_stencil_view_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %simage = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.image));
+    printf("%*s    %smipLevel = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.mipLevel));
+    printf("%*s    %sbaseArraySlice = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.baseArraySlice));
+    printf("%*s    %sarraySize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.arraySize));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_depth_stencil_view_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DEPTH_STENCIL_VIEW_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_depth_stencil_view_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DEPTH_STENCIL_VIEW_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_virtual_memory_remap_range_struct_wrapper class definition
+xgl_virtual_memory_remap_range_struct_wrapper::xgl_virtual_memory_remap_range_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_virtual_memory_remap_range_struct_wrapper::xgl_virtual_memory_remap_range_struct_wrapper(XGL_VIRTUAL_MEMORY_REMAP_RANGE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_virtual_memory_remap_range_struct_wrapper::xgl_virtual_memory_remap_range_struct_wrapper(const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_virtual_memory_remap_range_struct_wrapper::~xgl_virtual_memory_remap_range_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_virtual_memory_remap_range_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_VIRTUAL_MEMORY_REMAP_RANGE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_virtual_memory_remap_range_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %svirtualMem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.virtualMem));
+    printf("%*s    %svirtualStartPage = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.virtualStartPage));
+    printf("%*s    %srealMem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.realMem));
+    printf("%*s    %srealStartPage = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.realStartPage));
+    printf("%*s    %spageCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.pageCount));
+}
+
+// Output all struct elements, each on their own line
+void xgl_virtual_memory_remap_range_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_VIRTUAL_MEMORY_REMAP_RANGE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_virtual_memory_remap_range_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_VIRTUAL_MEMORY_REMAP_RANGE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_cmd_buffer_create_info_struct_wrapper class definition
+xgl_cmd_buffer_create_info_struct_wrapper::xgl_cmd_buffer_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_cmd_buffer_create_info_struct_wrapper::xgl_cmd_buffer_create_info_struct_wrapper(XGL_CMD_BUFFER_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_cmd_buffer_create_info_struct_wrapper::xgl_cmd_buffer_create_info_struct_wrapper(const XGL_CMD_BUFFER_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_cmd_buffer_create_info_struct_wrapper::~xgl_cmd_buffer_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_cmd_buffer_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_CMD_BUFFER_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_cmd_buffer_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %squeueType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_QUEUE_TYPE(m_struct.queueType));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_cmd_buffer_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_CMD_BUFFER_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_cmd_buffer_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_CMD_BUFFER_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_format_properties_struct_wrapper class definition
+xgl_format_properties_struct_wrapper::xgl_format_properties_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_format_properties_struct_wrapper::xgl_format_properties_struct_wrapper(XGL_FORMAT_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_format_properties_struct_wrapper::xgl_format_properties_struct_wrapper(const XGL_FORMAT_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_format_properties_struct_wrapper::~xgl_format_properties_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_format_properties_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_FORMAT_PROPERTIES = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_format_properties_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %slinearTilingFeatures = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.linearTilingFeatures));
+    printf("%*s    %soptimalTilingFeatures = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.optimalTilingFeatures));
+}
+
+// Output all struct elements, each on their own line
+void xgl_format_properties_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_FORMAT_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_format_properties_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_FORMAT_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_physical_gpu_properties_struct_wrapper class definition
+xgl_physical_gpu_properties_struct_wrapper::xgl_physical_gpu_properties_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_physical_gpu_properties_struct_wrapper::xgl_physical_gpu_properties_struct_wrapper(XGL_PHYSICAL_GPU_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_properties_struct_wrapper::xgl_physical_gpu_properties_struct_wrapper(const XGL_PHYSICAL_GPU_PROPERTIES* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_physical_gpu_properties_struct_wrapper::~xgl_physical_gpu_properties_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_physical_gpu_properties_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PHYSICAL_GPU_PROPERTIES = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_physical_gpu_properties_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sstructSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.structSize));
+    printf("%*s    %sapiVersion = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.apiVersion));
+    printf("%*s    %sdriverVersion = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.driverVersion));
+    printf("%*s    %svendorId = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.vendorId));
+    printf("%*s    %sdeviceId = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.deviceId));
+    printf("%*s    %sgpuType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_PHYSICAL_GPU_TYPE(m_struct.gpuType));
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_PHYSICAL_GPU_NAME; i++) {
+        printf("%*s    %sgpuName = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.gpuName));
+    }
+    printf("%*s    %smaxMemRefsPerSubmission = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.maxMemRefsPerSubmission));
+    printf("%*s    %svirtualMemPageSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.virtualMemPageSize));
+    printf("%*s    %smaxInlineMemoryUpdateSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.maxInlineMemoryUpdateSize));
+    printf("%*s    %smaxBoundDescriptorSets = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.maxBoundDescriptorSets));
+    printf("%*s    %smaxThreadGroupSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.maxThreadGroupSize));
+    printf("%*s    %stimestampFrequency = %lu\n", m_indent, "", &m_dummy_prefix, (m_struct.timestampFrequency));
+    printf("%*s    %smultiColorAttachmentClears = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.multiColorAttachmentClears) ? "TRUE" : "FALSE");
+}
+
+// Output all struct elements, each on their own line
+void xgl_physical_gpu_properties_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_physical_gpu_properties_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PHYSICAL_GPU_PROPERTIES struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_depth_stencil_bind_info_struct_wrapper class definition
+xgl_depth_stencil_bind_info_struct_wrapper::xgl_depth_stencil_bind_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_depth_stencil_bind_info_struct_wrapper::xgl_depth_stencil_bind_info_struct_wrapper(XGL_DEPTH_STENCIL_BIND_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_depth_stencil_bind_info_struct_wrapper::xgl_depth_stencil_bind_info_struct_wrapper(const XGL_DEPTH_STENCIL_BIND_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_depth_stencil_bind_info_struct_wrapper::~xgl_depth_stencil_bind_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_depth_stencil_bind_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DEPTH_STENCIL_BIND_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_depth_stencil_bind_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sview = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.view));
+    printf("%*s    %sdepthState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_STATE(m_struct.depthState));
+    printf("%*s    %sstencilState = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_IMAGE_STATE(m_struct.stencilState));
+}
+
+// Output all struct elements, each on their own line
+void xgl_depth_stencil_bind_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DEPTH_STENCIL_BIND_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_depth_stencil_bind_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DEPTH_STENCIL_BIND_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_draw_indirect_cmd_struct_wrapper class definition
+xgl_draw_indirect_cmd_struct_wrapper::xgl_draw_indirect_cmd_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_draw_indirect_cmd_struct_wrapper::xgl_draw_indirect_cmd_struct_wrapper(XGL_DRAW_INDIRECT_CMD* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_draw_indirect_cmd_struct_wrapper::xgl_draw_indirect_cmd_struct_wrapper(const XGL_DRAW_INDIRECT_CMD* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_draw_indirect_cmd_struct_wrapper::~xgl_draw_indirect_cmd_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_draw_indirect_cmd_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DRAW_INDIRECT_CMD = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_draw_indirect_cmd_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %svertexCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.vertexCount));
+    printf("%*s    %sinstanceCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.instanceCount));
+    printf("%*s    %sfirstVertex = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.firstVertex));
+    printf("%*s    %sfirstInstance = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.firstInstance));
+}
+
+// Output all struct elements, each on their own line
+void xgl_draw_indirect_cmd_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DRAW_INDIRECT_CMD struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_draw_indirect_cmd_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DRAW_INDIRECT_CMD struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_graphics_pipeline_create_info_struct_wrapper class definition
+xgl_graphics_pipeline_create_info_struct_wrapper::xgl_graphics_pipeline_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_graphics_pipeline_create_info_struct_wrapper::xgl_graphics_pipeline_create_info_struct_wrapper(XGL_GRAPHICS_PIPELINE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_graphics_pipeline_create_info_struct_wrapper::xgl_graphics_pipeline_create_info_struct_wrapper(const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_graphics_pipeline_create_info_struct_wrapper::~xgl_graphics_pipeline_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_graphics_pipeline_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_GRAPHICS_PIPELINE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_graphics_pipeline_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_graphics_pipeline_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_GRAPHICS_PIPELINE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_graphics_pipeline_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_GRAPHICS_PIPELINE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_pipeline_ia_state_create_info_struct_wrapper class definition
+xgl_pipeline_ia_state_create_info_struct_wrapper::xgl_pipeline_ia_state_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_ia_state_create_info_struct_wrapper::xgl_pipeline_ia_state_create_info_struct_wrapper(XGL_PIPELINE_IA_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_ia_state_create_info_struct_wrapper::xgl_pipeline_ia_state_create_info_struct_wrapper(const XGL_PIPELINE_IA_STATE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_ia_state_create_info_struct_wrapper::~xgl_pipeline_ia_state_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_ia_state_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_IA_STATE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_ia_state_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %stopology = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_PRIMITIVE_TOPOLOGY(m_struct.topology));
+    printf("%*s    %sdisableVertexReuse = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.disableVertexReuse) ? "TRUE" : "FALSE");
+    printf("%*s    %sprovokingVertex = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_PROVOKING_VERTEX_CONVENTION(m_struct.provokingVertex));
+    printf("%*s    %sprimitiveRestartEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.primitiveRestartEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %sprimitiveRestartIndex = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.primitiveRestartIndex));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_ia_state_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_IA_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_ia_state_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_IA_STATE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_color_attachment_blend_state_struct_wrapper class definition
+xgl_color_attachment_blend_state_struct_wrapper::xgl_color_attachment_blend_state_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_color_attachment_blend_state_struct_wrapper::xgl_color_attachment_blend_state_struct_wrapper(XGL_COLOR_ATTACHMENT_BLEND_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_attachment_blend_state_struct_wrapper::xgl_color_attachment_blend_state_struct_wrapper(const XGL_COLOR_ATTACHMENT_BLEND_STATE* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_color_attachment_blend_state_struct_wrapper::~xgl_color_attachment_blend_state_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_color_attachment_blend_state_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_COLOR_ATTACHMENT_BLEND_STATE = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_color_attachment_blend_state_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sblendEnable = %s\n", m_indent, "", &m_dummy_prefix, (m_struct.blendEnable) ? "TRUE" : "FALSE");
+    printf("%*s    %ssrcBlendColor = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BLEND(m_struct.srcBlendColor));
+    printf("%*s    %sdestBlendColor = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BLEND(m_struct.destBlendColor));
+    printf("%*s    %sblendFuncColor = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BLEND_FUNC(m_struct.blendFuncColor));
+    printf("%*s    %ssrcBlendAlpha = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BLEND(m_struct.srcBlendAlpha));
+    printf("%*s    %sdestBlendAlpha = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BLEND(m_struct.destBlendAlpha));
+    printf("%*s    %sblendFuncAlpha = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_BLEND_FUNC(m_struct.blendFuncAlpha));
+}
+
+// Output all struct elements, each on their own line
+void xgl_color_attachment_blend_state_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_COLOR_ATTACHMENT_BLEND_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_color_attachment_blend_state_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_COLOR_ATTACHMENT_BLEND_STATE struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_extent2d_struct_wrapper class definition
+xgl_extent2d_struct_wrapper::xgl_extent2d_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_extent2d_struct_wrapper::xgl_extent2d_struct_wrapper(XGL_EXTENT2D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_extent2d_struct_wrapper::xgl_extent2d_struct_wrapper(const XGL_EXTENT2D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_extent2d_struct_wrapper::~xgl_extent2d_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_extent2d_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_EXTENT2D = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_extent2d_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %swidth = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.width));
+    printf("%*s    %sheight = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.height));
+}
+
+// Output all struct elements, each on their own line
+void xgl_extent2d_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_EXTENT2D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_extent2d_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_EXTENT2D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_memory_alloc_info_struct_wrapper class definition
+xgl_memory_alloc_info_struct_wrapper::xgl_memory_alloc_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_alloc_info_struct_wrapper::xgl_memory_alloc_info_struct_wrapper(XGL_MEMORY_ALLOC_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_alloc_info_struct_wrapper::xgl_memory_alloc_info_struct_wrapper(const XGL_MEMORY_ALLOC_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_alloc_info_struct_wrapper::~xgl_memory_alloc_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_alloc_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_ALLOC_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_alloc_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sallocationSize = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.allocationSize));
+    printf("%*s    %salignment = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.alignment));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+    printf("%*s    %sheapCount = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.heapCount));
+    uint32_t i;
+    for (i = 0; i<XGL_MAX_MEMORY_HEAPS; i++) {
+        printf("%*s    %sheaps[%u] = %u\n", m_indent, "", &m_dummy_prefix, i, (m_struct.heaps)[i]);
+    }
+    printf("%*s    %smemPriority = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_MEMORY_PRIORITY(m_struct.memPriority));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_alloc_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_ALLOC_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_alloc_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_ALLOC_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_memory_ref_struct_wrapper class definition
+xgl_memory_ref_struct_wrapper::xgl_memory_ref_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_ref_struct_wrapper::xgl_memory_ref_struct_wrapper(XGL_MEMORY_REF* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_ref_struct_wrapper::xgl_memory_ref_struct_wrapper(const XGL_MEMORY_REF* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_ref_struct_wrapper::~xgl_memory_ref_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_ref_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_REF = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_ref_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %smem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.mem));
+    printf("%*s    %sflags = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.flags));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_ref_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_REF struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_ref_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_REF struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_query_pool_create_info_struct_wrapper class definition
+xgl_query_pool_create_info_struct_wrapper::xgl_query_pool_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_query_pool_create_info_struct_wrapper::xgl_query_pool_create_info_struct_wrapper(XGL_QUERY_POOL_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_query_pool_create_info_struct_wrapper::xgl_query_pool_create_info_struct_wrapper(const XGL_QUERY_POOL_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_query_pool_create_info_struct_wrapper::~xgl_query_pool_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_query_pool_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_QUERY_POOL_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_query_pool_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %squeryType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_QUERY_TYPE(m_struct.queryType));
+    printf("%*s    %sslots = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.slots));
+}
+
+// Output all struct elements, each on their own line
+void xgl_query_pool_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_QUERY_POOL_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_query_pool_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_QUERY_POOL_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_offset3d_struct_wrapper class definition
+xgl_offset3d_struct_wrapper::xgl_offset3d_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_offset3d_struct_wrapper::xgl_offset3d_struct_wrapper(XGL_OFFSET3D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_offset3d_struct_wrapper::xgl_offset3d_struct_wrapper(const XGL_OFFSET3D* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_offset3d_struct_wrapper::~xgl_offset3d_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_offset3d_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_OFFSET3D = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_offset3d_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sx = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.x));
+    printf("%*s    %sy = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.y));
+    printf("%*s    %sz = %i\n", m_indent, "", &m_dummy_prefix, (m_struct.z));
+}
+
+// Output all struct elements, each on their own line
+void xgl_offset3d_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_OFFSET3D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_offset3d_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_OFFSET3D struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+
+// xgl_pipeline_shader_stage_create_info_struct_wrapper class definition
+xgl_pipeline_shader_stage_create_info_struct_wrapper::xgl_pipeline_shader_stage_create_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_pipeline_shader_stage_create_info_struct_wrapper::xgl_pipeline_shader_stage_create_info_struct_wrapper(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_shader_stage_create_info_struct_wrapper::xgl_pipeline_shader_stage_create_info_struct_wrapper(const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_pipeline_shader_stage_create_info_struct_wrapper::~xgl_pipeline_shader_stage_create_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_pipeline_shader_stage_create_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_PIPELINE_SHADER_STAGE_CREATE_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_pipeline_shader_stage_create_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %sshader = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.shader));
+}
+
+// Output all struct elements, each on their own line
+void xgl_pipeline_shader_stage_create_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_PIPELINE_SHADER_STAGE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_pipeline_shader_stage_create_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_PIPELINE_SHADER_STAGE_CREATE_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.shader) {
+        xgl_pipeline_shader_struct_wrapper class0(&m_struct.shader);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_memory_view_attach_info_struct_wrapper class definition
+xgl_memory_view_attach_info_struct_wrapper::xgl_memory_view_attach_info_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_memory_view_attach_info_struct_wrapper::xgl_memory_view_attach_info_struct_wrapper(XGL_MEMORY_VIEW_ATTACH_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_view_attach_info_struct_wrapper::xgl_memory_view_attach_info_struct_wrapper(const XGL_MEMORY_VIEW_ATTACH_INFO* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_memory_view_attach_info_struct_wrapper::~xgl_memory_view_attach_info_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_memory_view_attach_info_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_MEMORY_VIEW_ATTACH_INFO = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_memory_view_attach_info_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %ssType = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_STRUCTURE_TYPE(m_struct.sType));
+    printf("%*s    %spNext = %p\n", m_indent, "", &m_dummy_prefix, (m_struct.pNext));
+    printf("%*s    %smem = %p\n", m_indent, "", &m_dummy_prefix, (void*)(m_struct.mem));
+    printf("%*s    %soffset = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.offset));
+    printf("%*s    %srange = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.range));
+    printf("%*s    %sstride = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.stride));
+    printf("%*s    %sformat = %p\n", m_indent, "", &m_dummy_prefix, (void*)&(m_struct.format));
+    printf("%*s    %sstate = %s\n", m_indent, "", &m_dummy_prefix, string_XGL_MEMORY_STATE(m_struct.state));
+}
+
+// Output all struct elements, each on their own line
+void xgl_memory_view_attach_info_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_MEMORY_VIEW_ATTACH_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_memory_view_attach_info_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_MEMORY_VIEW_ATTACH_INFO struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+    if (&m_struct.format) {
+        xgl_format_struct_wrapper class0(&m_struct.format);
+        class0.set_indent(m_indent + 4);
+        class0.display_full_txt();
+    }
+    if (m_struct.pNext) {
+        dynamic_display_full_txt(m_struct.pNext, m_indent);
+    }
+}
+
+
+// xgl_dispatch_indirect_cmd_struct_wrapper class definition
+xgl_dispatch_indirect_cmd_struct_wrapper::xgl_dispatch_indirect_cmd_struct_wrapper() : m_struct(), m_indent(0), m_dummy_prefix('\0'), m_origStructAddr(NULL) {}
+xgl_dispatch_indirect_cmd_struct_wrapper::xgl_dispatch_indirect_cmd_struct_wrapper(XGL_DISPATCH_INDIRECT_CMD* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_dispatch_indirect_cmd_struct_wrapper::xgl_dispatch_indirect_cmd_struct_wrapper(const XGL_DISPATCH_INDIRECT_CMD* pInStruct) : m_indent(0), m_dummy_prefix('\0')
+{
+    m_struct = *pInStruct;
+    m_origStructAddr = pInStruct;
+}
+xgl_dispatch_indirect_cmd_struct_wrapper::~xgl_dispatch_indirect_cmd_struct_wrapper() {}
+// Output 'structname = struct_address' on a single line
+void xgl_dispatch_indirect_cmd_struct_wrapper::display_single_txt()
+{
+    printf(" %*sXGL_DISPATCH_INDIRECT_CMD = %p", m_indent, "", (void*)m_origStructAddr);
+}
+
+// Private helper function that displays the members of the wrapped struct
+void xgl_dispatch_indirect_cmd_struct_wrapper::display_struct_members()
+{
+    printf("%*s    %sx = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.x));
+    printf("%*s    %sy = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.y));
+    printf("%*s    %sz = %u\n", m_indent, "", &m_dummy_prefix, (m_struct.z));
+}
+
+// Output all struct elements, each on their own line
+void xgl_dispatch_indirect_cmd_struct_wrapper::display_txt()
+{
+    printf("%*sXGL_DISPATCH_INDIRECT_CMD struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+// Output all struct elements, and for any structs pointed to, print complete contents
+void xgl_dispatch_indirect_cmd_struct_wrapper::display_full_txt()
+{
+    printf("%*sXGL_DISPATCH_INDIRECT_CMD struct contents at %p:\n", m_indent, "", (void*)m_origStructAddr);
+    this->display_struct_members();
+}
+
+//any footer info for class
diff --git a/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_wrappers.h b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_wrappers.h
new file mode 100644
index 0000000..360c0f9
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glave_xgl_gen/xgl_struct_wrappers.h
@@ -0,0 +1,2799 @@
+//This is the copyright
+//#includes, #defines, globals and such...
+#include <xgl.h>
+#include <xgl_string_helper.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+//class declaration
+class xgl_raster_state_create_info_struct_wrapper
+{
+public:
+    xgl_raster_state_create_info_struct_wrapper();
+    xgl_raster_state_create_info_struct_wrapper(XGL_RASTER_STATE_CREATE_INFO* pInStruct);
+    xgl_raster_state_create_info_struct_wrapper(const XGL_RASTER_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_raster_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_FILL_MODE get_fillMode() { return m_struct.fillMode; }
+    void set_fillMode(XGL_FILL_MODE inValue) { m_struct.fillMode = inValue; }
+    XGL_CULL_MODE get_cullMode() { return m_struct.cullMode; }
+    void set_cullMode(XGL_CULL_MODE inValue) { m_struct.cullMode = inValue; }
+    XGL_FACE_ORIENTATION get_frontFace() { return m_struct.frontFace; }
+    void set_frontFace(XGL_FACE_ORIENTATION inValue) { m_struct.frontFace = inValue; }
+    XGL_INT get_depthBias() { return m_struct.depthBias; }
+    void set_depthBias(XGL_INT inValue) { m_struct.depthBias = inValue; }
+    XGL_FLOAT get_depthBiasClamp() { return m_struct.depthBiasClamp; }
+    void set_depthBiasClamp(XGL_FLOAT inValue) { m_struct.depthBiasClamp = inValue; }
+    XGL_FLOAT get_slopeScaledDepthBias() { return m_struct.slopeScaledDepthBias; }
+    void set_slopeScaledDepthBias(XGL_FLOAT inValue) { m_struct.slopeScaledDepthBias = inValue; }
+
+
+private:
+    XGL_RASTER_STATE_CREATE_INFO m_struct;
+    const XGL_RASTER_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_gpu_compatibility_info_struct_wrapper
+{
+public:
+    xgl_gpu_compatibility_info_struct_wrapper();
+    xgl_gpu_compatibility_info_struct_wrapper(XGL_GPU_COMPATIBILITY_INFO* pInStruct);
+    xgl_gpu_compatibility_info_struct_wrapper(const XGL_GPU_COMPATIBILITY_INFO* pInStruct);
+
+    virtual ~xgl_gpu_compatibility_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_FLAGS get_compatibilityFlags() { return m_struct.compatibilityFlags; }
+    void set_compatibilityFlags(XGL_FLAGS inValue) { m_struct.compatibilityFlags = inValue; }
+
+
+private:
+    XGL_GPU_COMPATIBILITY_INFO m_struct;
+    const XGL_GPU_COMPATIBILITY_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_view_create_info_struct_wrapper
+{
+public:
+    xgl_image_view_create_info_struct_wrapper();
+    xgl_image_view_create_info_struct_wrapper(XGL_IMAGE_VIEW_CREATE_INFO* pInStruct);
+    xgl_image_view_create_info_struct_wrapper(const XGL_IMAGE_VIEW_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_image_view_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_IMAGE get_image() { return m_struct.image; }
+    void set_image(XGL_IMAGE inValue) { m_struct.image = inValue; }
+    XGL_IMAGE_VIEW_TYPE get_viewType() { return m_struct.viewType; }
+    void set_viewType(XGL_IMAGE_VIEW_TYPE inValue) { m_struct.viewType = inValue; }
+    XGL_FORMAT get_format() { return m_struct.format; }
+    void set_format(XGL_FORMAT inValue) { m_struct.format = inValue; }
+    XGL_CHANNEL_MAPPING get_channels() { return m_struct.channels; }
+    void set_channels(XGL_CHANNEL_MAPPING inValue) { m_struct.channels = inValue; }
+    XGL_IMAGE_SUBRESOURCE_RANGE get_subresourceRange() { return m_struct.subresourceRange; }
+    void set_subresourceRange(XGL_IMAGE_SUBRESOURCE_RANGE inValue) { m_struct.subresourceRange = inValue; }
+    XGL_FLOAT get_minLod() { return m_struct.minLod; }
+    void set_minLod(XGL_FLOAT inValue) { m_struct.minLod = inValue; }
+
+
+private:
+    XGL_IMAGE_VIEW_CREATE_INFO m_struct;
+    const XGL_IMAGE_VIEW_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_open_info_struct_wrapper
+{
+public:
+    xgl_memory_open_info_struct_wrapper();
+    xgl_memory_open_info_struct_wrapper(XGL_MEMORY_OPEN_INFO* pInStruct);
+    xgl_memory_open_info_struct_wrapper(const XGL_MEMORY_OPEN_INFO* pInStruct);
+
+    virtual ~xgl_memory_open_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_GPU_MEMORY get_sharedMem() { return m_struct.sharedMem; }
+    void set_sharedMem(XGL_GPU_MEMORY inValue) { m_struct.sharedMem = inValue; }
+
+
+private:
+    XGL_MEMORY_OPEN_INFO m_struct;
+    const XGL_MEMORY_OPEN_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_heap_properties_struct_wrapper
+{
+public:
+    xgl_memory_heap_properties_struct_wrapper();
+    xgl_memory_heap_properties_struct_wrapper(XGL_MEMORY_HEAP_PROPERTIES* pInStruct);
+    xgl_memory_heap_properties_struct_wrapper(const XGL_MEMORY_HEAP_PROPERTIES* pInStruct);
+
+    virtual ~xgl_memory_heap_properties_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_SIZE get_structSize() { return m_struct.structSize; }
+    void set_structSize(XGL_SIZE inValue) { m_struct.structSize = inValue; }
+    XGL_HEAP_MEMORY_TYPE get_heapMemoryType() { return m_struct.heapMemoryType; }
+    void set_heapMemoryType(XGL_HEAP_MEMORY_TYPE inValue) { m_struct.heapMemoryType = inValue; }
+    XGL_GPU_SIZE get_heapSize() { return m_struct.heapSize; }
+    void set_heapSize(XGL_GPU_SIZE inValue) { m_struct.heapSize = inValue; }
+    XGL_GPU_SIZE get_pageSize() { return m_struct.pageSize; }
+    void set_pageSize(XGL_GPU_SIZE inValue) { m_struct.pageSize = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+    XGL_FLOAT get_gpuReadPerfRating() { return m_struct.gpuReadPerfRating; }
+    void set_gpuReadPerfRating(XGL_FLOAT inValue) { m_struct.gpuReadPerfRating = inValue; }
+    XGL_FLOAT get_gpuWritePerfRating() { return m_struct.gpuWritePerfRating; }
+    void set_gpuWritePerfRating(XGL_FLOAT inValue) { m_struct.gpuWritePerfRating = inValue; }
+    XGL_FLOAT get_cpuReadPerfRating() { return m_struct.cpuReadPerfRating; }
+    void set_cpuReadPerfRating(XGL_FLOAT inValue) { m_struct.cpuReadPerfRating = inValue; }
+    XGL_FLOAT get_cpuWritePerfRating() { return m_struct.cpuWritePerfRating; }
+    void set_cpuWritePerfRating(XGL_FLOAT inValue) { m_struct.cpuWritePerfRating = inValue; }
+
+
+private:
+    XGL_MEMORY_HEAP_PROPERTIES m_struct;
+    const XGL_MEMORY_HEAP_PROPERTIES* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_subresource_struct_wrapper
+{
+public:
+    xgl_image_subresource_struct_wrapper();
+    xgl_image_subresource_struct_wrapper(XGL_IMAGE_SUBRESOURCE* pInStruct);
+    xgl_image_subresource_struct_wrapper(const XGL_IMAGE_SUBRESOURCE* pInStruct);
+
+    virtual ~xgl_image_subresource_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_IMAGE_ASPECT get_aspect() { return m_struct.aspect; }
+    void set_aspect(XGL_IMAGE_ASPECT inValue) { m_struct.aspect = inValue; }
+    XGL_UINT get_mipLevel() { return m_struct.mipLevel; }
+    void set_mipLevel(XGL_UINT inValue) { m_struct.mipLevel = inValue; }
+    XGL_UINT get_arraySlice() { return m_struct.arraySlice; }
+    void set_arraySlice(XGL_UINT inValue) { m_struct.arraySlice = inValue; }
+
+
+private:
+    XGL_IMAGE_SUBRESOURCE m_struct;
+    const XGL_IMAGE_SUBRESOURCE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_physical_gpu_performance_struct_wrapper
+{
+public:
+    xgl_physical_gpu_performance_struct_wrapper();
+    xgl_physical_gpu_performance_struct_wrapper(XGL_PHYSICAL_GPU_PERFORMANCE* pInStruct);
+    xgl_physical_gpu_performance_struct_wrapper(const XGL_PHYSICAL_GPU_PERFORMANCE* pInStruct);
+
+    virtual ~xgl_physical_gpu_performance_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_FLOAT get_maxGpuClock() { return m_struct.maxGpuClock; }
+    void set_maxGpuClock(XGL_FLOAT inValue) { m_struct.maxGpuClock = inValue; }
+    XGL_FLOAT get_aluPerClock() { return m_struct.aluPerClock; }
+    void set_aluPerClock(XGL_FLOAT inValue) { m_struct.aluPerClock = inValue; }
+    XGL_FLOAT get_texPerClock() { return m_struct.texPerClock; }
+    void set_texPerClock(XGL_FLOAT inValue) { m_struct.texPerClock = inValue; }
+    XGL_FLOAT get_primsPerClock() { return m_struct.primsPerClock; }
+    void set_primsPerClock(XGL_FLOAT inValue) { m_struct.primsPerClock = inValue; }
+    XGL_FLOAT get_pixelsPerClock() { return m_struct.pixelsPerClock; }
+    void set_pixelsPerClock(XGL_FLOAT inValue) { m_struct.pixelsPerClock = inValue; }
+
+
+private:
+    XGL_PHYSICAL_GPU_PERFORMANCE m_struct;
+    const XGL_PHYSICAL_GPU_PERFORMANCE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_physical_gpu_memory_properties_struct_wrapper
+{
+public:
+    xgl_physical_gpu_memory_properties_struct_wrapper();
+    xgl_physical_gpu_memory_properties_struct_wrapper(XGL_PHYSICAL_GPU_MEMORY_PROPERTIES* pInStruct);
+    xgl_physical_gpu_memory_properties_struct_wrapper(const XGL_PHYSICAL_GPU_MEMORY_PROPERTIES* pInStruct);
+
+    virtual ~xgl_physical_gpu_memory_properties_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_SIZE get_structSize() { return m_struct.structSize; }
+    void set_structSize(XGL_SIZE inValue) { m_struct.structSize = inValue; }
+    XGL_BOOL get_supportsMigration() { return m_struct.supportsMigration; }
+    void set_supportsMigration(XGL_BOOL inValue) { m_struct.supportsMigration = inValue; }
+    XGL_BOOL get_supportsVirtualMemoryRemapping() { return m_struct.supportsVirtualMemoryRemapping; }
+    void set_supportsVirtualMemoryRemapping(XGL_BOOL inValue) { m_struct.supportsVirtualMemoryRemapping = inValue; }
+    XGL_BOOL get_supportsPinning() { return m_struct.supportsPinning; }
+    void set_supportsPinning(XGL_BOOL inValue) { m_struct.supportsPinning = inValue; }
+
+
+private:
+    XGL_PHYSICAL_GPU_MEMORY_PROPERTIES m_struct;
+    const XGL_PHYSICAL_GPU_MEMORY_PROPERTIES* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_shader_struct_wrapper
+{
+public:
+    xgl_pipeline_shader_struct_wrapper();
+    xgl_pipeline_shader_struct_wrapper(XGL_PIPELINE_SHADER* pInStruct);
+    xgl_pipeline_shader_struct_wrapper(const XGL_PIPELINE_SHADER* pInStruct);
+
+    virtual ~xgl_pipeline_shader_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_PIPELINE_SHADER_STAGE get_stage() { return m_struct.stage; }
+    void set_stage(XGL_PIPELINE_SHADER_STAGE inValue) { m_struct.stage = inValue; }
+    XGL_SHADER get_shader() { return m_struct.shader; }
+    void set_shader(XGL_SHADER inValue) { m_struct.shader = inValue; }
+    XGL_UINT get_linkConstBufferCount() { return m_struct.linkConstBufferCount; }
+    void set_linkConstBufferCount(XGL_UINT inValue) { m_struct.linkConstBufferCount = inValue; }
+    const XGL_LINK_CONST_BUFFER* get_pLinkConstBufferInfo() { return m_struct.pLinkConstBufferInfo; }
+    XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO get_dynamicMemoryViewMapping() { return m_struct.dynamicMemoryViewMapping; }
+    void set_dynamicMemoryViewMapping(XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO inValue) { m_struct.dynamicMemoryViewMapping = inValue; }
+
+
+private:
+    XGL_PIPELINE_SHADER m_struct;
+    const XGL_PIPELINE_SHADER* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_fence_create_info_struct_wrapper
+{
+public:
+    xgl_fence_create_info_struct_wrapper();
+    xgl_fence_create_info_struct_wrapper(XGL_FENCE_CREATE_INFO* pInStruct);
+    xgl_fence_create_info_struct_wrapper(const XGL_FENCE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_fence_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_FENCE_CREATE_INFO m_struct;
+    const XGL_FENCE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_cb_attachment_state_struct_wrapper
+{
+public:
+    xgl_pipeline_cb_attachment_state_struct_wrapper();
+    xgl_pipeline_cb_attachment_state_struct_wrapper(XGL_PIPELINE_CB_ATTACHMENT_STATE* pInStruct);
+    xgl_pipeline_cb_attachment_state_struct_wrapper(const XGL_PIPELINE_CB_ATTACHMENT_STATE* pInStruct);
+
+    virtual ~xgl_pipeline_cb_attachment_state_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_BOOL get_blendEnable() { return m_struct.blendEnable; }
+    void set_blendEnable(XGL_BOOL inValue) { m_struct.blendEnable = inValue; }
+    XGL_FORMAT get_format() { return m_struct.format; }
+    void set_format(XGL_FORMAT inValue) { m_struct.format = inValue; }
+    XGL_UINT8 get_channelWriteMask() { return m_struct.channelWriteMask; }
+    void set_channelWriteMask(XGL_UINT8 inValue) { m_struct.channelWriteMask = inValue; }
+
+
+private:
+    XGL_PIPELINE_CB_ATTACHMENT_STATE m_struct;
+    const XGL_PIPELINE_CB_ATTACHMENT_STATE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_alloc_callbacks_struct_wrapper
+{
+public:
+    xgl_alloc_callbacks_struct_wrapper();
+    xgl_alloc_callbacks_struct_wrapper(XGL_ALLOC_CALLBACKS* pInStruct);
+    xgl_alloc_callbacks_struct_wrapper(const XGL_ALLOC_CALLBACKS* pInStruct);
+
+    virtual ~xgl_alloc_callbacks_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_VOID* get_pUserData() { return m_struct.pUserData; }
+    void set_pUserData(XGL_VOID* inValue) { m_struct.pUserData = inValue; }
+    XGL_ALLOC_FUNCTION get_pfnAlloc() { return m_struct.pfnAlloc; }
+    void set_pfnAlloc(XGL_ALLOC_FUNCTION inValue) { m_struct.pfnAlloc = inValue; }
+    XGL_FREE_FUNCTION get_pfnFree() { return m_struct.pfnFree; }
+    void set_pfnFree(XGL_FREE_FUNCTION inValue) { m_struct.pfnFree = inValue; }
+
+
+private:
+    XGL_ALLOC_CALLBACKS m_struct;
+    const XGL_ALLOC_CALLBACKS* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_color_attachment_view_create_info_struct_wrapper
+{
+public:
+    xgl_color_attachment_view_create_info_struct_wrapper();
+    xgl_color_attachment_view_create_info_struct_wrapper(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pInStruct);
+    xgl_color_attachment_view_create_info_struct_wrapper(const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_color_attachment_view_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_IMAGE get_image() { return m_struct.image; }
+    void set_image(XGL_IMAGE inValue) { m_struct.image = inValue; }
+    XGL_FORMAT get_format() { return m_struct.format; }
+    void set_format(XGL_FORMAT inValue) { m_struct.format = inValue; }
+    XGL_UINT get_mipLevel() { return m_struct.mipLevel; }
+    void set_mipLevel(XGL_UINT inValue) { m_struct.mipLevel = inValue; }
+    XGL_UINT get_baseArraySlice() { return m_struct.baseArraySlice; }
+    void set_baseArraySlice(XGL_UINT inValue) { m_struct.baseArraySlice = inValue; }
+    XGL_UINT get_arraySize() { return m_struct.arraySize; }
+    void set_arraySize(XGL_UINT inValue) { m_struct.arraySize = inValue; }
+
+
+private:
+    XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO m_struct;
+    const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_copy_struct_wrapper
+{
+public:
+    xgl_image_copy_struct_wrapper();
+    xgl_image_copy_struct_wrapper(XGL_IMAGE_COPY* pInStruct);
+    xgl_image_copy_struct_wrapper(const XGL_IMAGE_COPY* pInStruct);
+
+    virtual ~xgl_image_copy_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_IMAGE_SUBRESOURCE get_srcSubresource() { return m_struct.srcSubresource; }
+    void set_srcSubresource(XGL_IMAGE_SUBRESOURCE inValue) { m_struct.srcSubresource = inValue; }
+    XGL_OFFSET3D get_srcOffset() { return m_struct.srcOffset; }
+    void set_srcOffset(XGL_OFFSET3D inValue) { m_struct.srcOffset = inValue; }
+    XGL_IMAGE_SUBRESOURCE get_destSubresource() { return m_struct.destSubresource; }
+    void set_destSubresource(XGL_IMAGE_SUBRESOURCE inValue) { m_struct.destSubresource = inValue; }
+    XGL_OFFSET3D get_destOffset() { return m_struct.destOffset; }
+    void set_destOffset(XGL_OFFSET3D inValue) { m_struct.destOffset = inValue; }
+    XGL_EXTENT3D get_extent() { return m_struct.extent; }
+    void set_extent(XGL_EXTENT3D inValue) { m_struct.extent = inValue; }
+
+
+private:
+    XGL_IMAGE_COPY m_struct;
+    const XGL_IMAGE_COPY* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_msaa_state_create_info_struct_wrapper
+{
+public:
+    xgl_msaa_state_create_info_struct_wrapper();
+    xgl_msaa_state_create_info_struct_wrapper(XGL_MSAA_STATE_CREATE_INFO* pInStruct);
+    xgl_msaa_state_create_info_struct_wrapper(const XGL_MSAA_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_msaa_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_UINT get_samples() { return m_struct.samples; }
+    void set_samples(XGL_UINT inValue) { m_struct.samples = inValue; }
+    XGL_SAMPLE_MASK get_sampleMask() { return m_struct.sampleMask; }
+    void set_sampleMask(XGL_SAMPLE_MASK inValue) { m_struct.sampleMask = inValue; }
+
+
+private:
+    XGL_MSAA_STATE_CREATE_INFO m_struct;
+    const XGL_MSAA_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_descriptor_set_create_info_struct_wrapper
+{
+public:
+    xgl_descriptor_set_create_info_struct_wrapper();
+    xgl_descriptor_set_create_info_struct_wrapper(XGL_DESCRIPTOR_SET_CREATE_INFO* pInStruct);
+    xgl_descriptor_set_create_info_struct_wrapper(const XGL_DESCRIPTOR_SET_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_descriptor_set_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_UINT get_slots() { return m_struct.slots; }
+    void set_slots(XGL_UINT inValue) { m_struct.slots = inValue; }
+
+
+private:
+    XGL_DESCRIPTOR_SET_CREATE_INFO m_struct;
+    const XGL_DESCRIPTOR_SET_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_color_attachment_bind_info_struct_wrapper
+{
+public:
+    xgl_color_attachment_bind_info_struct_wrapper();
+    xgl_color_attachment_bind_info_struct_wrapper(XGL_COLOR_ATTACHMENT_BIND_INFO* pInStruct);
+    xgl_color_attachment_bind_info_struct_wrapper(const XGL_COLOR_ATTACHMENT_BIND_INFO* pInStruct);
+
+    virtual ~xgl_color_attachment_bind_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_COLOR_ATTACHMENT_VIEW get_view() { return m_struct.view; }
+    void set_view(XGL_COLOR_ATTACHMENT_VIEW inValue) { m_struct.view = inValue; }
+    XGL_IMAGE_STATE get_colorAttachmentState() { return m_struct.colorAttachmentState; }
+    void set_colorAttachmentState(XGL_IMAGE_STATE inValue) { m_struct.colorAttachmentState = inValue; }
+
+
+private:
+    XGL_COLOR_ATTACHMENT_BIND_INFO m_struct;
+    const XGL_COLOR_ATTACHMENT_BIND_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_event_create_info_struct_wrapper
+{
+public:
+    xgl_event_create_info_struct_wrapper();
+    xgl_event_create_info_struct_wrapper(XGL_EVENT_CREATE_INFO* pInStruct);
+    xgl_event_create_info_struct_wrapper(const XGL_EVENT_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_event_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_EVENT_CREATE_INFO m_struct;
+    const XGL_EVENT_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_requirements_struct_wrapper
+{
+public:
+    xgl_memory_requirements_struct_wrapper();
+    xgl_memory_requirements_struct_wrapper(XGL_MEMORY_REQUIREMENTS* pInStruct);
+    xgl_memory_requirements_struct_wrapper(const XGL_MEMORY_REQUIREMENTS* pInStruct);
+
+    virtual ~xgl_memory_requirements_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_GPU_SIZE get_size() { return m_struct.size; }
+    void set_size(XGL_GPU_SIZE inValue) { m_struct.size = inValue; }
+    XGL_GPU_SIZE get_alignment() { return m_struct.alignment; }
+    void set_alignment(XGL_GPU_SIZE inValue) { m_struct.alignment = inValue; }
+    XGL_UINT get_heapCount() { return m_struct.heapCount; }
+    void set_heapCount(XGL_UINT inValue) { m_struct.heapCount = inValue; }
+
+
+private:
+    XGL_MEMORY_REQUIREMENTS m_struct;
+    const XGL_MEMORY_REQUIREMENTS* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_queue_semaphore_open_info_struct_wrapper
+{
+public:
+    xgl_queue_semaphore_open_info_struct_wrapper();
+    xgl_queue_semaphore_open_info_struct_wrapper(XGL_QUEUE_SEMAPHORE_OPEN_INFO* pInStruct);
+    xgl_queue_semaphore_open_info_struct_wrapper(const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pInStruct);
+
+    virtual ~xgl_queue_semaphore_open_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_QUEUE_SEMAPHORE get_sharedSemaphore() { return m_struct.sharedSemaphore; }
+    void set_sharedSemaphore(XGL_QUEUE_SEMAPHORE inValue) { m_struct.sharedSemaphore = inValue; }
+
+
+private:
+    XGL_QUEUE_SEMAPHORE_OPEN_INFO m_struct;
+    const XGL_QUEUE_SEMAPHORE_OPEN_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_resolve_struct_wrapper
+{
+public:
+    xgl_image_resolve_struct_wrapper();
+    xgl_image_resolve_struct_wrapper(XGL_IMAGE_RESOLVE* pInStruct);
+    xgl_image_resolve_struct_wrapper(const XGL_IMAGE_RESOLVE* pInStruct);
+
+    virtual ~xgl_image_resolve_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_IMAGE_SUBRESOURCE get_srcSubresource() { return m_struct.srcSubresource; }
+    void set_srcSubresource(XGL_IMAGE_SUBRESOURCE inValue) { m_struct.srcSubresource = inValue; }
+    XGL_OFFSET2D get_srcOffset() { return m_struct.srcOffset; }
+    void set_srcOffset(XGL_OFFSET2D inValue) { m_struct.srcOffset = inValue; }
+    XGL_IMAGE_SUBRESOURCE get_destSubresource() { return m_struct.destSubresource; }
+    void set_destSubresource(XGL_IMAGE_SUBRESOURCE inValue) { m_struct.destSubresource = inValue; }
+    XGL_OFFSET2D get_destOffset() { return m_struct.destOffset; }
+    void set_destOffset(XGL_OFFSET2D inValue) { m_struct.destOffset = inValue; }
+    XGL_EXTENT2D get_extent() { return m_struct.extent; }
+    void set_extent(XGL_EXTENT2D inValue) { m_struct.extent = inValue; }
+
+
+private:
+    XGL_IMAGE_RESOLVE m_struct;
+    const XGL_IMAGE_RESOLVE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_draw_indexed_indirect_cmd_struct_wrapper
+{
+public:
+    xgl_draw_indexed_indirect_cmd_struct_wrapper();
+    xgl_draw_indexed_indirect_cmd_struct_wrapper(XGL_DRAW_INDEXED_INDIRECT_CMD* pInStruct);
+    xgl_draw_indexed_indirect_cmd_struct_wrapper(const XGL_DRAW_INDEXED_INDIRECT_CMD* pInStruct);
+
+    virtual ~xgl_draw_indexed_indirect_cmd_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT32 get_indexCount() { return m_struct.indexCount; }
+    void set_indexCount(XGL_UINT32 inValue) { m_struct.indexCount = inValue; }
+    XGL_UINT32 get_instanceCount() { return m_struct.instanceCount; }
+    void set_instanceCount(XGL_UINT32 inValue) { m_struct.instanceCount = inValue; }
+    XGL_UINT32 get_firstIndex() { return m_struct.firstIndex; }
+    void set_firstIndex(XGL_UINT32 inValue) { m_struct.firstIndex = inValue; }
+    XGL_INT32 get_vertexOffset() { return m_struct.vertexOffset; }
+    void set_vertexOffset(XGL_INT32 inValue) { m_struct.vertexOffset = inValue; }
+    XGL_UINT32 get_firstInstance() { return m_struct.firstInstance; }
+    void set_firstInstance(XGL_UINT32 inValue) { m_struct.firstInstance = inValue; }
+
+
+private:
+    XGL_DRAW_INDEXED_INDIRECT_CMD m_struct;
+    const XGL_DRAW_INDEXED_INDIRECT_CMD* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_compute_pipeline_create_info_struct_wrapper
+{
+public:
+    xgl_compute_pipeline_create_info_struct_wrapper();
+    xgl_compute_pipeline_create_info_struct_wrapper(XGL_COMPUTE_PIPELINE_CREATE_INFO* pInStruct);
+    xgl_compute_pipeline_create_info_struct_wrapper(const XGL_COMPUTE_PIPELINE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_compute_pipeline_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_PIPELINE_SHADER get_cs() { return m_struct.cs; }
+    void set_cs(XGL_PIPELINE_SHADER inValue) { m_struct.cs = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_COMPUTE_PIPELINE_CREATE_INFO m_struct;
+    const XGL_COMPUTE_PIPELINE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_peer_image_open_info_struct_wrapper
+{
+public:
+    xgl_peer_image_open_info_struct_wrapper();
+    xgl_peer_image_open_info_struct_wrapper(XGL_PEER_IMAGE_OPEN_INFO* pInStruct);
+    xgl_peer_image_open_info_struct_wrapper(const XGL_PEER_IMAGE_OPEN_INFO* pInStruct);
+
+    virtual ~xgl_peer_image_open_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_IMAGE get_originalImage() { return m_struct.originalImage; }
+    void set_originalImage(XGL_IMAGE inValue) { m_struct.originalImage = inValue; }
+
+
+private:
+    XGL_PEER_IMAGE_OPEN_INFO m_struct;
+    const XGL_PEER_IMAGE_OPEN_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_physical_gpu_queue_properties_struct_wrapper
+{
+public:
+    xgl_physical_gpu_queue_properties_struct_wrapper();
+    xgl_physical_gpu_queue_properties_struct_wrapper(XGL_PHYSICAL_GPU_QUEUE_PROPERTIES* pInStruct);
+    xgl_physical_gpu_queue_properties_struct_wrapper(const XGL_PHYSICAL_GPU_QUEUE_PROPERTIES* pInStruct);
+
+    virtual ~xgl_physical_gpu_queue_properties_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_SIZE get_structSize() { return m_struct.structSize; }
+    void set_structSize(XGL_SIZE inValue) { m_struct.structSize = inValue; }
+    XGL_FLAGS get_queueFlags() { return m_struct.queueFlags; }
+    void set_queueFlags(XGL_FLAGS inValue) { m_struct.queueFlags = inValue; }
+    XGL_UINT get_queueCount() { return m_struct.queueCount; }
+    void set_queueCount(XGL_UINT inValue) { m_struct.queueCount = inValue; }
+    XGL_UINT get_maxAtomicCounters() { return m_struct.maxAtomicCounters; }
+    void set_maxAtomicCounters(XGL_UINT inValue) { m_struct.maxAtomicCounters = inValue; }
+    XGL_BOOL get_supportsTimestamps() { return m_struct.supportsTimestamps; }
+    void set_supportsTimestamps(XGL_BOOL inValue) { m_struct.supportsTimestamps = inValue; }
+
+
+private:
+    XGL_PHYSICAL_GPU_QUEUE_PROPERTIES m_struct;
+    const XGL_PHYSICAL_GPU_QUEUE_PROPERTIES* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_statistics_data_struct_wrapper
+{
+public:
+    xgl_pipeline_statistics_data_struct_wrapper();
+    xgl_pipeline_statistics_data_struct_wrapper(XGL_PIPELINE_STATISTICS_DATA* pInStruct);
+    xgl_pipeline_statistics_data_struct_wrapper(const XGL_PIPELINE_STATISTICS_DATA* pInStruct);
+
+    virtual ~xgl_pipeline_statistics_data_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT64 get_fsInvocations() { return m_struct.fsInvocations; }
+    void set_fsInvocations(XGL_UINT64 inValue) { m_struct.fsInvocations = inValue; }
+    XGL_UINT64 get_cPrimitives() { return m_struct.cPrimitives; }
+    void set_cPrimitives(XGL_UINT64 inValue) { m_struct.cPrimitives = inValue; }
+    XGL_UINT64 get_cInvocations() { return m_struct.cInvocations; }
+    void set_cInvocations(XGL_UINT64 inValue) { m_struct.cInvocations = inValue; }
+    XGL_UINT64 get_vsInvocations() { return m_struct.vsInvocations; }
+    void set_vsInvocations(XGL_UINT64 inValue) { m_struct.vsInvocations = inValue; }
+    XGL_UINT64 get_gsInvocations() { return m_struct.gsInvocations; }
+    void set_gsInvocations(XGL_UINT64 inValue) { m_struct.gsInvocations = inValue; }
+    XGL_UINT64 get_gsPrimitives() { return m_struct.gsPrimitives; }
+    void set_gsPrimitives(XGL_UINT64 inValue) { m_struct.gsPrimitives = inValue; }
+    XGL_UINT64 get_iaPrimitives() { return m_struct.iaPrimitives; }
+    void set_iaPrimitives(XGL_UINT64 inValue) { m_struct.iaPrimitives = inValue; }
+    XGL_UINT64 get_iaVertices() { return m_struct.iaVertices; }
+    void set_iaVertices(XGL_UINT64 inValue) { m_struct.iaVertices = inValue; }
+    XGL_UINT64 get_tcsInvocations() { return m_struct.tcsInvocations; }
+    void set_tcsInvocations(XGL_UINT64 inValue) { m_struct.tcsInvocations = inValue; }
+    XGL_UINT64 get_tesInvocations() { return m_struct.tesInvocations; }
+    void set_tesInvocations(XGL_UINT64 inValue) { m_struct.tesInvocations = inValue; }
+    XGL_UINT64 get_csInvocations() { return m_struct.csInvocations; }
+    void set_csInvocations(XGL_UINT64 inValue) { m_struct.csInvocations = inValue; }
+
+
+private:
+    XGL_PIPELINE_STATISTICS_DATA m_struct;
+    const XGL_PIPELINE_STATISTICS_DATA* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_device_queue_create_info_struct_wrapper
+{
+public:
+    xgl_device_queue_create_info_struct_wrapper();
+    xgl_device_queue_create_info_struct_wrapper(XGL_DEVICE_QUEUE_CREATE_INFO* pInStruct);
+    xgl_device_queue_create_info_struct_wrapper(const XGL_DEVICE_QUEUE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_device_queue_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT get_queueNodeIndex() { return m_struct.queueNodeIndex; }
+    void set_queueNodeIndex(XGL_UINT inValue) { m_struct.queueNodeIndex = inValue; }
+    XGL_UINT get_queueCount() { return m_struct.queueCount; }
+    void set_queueCount(XGL_UINT inValue) { m_struct.queueCount = inValue; }
+
+
+private:
+    XGL_DEVICE_QUEUE_CREATE_INFO m_struct;
+    const XGL_DEVICE_QUEUE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_sampler_create_info_struct_wrapper
+{
+public:
+    xgl_sampler_create_info_struct_wrapper();
+    xgl_sampler_create_info_struct_wrapper(XGL_SAMPLER_CREATE_INFO* pInStruct);
+    xgl_sampler_create_info_struct_wrapper(const XGL_SAMPLER_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_sampler_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_TEX_FILTER get_magFilter() { return m_struct.magFilter; }
+    void set_magFilter(XGL_TEX_FILTER inValue) { m_struct.magFilter = inValue; }
+    XGL_TEX_FILTER get_minFilter() { return m_struct.minFilter; }
+    void set_minFilter(XGL_TEX_FILTER inValue) { m_struct.minFilter = inValue; }
+    XGL_TEX_MIPMAP_MODE get_mipMode() { return m_struct.mipMode; }
+    void set_mipMode(XGL_TEX_MIPMAP_MODE inValue) { m_struct.mipMode = inValue; }
+    XGL_TEX_ADDRESS get_addressU() { return m_struct.addressU; }
+    void set_addressU(XGL_TEX_ADDRESS inValue) { m_struct.addressU = inValue; }
+    XGL_TEX_ADDRESS get_addressV() { return m_struct.addressV; }
+    void set_addressV(XGL_TEX_ADDRESS inValue) { m_struct.addressV = inValue; }
+    XGL_TEX_ADDRESS get_addressW() { return m_struct.addressW; }
+    void set_addressW(XGL_TEX_ADDRESS inValue) { m_struct.addressW = inValue; }
+    XGL_FLOAT get_mipLodBias() { return m_struct.mipLodBias; }
+    void set_mipLodBias(XGL_FLOAT inValue) { m_struct.mipLodBias = inValue; }
+    XGL_UINT get_maxAnisotropy() { return m_struct.maxAnisotropy; }
+    void set_maxAnisotropy(XGL_UINT inValue) { m_struct.maxAnisotropy = inValue; }
+    XGL_COMPARE_FUNC get_compareFunc() { return m_struct.compareFunc; }
+    void set_compareFunc(XGL_COMPARE_FUNC inValue) { m_struct.compareFunc = inValue; }
+    XGL_FLOAT get_minLod() { return m_struct.minLod; }
+    void set_minLod(XGL_FLOAT inValue) { m_struct.minLod = inValue; }
+    XGL_FLOAT get_maxLod() { return m_struct.maxLod; }
+    void set_maxLod(XGL_FLOAT inValue) { m_struct.maxLod = inValue; }
+    XGL_BORDER_COLOR_TYPE get_borderColorType() { return m_struct.borderColorType; }
+    void set_borderColorType(XGL_BORDER_COLOR_TYPE inValue) { m_struct.borderColorType = inValue; }
+
+
+private:
+    XGL_SAMPLER_CREATE_INFO m_struct;
+    const XGL_SAMPLER_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_queue_semaphore_create_info_struct_wrapper
+{
+public:
+    xgl_queue_semaphore_create_info_struct_wrapper();
+    xgl_queue_semaphore_create_info_struct_wrapper(XGL_QUEUE_SEMAPHORE_CREATE_INFO* pInStruct);
+    xgl_queue_semaphore_create_info_struct_wrapper(const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_queue_semaphore_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_UINT get_initialCount() { return m_struct.initialCount; }
+    void set_initialCount(XGL_UINT inValue) { m_struct.initialCount = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_QUEUE_SEMAPHORE_CREATE_INFO m_struct;
+    const XGL_QUEUE_SEMAPHORE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_format_struct_wrapper
+{
+public:
+    xgl_format_struct_wrapper();
+    xgl_format_struct_wrapper(XGL_FORMAT* pInStruct);
+    xgl_format_struct_wrapper(const XGL_FORMAT* pInStruct);
+
+    virtual ~xgl_format_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_CHANNEL_FORMAT get_channelFormat() { return m_struct.channelFormat; }
+    void set_channelFormat(XGL_CHANNEL_FORMAT inValue) { m_struct.channelFormat = inValue; }
+    XGL_NUM_FORMAT get_numericFormat() { return m_struct.numericFormat; }
+    void set_numericFormat(XGL_NUM_FORMAT inValue) { m_struct.numericFormat = inValue; }
+
+
+private:
+    XGL_FORMAT m_struct;
+    const XGL_FORMAT* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_state_transition_struct_wrapper
+{
+public:
+    xgl_memory_state_transition_struct_wrapper();
+    xgl_memory_state_transition_struct_wrapper(XGL_MEMORY_STATE_TRANSITION* pInStruct);
+    xgl_memory_state_transition_struct_wrapper(const XGL_MEMORY_STATE_TRANSITION* pInStruct);
+
+    virtual ~xgl_memory_state_transition_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_GPU_MEMORY get_mem() { return m_struct.mem; }
+    void set_mem(XGL_GPU_MEMORY inValue) { m_struct.mem = inValue; }
+    XGL_MEMORY_STATE get_oldState() { return m_struct.oldState; }
+    void set_oldState(XGL_MEMORY_STATE inValue) { m_struct.oldState = inValue; }
+    XGL_MEMORY_STATE get_newState() { return m_struct.newState; }
+    void set_newState(XGL_MEMORY_STATE inValue) { m_struct.newState = inValue; }
+    XGL_GPU_SIZE get_offset() { return m_struct.offset; }
+    void set_offset(XGL_GPU_SIZE inValue) { m_struct.offset = inValue; }
+    XGL_GPU_SIZE get_regionSize() { return m_struct.regionSize; }
+    void set_regionSize(XGL_GPU_SIZE inValue) { m_struct.regionSize = inValue; }
+
+
+private:
+    XGL_MEMORY_STATE_TRANSITION m_struct;
+    const XGL_MEMORY_STATE_TRANSITION* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_extent3d_struct_wrapper
+{
+public:
+    xgl_extent3d_struct_wrapper();
+    xgl_extent3d_struct_wrapper(XGL_EXTENT3D* pInStruct);
+    xgl_extent3d_struct_wrapper(const XGL_EXTENT3D* pInStruct);
+
+    virtual ~xgl_extent3d_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_INT get_width() { return m_struct.width; }
+    void set_width(XGL_INT inValue) { m_struct.width = inValue; }
+    XGL_INT get_height() { return m_struct.height; }
+    void set_height(XGL_INT inValue) { m_struct.height = inValue; }
+    XGL_INT get_depth() { return m_struct.depth; }
+    void set_depth(XGL_INT inValue) { m_struct.depth = inValue; }
+
+
+private:
+    XGL_EXTENT3D m_struct;
+    const XGL_EXTENT3D* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_dynamic_memory_view_slot_info_struct_wrapper
+{
+public:
+    xgl_dynamic_memory_view_slot_info_struct_wrapper();
+    xgl_dynamic_memory_view_slot_info_struct_wrapper(XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO* pInStruct);
+    xgl_dynamic_memory_view_slot_info_struct_wrapper(const XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO* pInStruct);
+
+    virtual ~xgl_dynamic_memory_view_slot_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_DESCRIPTOR_SET_SLOT_TYPE get_slotObjectType() { return m_struct.slotObjectType; }
+    void set_slotObjectType(XGL_DESCRIPTOR_SET_SLOT_TYPE inValue) { m_struct.slotObjectType = inValue; }
+    XGL_UINT get_shaderEntityIndex() { return m_struct.shaderEntityIndex; }
+    void set_shaderEntityIndex(XGL_UINT inValue) { m_struct.shaderEntityIndex = inValue; }
+
+
+private:
+    XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO m_struct;
+    const XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_view_attach_info_struct_wrapper
+{
+public:
+    xgl_image_view_attach_info_struct_wrapper();
+    xgl_image_view_attach_info_struct_wrapper(XGL_IMAGE_VIEW_ATTACH_INFO* pInStruct);
+    xgl_image_view_attach_info_struct_wrapper(const XGL_IMAGE_VIEW_ATTACH_INFO* pInStruct);
+
+    virtual ~xgl_image_view_attach_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_IMAGE_VIEW get_view() { return m_struct.view; }
+    void set_view(XGL_IMAGE_VIEW inValue) { m_struct.view = inValue; }
+    XGL_IMAGE_STATE get_state() { return m_struct.state; }
+    void set_state(XGL_IMAGE_STATE inValue) { m_struct.state = inValue; }
+
+
+private:
+    XGL_IMAGE_VIEW_ATTACH_INFO m_struct;
+    const XGL_IMAGE_VIEW_ATTACH_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_subresource_range_struct_wrapper
+{
+public:
+    xgl_image_subresource_range_struct_wrapper();
+    xgl_image_subresource_range_struct_wrapper(XGL_IMAGE_SUBRESOURCE_RANGE* pInStruct);
+    xgl_image_subresource_range_struct_wrapper(const XGL_IMAGE_SUBRESOURCE_RANGE* pInStruct);
+
+    virtual ~xgl_image_subresource_range_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_IMAGE_ASPECT get_aspect() { return m_struct.aspect; }
+    void set_aspect(XGL_IMAGE_ASPECT inValue) { m_struct.aspect = inValue; }
+    XGL_UINT get_baseMipLevel() { return m_struct.baseMipLevel; }
+    void set_baseMipLevel(XGL_UINT inValue) { m_struct.baseMipLevel = inValue; }
+    XGL_UINT get_mipLevels() { return m_struct.mipLevels; }
+    void set_mipLevels(XGL_UINT inValue) { m_struct.mipLevels = inValue; }
+    XGL_UINT get_baseArraySlice() { return m_struct.baseArraySlice; }
+    void set_baseArraySlice(XGL_UINT inValue) { m_struct.baseArraySlice = inValue; }
+    XGL_UINT get_arraySize() { return m_struct.arraySize; }
+    void set_arraySize(XGL_UINT inValue) { m_struct.arraySize = inValue; }
+
+
+private:
+    XGL_IMAGE_SUBRESOURCE_RANGE m_struct;
+    const XGL_IMAGE_SUBRESOURCE_RANGE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_db_state_create_info_struct_wrapper
+{
+public:
+    xgl_pipeline_db_state_create_info_struct_wrapper();
+    xgl_pipeline_db_state_create_info_struct_wrapper(XGL_PIPELINE_DB_STATE_CREATE_INFO* pInStruct);
+    xgl_pipeline_db_state_create_info_struct_wrapper(const XGL_PIPELINE_DB_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_pipeline_db_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_FORMAT get_format() { return m_struct.format; }
+    void set_format(XGL_FORMAT inValue) { m_struct.format = inValue; }
+
+
+private:
+    XGL_PIPELINE_DB_STATE_CREATE_INFO m_struct;
+    const XGL_PIPELINE_DB_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_application_info_struct_wrapper
+{
+public:
+    xgl_application_info_struct_wrapper();
+    xgl_application_info_struct_wrapper(XGL_APPLICATION_INFO* pInStruct);
+    xgl_application_info_struct_wrapper(const XGL_APPLICATION_INFO* pInStruct);
+
+    virtual ~xgl_application_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    const XGL_CHAR* get_pAppName() { return m_struct.pAppName; }
+    XGL_UINT32 get_appVersion() { return m_struct.appVersion; }
+    void set_appVersion(XGL_UINT32 inValue) { m_struct.appVersion = inValue; }
+    const XGL_CHAR* get_pEngineName() { return m_struct.pEngineName; }
+    XGL_UINT32 get_engineVersion() { return m_struct.engineVersion; }
+    void set_engineVersion(XGL_UINT32 inValue) { m_struct.engineVersion = inValue; }
+    XGL_UINT32 get_apiVersion() { return m_struct.apiVersion; }
+    void set_apiVersion(XGL_UINT32 inValue) { m_struct.apiVersion = inValue; }
+
+
+private:
+    XGL_APPLICATION_INFO m_struct;
+    const XGL_APPLICATION_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_offset2d_struct_wrapper
+{
+public:
+    xgl_offset2d_struct_wrapper();
+    xgl_offset2d_struct_wrapper(XGL_OFFSET2D* pInStruct);
+    xgl_offset2d_struct_wrapper(const XGL_OFFSET2D* pInStruct);
+
+    virtual ~xgl_offset2d_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_INT get_x() { return m_struct.x; }
+    void set_x(XGL_INT inValue) { m_struct.x = inValue; }
+    XGL_INT get_y() { return m_struct.y; }
+    void set_y(XGL_INT inValue) { m_struct.y = inValue; }
+
+
+private:
+    XGL_OFFSET2D m_struct;
+    const XGL_OFFSET2D* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_viewport_state_create_info_struct_wrapper
+{
+public:
+    xgl_viewport_state_create_info_struct_wrapper();
+    xgl_viewport_state_create_info_struct_wrapper(XGL_VIEWPORT_STATE_CREATE_INFO* pInStruct);
+    xgl_viewport_state_create_info_struct_wrapper(const XGL_VIEWPORT_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_viewport_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT get_viewportCount() { return m_struct.viewportCount; }
+    void set_viewportCount(XGL_UINT inValue) { m_struct.viewportCount = inValue; }
+    XGL_BOOL get_scissorEnable() { return m_struct.scissorEnable; }
+    void set_scissorEnable(XGL_BOOL inValue) { m_struct.scissorEnable = inValue; }
+
+
+private:
+    XGL_VIEWPORT_STATE_CREATE_INFO m_struct;
+    const XGL_VIEWPORT_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_state_transition_struct_wrapper
+{
+public:
+    xgl_image_state_transition_struct_wrapper();
+    xgl_image_state_transition_struct_wrapper(XGL_IMAGE_STATE_TRANSITION* pInStruct);
+    xgl_image_state_transition_struct_wrapper(const XGL_IMAGE_STATE_TRANSITION* pInStruct);
+
+    virtual ~xgl_image_state_transition_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_IMAGE get_image() { return m_struct.image; }
+    void set_image(XGL_IMAGE inValue) { m_struct.image = inValue; }
+    XGL_IMAGE_STATE get_oldState() { return m_struct.oldState; }
+    void set_oldState(XGL_IMAGE_STATE inValue) { m_struct.oldState = inValue; }
+    XGL_IMAGE_STATE get_newState() { return m_struct.newState; }
+    void set_newState(XGL_IMAGE_STATE inValue) { m_struct.newState = inValue; }
+    XGL_IMAGE_SUBRESOURCE_RANGE get_subresourceRange() { return m_struct.subresourceRange; }
+    void set_subresourceRange(XGL_IMAGE_SUBRESOURCE_RANGE inValue) { m_struct.subresourceRange = inValue; }
+
+
+private:
+    XGL_IMAGE_STATE_TRANSITION m_struct;
+    const XGL_IMAGE_STATE_TRANSITION* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_device_create_info_struct_wrapper
+{
+public:
+    xgl_device_create_info_struct_wrapper();
+    xgl_device_create_info_struct_wrapper(XGL_DEVICE_CREATE_INFO* pInStruct);
+    xgl_device_create_info_struct_wrapper(const XGL_DEVICE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_device_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_UINT get_queueRecordCount() { return m_struct.queueRecordCount; }
+    void set_queueRecordCount(XGL_UINT inValue) { m_struct.queueRecordCount = inValue; }
+    const XGL_DEVICE_QUEUE_CREATE_INFO* get_pRequestedQueues() { return m_struct.pRequestedQueues; }
+    XGL_UINT get_extensionCount() { return m_struct.extensionCount; }
+    void set_extensionCount(XGL_UINT inValue) { m_struct.extensionCount = inValue; }
+    const XGL_CHAR*const* get_ppEnabledExtensionNames() { return m_struct.ppEnabledExtensionNames; }
+    XGL_VALIDATION_LEVEL get_maxValidationLevel() { return m_struct.maxValidationLevel; }
+    void set_maxValidationLevel(XGL_VALIDATION_LEVEL inValue) { m_struct.maxValidationLevel = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_DEVICE_CREATE_INFO m_struct;
+    const XGL_DEVICE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_image_create_info_struct_wrapper
+{
+public:
+    xgl_image_create_info_struct_wrapper();
+    xgl_image_create_info_struct_wrapper(XGL_IMAGE_CREATE_INFO* pInStruct);
+    xgl_image_create_info_struct_wrapper(const XGL_IMAGE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_image_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_IMAGE_TYPE get_imageType() { return m_struct.imageType; }
+    void set_imageType(XGL_IMAGE_TYPE inValue) { m_struct.imageType = inValue; }
+    XGL_FORMAT get_format() { return m_struct.format; }
+    void set_format(XGL_FORMAT inValue) { m_struct.format = inValue; }
+    XGL_EXTENT3D get_extent() { return m_struct.extent; }
+    void set_extent(XGL_EXTENT3D inValue) { m_struct.extent = inValue; }
+    XGL_UINT get_mipLevels() { return m_struct.mipLevels; }
+    void set_mipLevels(XGL_UINT inValue) { m_struct.mipLevels = inValue; }
+    XGL_UINT get_arraySize() { return m_struct.arraySize; }
+    void set_arraySize(XGL_UINT inValue) { m_struct.arraySize = inValue; }
+    XGL_UINT get_samples() { return m_struct.samples; }
+    void set_samples(XGL_UINT inValue) { m_struct.samples = inValue; }
+    XGL_IMAGE_TILING get_tiling() { return m_struct.tiling; }
+    void set_tiling(XGL_IMAGE_TILING inValue) { m_struct.tiling = inValue; }
+    XGL_FLAGS get_usage() { return m_struct.usage; }
+    void set_usage(XGL_FLAGS inValue) { m_struct.usage = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_IMAGE_CREATE_INFO m_struct;
+    const XGL_IMAGE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_rect_struct_wrapper
+{
+public:
+    xgl_rect_struct_wrapper();
+    xgl_rect_struct_wrapper(XGL_RECT* pInStruct);
+    xgl_rect_struct_wrapper(const XGL_RECT* pInStruct);
+
+    virtual ~xgl_rect_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_OFFSET2D get_offset() { return m_struct.offset; }
+    void set_offset(XGL_OFFSET2D inValue) { m_struct.offset = inValue; }
+    XGL_EXTENT2D get_extent() { return m_struct.extent; }
+    void set_extent(XGL_EXTENT2D inValue) { m_struct.extent = inValue; }
+
+
+private:
+    XGL_RECT m_struct;
+    const XGL_RECT* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_copy_struct_wrapper
+{
+public:
+    xgl_memory_copy_struct_wrapper();
+    xgl_memory_copy_struct_wrapper(XGL_MEMORY_COPY* pInStruct);
+    xgl_memory_copy_struct_wrapper(const XGL_MEMORY_COPY* pInStruct);
+
+    virtual ~xgl_memory_copy_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_GPU_SIZE get_srcOffset() { return m_struct.srcOffset; }
+    void set_srcOffset(XGL_GPU_SIZE inValue) { m_struct.srcOffset = inValue; }
+    XGL_GPU_SIZE get_destOffset() { return m_struct.destOffset; }
+    void set_destOffset(XGL_GPU_SIZE inValue) { m_struct.destOffset = inValue; }
+    XGL_GPU_SIZE get_copySize() { return m_struct.copySize; }
+    void set_copySize(XGL_GPU_SIZE inValue) { m_struct.copySize = inValue; }
+
+
+private:
+    XGL_MEMORY_COPY m_struct;
+    const XGL_MEMORY_COPY* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_descriptor_slot_info_struct_wrapper
+{
+public:
+    xgl_descriptor_slot_info_struct_wrapper();
+    xgl_descriptor_slot_info_struct_wrapper(XGL_DESCRIPTOR_SLOT_INFO* pInStruct);
+    xgl_descriptor_slot_info_struct_wrapper(const XGL_DESCRIPTOR_SLOT_INFO* pInStruct);
+
+    virtual ~xgl_descriptor_slot_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_DESCRIPTOR_SET_SLOT_TYPE get_slotObjectType() { return m_struct.slotObjectType; }
+    void set_slotObjectType(XGL_DESCRIPTOR_SET_SLOT_TYPE inValue) { m_struct.slotObjectType = inValue; }
+    XGL_UINT get_shaderEntityIndex() { return m_struct.shaderEntityIndex; }
+    void set_shaderEntityIndex(XGL_UINT inValue) { m_struct.shaderEntityIndex = inValue; }
+    const struct _XGL_DESCRIPTOR_SET_MAPPING* get_pNextLevelSet() { return m_struct.pNextLevelSet; }
+
+
+private:
+    XGL_DESCRIPTOR_SLOT_INFO m_struct;
+    const XGL_DESCRIPTOR_SLOT_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_link_const_buffer_struct_wrapper
+{
+public:
+    xgl_link_const_buffer_struct_wrapper();
+    xgl_link_const_buffer_struct_wrapper(XGL_LINK_CONST_BUFFER* pInStruct);
+    xgl_link_const_buffer_struct_wrapper(const XGL_LINK_CONST_BUFFER* pInStruct);
+
+    virtual ~xgl_link_const_buffer_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT get_bufferId() { return m_struct.bufferId; }
+    void set_bufferId(XGL_UINT inValue) { m_struct.bufferId = inValue; }
+    XGL_SIZE get_bufferSize() { return m_struct.bufferSize; }
+    void set_bufferSize(XGL_SIZE inValue) { m_struct.bufferSize = inValue; }
+    const XGL_VOID* get_pBufferData() { return m_struct.pBufferData; }
+
+
+private:
+    XGL_LINK_CONST_BUFFER m_struct;
+    const XGL_LINK_CONST_BUFFER* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_image_copy_struct_wrapper
+{
+public:
+    xgl_memory_image_copy_struct_wrapper();
+    xgl_memory_image_copy_struct_wrapper(XGL_MEMORY_IMAGE_COPY* pInStruct);
+    xgl_memory_image_copy_struct_wrapper(const XGL_MEMORY_IMAGE_COPY* pInStruct);
+
+    virtual ~xgl_memory_image_copy_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_GPU_SIZE get_memOffset() { return m_struct.memOffset; }
+    void set_memOffset(XGL_GPU_SIZE inValue) { m_struct.memOffset = inValue; }
+    XGL_IMAGE_SUBRESOURCE get_imageSubresource() { return m_struct.imageSubresource; }
+    void set_imageSubresource(XGL_IMAGE_SUBRESOURCE inValue) { m_struct.imageSubresource = inValue; }
+    XGL_OFFSET3D get_imageOffset() { return m_struct.imageOffset; }
+    void set_imageOffset(XGL_OFFSET3D inValue) { m_struct.imageOffset = inValue; }
+    XGL_EXTENT3D get_imageExtent() { return m_struct.imageExtent; }
+    void set_imageExtent(XGL_EXTENT3D inValue) { m_struct.imageExtent = inValue; }
+
+
+private:
+    XGL_MEMORY_IMAGE_COPY m_struct;
+    const XGL_MEMORY_IMAGE_COPY* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_depth_stencil_state_create_info_struct_wrapper
+{
+public:
+    xgl_depth_stencil_state_create_info_struct_wrapper();
+    xgl_depth_stencil_state_create_info_struct_wrapper(XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pInStruct);
+    xgl_depth_stencil_state_create_info_struct_wrapper(const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_depth_stencil_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_BOOL get_depthTestEnable() { return m_struct.depthTestEnable; }
+    void set_depthTestEnable(XGL_BOOL inValue) { m_struct.depthTestEnable = inValue; }
+    XGL_BOOL get_depthWriteEnable() { return m_struct.depthWriteEnable; }
+    void set_depthWriteEnable(XGL_BOOL inValue) { m_struct.depthWriteEnable = inValue; }
+    XGL_COMPARE_FUNC get_depthFunc() { return m_struct.depthFunc; }
+    void set_depthFunc(XGL_COMPARE_FUNC inValue) { m_struct.depthFunc = inValue; }
+    XGL_BOOL get_depthBoundsEnable() { return m_struct.depthBoundsEnable; }
+    void set_depthBoundsEnable(XGL_BOOL inValue) { m_struct.depthBoundsEnable = inValue; }
+    XGL_FLOAT get_minDepth() { return m_struct.minDepth; }
+    void set_minDepth(XGL_FLOAT inValue) { m_struct.minDepth = inValue; }
+    XGL_FLOAT get_maxDepth() { return m_struct.maxDepth; }
+    void set_maxDepth(XGL_FLOAT inValue) { m_struct.maxDepth = inValue; }
+    XGL_BOOL get_stencilTestEnable() { return m_struct.stencilTestEnable; }
+    void set_stencilTestEnable(XGL_BOOL inValue) { m_struct.stencilTestEnable = inValue; }
+    XGL_UINT32 get_stencilReadMask() { return m_struct.stencilReadMask; }
+    void set_stencilReadMask(XGL_UINT32 inValue) { m_struct.stencilReadMask = inValue; }
+    XGL_UINT32 get_stencilWriteMask() { return m_struct.stencilWriteMask; }
+    void set_stencilWriteMask(XGL_UINT32 inValue) { m_struct.stencilWriteMask = inValue; }
+    XGL_STENCIL_OP_STATE get_front() { return m_struct.front; }
+    void set_front(XGL_STENCIL_OP_STATE inValue) { m_struct.front = inValue; }
+    XGL_STENCIL_OP_STATE get_back() { return m_struct.back; }
+    void set_back(XGL_STENCIL_OP_STATE inValue) { m_struct.back = inValue; }
+
+
+private:
+    XGL_DEPTH_STENCIL_STATE_CREATE_INFO m_struct;
+    const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_viewport_struct_wrapper
+{
+public:
+    xgl_viewport_struct_wrapper();
+    xgl_viewport_struct_wrapper(XGL_VIEWPORT* pInStruct);
+    xgl_viewport_struct_wrapper(const XGL_VIEWPORT* pInStruct);
+
+    virtual ~xgl_viewport_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_FLOAT get_originX() { return m_struct.originX; }
+    void set_originX(XGL_FLOAT inValue) { m_struct.originX = inValue; }
+    XGL_FLOAT get_originY() { return m_struct.originY; }
+    void set_originY(XGL_FLOAT inValue) { m_struct.originY = inValue; }
+    XGL_FLOAT get_width() { return m_struct.width; }
+    void set_width(XGL_FLOAT inValue) { m_struct.width = inValue; }
+    XGL_FLOAT get_height() { return m_struct.height; }
+    void set_height(XGL_FLOAT inValue) { m_struct.height = inValue; }
+    XGL_FLOAT get_minDepth() { return m_struct.minDepth; }
+    void set_minDepth(XGL_FLOAT inValue) { m_struct.minDepth = inValue; }
+    XGL_FLOAT get_maxDepth() { return m_struct.maxDepth; }
+    void set_maxDepth(XGL_FLOAT inValue) { m_struct.maxDepth = inValue; }
+
+
+private:
+    XGL_VIEWPORT m_struct;
+    const XGL_VIEWPORT* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_descriptor_set_mapping_struct_wrapper
+{
+public:
+    xgl_descriptor_set_mapping_struct_wrapper();
+    xgl_descriptor_set_mapping_struct_wrapper(XGL_DESCRIPTOR_SET_MAPPING* pInStruct);
+    xgl_descriptor_set_mapping_struct_wrapper(const XGL_DESCRIPTOR_SET_MAPPING* pInStruct);
+
+    virtual ~xgl_descriptor_set_mapping_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT get_descriptorCount() { return m_struct.descriptorCount; }
+    void set_descriptorCount(XGL_UINT inValue) { m_struct.descriptorCount = inValue; }
+    const XGL_DESCRIPTOR_SLOT_INFO* get_pDescriptorInfo() { return m_struct.pDescriptorInfo; }
+
+
+private:
+    XGL_DESCRIPTOR_SET_MAPPING m_struct;
+    const XGL_DESCRIPTOR_SET_MAPPING* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_peer_memory_open_info_struct_wrapper
+{
+public:
+    xgl_peer_memory_open_info_struct_wrapper();
+    xgl_peer_memory_open_info_struct_wrapper(XGL_PEER_MEMORY_OPEN_INFO* pInStruct);
+    xgl_peer_memory_open_info_struct_wrapper(const XGL_PEER_MEMORY_OPEN_INFO* pInStruct);
+
+    virtual ~xgl_peer_memory_open_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_GPU_MEMORY get_originalMem() { return m_struct.originalMem; }
+    void set_originalMem(XGL_GPU_MEMORY inValue) { m_struct.originalMem = inValue; }
+
+
+private:
+    XGL_PEER_MEMORY_OPEN_INFO m_struct;
+    const XGL_PEER_MEMORY_OPEN_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_subresource_layout_struct_wrapper
+{
+public:
+    xgl_subresource_layout_struct_wrapper();
+    xgl_subresource_layout_struct_wrapper(XGL_SUBRESOURCE_LAYOUT* pInStruct);
+    xgl_subresource_layout_struct_wrapper(const XGL_SUBRESOURCE_LAYOUT* pInStruct);
+
+    virtual ~xgl_subresource_layout_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_GPU_SIZE get_offset() { return m_struct.offset; }
+    void set_offset(XGL_GPU_SIZE inValue) { m_struct.offset = inValue; }
+    XGL_GPU_SIZE get_size() { return m_struct.size; }
+    void set_size(XGL_GPU_SIZE inValue) { m_struct.size = inValue; }
+    XGL_GPU_SIZE get_rowPitch() { return m_struct.rowPitch; }
+    void set_rowPitch(XGL_GPU_SIZE inValue) { m_struct.rowPitch = inValue; }
+    XGL_GPU_SIZE get_depthPitch() { return m_struct.depthPitch; }
+    void set_depthPitch(XGL_GPU_SIZE inValue) { m_struct.depthPitch = inValue; }
+
+
+private:
+    XGL_SUBRESOURCE_LAYOUT m_struct;
+    const XGL_SUBRESOURCE_LAYOUT* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_descriptor_set_attach_info_struct_wrapper
+{
+public:
+    xgl_descriptor_set_attach_info_struct_wrapper();
+    xgl_descriptor_set_attach_info_struct_wrapper(XGL_DESCRIPTOR_SET_ATTACH_INFO* pInStruct);
+    xgl_descriptor_set_attach_info_struct_wrapper(const XGL_DESCRIPTOR_SET_ATTACH_INFO* pInStruct);
+
+    virtual ~xgl_descriptor_set_attach_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_DESCRIPTOR_SET get_descriptorSet() { return m_struct.descriptorSet; }
+    void set_descriptorSet(XGL_DESCRIPTOR_SET inValue) { m_struct.descriptorSet = inValue; }
+    XGL_UINT get_slotOffset() { return m_struct.slotOffset; }
+    void set_slotOffset(XGL_UINT inValue) { m_struct.slotOffset = inValue; }
+
+
+private:
+    XGL_DESCRIPTOR_SET_ATTACH_INFO m_struct;
+    const XGL_DESCRIPTOR_SET_ATTACH_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_tess_state_create_info_struct_wrapper
+{
+public:
+    xgl_pipeline_tess_state_create_info_struct_wrapper();
+    xgl_pipeline_tess_state_create_info_struct_wrapper(XGL_PIPELINE_TESS_STATE_CREATE_INFO* pInStruct);
+    xgl_pipeline_tess_state_create_info_struct_wrapper(const XGL_PIPELINE_TESS_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_pipeline_tess_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_UINT get_patchControlPoints() { return m_struct.patchControlPoints; }
+    void set_patchControlPoints(XGL_UINT inValue) { m_struct.patchControlPoints = inValue; }
+    XGL_FLOAT get_optimalTessFactor() { return m_struct.optimalTessFactor; }
+    void set_optimalTessFactor(XGL_FLOAT inValue) { m_struct.optimalTessFactor = inValue; }
+    XGL_FLOAT get_fixedTessFactor() { return m_struct.fixedTessFactor; }
+    void set_fixedTessFactor(XGL_FLOAT inValue) { m_struct.fixedTessFactor = inValue; }
+
+
+private:
+    XGL_PIPELINE_TESS_STATE_CREATE_INFO m_struct;
+    const XGL_PIPELINE_TESS_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_rs_state_create_info_struct_wrapper
+{
+public:
+    xgl_pipeline_rs_state_create_info_struct_wrapper();
+    xgl_pipeline_rs_state_create_info_struct_wrapper(XGL_PIPELINE_RS_STATE_CREATE_INFO* pInStruct);
+    xgl_pipeline_rs_state_create_info_struct_wrapper(const XGL_PIPELINE_RS_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_pipeline_rs_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_BOOL get_depthClipEnable() { return m_struct.depthClipEnable; }
+    void set_depthClipEnable(XGL_BOOL inValue) { m_struct.depthClipEnable = inValue; }
+    XGL_BOOL get_rasterizerDiscardEnable() { return m_struct.rasterizerDiscardEnable; }
+    void set_rasterizerDiscardEnable(XGL_BOOL inValue) { m_struct.rasterizerDiscardEnable = inValue; }
+    XGL_FLOAT get_pointSize() { return m_struct.pointSize; }
+    void set_pointSize(XGL_FLOAT inValue) { m_struct.pointSize = inValue; }
+
+
+private:
+    XGL_PIPELINE_RS_STATE_CREATE_INFO m_struct;
+    const XGL_PIPELINE_RS_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_stencil_op_state_struct_wrapper
+{
+public:
+    xgl_stencil_op_state_struct_wrapper();
+    xgl_stencil_op_state_struct_wrapper(XGL_STENCIL_OP_STATE* pInStruct);
+    xgl_stencil_op_state_struct_wrapper(const XGL_STENCIL_OP_STATE* pInStruct);
+
+    virtual ~xgl_stencil_op_state_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STENCIL_OP get_stencilFailOp() { return m_struct.stencilFailOp; }
+    void set_stencilFailOp(XGL_STENCIL_OP inValue) { m_struct.stencilFailOp = inValue; }
+    XGL_STENCIL_OP get_stencilPassOp() { return m_struct.stencilPassOp; }
+    void set_stencilPassOp(XGL_STENCIL_OP inValue) { m_struct.stencilPassOp = inValue; }
+    XGL_STENCIL_OP get_stencilDepthFailOp() { return m_struct.stencilDepthFailOp; }
+    void set_stencilDepthFailOp(XGL_STENCIL_OP inValue) { m_struct.stencilDepthFailOp = inValue; }
+    XGL_COMPARE_FUNC get_stencilFunc() { return m_struct.stencilFunc; }
+    void set_stencilFunc(XGL_COMPARE_FUNC inValue) { m_struct.stencilFunc = inValue; }
+    XGL_UINT32 get_stencilRef() { return m_struct.stencilRef; }
+    void set_stencilRef(XGL_UINT32 inValue) { m_struct.stencilRef = inValue; }
+
+
+private:
+    XGL_STENCIL_OP_STATE m_struct;
+    const XGL_STENCIL_OP_STATE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_shader_create_info_struct_wrapper
+{
+public:
+    xgl_shader_create_info_struct_wrapper();
+    xgl_shader_create_info_struct_wrapper(XGL_SHADER_CREATE_INFO* pInStruct);
+    xgl_shader_create_info_struct_wrapper(const XGL_SHADER_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_shader_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_SIZE get_codeSize() { return m_struct.codeSize; }
+    void set_codeSize(XGL_SIZE inValue) { m_struct.codeSize = inValue; }
+    const XGL_VOID* get_pCode() { return m_struct.pCode; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_SHADER_CREATE_INFO m_struct;
+    const XGL_SHADER_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_color_blend_state_create_info_struct_wrapper
+{
+public:
+    xgl_color_blend_state_create_info_struct_wrapper();
+    xgl_color_blend_state_create_info_struct_wrapper(XGL_COLOR_BLEND_STATE_CREATE_INFO* pInStruct);
+    xgl_color_blend_state_create_info_struct_wrapper(const XGL_COLOR_BLEND_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_color_blend_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+
+
+private:
+    XGL_COLOR_BLEND_STATE_CREATE_INFO m_struct;
+    const XGL_COLOR_BLEND_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_cb_state_create_info_struct_wrapper
+{
+public:
+    xgl_pipeline_cb_state_create_info_struct_wrapper();
+    xgl_pipeline_cb_state_create_info_struct_wrapper(XGL_PIPELINE_CB_STATE* pInStruct);
+    xgl_pipeline_cb_state_create_info_struct_wrapper(const XGL_PIPELINE_CB_STATE* pInStruct);
+
+    virtual ~xgl_pipeline_cb_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_BOOL get_alphaToCoverageEnable() { return m_struct.alphaToCoverageEnable; }
+    void set_alphaToCoverageEnable(XGL_BOOL inValue) { m_struct.alphaToCoverageEnable = inValue; }
+    XGL_BOOL get_dualSourceBlendEnable() { return m_struct.dualSourceBlendEnable; }
+    void set_dualSourceBlendEnable(XGL_BOOL inValue) { m_struct.dualSourceBlendEnable = inValue; }
+    XGL_LOGIC_OP get_logicOp() { return m_struct.logicOp; }
+    void set_logicOp(XGL_LOGIC_OP inValue) { m_struct.logicOp = inValue; }
+
+
+private:
+    XGL_PIPELINE_CB_STATE m_struct;
+    const XGL_PIPELINE_CB_STATE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_channel_mapping_struct_wrapper
+{
+public:
+    xgl_channel_mapping_struct_wrapper();
+    xgl_channel_mapping_struct_wrapper(XGL_CHANNEL_MAPPING* pInStruct);
+    xgl_channel_mapping_struct_wrapper(const XGL_CHANNEL_MAPPING* pInStruct);
+
+    virtual ~xgl_channel_mapping_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_CHANNEL_SWIZZLE get_r() { return m_struct.r; }
+    void set_r(XGL_CHANNEL_SWIZZLE inValue) { m_struct.r = inValue; }
+    XGL_CHANNEL_SWIZZLE get_g() { return m_struct.g; }
+    void set_g(XGL_CHANNEL_SWIZZLE inValue) { m_struct.g = inValue; }
+    XGL_CHANNEL_SWIZZLE get_b() { return m_struct.b; }
+    void set_b(XGL_CHANNEL_SWIZZLE inValue) { m_struct.b = inValue; }
+    XGL_CHANNEL_SWIZZLE get_a() { return m_struct.a; }
+    void set_a(XGL_CHANNEL_SWIZZLE inValue) { m_struct.a = inValue; }
+
+
+private:
+    XGL_CHANNEL_MAPPING m_struct;
+    const XGL_CHANNEL_MAPPING* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_depth_stencil_view_create_info_struct_wrapper
+{
+public:
+    xgl_depth_stencil_view_create_info_struct_wrapper();
+    xgl_depth_stencil_view_create_info_struct_wrapper(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pInStruct);
+    xgl_depth_stencil_view_create_info_struct_wrapper(const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_depth_stencil_view_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_IMAGE get_image() { return m_struct.image; }
+    void set_image(XGL_IMAGE inValue) { m_struct.image = inValue; }
+    XGL_UINT get_mipLevel() { return m_struct.mipLevel; }
+    void set_mipLevel(XGL_UINT inValue) { m_struct.mipLevel = inValue; }
+    XGL_UINT get_baseArraySlice() { return m_struct.baseArraySlice; }
+    void set_baseArraySlice(XGL_UINT inValue) { m_struct.baseArraySlice = inValue; }
+    XGL_UINT get_arraySize() { return m_struct.arraySize; }
+    void set_arraySize(XGL_UINT inValue) { m_struct.arraySize = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_DEPTH_STENCIL_VIEW_CREATE_INFO m_struct;
+    const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_virtual_memory_remap_range_struct_wrapper
+{
+public:
+    xgl_virtual_memory_remap_range_struct_wrapper();
+    xgl_virtual_memory_remap_range_struct_wrapper(XGL_VIRTUAL_MEMORY_REMAP_RANGE* pInStruct);
+    xgl_virtual_memory_remap_range_struct_wrapper(const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pInStruct);
+
+    virtual ~xgl_virtual_memory_remap_range_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_GPU_MEMORY get_virtualMem() { return m_struct.virtualMem; }
+    void set_virtualMem(XGL_GPU_MEMORY inValue) { m_struct.virtualMem = inValue; }
+    XGL_GPU_SIZE get_virtualStartPage() { return m_struct.virtualStartPage; }
+    void set_virtualStartPage(XGL_GPU_SIZE inValue) { m_struct.virtualStartPage = inValue; }
+    XGL_GPU_MEMORY get_realMem() { return m_struct.realMem; }
+    void set_realMem(XGL_GPU_MEMORY inValue) { m_struct.realMem = inValue; }
+    XGL_GPU_SIZE get_realStartPage() { return m_struct.realStartPage; }
+    void set_realStartPage(XGL_GPU_SIZE inValue) { m_struct.realStartPage = inValue; }
+    XGL_GPU_SIZE get_pageCount() { return m_struct.pageCount; }
+    void set_pageCount(XGL_GPU_SIZE inValue) { m_struct.pageCount = inValue; }
+
+
+private:
+    XGL_VIRTUAL_MEMORY_REMAP_RANGE m_struct;
+    const XGL_VIRTUAL_MEMORY_REMAP_RANGE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_cmd_buffer_create_info_struct_wrapper
+{
+public:
+    xgl_cmd_buffer_create_info_struct_wrapper();
+    xgl_cmd_buffer_create_info_struct_wrapper(XGL_CMD_BUFFER_CREATE_INFO* pInStruct);
+    xgl_cmd_buffer_create_info_struct_wrapper(const XGL_CMD_BUFFER_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_cmd_buffer_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_QUEUE_TYPE get_queueType() { return m_struct.queueType; }
+    void set_queueType(XGL_QUEUE_TYPE inValue) { m_struct.queueType = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_CMD_BUFFER_CREATE_INFO m_struct;
+    const XGL_CMD_BUFFER_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_format_properties_struct_wrapper
+{
+public:
+    xgl_format_properties_struct_wrapper();
+    xgl_format_properties_struct_wrapper(XGL_FORMAT_PROPERTIES* pInStruct);
+    xgl_format_properties_struct_wrapper(const XGL_FORMAT_PROPERTIES* pInStruct);
+
+    virtual ~xgl_format_properties_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_FLAGS get_linearTilingFeatures() { return m_struct.linearTilingFeatures; }
+    void set_linearTilingFeatures(XGL_FLAGS inValue) { m_struct.linearTilingFeatures = inValue; }
+    XGL_FLAGS get_optimalTilingFeatures() { return m_struct.optimalTilingFeatures; }
+    void set_optimalTilingFeatures(XGL_FLAGS inValue) { m_struct.optimalTilingFeatures = inValue; }
+
+
+private:
+    XGL_FORMAT_PROPERTIES m_struct;
+    const XGL_FORMAT_PROPERTIES* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_physical_gpu_properties_struct_wrapper
+{
+public:
+    xgl_physical_gpu_properties_struct_wrapper();
+    xgl_physical_gpu_properties_struct_wrapper(XGL_PHYSICAL_GPU_PROPERTIES* pInStruct);
+    xgl_physical_gpu_properties_struct_wrapper(const XGL_PHYSICAL_GPU_PROPERTIES* pInStruct);
+
+    virtual ~xgl_physical_gpu_properties_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_SIZE get_structSize() { return m_struct.structSize; }
+    void set_structSize(XGL_SIZE inValue) { m_struct.structSize = inValue; }
+    XGL_UINT32 get_apiVersion() { return m_struct.apiVersion; }
+    void set_apiVersion(XGL_UINT32 inValue) { m_struct.apiVersion = inValue; }
+    XGL_UINT32 get_driverVersion() { return m_struct.driverVersion; }
+    void set_driverVersion(XGL_UINT32 inValue) { m_struct.driverVersion = inValue; }
+    XGL_UINT32 get_vendorId() { return m_struct.vendorId; }
+    void set_vendorId(XGL_UINT32 inValue) { m_struct.vendorId = inValue; }
+    XGL_UINT32 get_deviceId() { return m_struct.deviceId; }
+    void set_deviceId(XGL_UINT32 inValue) { m_struct.deviceId = inValue; }
+    XGL_PHYSICAL_GPU_TYPE get_gpuType() { return m_struct.gpuType; }
+    void set_gpuType(XGL_PHYSICAL_GPU_TYPE inValue) { m_struct.gpuType = inValue; }
+    XGL_UINT get_maxMemRefsPerSubmission() { return m_struct.maxMemRefsPerSubmission; }
+    void set_maxMemRefsPerSubmission(XGL_UINT inValue) { m_struct.maxMemRefsPerSubmission = inValue; }
+    XGL_GPU_SIZE get_virtualMemPageSize() { return m_struct.virtualMemPageSize; }
+    void set_virtualMemPageSize(XGL_GPU_SIZE inValue) { m_struct.virtualMemPageSize = inValue; }
+    XGL_GPU_SIZE get_maxInlineMemoryUpdateSize() { return m_struct.maxInlineMemoryUpdateSize; }
+    void set_maxInlineMemoryUpdateSize(XGL_GPU_SIZE inValue) { m_struct.maxInlineMemoryUpdateSize = inValue; }
+    XGL_UINT get_maxBoundDescriptorSets() { return m_struct.maxBoundDescriptorSets; }
+    void set_maxBoundDescriptorSets(XGL_UINT inValue) { m_struct.maxBoundDescriptorSets = inValue; }
+    XGL_UINT get_maxThreadGroupSize() { return m_struct.maxThreadGroupSize; }
+    void set_maxThreadGroupSize(XGL_UINT inValue) { m_struct.maxThreadGroupSize = inValue; }
+    XGL_UINT64 get_timestampFrequency() { return m_struct.timestampFrequency; }
+    void set_timestampFrequency(XGL_UINT64 inValue) { m_struct.timestampFrequency = inValue; }
+    XGL_BOOL get_multiColorAttachmentClears() { return m_struct.multiColorAttachmentClears; }
+    void set_multiColorAttachmentClears(XGL_BOOL inValue) { m_struct.multiColorAttachmentClears = inValue; }
+
+
+private:
+    XGL_PHYSICAL_GPU_PROPERTIES m_struct;
+    const XGL_PHYSICAL_GPU_PROPERTIES* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_depth_stencil_bind_info_struct_wrapper
+{
+public:
+    xgl_depth_stencil_bind_info_struct_wrapper();
+    xgl_depth_stencil_bind_info_struct_wrapper(XGL_DEPTH_STENCIL_BIND_INFO* pInStruct);
+    xgl_depth_stencil_bind_info_struct_wrapper(const XGL_DEPTH_STENCIL_BIND_INFO* pInStruct);
+
+    virtual ~xgl_depth_stencil_bind_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_DEPTH_STENCIL_VIEW get_view() { return m_struct.view; }
+    void set_view(XGL_DEPTH_STENCIL_VIEW inValue) { m_struct.view = inValue; }
+    XGL_IMAGE_STATE get_depthState() { return m_struct.depthState; }
+    void set_depthState(XGL_IMAGE_STATE inValue) { m_struct.depthState = inValue; }
+    XGL_IMAGE_STATE get_stencilState() { return m_struct.stencilState; }
+    void set_stencilState(XGL_IMAGE_STATE inValue) { m_struct.stencilState = inValue; }
+
+
+private:
+    XGL_DEPTH_STENCIL_BIND_INFO m_struct;
+    const XGL_DEPTH_STENCIL_BIND_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_draw_indirect_cmd_struct_wrapper
+{
+public:
+    xgl_draw_indirect_cmd_struct_wrapper();
+    xgl_draw_indirect_cmd_struct_wrapper(XGL_DRAW_INDIRECT_CMD* pInStruct);
+    xgl_draw_indirect_cmd_struct_wrapper(const XGL_DRAW_INDIRECT_CMD* pInStruct);
+
+    virtual ~xgl_draw_indirect_cmd_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT32 get_vertexCount() { return m_struct.vertexCount; }
+    void set_vertexCount(XGL_UINT32 inValue) { m_struct.vertexCount = inValue; }
+    XGL_UINT32 get_instanceCount() { return m_struct.instanceCount; }
+    void set_instanceCount(XGL_UINT32 inValue) { m_struct.instanceCount = inValue; }
+    XGL_UINT32 get_firstVertex() { return m_struct.firstVertex; }
+    void set_firstVertex(XGL_UINT32 inValue) { m_struct.firstVertex = inValue; }
+    XGL_UINT32 get_firstInstance() { return m_struct.firstInstance; }
+    void set_firstInstance(XGL_UINT32 inValue) { m_struct.firstInstance = inValue; }
+
+
+private:
+    XGL_DRAW_INDIRECT_CMD m_struct;
+    const XGL_DRAW_INDIRECT_CMD* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_graphics_pipeline_create_info_struct_wrapper
+{
+public:
+    xgl_graphics_pipeline_create_info_struct_wrapper();
+    xgl_graphics_pipeline_create_info_struct_wrapper(XGL_GRAPHICS_PIPELINE_CREATE_INFO* pInStruct);
+    xgl_graphics_pipeline_create_info_struct_wrapper(const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_graphics_pipeline_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_GRAPHICS_PIPELINE_CREATE_INFO m_struct;
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_ia_state_create_info_struct_wrapper
+{
+public:
+    xgl_pipeline_ia_state_create_info_struct_wrapper();
+    xgl_pipeline_ia_state_create_info_struct_wrapper(XGL_PIPELINE_IA_STATE_CREATE_INFO* pInStruct);
+    xgl_pipeline_ia_state_create_info_struct_wrapper(const XGL_PIPELINE_IA_STATE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_pipeline_ia_state_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_PRIMITIVE_TOPOLOGY get_topology() { return m_struct.topology; }
+    void set_topology(XGL_PRIMITIVE_TOPOLOGY inValue) { m_struct.topology = inValue; }
+    XGL_BOOL get_disableVertexReuse() { return m_struct.disableVertexReuse; }
+    void set_disableVertexReuse(XGL_BOOL inValue) { m_struct.disableVertexReuse = inValue; }
+    XGL_PROVOKING_VERTEX_CONVENTION get_provokingVertex() { return m_struct.provokingVertex; }
+    void set_provokingVertex(XGL_PROVOKING_VERTEX_CONVENTION inValue) { m_struct.provokingVertex = inValue; }
+    XGL_BOOL get_primitiveRestartEnable() { return m_struct.primitiveRestartEnable; }
+    void set_primitiveRestartEnable(XGL_BOOL inValue) { m_struct.primitiveRestartEnable = inValue; }
+    XGL_UINT32 get_primitiveRestartIndex() { return m_struct.primitiveRestartIndex; }
+    void set_primitiveRestartIndex(XGL_UINT32 inValue) { m_struct.primitiveRestartIndex = inValue; }
+
+
+private:
+    XGL_PIPELINE_IA_STATE_CREATE_INFO m_struct;
+    const XGL_PIPELINE_IA_STATE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_color_attachment_blend_state_struct_wrapper
+{
+public:
+    xgl_color_attachment_blend_state_struct_wrapper();
+    xgl_color_attachment_blend_state_struct_wrapper(XGL_COLOR_ATTACHMENT_BLEND_STATE* pInStruct);
+    xgl_color_attachment_blend_state_struct_wrapper(const XGL_COLOR_ATTACHMENT_BLEND_STATE* pInStruct);
+
+    virtual ~xgl_color_attachment_blend_state_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_BOOL get_blendEnable() { return m_struct.blendEnable; }
+    void set_blendEnable(XGL_BOOL inValue) { m_struct.blendEnable = inValue; }
+    XGL_BLEND get_srcBlendColor() { return m_struct.srcBlendColor; }
+    void set_srcBlendColor(XGL_BLEND inValue) { m_struct.srcBlendColor = inValue; }
+    XGL_BLEND get_destBlendColor() { return m_struct.destBlendColor; }
+    void set_destBlendColor(XGL_BLEND inValue) { m_struct.destBlendColor = inValue; }
+    XGL_BLEND_FUNC get_blendFuncColor() { return m_struct.blendFuncColor; }
+    void set_blendFuncColor(XGL_BLEND_FUNC inValue) { m_struct.blendFuncColor = inValue; }
+    XGL_BLEND get_srcBlendAlpha() { return m_struct.srcBlendAlpha; }
+    void set_srcBlendAlpha(XGL_BLEND inValue) { m_struct.srcBlendAlpha = inValue; }
+    XGL_BLEND get_destBlendAlpha() { return m_struct.destBlendAlpha; }
+    void set_destBlendAlpha(XGL_BLEND inValue) { m_struct.destBlendAlpha = inValue; }
+    XGL_BLEND_FUNC get_blendFuncAlpha() { return m_struct.blendFuncAlpha; }
+    void set_blendFuncAlpha(XGL_BLEND_FUNC inValue) { m_struct.blendFuncAlpha = inValue; }
+
+
+private:
+    XGL_COLOR_ATTACHMENT_BLEND_STATE m_struct;
+    const XGL_COLOR_ATTACHMENT_BLEND_STATE* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_extent2d_struct_wrapper
+{
+public:
+    xgl_extent2d_struct_wrapper();
+    xgl_extent2d_struct_wrapper(XGL_EXTENT2D* pInStruct);
+    xgl_extent2d_struct_wrapper(const XGL_EXTENT2D* pInStruct);
+
+    virtual ~xgl_extent2d_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_INT get_width() { return m_struct.width; }
+    void set_width(XGL_INT inValue) { m_struct.width = inValue; }
+    XGL_INT get_height() { return m_struct.height; }
+    void set_height(XGL_INT inValue) { m_struct.height = inValue; }
+
+
+private:
+    XGL_EXTENT2D m_struct;
+    const XGL_EXTENT2D* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_alloc_info_struct_wrapper
+{
+public:
+    xgl_memory_alloc_info_struct_wrapper();
+    xgl_memory_alloc_info_struct_wrapper(XGL_MEMORY_ALLOC_INFO* pInStruct);
+    xgl_memory_alloc_info_struct_wrapper(const XGL_MEMORY_ALLOC_INFO* pInStruct);
+
+    virtual ~xgl_memory_alloc_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_GPU_SIZE get_allocationSize() { return m_struct.allocationSize; }
+    void set_allocationSize(XGL_GPU_SIZE inValue) { m_struct.allocationSize = inValue; }
+    XGL_GPU_SIZE get_alignment() { return m_struct.alignment; }
+    void set_alignment(XGL_GPU_SIZE inValue) { m_struct.alignment = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+    XGL_UINT get_heapCount() { return m_struct.heapCount; }
+    void set_heapCount(XGL_UINT inValue) { m_struct.heapCount = inValue; }
+    XGL_MEMORY_PRIORITY get_memPriority() { return m_struct.memPriority; }
+    void set_memPriority(XGL_MEMORY_PRIORITY inValue) { m_struct.memPriority = inValue; }
+
+
+private:
+    XGL_MEMORY_ALLOC_INFO m_struct;
+    const XGL_MEMORY_ALLOC_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_ref_struct_wrapper
+{
+public:
+    xgl_memory_ref_struct_wrapper();
+    xgl_memory_ref_struct_wrapper(XGL_MEMORY_REF* pInStruct);
+    xgl_memory_ref_struct_wrapper(const XGL_MEMORY_REF* pInStruct);
+
+    virtual ~xgl_memory_ref_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_GPU_MEMORY get_mem() { return m_struct.mem; }
+    void set_mem(XGL_GPU_MEMORY inValue) { m_struct.mem = inValue; }
+    XGL_FLAGS get_flags() { return m_struct.flags; }
+    void set_flags(XGL_FLAGS inValue) { m_struct.flags = inValue; }
+
+
+private:
+    XGL_MEMORY_REF m_struct;
+    const XGL_MEMORY_REF* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_query_pool_create_info_struct_wrapper
+{
+public:
+    xgl_query_pool_create_info_struct_wrapper();
+    xgl_query_pool_create_info_struct_wrapper(XGL_QUERY_POOL_CREATE_INFO* pInStruct);
+    xgl_query_pool_create_info_struct_wrapper(const XGL_QUERY_POOL_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_query_pool_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_QUERY_TYPE get_queryType() { return m_struct.queryType; }
+    void set_queryType(XGL_QUERY_TYPE inValue) { m_struct.queryType = inValue; }
+    XGL_UINT get_slots() { return m_struct.slots; }
+    void set_slots(XGL_UINT inValue) { m_struct.slots = inValue; }
+
+
+private:
+    XGL_QUERY_POOL_CREATE_INFO m_struct;
+    const XGL_QUERY_POOL_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_offset3d_struct_wrapper
+{
+public:
+    xgl_offset3d_struct_wrapper();
+    xgl_offset3d_struct_wrapper(XGL_OFFSET3D* pInStruct);
+    xgl_offset3d_struct_wrapper(const XGL_OFFSET3D* pInStruct);
+
+    virtual ~xgl_offset3d_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_INT get_x() { return m_struct.x; }
+    void set_x(XGL_INT inValue) { m_struct.x = inValue; }
+    XGL_INT get_y() { return m_struct.y; }
+    void set_y(XGL_INT inValue) { m_struct.y = inValue; }
+    XGL_INT get_z() { return m_struct.z; }
+    void set_z(XGL_INT inValue) { m_struct.z = inValue; }
+
+
+private:
+    XGL_OFFSET3D m_struct;
+    const XGL_OFFSET3D* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_pipeline_shader_stage_create_info_struct_wrapper
+{
+public:
+    xgl_pipeline_shader_stage_create_info_struct_wrapper();
+    xgl_pipeline_shader_stage_create_info_struct_wrapper(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pInStruct);
+    xgl_pipeline_shader_stage_create_info_struct_wrapper(const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pInStruct);
+
+    virtual ~xgl_pipeline_shader_stage_create_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    const XGL_VOID* get_pNext() { return m_struct.pNext; }
+    XGL_PIPELINE_SHADER get_shader() { return m_struct.shader; }
+    void set_shader(XGL_PIPELINE_SHADER inValue) { m_struct.shader = inValue; }
+
+
+private:
+    XGL_PIPELINE_SHADER_STAGE_CREATE_INFO m_struct;
+    const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_memory_view_attach_info_struct_wrapper
+{
+public:
+    xgl_memory_view_attach_info_struct_wrapper();
+    xgl_memory_view_attach_info_struct_wrapper(XGL_MEMORY_VIEW_ATTACH_INFO* pInStruct);
+    xgl_memory_view_attach_info_struct_wrapper(const XGL_MEMORY_VIEW_ATTACH_INFO* pInStruct);
+
+    virtual ~xgl_memory_view_attach_info_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_STRUCTURE_TYPE get_sType() { return m_struct.sType; }
+    void set_sType(XGL_STRUCTURE_TYPE inValue) { m_struct.sType = inValue; }
+    XGL_VOID* get_pNext() { return m_struct.pNext; }
+    void set_pNext(XGL_VOID* inValue) { m_struct.pNext = inValue; }
+    XGL_GPU_MEMORY get_mem() { return m_struct.mem; }
+    void set_mem(XGL_GPU_MEMORY inValue) { m_struct.mem = inValue; }
+    XGL_GPU_SIZE get_offset() { return m_struct.offset; }
+    void set_offset(XGL_GPU_SIZE inValue) { m_struct.offset = inValue; }
+    XGL_GPU_SIZE get_range() { return m_struct.range; }
+    void set_range(XGL_GPU_SIZE inValue) { m_struct.range = inValue; }
+    XGL_GPU_SIZE get_stride() { return m_struct.stride; }
+    void set_stride(XGL_GPU_SIZE inValue) { m_struct.stride = inValue; }
+    XGL_FORMAT get_format() { return m_struct.format; }
+    void set_format(XGL_FORMAT inValue) { m_struct.format = inValue; }
+    XGL_MEMORY_STATE get_state() { return m_struct.state; }
+    void set_state(XGL_MEMORY_STATE inValue) { m_struct.state = inValue; }
+
+
+private:
+    XGL_MEMORY_VIEW_ATTACH_INFO m_struct;
+    const XGL_MEMORY_VIEW_ATTACH_INFO* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+
+//class declaration
+class xgl_dispatch_indirect_cmd_struct_wrapper
+{
+public:
+    xgl_dispatch_indirect_cmd_struct_wrapper();
+    xgl_dispatch_indirect_cmd_struct_wrapper(XGL_DISPATCH_INDIRECT_CMD* pInStruct);
+    xgl_dispatch_indirect_cmd_struct_wrapper(const XGL_DISPATCH_INDIRECT_CMD* pInStruct);
+
+    virtual ~xgl_dispatch_indirect_cmd_struct_wrapper();
+
+    void display_txt();
+    void display_single_txt();
+    void display_full_txt();
+
+    void set_indent(uint32_t indent) { m_indent = indent; }
+    XGL_UINT32 get_x() { return m_struct.x; }
+    void set_x(XGL_UINT32 inValue) { m_struct.x = inValue; }
+    XGL_UINT32 get_y() { return m_struct.y; }
+    void set_y(XGL_UINT32 inValue) { m_struct.y = inValue; }
+    XGL_UINT32 get_z() { return m_struct.z; }
+    void set_z(XGL_UINT32 inValue) { m_struct.z = inValue; }
+
+
+private:
+    XGL_DISPATCH_INDIRECT_CMD m_struct;
+    const XGL_DISPATCH_INDIRECT_CMD* m_origStructAddr;
+    uint32_t m_indent;
+    const char m_dummy_prefix;
+    void display_struct_members();
+
+};
+
+//any footer info for class
diff --git a/tools/glave/src/glv_extensions/glvreplay_xgl/CMakeLists.txt b/tools/glave/src/glv_extensions/glvreplay_xgl/CMakeLists.txt
new file mode 100644
index 0000000..80a813a
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvreplay_xgl/CMakeLists.txt
@@ -0,0 +1,53 @@
+cmake_minimum_required(VERSION 2.8)
+
+# this project is currently only available on Linux
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+project(glvreplay_xgl)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${SRC_DIR}/thirdparty/xgl/inc/)
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+set(OS_REPLAYER_LIBS
+    ${SRC_DIR}/thirdparty/xgl/lib/xgl64.lib
+)
+endif()
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+set(OS_REPLAYER_LIBS
+    ${SRC_DIR}/thirdparty/xgl/lib/libXGL.so
+    xcb
+)
+endif()
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glvreplay_xgl.cpp
+    glvreplay_xgl_replay.cpp
+)
+
+set (HDR_LIST
+    glvreplay_xgl.h
+    glvreplay_xgl_replay.h
+)
+
+include_directories(
+    ${SRC_DIR}/glvreplay
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/thirdparty
+    ${SRC_DIR}/glv_extensions/glvtrace_xgl
+)
+
+add_library(${PROJECT_NAME} SHARED ${SRC_LIST} ${HDR_LIST})
+
+target_link_libraries(${PROJECT_NAME} 
+    ${OS_REPLAYER_LIBS}
+    getopt_bundled
+    glvcommon
+)
+
+build_options_finalize()
+
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
diff --git a/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl.cpp b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl.cpp
new file mode 100644
index 0000000..c555681
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl.cpp
@@ -0,0 +1,64 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software, 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 "glvreplay_xgl.h"
+#include "glvreplay_xgl_replay.h"
+
+ApiReplay* g_pReplayer = NULL;
+
+GLVTRACER_EXPORT int GLVTRACER_STDCALL Initialize(glv_replay::Display* pDisplay, unsigned int debugLevel)
+{
+    try
+    {
+        g_pReplayer = (ApiReplay*)new xglReplay(debugLevel);
+    }
+    catch (int e)
+    {
+        glv_LogError("Failed to create xglReplay, probably out of memory. Error %d\n", e);
+        return -1;
+    }
+
+    int result = g_pReplayer->init(*pDisplay);
+    return result;
+}
+
+GLVTRACER_EXPORT void GLVTRACER_STDCALL Deinitialize()
+{
+    if (g_pReplayer != NULL)
+    {
+        delete g_pReplayer;
+        g_pReplayer = NULL;
+    }
+}
+
+GLVTRACER_EXPORT glv_replay::GLV_REPLAY_RESULT GLVTRACER_STDCALL Replay(glv_trace_packet_header* pPacket)
+{
+    glv_replay::GLV_REPLAY_RESULT result = glv_replay::GLV_REPLAY_ERROR;
+    if (g_pReplayer != NULL)
+    {
+        result = g_pReplayer->replay(pPacket);
+    }
+    return result;
+}
+
diff --git a/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl.h b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl.h
new file mode 100644
index 0000000..f503339
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl.h
@@ -0,0 +1,34 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software, 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.
+ *
+ **************************************************************************/
+#pragma once
+#include "glvreplay_window.h"
+#include "glvreplay_factory.h"
+
+extern "C"
+{
+GLVTRACER_EXPORT int GLVTRACER_STDCALL Initialize(glv_replay::Display* pDisplay, unsigned int debugLevel);
+GLVTRACER_EXPORT void GLVTRACER_STDCALL Deinitialize();
+GLVTRACER_EXPORT glv_replay::GLV_REPLAY_RESULT GLVTRACER_STDCALL Replay(glv_trace_packet_header* pPacket);
+}
diff --git a/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl_replay.cpp b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl_replay.cpp
new file mode 100644
index 0000000..acd771b
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl_replay.cpp
@@ -0,0 +1,1931 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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 "glvreplay_xgl_replay.h"
+
+
+extern "C" {
+#include "glvtrace_xgl_xgl_structs.h"
+#include "glvtrace_xgl_xgldbg_structs.h"
+#include "glvtrace_xgl_xglwsix11ext_structs.h"
+#include "glvtrace_xgl_packet_id.h"
+}
+
+#define APP_NAME "glvreplay_xgl"
+#define IDI_ICON 101
+
+static const char* g_extensions[] =
+{
+        "XGL_WSI_WINDOWS",
+        "XGL_TIMER_QUEUE",
+        "XGL_GPU_TIMESTAMP_CALIBRATION",
+        "XGL_DMA_QUEUE",
+        "XGL_COMMAND_BUFFER_CONTROL_FLOW",
+        "XGL_COPY_OCCLUSION_QUERY_DATA",
+        "XGL_ADVANCED_MULTISAMPLING",
+        "XGL_BORDER_COLOR_PALETTE"
+};
+
+XGL_RESULT xglDisplay::init_xgl(unsigned int gpu_idx)
+{
+#if 0
+    XGL_APPLICATION_INFO appInfo = {};
+    appInfo.pAppName = APP_NAME;
+    appInfo.pEngineName = "";
+    appInfo.apiVersion = XGL_API_VERSION;
+
+    XGL_RESULT res = xglInitAndEnumerateGpus(&appInfo, NULL, XGL_MAX_PHYSICAL_GPUS, &m_gpuCount, m_gpus);
+
+    if ( res == XGL_SUCCESS ) {
+        // retrieve the GPU information for all GPUs
+        for( XGL_UINT32 gpu = 0; gpu < m_gpuCount; gpu++)
+        {
+            XGL_SIZE gpuInfoSize = sizeof(m_gpuProps[0]);
+
+            // get the GPU physical properties:
+            res = xglGetGpuInfo( m_gpus[gpu], XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES, &gpuInfoSize, &m_gpuProps[gpu]);
+            if (res != XGL_SUCCESS)
+                glv_LogWarn("Failed to retrieve properties for gpu[%d] result %d\n", gpu, res);
+        }
+        res = XGL_SUCCESS;
+    } else if ((gpu_idx + 1) > m_gpuCount) {
+        glv_LogError("xglInitAndEnumerate number of gpus doesn't include requested index: num %d, requested %d\n", m_gpuCount, gpu_idx);
+        return -1;
+    } else {
+        glv_LogError("xglInitAndEnumerate failed");
+        return res;
+    }
+
+    // TODO add multi-gpu support always use gpu[gpu_idx] for now
+
+    // get all extensions supported by this device gpu[gpu_idx]
+    // first check if extensions are available and save a list of them
+    bool foundWSIExt = false;
+    for( int ext = 0; ext < sizeof( extensions ) / sizeof( extensions[0] ); ext++)
+    {
+        res = xglGetExtensionSupport( m_gpus[gpu_idx], extensions[ext] );
+        if (res == XGL_SUCCESS) {
+            m_extensions.push_back((XGL_CHAR *) extensions[ext]);
+            if (!strcmp(extensions[ext], "XGL_WSI_WINDOWS"))
+                foundWSIExt = true;
+        }
+    }
+
+    if (!foundWSIExt) {
+        glv_LogError("XGL_WSI_WINDOWS extension not supported by gpu[%d]\n", gpu_idx);
+        return XGL_ERROR_INCOMPATIBLE_DEVICE;
+    }
+
+    // TODO generalize this: use one universal queue for now
+    XGL_DEVICE_QUEUE_CREATE_INFO dqci = {};
+    dqci.queueCount = 1;
+    dqci.queueType = XGL_QUEUE_UNIVERSAL;
+
+    // create the device enabling validation level 4
+    const XGL_CHAR * const * extNames = &m_extensions[0];
+    XGL_DEVICE_CREATE_INFO info = {};
+    info.queueRecordCount = 1;
+    info.pRequestedQueues = &dqci;
+    info.extensionCount = static_cast <XGL_UINT> (m_extensions.size());
+    info.ppEnabledExtensionNames = extNames;
+    info.flags = XGL_DEVICE_CREATE_VALIDATION;
+    info.maxValidationLevel = XGL_VALIDATION_LEVEL_4;
+    XGL_BOOL xglTrue = XGL_TRUE;
+    res = xglDbgSetGlobalOption( XGL_DBG_OPTION_BREAK_ON_ERROR, sizeof( xglTrue ), &xglTrue );
+    if (res != XGL_SUCCESS)
+        glv_LogWarn("Couldn't set debug option break on error\n");
+    res = xglCreateDevice( m_gpus[0], &info, &m_dev[gpu_idx]);
+    return res;
+#else
+    return XGL_ERROR_INITIALIZATION_FAILED;
+#endif
+}
+
+int xglDisplay::init(const unsigned int gpu_idx)
+{
+
+    //m_gpuIdx = gpu_idx;
+#if 0
+    XGL_RESULT result = init_xgl(gpu_idx);
+    if (result != XGL_SUCCESS) {
+        glv_LogError("couldn't init xgl library");
+        return -1;
+    } else {
+        m_initedXGL = true;
+    }
+#endif
+#if defined(PLATFORM_LINUX)
+
+    const xcb_setup_t *setup;
+    xcb_screen_iterator_t iter;
+    int scr;
+    xcb_connection_t *pConnection;
+
+    pConnection = xcb_connect(NULL, &scr);
+
+    setup = xcb_get_setup(pConnection);
+    iter = xcb_setup_roots_iterator(setup);
+    while (scr-- > 0)
+        xcb_screen_next(&iter);
+
+    m_pXcbScreen = iter.data;
+    m_WsiConnection.pConnection = pConnection;
+    m_WsiConnection.root = m_pXcbScreen->root;
+#endif
+    return 0;
+}
+
+xglDisplay::xglDisplay() 
+    : m_initedXGL(false),
+    m_windowWidth(0),
+    m_windowHeight(0)
+{
+#if defined(WIN32)
+    m_windowHandle = NULL;
+#elif defined(PLATFORM_LINUX)
+    m_WsiConnection.pConnection = NULL;
+    m_WsiConnection.root = 0;
+    m_WsiConnection.provider = 0;
+    m_pXcbScreen = NULL;
+    m_XcbWindow = 0;
+#endif
+}
+
+xglDisplay::~xglDisplay()
+{
+#ifdef PLATFORM_LINUX
+    xcb_destroy_window(m_WsiConnection.pConnection, m_XcbWindow);
+    xcb_disconnect(m_WsiConnection.pConnection);
+#endif
+}
+
+#if defined(WIN32)
+LRESULT WINAPI WindowProcXgl( HWND window, unsigned int msg, WPARAM wp, LPARAM lp)
+{
+    switch(msg)
+    {
+        case WM_CLOSE:
+            DestroyWindow( window);
+            // fall-thru
+        case WM_DESTROY:
+            PostQuitMessage(0) ;
+            return 0L ;
+        default:
+            return DefWindowProc( window, msg, wp, lp ) ;
+    }
+}
+#endif
+
+int xglDisplay::set_window(glv_window_handle hWindow, unsigned int width, unsigned int height)
+{
+#if defined(WIN32)
+    m_windowHandle = hWindow;
+#endif
+    m_windowWidth = width;
+    m_windowHeight = height;
+    return 0;
+}
+
+int xglDisplay::create_window(const unsigned int width, const unsigned int height)
+{
+#if defined(WIN32)
+    // Register Window class
+    WNDCLASSEX wcex = {};
+    wcex.cbSize = sizeof( WNDCLASSEX);
+    wcex.style = CS_HREDRAW | CS_VREDRAW;
+    wcex.lpfnWndProc = WindowProcXgl;
+    wcex.cbClsExtra = 0;
+    wcex.cbWndExtra = 0;
+    wcex.hInstance = GetModuleHandle(0);
+    wcex.hIcon = LoadIcon(wcex.hInstance, MAKEINTRESOURCE( IDI_ICON));
+    wcex.hCursor = LoadCursor( NULL, IDC_ARROW);
+    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1);
+    wcex.lpszMenuName = NULL;
+    wcex.lpszClassName = APP_NAME;
+    wcex.hIconSm = LoadIcon( wcex.hInstance, MAKEINTRESOURCE( IDI_ICON));
+    if( !RegisterClassEx( &wcex))
+    {
+        glv_LogError("Failed to register windows class\n");
+        return -1;
+    }
+
+    // create the window
+    m_windowHandle = CreateWindow(APP_NAME, APP_NAME, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, 0, 0,
+                          width, height, NULL, NULL, wcex.hInstance, NULL);
+
+    if (m_windowHandle)
+    {
+        ShowWindow( m_windowHandle, SW_SHOWDEFAULT);
+        m_windowWidth = width;
+        m_windowHeight = height;
+    } else {
+        glv_LogError("Failed to create window\n");
+        return -1;
+    }
+
+    return 0;
+#elif defined(PLATFORM_LINUX)
+
+    uint32_t value_mask, value_list[32];
+    m_XcbWindow = xcb_generate_id(m_WsiConnection.pConnection);
+
+    value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+    value_list[0] = m_pXcbScreen->black_pixel;
+    value_list[1] = XCB_EVENT_MASK_KEY_RELEASE |
+                    XCB_EVENT_MASK_EXPOSURE;
+
+    xcb_create_window(m_WsiConnection.pConnection,
+            XCB_COPY_FROM_PARENT,
+            m_XcbWindow, m_WsiConnection.root,
+            0, 0, width, height, 0,
+            XCB_WINDOW_CLASS_INPUT_OUTPUT,
+            m_pXcbScreen->root_visual,
+            value_mask, value_list);
+
+    xcb_map_window(m_WsiConnection.pConnection, m_XcbWindow);
+    xcb_flush(m_WsiConnection.pConnection);
+    return 0;
+#endif
+}
+
+void xglDisplay::resize_window(const unsigned int width, const unsigned int height)
+{
+#if defined(WIN32)
+    if (width != m_windowWidth || height != m_windowHeight)
+    {
+        SetWindowPos(get_window_handle(), HWND_TOP, 0, 0, width, height, SWP_NOMOVE);
+        m_windowWidth = width;
+        m_windowHeight = height;
+    }
+#elif defined(PLATFORM_LINUX)
+    if (width != m_windowWidth || height != m_windowHeight)
+    {
+        uint32_t values[2];
+        values[0] = width;
+        values[1] = height;
+        xcb_configure_window(m_WsiConnection.pConnection, m_XcbWindow, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
+        m_windowWidth = width;
+        m_windowHeight = height;
+    }
+#endif
+}
+
+void xglDisplay::process_event()
+{
+}
+
+xglReplay::xglReplay(unsigned int debugLevel)
+{
+    m_display = new xglDisplay();
+    m_debugLevel = debugLevel;
+}
+
+xglReplay::~xglReplay()
+{
+    delete m_display;
+    glv_platform_close_library(m_xglFuncs.m_libHandle);
+}
+
+int xglReplay::init(glv_replay::Display & disp)
+{
+    int err;
+#if defined _WIN64
+    HMODULE handle = LoadLibrary("xgl64.dll" );
+#elif defined _WIN32
+    HMODULE handle = LoadLibrary("xgl32.dll" );
+#elif defined PLATFORM_LINUX
+    void * handle = dlopen("libXGL.so", RTLD_LAZY);
+#endif
+
+    if (handle == NULL) {
+        glv_LogError("Failed to open xgl library.\n");
+        return -1;
+    }
+
+    m_xglFuncs.init_funcs(handle);
+
+    disp.set_implementation(m_display);
+
+    if ((err = m_display->init(disp.get_gpu())) != 0) {
+        glv_LogError("Failed to init XGL display.\n");
+        return err;
+    }
+
+    if (disp.get_window_handle() == 0)
+    {
+        if ((err = m_display->create_window(disp.get_width(), disp.get_height())) != 0) {
+            glv_LogError("Failed to create Window\n");
+            return err;
+        }
+    }
+    else
+    {
+        if ((err = m_display->set_window(disp.get_window_handle(), disp.get_width(), disp.get_height())) != 0)
+        {
+            glv_LogError("Failed to set Window\n");
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+void xglReplay::copy_mem_remap_range_struct(XGL_VIRTUAL_MEMORY_REMAP_RANGE *outRange, const XGL_VIRTUAL_MEMORY_REMAP_RANGE *inRange)
+{
+    outRange->pageCount = inRange->pageCount;
+    outRange->realStartPage = inRange->realStartPage;
+    outRange->realMem = remap(inRange->realMem);
+    outRange->virtualStartPage = inRange->virtualStartPage;
+    outRange->virtualMem = remap(inRange->virtualMem);
+}
+
+glv_replay::GLV_REPLAY_RESULT xglReplay::handle_replay_errors(const char* entrypointName, const XGL_RESULT resCall, const XGL_RESULT resTrace, const glv_replay::GLV_REPLAY_RESULT resIn)
+{
+    glv_replay::GLV_REPLAY_RESULT res = resIn;
+    if (resCall != resTrace) {
+        glv_LogWarn("Mismatched return from API call (%s) traced result %s, replay result %s\n", entrypointName,
+                string_XGL_RESULT(resTrace), string_XGL_RESULT(resCall));
+        res = glv_replay::GLV_REPLAY_BAD_RETURN;
+    }
+
+#if 0
+    if (resCall != XGL_SUCCESS) {
+        glv_LogWarn("API call (%s) returned failed result %s\n", entrypointName, string_XGL_RESULT(resCall));
+    }
+#endif
+    return res;
+}
+
+void xglFuncs::init_funcs(void * handle)
+{
+    m_libHandle = handle;
+    real_xglInitAndEnumerateGpus = (type_xglInitAndEnumerateGpus)(glv_platform_get_library_entrypoint(handle, "xglInitAndEnumerateGpus"));
+    real_xglGetGpuInfo = (type_xglGetGpuInfo)(glv_platform_get_library_entrypoint(handle, "xglGetGpuInfo"));
+    real_xglCreateDevice = (type_xglCreateDevice)(glv_platform_get_library_entrypoint(handle, "xglCreateDevice"));
+    real_xglDestroyDevice = (type_xglDestroyDevice)(glv_platform_get_library_entrypoint(handle, "xglDestroyDevice"));
+    real_xglGetExtensionSupport = (type_xglGetExtensionSupport)(glv_platform_get_library_entrypoint(handle, "xglGetExtensionSupport"));
+    real_xglGetDeviceQueue = (type_xglGetDeviceQueue)(glv_platform_get_library_entrypoint(handle, "xglGetDeviceQueue"));
+    real_xglQueueSubmit = (type_xglQueueSubmit)(glv_platform_get_library_entrypoint(handle, "xglQueueSubmit"));
+    real_xglQueueSetGlobalMemReferences = (type_xglQueueSetGlobalMemReferences)(glv_platform_get_library_entrypoint(handle, "xglQueueSetGlobalMemReferences"));
+    real_xglQueueWaitIdle = (type_xglQueueWaitIdle)(glv_platform_get_library_entrypoint(handle, "xglQueueWaitIdle"));
+    real_xglDeviceWaitIdle = (type_xglDeviceWaitIdle)(glv_platform_get_library_entrypoint(handle, "xglDeviceWaitIdle"));
+    real_xglGetMemoryHeapCount = (type_xglGetMemoryHeapCount)(glv_platform_get_library_entrypoint(handle, "xglGetMemoryHeapCount"));
+    real_xglGetMemoryHeapInfo = (type_xglGetMemoryHeapInfo)(glv_platform_get_library_entrypoint(handle, "xglGetMemoryHeapInfo"));
+    real_xglAllocMemory = (type_xglAllocMemory)(glv_platform_get_library_entrypoint(handle, "xglAllocMemory"));
+    real_xglFreeMemory = (type_xglFreeMemory)(glv_platform_get_library_entrypoint(handle, "xglFreeMemory"));
+    real_xglSetMemoryPriority = (type_xglSetMemoryPriority)(glv_platform_get_library_entrypoint(handle, "xglSetMemoryPriority"));
+    real_xglMapMemory = (type_xglMapMemory)(glv_platform_get_library_entrypoint(handle, "xglMapMemory"));
+    real_xglUnmapMemory = (type_xglUnmapMemory)(glv_platform_get_library_entrypoint(handle, "xglUnmapMemory"));
+    real_xglPinSystemMemory = (type_xglPinSystemMemory)(glv_platform_get_library_entrypoint(handle, "xglPinSystemMemory"));
+    real_xglRemapVirtualMemoryPages = (type_xglRemapVirtualMemoryPages)(glv_platform_get_library_entrypoint(handle, "xglRemapVirtualMemoryPages"));
+    real_xglGetMultiGpuCompatibility = (type_xglGetMultiGpuCompatibility)(glv_platform_get_library_entrypoint(handle, "xglGetMultiGpuCompatibility"));
+    real_xglOpenSharedMemory = (type_xglOpenSharedMemory)(glv_platform_get_library_entrypoint(handle, "xglOpenSharedMemory"));
+    real_xglOpenSharedQueueSemaphore = (type_xglOpenSharedQueueSemaphore)(glv_platform_get_library_entrypoint(handle, "xglOpenSharedQueueSemaphore"));
+    real_xglOpenPeerMemory = (type_xglOpenPeerMemory)(glv_platform_get_library_entrypoint(handle, "xglOpenPeerMemory"));
+    real_xglOpenPeerImage = (type_xglOpenPeerImage)(glv_platform_get_library_entrypoint(handle, "xglOpenPeerImage"));
+    real_xglDestroyObject = (type_xglDestroyObject)(glv_platform_get_library_entrypoint(handle, "xglDestroyObject"));
+    real_xglGetObjectInfo = (type_xglGetObjectInfo)(glv_platform_get_library_entrypoint(handle, "xglGetObjectInfo"));
+    real_xglBindObjectMemory = (type_xglBindObjectMemory)(glv_platform_get_library_entrypoint(handle, "xglBindObjectMemory"));
+    real_xglCreateFence = (type_xglCreateFence)(glv_platform_get_library_entrypoint(handle, "xglCreateFence"));
+    real_xglGetFenceStatus = (type_xglGetFenceStatus)(glv_platform_get_library_entrypoint(handle, "xglGetFenceStatus"));
+    real_xglWaitForFences = (type_xglWaitForFences)(glv_platform_get_library_entrypoint(handle, "xglWaitForFences"));
+    real_xglCreateQueueSemaphore = (type_xglCreateQueueSemaphore)(glv_platform_get_library_entrypoint(handle, "xglCreateQueueSemaphore"));
+    real_xglSignalQueueSemaphore = (type_xglSignalQueueSemaphore)(glv_platform_get_library_entrypoint(handle, "xglSignalQueueSemaphore"));
+    real_xglWaitQueueSemaphore = (type_xglWaitQueueSemaphore)(glv_platform_get_library_entrypoint(handle, "xglWaitQueueSemaphore"));
+    real_xglCreateEvent = (type_xglCreateEvent)(glv_platform_get_library_entrypoint(handle, "xglCreateEvent"));
+    real_xglGetEventStatus = (type_xglGetEventStatus)(glv_platform_get_library_entrypoint(handle, "xglGetEventStatus"));
+    real_xglSetEvent = (type_xglSetEvent)(glv_platform_get_library_entrypoint(handle, "xglSetEvent"));
+    real_xglResetEvent = (type_xglResetEvent)(glv_platform_get_library_entrypoint(handle, "xglResetEvent"));
+    real_xglCreateQueryPool = (type_xglCreateQueryPool)(glv_platform_get_library_entrypoint(handle, "xglCreateQueryPool"));
+    real_xglGetQueryPoolResults = (type_xglGetQueryPoolResults)(glv_platform_get_library_entrypoint(handle, "xglGetQueryPoolResults"));
+    real_xglGetFormatInfo = (type_xglGetFormatInfo)(glv_platform_get_library_entrypoint(handle, "xglGetFormatInfo"));
+    real_xglCreateImage = (type_xglCreateImage)(glv_platform_get_library_entrypoint(handle, "xglCreateImage"));
+    real_xglGetImageSubresourceInfo = (type_xglGetImageSubresourceInfo)(glv_platform_get_library_entrypoint(handle, "xglGetImageSubresourceInfo"));
+    real_xglCreateImageView = (type_xglCreateImageView)(glv_platform_get_library_entrypoint(handle, "xglCreateImageView"));
+    real_xglCreateColorAttachmentView = (type_xglCreateColorAttachmentView)(glv_platform_get_library_entrypoint(handle, "xglCreateColorAttachmentView"));
+    real_xglCreateDepthStencilView = (type_xglCreateDepthStencilView)(glv_platform_get_library_entrypoint(handle, "xglCreateDepthStencilView"));
+    real_xglCreateShader = (type_xglCreateShader)(glv_platform_get_library_entrypoint(handle, "xglCreateShader"));
+    real_xglCreateGraphicsPipeline = (type_xglCreateGraphicsPipeline)(glv_platform_get_library_entrypoint(handle, "xglCreateGraphicsPipeline"));
+    real_xglCreateComputePipeline = (type_xglCreateComputePipeline)(glv_platform_get_library_entrypoint(handle, "xglCreateComputePipeline"));
+    real_xglStorePipeline = (type_xglStorePipeline)(glv_platform_get_library_entrypoint(handle, "xglStorePipeline"));
+    real_xglCreatePipelineDelta = (type_xglCreatePipelineDelta)(glv_platform_get_library_entrypoint(handle, "xglCreatePipelineDelta"));
+    real_xglLoadPipeline = (type_xglLoadPipeline)(glv_platform_get_library_entrypoint(handle, "xglLoadPipeline"));
+    real_xglCreateSampler = (type_xglCreateSampler)(glv_platform_get_library_entrypoint(handle, "xglCreateSampler"));
+    real_xglCreateDescriptorSet = (type_xglCreateDescriptorSet)(glv_platform_get_library_entrypoint(handle, "xglCreateDescriptorSet"));
+    real_xglBeginDescriptorSetUpdate = (type_xglBeginDescriptorSetUpdate)(glv_platform_get_library_entrypoint(handle, "xglBeginDescriptorSetUpdate"));
+    real_xglEndDescriptorSetUpdate = (type_xglEndDescriptorSetUpdate)(glv_platform_get_library_entrypoint(handle, "xglEndDescriptorSetUpdate"));
+    real_xglAttachSamplerDescriptors = (type_xglAttachSamplerDescriptors)(glv_platform_get_library_entrypoint(handle, "xglAttachSamplerDescriptors"));
+    real_xglAttachImageViewDescriptors = (type_xglAttachImageViewDescriptors)(glv_platform_get_library_entrypoint(handle, "xglAttachImageViewDescriptors"));
+    real_xglAttachMemoryViewDescriptors = (type_xglAttachMemoryViewDescriptors)(glv_platform_get_library_entrypoint(handle, "xglAttachMemoryViewDescriptors"));
+    real_xglAttachNestedDescriptors = (type_xglAttachNestedDescriptors)(glv_platform_get_library_entrypoint(handle, "xglAttachNestedDescriptors"));
+    real_xglClearDescriptorSetSlots = (type_xglClearDescriptorSetSlots)(glv_platform_get_library_entrypoint(handle, "xglClearDescriptorSetSlots"));
+    real_xglCreateViewportState = (type_xglCreateViewportState)(glv_platform_get_library_entrypoint(handle, "xglCreateViewportState"));
+    real_xglCreateRasterState = (type_xglCreateRasterState)(glv_platform_get_library_entrypoint(handle, "xglCreateRasterState"));
+    real_xglCreateMsaaState = (type_xglCreateMsaaState)(glv_platform_get_library_entrypoint(handle, "xglCreateMsaaState"));
+    real_xglCreateColorBlendState = (type_xglCreateColorBlendState)(glv_platform_get_library_entrypoint(handle, "xglCreateColorBlendState"));
+    real_xglCreateDepthStencilState = (type_xglCreateDepthStencilState)(glv_platform_get_library_entrypoint(handle, "xglCreateDepthStencilState"));
+    real_xglCreateCommandBuffer = (type_xglCreateCommandBuffer)(glv_platform_get_library_entrypoint(handle, "xglCreateCommandBuffer"));
+    real_xglBeginCommandBuffer = (type_xglBeginCommandBuffer)(glv_platform_get_library_entrypoint(handle, "xglBeginCommandBuffer"));
+    real_xglEndCommandBuffer = (type_xglEndCommandBuffer)(glv_platform_get_library_entrypoint(handle, "xglEndCommandBuffer"));
+    real_xglResetCommandBuffer = (type_xglResetCommandBuffer)(glv_platform_get_library_entrypoint(handle, "xglResetCommandBuffer"));
+    real_xglCmdBindPipeline = (type_xglCmdBindPipeline)(glv_platform_get_library_entrypoint(handle, "xglCmdBindPipeline"));
+    real_xglCmdBindPipelineDelta = (type_xglCmdBindPipelineDelta)(glv_platform_get_library_entrypoint(handle, "xglCmdBindPipelineDelta"));
+    real_xglCmdBindStateObject = (type_xglCmdBindStateObject)(glv_platform_get_library_entrypoint(handle, "xglCmdBindStateObject"));
+    real_xglCmdBindDescriptorSet = (type_xglCmdBindDescriptorSet)(glv_platform_get_library_entrypoint(handle, "xglCmdBindDescriptorSet"));
+    real_xglCmdBindDynamicMemoryView = (type_xglCmdBindDynamicMemoryView)(glv_platform_get_library_entrypoint(handle, "xglCmdBindDynamicMemoryView"));
+    real_xglCmdBindIndexData = (type_xglCmdBindIndexData)(glv_platform_get_library_entrypoint(handle, "xglCmdBindIndexData"));
+    real_xglCmdBindAttachments = (type_xglCmdBindAttachments)(glv_platform_get_library_entrypoint(handle, "xglCmdBindAttachments"));
+    real_xglCmdPrepareMemoryRegions = (type_xglCmdPrepareMemoryRegions)(glv_platform_get_library_entrypoint(handle, "xglCmdPrepareMemoryRegions"));
+    real_xglCmdPrepareImages = (type_xglCmdPrepareImages)(glv_platform_get_library_entrypoint(handle, "xglCmdPrepareImages"));
+    real_xglCmdDraw = (type_xglCmdDraw)(glv_platform_get_library_entrypoint(handle, "xglCmdDraw"));
+    real_xglCmdDrawIndexed = (type_xglCmdDrawIndexed)(glv_platform_get_library_entrypoint(handle, "xglCmdDrawIndexed"));
+    real_xglCmdDrawIndirect = (type_xglCmdDrawIndirect)(glv_platform_get_library_entrypoint(handle, "xglCmdDrawIndirect"));
+    real_xglCmdDrawIndexedIndirect = (type_xglCmdDrawIndexedIndirect)(glv_platform_get_library_entrypoint(handle, "xglCmdDrawIndexedIndirect"));
+    real_xglCmdDispatch = (type_xglCmdDispatch)(glv_platform_get_library_entrypoint(handle, "xglCmdDispatch"));
+    real_xglCmdDispatchIndirect = (type_xglCmdDispatchIndirect)(glv_platform_get_library_entrypoint(handle, "xglCmdDispatchIndirect"));
+    real_xglCmdCopyMemory = (type_xglCmdCopyMemory)(glv_platform_get_library_entrypoint(handle, "xglCmdCopyMemory"));
+    real_xglCmdCopyImage = (type_xglCmdCopyImage)(glv_platform_get_library_entrypoint(handle, "xglCmdCopyImage"));
+    real_xglCmdCopyMemoryToImage = (type_xglCmdCopyMemoryToImage)(glv_platform_get_library_entrypoint(handle, "xglCmdCopyMemoryToImage"));
+    real_xglCmdCopyImageToMemory = (type_xglCmdCopyImageToMemory)(glv_platform_get_library_entrypoint(handle, "xglCmdCopyImageToMemory"));
+    real_xglCmdCloneImageData = (type_xglCmdCloneImageData)(glv_platform_get_library_entrypoint(handle, "xglCmdCloneImageData"));
+    real_xglCmdUpdateMemory = (type_xglCmdUpdateMemory)(glv_platform_get_library_entrypoint(handle, "xglCmdUpdateMemory"));
+    real_xglCmdFillMemory = (type_xglCmdFillMemory)(glv_platform_get_library_entrypoint(handle, "xglCmdFillMemory"));
+    real_xglCmdClearColorImage = (type_xglCmdClearColorImage)(glv_platform_get_library_entrypoint(handle, "xglCmdClearColorImage"));
+    real_xglCmdClearColorImageRaw = (type_xglCmdClearColorImageRaw)(glv_platform_get_library_entrypoint(handle, "xglCmdClearColorImageRaw"));
+    real_xglCmdClearDepthStencil = (type_xglCmdClearDepthStencil)(glv_platform_get_library_entrypoint(handle, "xglCmdClearDepthStencil"));
+    real_xglCmdResolveImage = (type_xglCmdResolveImage)(glv_platform_get_library_entrypoint(handle, "xglCmdResolveImage"));
+    real_xglCmdSetEvent = (type_xglCmdSetEvent)(glv_platform_get_library_entrypoint(handle, "xglCmdSetEvent"));
+    real_xglCmdResetEvent = (type_xglCmdResetEvent)(glv_platform_get_library_entrypoint(handle, "xglCmdResetEvent"));
+    real_xglCmdMemoryAtomic = (type_xglCmdMemoryAtomic)(glv_platform_get_library_entrypoint(handle, "xglCmdMemoryAtomic"));
+    real_xglCmdBeginQuery = (type_xglCmdBeginQuery)(glv_platform_get_library_entrypoint(handle, "xglCmdBeginQuery"));
+    real_xglCmdEndQuery = (type_xglCmdEndQuery)(glv_platform_get_library_entrypoint(handle, "xglCmdEndQuery"));
+    real_xglCmdResetQueryPool = (type_xglCmdResetQueryPool)(glv_platform_get_library_entrypoint(handle, "xglCmdResetQueryPool"));
+    real_xglCmdWriteTimestamp = (type_xglCmdWriteTimestamp)(glv_platform_get_library_entrypoint(handle, "xglCmdWriteTimestamp"));
+    real_xglCmdInitAtomicCounters = (type_xglCmdInitAtomicCounters)(glv_platform_get_library_entrypoint(handle, "xglCmdInitAtomicCounters"));
+    real_xglCmdLoadAtomicCounters = (type_xglCmdLoadAtomicCounters)(glv_platform_get_library_entrypoint(handle, "xglCmdLoadAtomicCounters"));
+    real_xglCmdSaveAtomicCounters = (type_xglCmdSaveAtomicCounters)(glv_platform_get_library_entrypoint(handle, "xglCmdSaveAtomicCounters"));
+
+    // debug entrypoints
+    real_xglDbgSetValidationLevel = (type_xglDbgSetValidationLevel)(glv_platform_get_library_entrypoint(handle, "xglDbgSetValidationLevel"));
+    real_xglDbgRegisterMsgCallback = (type_xglDbgRegisterMsgCallback)(glv_platform_get_library_entrypoint(handle, "xglDbgRegisterMsgCallback"));
+    real_xglDbgUnregisterMsgCallback = (type_xglDbgUnregisterMsgCallback)(glv_platform_get_library_entrypoint(handle, "xglDbgUnregisterMsgCallback"));
+    real_xglDbgSetMessageFilter = (type_xglDbgSetMessageFilter)(glv_platform_get_library_entrypoint(handle, "xglDbgSetMessageFilter"));
+    real_xglDbgSetObjectTag = (type_xglDbgSetObjectTag)(glv_platform_get_library_entrypoint(handle, "xglDbgSetObjectTag"));
+    real_xglDbgSetGlobalOption = (type_xglDbgSetGlobalOption)(glv_platform_get_library_entrypoint(handle, "xglDbgSetGlobalOption"));
+    real_xglDbgSetDeviceOption = (type_xglDbgSetDeviceOption)(glv_platform_get_library_entrypoint(handle, "xglDbgSetDeviceOption"));
+    real_xglCmdDbgMarkerBegin = (type_xglCmdDbgMarkerBegin)(glv_platform_get_library_entrypoint(handle, "xglCmdDbgMarkerBegin"));
+    real_xglCmdDbgMarkerEnd = (type_xglCmdDbgMarkerEnd)(glv_platform_get_library_entrypoint(handle, "xglCmdDbgMarkerEnd"));
+
+    // WsiX11Ext entrypoints
+    real_xglWsiX11AssociateConnection = (type_xglWsiX11AssociateConnection)(glv_platform_get_library_entrypoint(handle, "xglWsiX11AssociateConnection"));
+    real_xglWsiX11GetMSC = (type_xglWsiX11GetMSC)(glv_platform_get_library_entrypoint(handle, "xglWsiX11GetMSC"));
+    real_xglWsiX11CreatePresentableImage = (type_xglWsiX11CreatePresentableImage)(glv_platform_get_library_entrypoint(handle, "xglWsiX11CreatePresentableImage"));
+    real_xglWsiX11QueuePresent = (type_xglWsiX11QueuePresent)(glv_platform_get_library_entrypoint(handle, "xglWsiX11QueuePresent"));
+}
+
+#define CHECK_RETURN_VALUE(entrypoint) returnValue = handle_replay_errors(#entrypoint, replayResult, pPacket->result, returnValue);
+
+glv_replay::GLV_REPLAY_RESULT xglReplay::replay(glv_trace_packet_header *packet)
+{
+    glv_replay::GLV_REPLAY_RESULT returnValue = glv_replay::GLV_REPLAY_SUCCESS;
+    XGL_RESULT replayResult = XGL_ERROR_UNKNOWN;
+
+    switch (packet->packet_id)
+    {
+        case GLV_TPI_XGL_xglInitAndEnumerateGpus:
+        {
+            struct_xglInitAndEnumerateGpus* pPacket;
+            pPacket = interpret_body_as_xglInitAndEnumerateGpus(packet);
+
+            // skip this call if XGL already inited
+            if (!m_display->m_initedXGL)
+            {
+                XGL_UINT gpuCount;
+                XGL_PHYSICAL_GPU gpus[XGL_MAX_PHYSICAL_GPUS];
+                XGL_UINT maxGpus = (pPacket->maxGpus < XGL_MAX_PHYSICAL_GPUS) ? pPacket->maxGpus : XGL_MAX_PHYSICAL_GPUS;
+                replayResult = m_xglFuncs.real_xglInitAndEnumerateGpus(pPacket->pAppInfo, pPacket->pAllocCb, maxGpus, &gpuCount, &gpus[0]);
+                CHECK_RETURN_VALUE(xglInitAndEnumerateGpus);
+                //TODO handle different number of gpus in trace versus replay
+                if (gpuCount != *(pPacket->pGpuCount))
+                {
+                    glv_LogWarn("number of gpus mismatched in replay %u versus trace %u\n", gpuCount, *(pPacket->pGpuCount));
+                }
+                else if (gpuCount == 0)
+                {
+                     glv_LogError("xglInitAndEnumerateGpus number of gpus is zero\n");
+                }
+                else
+                {
+                    glv_LogInfo("Enumerated %d GPUs in the system\n", gpuCount);
+                }
+                clear_all_map_handles();
+                // TODO handle enumeration results in a different order from trace to replay
+                for (XGL_UINT i = 0; i < gpuCount; i++)
+                {
+                    if (pPacket->pGpus)
+                        add_to_map(&(pPacket->pGpus[i]), &(gpus[i]));
+                }
+            }
+            //TODO check gpu handles for consistency with trace  gpus using xglGetGPUInfo
+            break;
+        }
+        case GLV_TPI_XGL_xglGetGpuInfo:
+        {
+            struct_xglGetGpuInfo * pPacket;
+            pPacket = interpret_body_as_xglGetGpuInfo(packet);
+
+            // skip this call if xgl inited
+            if (!m_display->m_initedXGL)
+            {
+                switch (pPacket->infoType) {
+                case XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES:
+                {
+                    XGL_PHYSICAL_GPU_PROPERTIES gpuProps;
+                    XGL_SIZE dataSize = sizeof(XGL_PHYSICAL_GPU_PROPERTIES);
+                    replayResult = m_xglFuncs.real_xglGetGpuInfo(remap(pPacket->gpu), pPacket->infoType, &dataSize,
+                                    (pPacket->pData == NULL) ? NULL : &gpuProps);
+                    if (pPacket->pData != NULL)
+                    {
+                        glv_LogInfo("Replay Gpu Properties\n");
+                        glv_LogInfo("Vendor ID %x, Device ID %x, name %s\n",gpuProps.vendorId, gpuProps.deviceId, gpuProps.gpuName);
+                        glv_LogInfo("API version %u, Driver version %u, gpu Type %u\n",gpuProps.apiVersion, gpuProps.driverVersion, gpuProps.gpuType);
+                    }
+                    break;
+                }
+                case XGL_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE:
+                {
+                    XGL_PHYSICAL_GPU_PERFORMANCE gpuPerfs;
+                    XGL_SIZE dataSize = sizeof(XGL_PHYSICAL_GPU_PERFORMANCE);
+                    replayResult = m_xglFuncs.real_xglGetGpuInfo(remap(pPacket->gpu), pPacket->infoType, &dataSize,
+                                    (pPacket->pData == NULL) ? NULL : &gpuPerfs);
+                    if (pPacket->pData != NULL)
+                    {
+                        glv_LogInfo("Replay Gpu Performance\n");
+                        glv_LogInfo("Max GPU clock %f, max shader ALUs/clock %f, max texel fetches/clock %f\n",gpuPerfs.maxGpuClock, gpuPerfs.aluPerClock, gpuPerfs.texPerClock);
+                        glv_LogInfo("Max primitives/clock %f, Max pixels/clock %f\n",gpuPerfs.primsPerClock, gpuPerfs.pixelsPerClock);
+                    }
+                    break;
+                }
+                case XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES:
+                {
+                    XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *pGpuQueue, *pQ;
+                    XGL_SIZE dataSize = sizeof(XGL_PHYSICAL_GPU_QUEUE_PROPERTIES);
+                    XGL_SIZE numQueues = 1;
+                    assert(pPacket->pDataSize);
+                    if ((*(pPacket->pDataSize) % dataSize) != 0)
+                        glv_LogWarn("xglGetGpuInfo() for GPU_QUEUE_PROPERTIES not an integral data size assuming 1\n");
+                    else
+                        numQueues = *(pPacket->pDataSize) / dataSize;
+                    dataSize = numQueues * dataSize;
+                    pQ = static_cast < XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *> (glv_malloc(dataSize));
+                    pGpuQueue = pQ;
+                    replayResult = m_xglFuncs.real_xglGetGpuInfo(remap(pPacket->gpu), pPacket->infoType, &dataSize,
+                                    (pPacket->pData == NULL) ? NULL : pGpuQueue);
+                    if (pPacket->pData != NULL)
+                    {
+                        for (unsigned int i = 0; i < numQueues; i++)
+                        {
+                            glv_LogInfo("Replay Gpu Queue Property for index %d, flags %u\n", i, pGpuQueue->queueFlags);
+                            glv_LogInfo("Max available count %u, max atomic counters %u, supports timestamps %u\n",pGpuQueue->queueCount, pGpuQueue->maxAtomicCounters, pGpuQueue->supportsTimestamps);
+                            pGpuQueue++;
+                        }
+                    }
+                    glv_free(pQ);
+                    break;
+                }
+                default:
+                {
+                    XGL_SIZE size = 0;
+                    void* pData = NULL;
+                    if (pPacket->pData != NULL && pPacket->pDataSize != NULL)
+                    {
+                        size = *pPacket->pDataSize;
+                        pData = glv_malloc(*pPacket->pDataSize);
+                    }
+                    replayResult = m_xglFuncs.real_xglGetGpuInfo(remap(pPacket->gpu), pPacket->infoType, &size, pData);
+                    if (replayResult == XGL_SUCCESS)
+                    {
+                        if (size != *pPacket->pDataSize && pData == NULL)
+                        {
+                            glv_LogWarn("xglGetGpuInfo returned a differing data size: replay (%d bytes) vs trace (%d bytes)\n", size, *pPacket->pDataSize);
+                        }
+                        else if (pData != NULL && memcmp(pData, pPacket->pData, size) != 0)
+                        {
+                            glv_LogWarn("xglGetGpuInfo returned differing data contents than the trace file contained.\n");
+                        }
+                    }
+                    glv_free(pData);
+                    break;
+                }
+                };
+                CHECK_RETURN_VALUE(xglGetGpuInfo);
+            }
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateDevice:
+        {
+            struct_xglCreateDevice * pPacket;
+            pPacket = interpret_body_as_xglCreateDevice(packet);
+            if (!m_display->m_initedXGL)
+            {
+                XGL_DEVICE device;
+                XGL_DEVICE_CREATE_INFO cInfo;
+
+                if (m_debugLevel > 0)
+                {
+                    memcpy(&cInfo, pPacket->pCreateInfo, sizeof(XGL_DEVICE_CREATE_INFO));
+                    cInfo.flags = pPacket->pCreateInfo->flags | XGL_DEVICE_CREATE_VALIDATION_BIT;
+                    cInfo.maxValidationLevel = (XGL_VALIDATION_LEVEL)((m_debugLevel <= 4) ? XGL_VALIDATION_LEVEL_0 + m_debugLevel : XGL_VALIDATION_LEVEL_0);
+                    pPacket->pCreateInfo = &cInfo;
+                }
+                replayResult = m_xglFuncs.real_xglCreateDevice(remap(pPacket->gpu), pPacket->pCreateInfo, &device);
+                CHECK_RETURN_VALUE(xglCreateDevice);
+                if (replayResult == XGL_SUCCESS)
+                {
+                    add_to_map(pPacket->pDevice, &device);
+                }
+            }
+            break;
+        }
+        case GLV_TPI_XGL_xglDestroyDevice:
+        {
+            struct_xglDestroyDevice * pPacket;
+            pPacket = interpret_body_as_xglDestroyDevice(packet);
+            replayResult = m_xglFuncs.real_xglDestroyDevice(remap(pPacket->device));
+            if (replayResult == XGL_SUCCESS)
+            {
+                rm_from_map(pPacket->device);
+                m_display->m_initedXGL = false;
+            }
+            CHECK_RETURN_VALUE(xglDestroyDevice);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetExtensionSupport:
+        {
+            struct_xglGetExtensionSupport * pPacket;
+            pPacket = interpret_body_as_xglGetExtensionSupport(packet);
+            if (!m_display->m_initedXGL) {
+                replayResult = m_xglFuncs.real_xglGetExtensionSupport(remap(pPacket->gpu), pPacket->pExtName);
+                CHECK_RETURN_VALUE(xglGetExtensionSupport);
+                if (replayResult == XGL_SUCCESS) {
+                    for (unsigned int ext = 0; ext < sizeof(g_extensions) / sizeof(g_extensions[0]); ext++)
+                    {
+                        if (!strncmp((const char *)g_extensions[ext], (const char *)pPacket->pExtName, strlen(g_extensions[ext]))) {
+                            bool extInList = false;
+                            for (unsigned int j = 0; j < m_display->m_extensions.size(); ++j) {
+                                if (!strncmp((const char *)m_display->m_extensions[j], (const char *)g_extensions[ext], strlen(g_extensions[ext])))
+                                    extInList = true;
+                                break;
+                            }
+                            if (!extInList)
+                                m_display->m_extensions.push_back((XGL_CHAR *) g_extensions[ext]);
+                            break;
+                        }
+                    }
+                }
+            }
+            break;
+        }
+        case GLV_TPI_XGL_xglGetDeviceQueue:
+        {
+            struct_xglGetDeviceQueue *pPacket;
+            pPacket = interpret_body_as_xglGetDeviceQueue(packet);
+            XGL_QUEUE q;
+            replayResult = m_xglFuncs.real_xglGetDeviceQueue(remap(pPacket->device), pPacket->queueType, pPacket->queueIndex, &q);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pQueue, &q);
+            }
+            CHECK_RETURN_VALUE(xglGetDeviceQueue);
+            break;
+        }
+        case GLV_TPI_XGL_xglQueueSubmit:
+        {
+            struct_xglQueueSubmit *pPacket;
+            pPacket = interpret_body_as_xglQueueSubmit(packet);
+            XGL_CMD_BUFFER *remappedBuffers = NULL;
+            if (pPacket->pCmdBuffers != NULL)
+            {
+                remappedBuffers = GLV_NEW_ARRAY( XGL_CMD_BUFFER, pPacket->cmdBufferCount);
+                for (XGL_UINT i = 0; i < pPacket->cmdBufferCount; i++)
+                {
+                    *(remappedBuffers + i) = remap(*(pPacket->pCmdBuffers + i));
+                }
+            }
+
+            XGL_MEMORY_REF* memRefs = NULL;
+            if (pPacket->pMemRefs != NULL)
+            {
+                memRefs = GLV_NEW_ARRAY(XGL_MEMORY_REF, pPacket->memRefCount);
+                memcpy(memRefs, pPacket->pMemRefs, sizeof(XGL_MEMORY_REF) * pPacket->memRefCount);
+                for (XGL_UINT i = 0; i < pPacket->memRefCount; i++)
+                {
+                    memRefs[i].mem = remap(pPacket->pMemRefs[i].mem);
+                }
+            }
+
+            replayResult = m_xglFuncs.real_xglQueueSubmit(remap(pPacket->queue), pPacket->cmdBufferCount, remappedBuffers, pPacket->memRefCount,
+                memRefs, remap(pPacket->fence));
+            GLV_DELETE(remappedBuffers);
+            GLV_DELETE(memRefs);
+            CHECK_RETURN_VALUE(xglQueueSubmit);
+            break;
+        }
+        case GLV_TPI_XGL_xglQueueSetGlobalMemReferences:
+        {
+            struct_xglQueueSetGlobalMemReferences *pPacket;
+            pPacket = interpret_body_as_xglQueueSetGlobalMemReferences(packet);
+            replayResult = m_xglFuncs.real_xglQueueSetGlobalMemReferences(remap(pPacket->queue), pPacket->memRefCount, pPacket->pMemRefs);
+            CHECK_RETURN_VALUE(xglQueueSetGlobalMemReferences);
+            break;
+        }
+        case GLV_TPI_XGL_xglQueueWaitIdle:
+        {
+            struct_xglQueueWaitIdle *pPacket;
+            pPacket = interpret_body_as_xglQueueWaitIdle(packet);
+            replayResult = m_xglFuncs.real_xglQueueWaitIdle(remap(pPacket->queue));
+            CHECK_RETURN_VALUE(xglQueueWaitIdle);
+            break;
+        }
+        case GLV_TPI_XGL_xglDeviceWaitIdle:
+        {
+            struct_xglDeviceWaitIdle *pPacket;
+            pPacket = interpret_body_as_xglDeviceWaitIdle(packet);
+            replayResult = m_xglFuncs.real_xglDeviceWaitIdle(remap(pPacket->device));
+            CHECK_RETURN_VALUE(xglDeviceWaitIdle);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetMemoryHeapCount:
+        {
+            struct_xglGetMemoryHeapCount *pPacket;
+            XGL_UINT count;
+            pPacket = interpret_body_as_xglGetMemoryHeapCount(packet);
+            replayResult = m_xglFuncs.real_xglGetMemoryHeapCount(remap(pPacket->device), &count);
+            if (count < 1 || count >= XGL_MAX_MEMORY_HEAPS)
+                glv_LogError("xglGetMemoryHeapCount returned bad value count = %u\n", count);
+            CHECK_RETURN_VALUE(xglGetMemoryHeapCount);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetMemoryHeapInfo:
+        {
+            // TODO handle case where traced heap count, ids and properties do not match replay heaps
+            struct_xglGetMemoryHeapInfo *pPacket;
+            XGL_SIZE dataSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
+            pPacket = interpret_body_as_xglGetMemoryHeapInfo(packet);
+            // TODO check returned properties match queried properties if this makes sense
+            if (pPacket->heapId >= XGL_MAX_MEMORY_HEAPS)
+            {
+                glv_LogError("xglGetMemoryHeapInfo bad heapid (%d) skipping packet\n");
+                break;
+            }
+            replayResult = m_xglFuncs.real_xglGetMemoryHeapInfo(remap(pPacket->device), pPacket->heapId, pPacket->infoType, &dataSize,
+                                               static_cast <XGL_VOID *> (&(m_heapProps[pPacket->heapId])));
+            if (dataSize != sizeof(XGL_MEMORY_HEAP_PROPERTIES))
+                glv_LogError("xglGetMemoryHeapInfo returned bad size = %u\n", dataSize);
+            CHECK_RETURN_VALUE(xglGetMemoryHeapCount);
+            break;
+        }
+        case GLV_TPI_XGL_xglAllocMemory:
+        {
+            struct_xglAllocMemory *pPacket;
+            XGL_GPU_MEMORY handle;
+            pPacket = interpret_body_as_xglAllocMemory(packet);
+            replayResult = m_xglFuncs.real_xglAllocMemory(remap(pPacket->device), pPacket->pAllocInfo, &handle);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pMem, &handle);
+                add_entry_to_mapData(handle, pPacket->pAllocInfo->allocationSize);
+            }
+            CHECK_RETURN_VALUE(xglAllocMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglFreeMemory:
+        {
+            struct_xglFreeMemory *pPacket;
+            pPacket = interpret_body_as_xglFreeMemory(packet);
+            XGL_GPU_MEMORY handle = remap(pPacket->mem);
+            replayResult = m_xglFuncs.real_xglFreeMemory(handle);
+            if (replayResult == XGL_SUCCESS) 
+            {
+                rm_entry_from_mapData(handle);
+                rm_from_map(pPacket->mem);
+            }
+            CHECK_RETURN_VALUE(xglFreeMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglSetMemoryPriority:
+        {
+            struct_xglSetMemoryPriority *pPacket;
+            pPacket = interpret_body_as_xglSetMemoryPriority(packet);
+            replayResult = m_xglFuncs.real_xglSetMemoryPriority(remap(pPacket->mem), pPacket->priority);
+            CHECK_RETURN_VALUE(xglSetMemoryPriority);
+            break;
+        }
+        case GLV_TPI_XGL_xglMapMemory:
+        {
+            struct_xglMapMemory *pPacket;
+            pPacket = interpret_body_as_xglMapMemory(packet);
+            XGL_GPU_MEMORY handle = remap(pPacket->mem);
+            XGL_VOID* pData;
+            replayResult = m_xglFuncs.real_xglMapMemory(handle, pPacket->flags, &pData);
+            if (replayResult == XGL_SUCCESS)
+               add_mapping_to_mapData(handle, pData);
+            CHECK_RETURN_VALUE(xglMapMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglUnmapMemory:
+        {
+            struct_xglUnmapMemory *pPacket;
+            pPacket = interpret_body_as_xglUnmapMemory(packet);
+            XGL_GPU_MEMORY handle = remap(pPacket->mem);
+            rm_mapping_from_mapData(handle, pPacket->pData);  // copies data from packet into memory buffer
+            replayResult = m_xglFuncs.real_xglUnmapMemory(handle);
+            CHECK_RETURN_VALUE(xglUnmapMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglPinSystemMemory:
+        {
+            struct_xglPinSystemMemory *pPacket;
+            pPacket = interpret_body_as_xglPinSystemMemory(packet);
+            XGL_GPU_MEMORY memHandle;
+            replayResult = m_xglFuncs.real_xglPinSystemMemory(remap(pPacket->device), pPacket->pSysMem, pPacket->memSize, &memHandle);
+            if (replayResult == XGL_SUCCESS)
+                add_to_map(pPacket->pMem, &memHandle);
+            CHECK_RETURN_VALUE(xglPinSystemMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglRemapVirtualMemoryPages:
+        {
+            struct_xglRemapVirtualMemoryPages *pPacket;
+            pPacket = interpret_body_as_xglRemapVirtualMemoryPages(packet);
+            XGL_VIRTUAL_MEMORY_REMAP_RANGE *pRemappedRanges = GLV_NEW_ARRAY( XGL_VIRTUAL_MEMORY_REMAP_RANGE, pPacket->rangeCount);
+            for (XGL_UINT i = 0; i < pPacket->rangeCount; i++)
+            {
+                copy_mem_remap_range_struct(pRemappedRanges + i, (pPacket->pRanges + i));
+            }
+            XGL_QUEUE_SEMAPHORE *pRemappedPreSema = GLV_NEW_ARRAY(XGL_QUEUE_SEMAPHORE, pPacket->preWaitSemaphoreCount);
+            for (XGL_UINT i = 0; i < pPacket->preWaitSemaphoreCount; i++)
+            {
+                *(pRemappedPreSema + i) = *(pPacket->pPreWaitSemaphores + i);
+            }
+            XGL_QUEUE_SEMAPHORE *pRemappedPostSema = GLV_NEW_ARRAY(XGL_QUEUE_SEMAPHORE, pPacket->postSignalSemaphoreCount);
+            for (XGL_UINT i = 0; i < pPacket->postSignalSemaphoreCount; i++)
+            {
+                *(pRemappedPostSema + i) = *(pPacket->pPostSignalSemaphores + i);
+            }
+            replayResult = m_xglFuncs.real_xglRemapVirtualMemoryPages(remap(pPacket->device), pPacket->rangeCount, pRemappedRanges, pPacket->preWaitSemaphoreCount,
+                                                     pPacket->pPreWaitSemaphores, pPacket->postSignalSemaphoreCount, pPacket->pPostSignalSemaphores);
+            GLV_DELETE(pRemappedRanges);
+            GLV_DELETE(pRemappedPreSema);
+            GLV_DELETE(pRemappedPostSema);
+            CHECK_RETURN_VALUE(xglRemapVirtualMemoryPages);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetMultiGpuCompatibility:
+        {
+            struct_xglGetMultiGpuCompatibility *pPacket;
+            XGL_GPU_COMPATIBILITY_INFO cInfo;
+            XGL_PHYSICAL_GPU handle0, handle1;
+            pPacket = interpret_body_as_xglGetMultiGpuCompatibility(packet);
+            handle0 = remap(pPacket->gpu0);
+            handle1 = remap(pPacket->gpu1);
+            replayResult = m_xglFuncs.real_xglGetMultiGpuCompatibility(handle0, handle1, &cInfo);
+            CHECK_RETURN_VALUE(xglGetMultiGpuCompatibility);
+            break;
+        }
+        case GLV_TPI_XGL_xglOpenSharedMemory:
+        {
+            struct_xglOpenSharedMemory *pPacket;
+            XGL_DEVICE handle;
+            XGL_GPU_MEMORY mem;
+            pPacket = interpret_body_as_xglOpenSharedMemory(packet);
+            handle = remap(pPacket->device);
+            replayResult = m_xglFuncs.real_xglOpenSharedMemory(handle, pPacket->pOpenInfo, &mem);
+            CHECK_RETURN_VALUE(xglOpenSharedMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglOpenSharedQueueSemaphore:
+        {
+            struct_xglOpenSharedQueueSemaphore *pPacket;
+            XGL_DEVICE handle;
+            XGL_QUEUE_SEMAPHORE sema;
+            pPacket = interpret_body_as_xglOpenSharedQueueSemaphore(packet);
+            handle = remap(pPacket->device);
+            replayResult = m_xglFuncs.real_xglOpenSharedQueueSemaphore(handle, pPacket->pOpenInfo, &sema);
+            CHECK_RETURN_VALUE(xglOpenSharedQueueSemaphore);
+            break;
+        }
+        case GLV_TPI_XGL_xglOpenPeerMemory:
+        {
+            struct_xglOpenPeerMemory *pPacket;
+            XGL_DEVICE handle;
+            XGL_GPU_MEMORY mem;
+            pPacket = interpret_body_as_xglOpenPeerMemory(packet);
+            handle = remap(pPacket->device);
+            replayResult = m_xglFuncs.real_xglOpenPeerMemory(handle, pPacket->pOpenInfo, &mem);
+            CHECK_RETURN_VALUE(xglOpenPeerMemory);
+            break;
+        }
+        case GLV_TPI_XGL_xglOpenPeerImage:
+        {
+            struct_xglOpenPeerImage *pPacket;
+            XGL_DEVICE handle;
+            XGL_GPU_MEMORY mem;
+            XGL_IMAGE img;
+            pPacket = interpret_body_as_xglOpenPeerImage(packet);
+            handle = remap(pPacket->device);
+            replayResult = m_xglFuncs.real_xglOpenPeerImage(handle, pPacket->pOpenInfo, &img, &mem);
+            CHECK_RETURN_VALUE(xglOpenPeerImage);
+            break;
+        }
+        case GLV_TPI_XGL_xglDestroyObject:
+        {
+            struct_xglDestroyObject *pPacket;
+            pPacket = interpret_body_as_xglDestroyObject(packet);
+            XGL_OBJECT object = remap(pPacket->object);
+            if (object != XGL_NULL_HANDLE)
+                replayResult = m_xglFuncs.real_xglDestroyObject(object);
+            if (replayResult == XGL_SUCCESS)
+                rm_from_map(pPacket->object);
+            CHECK_RETURN_VALUE(xglDestroyObject);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetObjectInfo:
+        {
+            struct_xglGetObjectInfo *pPacket;
+            pPacket = interpret_body_as_xglGetObjectInfo(packet);
+
+            XGL_SIZE size = 0;
+            void* pData = NULL;
+            if (pPacket->pData != NULL && pPacket->pDataSize != NULL)
+            {
+                size = *pPacket->pDataSize;
+                pData = glv_malloc(*pPacket->pDataSize);
+                memcpy(pData, pPacket->pData, *pPacket->pDataSize);
+            }
+            replayResult = m_xglFuncs.real_xglGetObjectInfo(remap(pPacket->object), pPacket->infoType, &size, pData);
+            if (replayResult == XGL_SUCCESS)
+            {
+                if (size != *pPacket->pDataSize && pData == NULL)
+                {
+                    glv_LogWarn("xglGetObjectInfo returned a differing data size: replay (%d bytes) vs trace (%d bytes)\n", size, *pPacket->pDataSize);
+                }
+                else if (pData != NULL && memcmp(pData, pPacket->pData, size) != 0)
+                {
+                    glv_LogWarn("xglGetObjectInfo returned differing data contents than the trace file contained.\n");
+                }
+            }
+            glv_free(pData);
+            CHECK_RETURN_VALUE(xglGetObjectInfo);
+            break;
+        }
+        case GLV_TPI_XGL_xglBindObjectMemory:
+        {
+            struct_xglBindObjectMemory *pPacket;
+            pPacket = interpret_body_as_xglBindObjectMemory(packet);
+            replayResult = m_xglFuncs.real_xglBindObjectMemory(remap(pPacket->object), remap(pPacket->mem), pPacket->offset);
+            CHECK_RETURN_VALUE(xglBindObjectInfo);
+            break;
+        }
+        case  GLV_TPI_XGL_xglCreateFence:
+        {
+            struct_xglCreateFence* pPacket = interpret_body_as_xglCreateFence(packet);
+            XGL_FENCE fence;
+            replayResult = m_xglFuncs.real_xglCreateFence(remap(pPacket->device), pPacket->pCreateInfo, &fence);
+            if (replayResult == XGL_SUCCESS)
+                add_to_map(pPacket->pFence, &fence);
+            CHECK_RETURN_VALUE(xglCreateFence);
+            break;
+        }
+        case  GLV_TPI_XGL_xglGetFenceStatus:
+        {
+            struct_xglGetFenceStatus* pPacket = interpret_body_as_xglGetFenceStatus(packet);
+            replayResult = m_xglFuncs.real_xglGetFenceStatus(remap(pPacket->fence));
+            CHECK_RETURN_VALUE(xglGetFenceStatus);
+            break;
+        }
+        case  GLV_TPI_XGL_xglWaitForFences:
+        {
+            struct_xglWaitForFences* pPacket = interpret_body_as_xglWaitForFences(packet);
+            XGL_FENCE *pFence = GLV_NEW_ARRAY(XGL_FENCE, pPacket->fenceCount);
+            for (XGL_UINT i = 0; i < pPacket->fenceCount; i++)
+            {
+                *(pFence + i) = remap(*(pPacket->pFences + i));
+            }
+            replayResult = m_xglFuncs.real_xglWaitForFences(remap(pPacket->device), pPacket->fenceCount, pFence, pPacket->waitAll, pPacket->timeout);
+            GLV_DELETE(pFence);
+            CHECK_RETURN_VALUE(xglWaitForFences);
+            break;
+        }
+        case  GLV_TPI_XGL_xglCreateQueueSemaphore:
+        {
+            struct_xglCreateQueueSemaphore* pPacket = interpret_body_as_xglCreateQueueSemaphore(packet);
+            XGL_QUEUE_SEMAPHORE sema;
+            replayResult = m_xglFuncs.real_xglCreateQueueSemaphore(remap(pPacket->device), pPacket->pCreateInfo, &sema);
+            if (replayResult == XGL_SUCCESS)
+                add_to_map(pPacket->pSemaphore, &sema);
+            CHECK_RETURN_VALUE(xglCreateQueueSemaphore);
+            break;
+        }
+        case  GLV_TPI_XGL_xglSignalQueueSemaphore:
+        {
+            struct_xglSignalQueueSemaphore* pPacket = interpret_body_as_xglSignalQueueSemaphore(packet);
+            replayResult = m_xglFuncs.real_xglSignalQueueSemaphore(remap(pPacket->queue), remap(pPacket->semaphore));
+            CHECK_RETURN_VALUE(xglSignalQueueSemaphore);
+            break;
+        }
+        case  GLV_TPI_XGL_xglWaitQueueSemaphore:
+        {
+            struct_xglWaitQueueSemaphore* pPacket = interpret_body_as_xglWaitQueueSemaphore(packet);
+            replayResult = m_xglFuncs.real_xglWaitQueueSemaphore(remap(pPacket->queue), remap(pPacket->semaphore));
+            CHECK_RETURN_VALUE(xglWaitQueueSemaphore);
+            break;
+        }
+        case  GLV_TPI_XGL_xglCreateEvent:
+        {
+            struct_xglCreateEvent* pPacket = interpret_body_as_xglCreateEvent(packet);
+            XGL_EVENT event;
+            replayResult = m_xglFuncs.real_xglCreateEvent(remap(pPacket->device), pPacket->pCreateInfo, &event);
+            if (replayResult == XGL_SUCCESS)
+                add_to_map(pPacket->pEvent, &event);
+            CHECK_RETURN_VALUE(xglCreateEvent);
+            break;
+        }
+        case  GLV_TPI_XGL_xglGetEventStatus:
+        {
+            struct_xglGetEventStatus* pPacket = interpret_body_as_xglGetEventStatus(packet);
+            replayResult = m_xglFuncs.real_xglGetEventStatus(remap(pPacket->event));
+            if (replayResult != pPacket->result)
+            {
+                glv_LogWarn("Mismatched return from xglGetEventStatus() traced result %s, replay result %s\n",
+                string_XGL_RESULT(pPacket->result), string_XGL_RESULT(replayResult));
+                returnValue = glv_replay::GLV_REPLAY_BAD_RETURN;
+            }
+
+            if (replayResult != XGL_EVENT_SET && replayResult != XGL_EVENT_RESET)
+            {
+                glv_LogWarn("xglGetEventStatus() returned failed result %s\n", string_XGL_RESULT(replayResult));
+                returnValue = glv_replay::GLV_REPLAY_CALL_ERROR;
+            }
+            break;
+        }
+        case  GLV_TPI_XGL_xglSetEvent:
+        {
+            struct_xglSetEvent* pPacket = interpret_body_as_xglSetEvent(packet);
+            replayResult = m_xglFuncs.real_xglSetEvent(remap(pPacket->event));
+            CHECK_RETURN_VALUE(xglSetEvent);
+            break;
+        }
+        case  GLV_TPI_XGL_xglResetEvent:
+        {
+            struct_xglResetEvent* pPacket = interpret_body_as_xglResetEvent(packet);
+            replayResult = m_xglFuncs.real_xglResetEvent(remap(pPacket->event));
+            CHECK_RETURN_VALUE(xglResetEvent);
+            break;
+        }
+        case  GLV_TPI_XGL_xglCreateQueryPool:
+        {
+            struct_xglCreateQueryPool* pPacket = interpret_body_as_xglCreateQueryPool(packet);
+            XGL_QUERY_POOL query;
+            replayResult = m_xglFuncs.real_xglCreateQueryPool(remap(pPacket->device), pPacket->pCreateInfo, &query);
+            if (replayResult == XGL_SUCCESS)
+                add_to_map(pPacket->pQueryPool, &query);
+            CHECK_RETURN_VALUE(xglCreateQueryPool);
+            break;
+        }
+        case  GLV_TPI_XGL_xglGetQueryPoolResults:
+        {
+            struct_xglGetQueryPoolResults* pPacket = interpret_body_as_xglGetQueryPoolResults(packet);
+            replayResult = m_xglFuncs.real_xglGetQueryPoolResults(remap(pPacket->queryPool), pPacket->startQuery, pPacket->queryCount, pPacket->pDataSize, pPacket->pData);
+            CHECK_RETURN_VALUE(xglGetQueryPoolResults);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetFormatInfo:
+        {
+            struct_xglGetFormatInfo* pPacket = interpret_body_as_xglGetFormatInfo(packet);
+            XGL_SIZE size = 0;
+            void* pData = NULL;
+            if (pPacket->pData != NULL && pPacket->pDataSize != NULL)
+            {
+                size = *pPacket->pDataSize;
+                pData = glv_malloc(*pPacket->pDataSize);
+            }
+            replayResult = m_xglFuncs.real_xglGetFormatInfo(remap(pPacket->device), pPacket->format, pPacket->infoType, &size, pData);
+            if (replayResult == XGL_SUCCESS)
+            {
+                if (size != *pPacket->pDataSize && pData == NULL)
+                {
+                    glv_LogWarn("xglGetFormatInfo returned a differing data size: replay (%d bytes) vs trace (%d bytes)\n", size, *pPacket->pDataSize);
+                }
+                else if (pData != NULL && memcmp(pData, pPacket->pData, size) != 0)
+                {
+                    glv_LogWarn("xglGetFormatInfo returned differing data contents than the trace file contained.\n");
+                }
+            }
+            glv_free(pData);
+            CHECK_RETURN_VALUE(xglGetFormatInfo);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateImage:
+        {
+            struct_xglCreateImage* pPacket = interpret_body_as_xglCreateImage(packet);
+            XGL_IMAGE image;
+            replayResult = m_xglFuncs.real_xglCreateImage(remap(pPacket->device), pPacket->pCreateInfo, &image);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pImage, &image);
+            }
+            CHECK_RETURN_VALUE(xglCreateImage);
+            break;
+        }
+        case GLV_TPI_XGL_xglGetImageSubresourceInfo:
+        {
+            struct_xglGetImageSubresourceInfo* pPacket = interpret_body_as_xglGetImageSubresourceInfo(packet);
+            XGL_SIZE size = 0;
+            void* pData = NULL;
+            if (pPacket->pData != NULL && pPacket->pDataSize != NULL)
+            {
+                size = *pPacket->pDataSize;
+                pData = glv_malloc(*pPacket->pDataSize);
+            }
+            replayResult = m_xglFuncs.real_xglGetImageSubresourceInfo(remap(pPacket->image), pPacket->pSubresource, pPacket->infoType, &size, pData);
+            if (replayResult == XGL_SUCCESS)
+            {
+                if (size != *pPacket->pDataSize && pData == NULL)
+                {
+                    glv_LogWarn("xglGetImageSubresourceInfo returned a differing data size: replay (%d bytes) vs trace (%d bytes)\n", size, *pPacket->pDataSize);
+                }
+                else if (pData != NULL && memcmp(pData, pPacket->pData, size) != 0)
+                {
+                    glv_LogWarn("xglGetImageSubresourceInfo returned differing data contents than the trace file contained.\n");
+                }
+            }
+            glv_free(pData);
+            CHECK_RETURN_VALUE(xglGetImageSubresourceInfo);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateImageView:
+        {
+            struct_xglCreateImageView* pPacket = interpret_body_as_xglCreateImageView(packet);
+            XGL_IMAGE_VIEW_CREATE_INFO createInfo;
+            memcpy(&createInfo, pPacket->pCreateInfo, sizeof(XGL_IMAGE_VIEW_CREATE_INFO));
+            createInfo.image = remap(pPacket->pCreateInfo->image);
+            XGL_IMAGE_VIEW imageView;
+            replayResult = m_xglFuncs.real_xglCreateImageView(remap(pPacket->device), &createInfo, &imageView);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pView, &imageView);
+            }
+            CHECK_RETURN_VALUE(xglCreateImageView);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateColorAttachmentView:
+        {
+            struct_xglCreateColorAttachmentView* pPacket = interpret_body_as_xglCreateColorAttachmentView(packet);
+            XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO createInfo;
+            memcpy(&createInfo, pPacket->pCreateInfo, sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO));
+            createInfo.image = remap(pPacket->pCreateInfo->image);
+            XGL_COLOR_ATTACHMENT_VIEW ColorAttachmentView;
+            replayResult = m_xglFuncs.real_xglCreateColorAttachmentView(remap(pPacket->device), &createInfo, &ColorAttachmentView);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pView, &ColorAttachmentView);
+            }
+            CHECK_RETURN_VALUE(xglCreateColorAttachmentView);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateDepthStencilView:
+        {
+            struct_xglCreateDepthStencilView* pPacket = interpret_body_as_xglCreateDepthStencilView(packet);
+            XGL_DEPTH_STENCIL_VIEW_CREATE_INFO createInfo;
+            memcpy(&createInfo, pPacket->pCreateInfo, sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO));
+            createInfo.image = remap(pPacket->pCreateInfo->image);
+            XGL_DEPTH_STENCIL_VIEW view;
+            replayResult = m_xglFuncs.real_xglCreateDepthStencilView(remap(pPacket->device), &createInfo, &view);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pView, &view);
+            }
+            CHECK_RETURN_VALUE(xglCreateDepthStencilView);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateShader:
+        {
+            struct_xglCreateShader* pPacket = interpret_body_as_xglCreateShader(packet);
+            XGL_SHADER shader;
+            replayResult = m_xglFuncs.real_xglCreateShader(remap(pPacket->device), pPacket->pCreateInfo, &shader);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pShader, &shader);
+            }
+            CHECK_RETURN_VALUE(xglCreateShader);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateGraphicsPipeline:
+        {
+            struct_xglCreateGraphicsPipeline* pPacket = interpret_body_as_xglCreateGraphicsPipeline(packet);
+            XGL_GRAPHICS_PIPELINE_CREATE_INFO createInfo;
+            memcpy(&createInfo, pPacket->pCreateInfo, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO));
+            // Cast to shader type, as those are of primariy interest and all structs in LL have same header w/ sType & pNext
+            XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pPacketNext = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pPacket->pCreateInfo->pNext;
+            XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pNext = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)createInfo.pNext;
+            while ((NULL != pPacketNext) && (XGL_NULL_HANDLE != pPacketNext)) // TODO : Shouldn't need both of these checks
+            {
+                if (XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO == pNext->sType)
+                    pNext->shader.shader = remap(pPacketNext->shader.shader);
+                // TODO : Do we need to do anything here for non-shader blocks?
+                pPacketNext = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pPacketNext->pNext;
+                pNext = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pNext->pNext;
+            }
+            XGL_PIPELINE pipeline;
+            replayResult = m_xglFuncs.real_xglCreateGraphicsPipeline(remap(pPacket->device), &createInfo, &pipeline);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pPipeline, &pipeline);
+            }
+            CHECK_RETURN_VALUE(xglCreateGraphicsPipeline);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateComputePipeline:
+        {
+            struct_xglCreateComputePipeline* pPacket = interpret_body_as_xglCreateComputePipeline(packet);
+            XGL_COMPUTE_PIPELINE_CREATE_INFO createInfo;
+            memcpy(&createInfo, pPacket->pCreateInfo, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO));
+            createInfo.cs.shader = remap(pPacket->pCreateInfo->cs.shader);
+            XGL_PIPELINE pipeline;
+            replayResult = m_xglFuncs.real_xglCreateComputePipeline(remap(pPacket->device), &createInfo, &pipeline);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pPipeline, &pipeline);
+            }
+            CHECK_RETURN_VALUE(xglCreateComputePipeline);
+            break;
+        }
+        case GLV_TPI_XGL_xglStorePipeline:
+        {
+            struct_xglStorePipeline* pPacket = interpret_body_as_xglStorePipeline(packet);
+            XGL_SIZE size = 0;
+            void* pData = NULL;
+            if (pPacket->pData != NULL && pPacket->pDataSize != NULL)
+            {
+                size = *pPacket->pDataSize;
+                pData = glv_malloc(*pPacket->pDataSize);
+            }
+            replayResult = m_xglFuncs.real_xglStorePipeline(remap(pPacket->pipeline), &size, pData);
+            if (replayResult == XGL_SUCCESS)
+            {
+                if (size != *pPacket->pDataSize && pData == NULL)
+                {
+                    glv_LogWarn("xglStorePipeline returned a differing data size: replay (%d bytes) vs trace (%d bytes)\n", size, *pPacket->pDataSize);
+                }
+                else if (pData != NULL && memcmp(pData, pPacket->pData, size) != 0)
+                {
+                    glv_LogWarn("xglStorePipeline returned differing data contents than the trace file contained.\n");
+                }
+            }
+            glv_free(pData);
+            CHECK_RETURN_VALUE(xglStorePipeline);
+            break;
+        }
+        case GLV_TPI_XGL_xglLoadPipeline:
+        {
+            struct_xglLoadPipeline* pPacket = interpret_body_as_xglLoadPipeline(packet);
+            XGL_PIPELINE pipeline;
+            replayResult = m_xglFuncs.real_xglLoadPipeline(remap(pPacket->device), pPacket->dataSize, pPacket->pData, &pipeline);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pPipeline, &pipeline);
+            }
+            CHECK_RETURN_VALUE(xglLoadPipeline);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreatePipelineDelta:
+        {
+            struct_xglCreatePipelineDelta* pPacket = interpret_body_as_xglCreatePipelineDelta(packet);
+            XGL_PIPELINE_DELTA pipeline;
+            replayResult = m_xglFuncs.real_xglCreatePipelineDelta(remap(pPacket->device), pPacket->p1, pPacket->p2, &pipeline);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->delta, &pipeline);
+            }
+            CHECK_RETURN_VALUE(xglCreatePipelineDelta);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateSampler:
+        {
+            struct_xglCreateSampler* pPacket = interpret_body_as_xglCreateSampler(packet);
+            XGL_SAMPLER sampler;
+            replayResult = m_xglFuncs.real_xglCreateSampler(remap(pPacket->device), pPacket->pCreateInfo, &sampler);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pSampler, &sampler);
+            }
+            CHECK_RETURN_VALUE(xglCreateSampler);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateDescriptorSet:
+        {
+            struct_xglCreateDescriptorSet* pPacket = interpret_body_as_xglCreateDescriptorSet(packet);
+            XGL_DESCRIPTOR_SET descriptorSet;
+            replayResult = m_xglFuncs.real_xglCreateDescriptorSet(remap(pPacket->device), pPacket->pCreateInfo, &descriptorSet);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pDescriptorSet, &descriptorSet);
+            }
+            CHECK_RETURN_VALUE(xglCreateDescriptorSet);
+            break;
+        }
+        case GLV_TPI_XGL_xglBeginDescriptorSetUpdate:
+        {
+            struct_xglBeginDescriptorSetUpdate* pPacket = interpret_body_as_xglBeginDescriptorSetUpdate(packet);
+             m_xglFuncs.real_xglBeginDescriptorSetUpdate(remap(pPacket->descriptorSet));
+            break;
+        }
+        case GLV_TPI_XGL_xglEndDescriptorSetUpdate:
+        {
+            struct_xglEndDescriptorSetUpdate* pPacket = interpret_body_as_xglEndDescriptorSetUpdate(packet);
+             m_xglFuncs.real_xglEndDescriptorSetUpdate(remap(pPacket->descriptorSet));
+            break;
+        }
+        case GLV_TPI_XGL_xglAttachSamplerDescriptors:
+        {
+            struct_xglAttachSamplerDescriptors* pPacket = interpret_body_as_xglAttachSamplerDescriptors(packet);
+            XGL_SAMPLER* pSamplers = GLV_NEW_ARRAY(XGL_SAMPLER, pPacket->slotCount);
+            memcpy(pSamplers, pPacket->pSamplers, pPacket->slotCount * sizeof(XGL_SAMPLER));
+            for (XGL_UINT i = 0; i < pPacket->slotCount; i++)
+            {
+                pSamplers[i] = remap(pPacket->pSamplers[i]);
+            }
+             m_xglFuncs.real_xglAttachSamplerDescriptors(remap(pPacket->descriptorSet), pPacket->startSlot, pPacket->slotCount, pSamplers);
+            GLV_DELETE(pSamplers);
+            break;
+        }
+        case GLV_TPI_XGL_xglAttachImageViewDescriptors:
+        {
+            struct_xglAttachImageViewDescriptors* pPacket = interpret_body_as_xglAttachImageViewDescriptors(packet);
+            XGL_IMAGE_VIEW_ATTACH_INFO* pImageViews = GLV_NEW_ARRAY(XGL_IMAGE_VIEW_ATTACH_INFO, pPacket->slotCount);
+            memcpy(pImageViews, pPacket->pImageViews, pPacket->slotCount * sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
+            for (XGL_UINT i = 0; i < pPacket->slotCount; i++)
+            {
+                pImageViews[i].view = remap(pPacket->pImageViews[i].view);
+            }
+             m_xglFuncs.real_xglAttachImageViewDescriptors(remap(pPacket->descriptorSet), pPacket->startSlot, pPacket->slotCount, pImageViews);
+            GLV_DELETE(pImageViews);
+            break;
+        }
+        case GLV_TPI_XGL_xglAttachMemoryViewDescriptors:
+        {
+            struct_xglAttachMemoryViewDescriptors* pPacket = interpret_body_as_xglAttachMemoryViewDescriptors(packet);
+            XGL_MEMORY_VIEW_ATTACH_INFO* pMemViews = GLV_NEW_ARRAY(XGL_MEMORY_VIEW_ATTACH_INFO, pPacket->slotCount);
+            memcpy(pMemViews, pPacket->pMemViews, pPacket->slotCount * sizeof(XGL_MEMORY_VIEW_ATTACH_INFO));
+            for (XGL_UINT i = 0; i < pPacket->slotCount; i++)
+            {
+                pMemViews[i].mem = remap(pPacket->pMemViews[i].mem);
+            }
+             m_xglFuncs.real_xglAttachMemoryViewDescriptors(remap(pPacket->descriptorSet), pPacket->startSlot, pPacket->slotCount, pMemViews);
+            GLV_DELETE(pMemViews);
+            break;
+        }
+        case GLV_TPI_XGL_xglAttachNestedDescriptors:
+        {
+            struct_xglAttachNestedDescriptors* pPacket = interpret_body_as_xglAttachNestedDescriptors(packet);
+            XGL_DESCRIPTOR_SET_ATTACH_INFO* pNestedDescriptorSets = GLV_NEW_ARRAY(XGL_DESCRIPTOR_SET_ATTACH_INFO, pPacket->slotCount);
+            memcpy(pNestedDescriptorSets, pPacket->pNestedDescriptorSets, pPacket->slotCount * sizeof(XGL_DESCRIPTOR_SET_ATTACH_INFO));
+            for (XGL_UINT i = 0; i < pPacket->slotCount; i++)
+            {
+                pNestedDescriptorSets[i].descriptorSet = remap(pPacket->pNestedDescriptorSets[i].descriptorSet);
+            }
+             m_xglFuncs.real_xglAttachNestedDescriptors(remap(pPacket->descriptorSet), pPacket->startSlot, pPacket->slotCount, pNestedDescriptorSets);
+            GLV_DELETE(pNestedDescriptorSets);
+            break;
+        }
+        case GLV_TPI_XGL_xglClearDescriptorSetSlots:
+        {
+            struct_xglClearDescriptorSetSlots* pPacket = interpret_body_as_xglClearDescriptorSetSlots(packet);
+             m_xglFuncs.real_xglClearDescriptorSetSlots(remap(pPacket->descriptorSet), pPacket->startSlot, pPacket->slotCount);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateViewportState:
+        {
+            struct_xglCreateViewportState* pPacket = interpret_body_as_xglCreateViewportState(packet);
+            XGL_VIEWPORT_STATE_OBJECT state;
+            replayResult = m_xglFuncs.real_xglCreateViewportState(remap(pPacket->device), pPacket->pCreateInfo, &state);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pState, &state);
+            }
+            CHECK_RETURN_VALUE(xglCreateViewportState);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateRasterState:
+        {
+            struct_xglCreateRasterState* pPacket = interpret_body_as_xglCreateRasterState(packet);
+            XGL_RASTER_STATE_OBJECT state;
+            replayResult = m_xglFuncs.real_xglCreateRasterState(remap(pPacket->device), pPacket->pCreateInfo, &state);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pState, &state);
+            }
+            CHECK_RETURN_VALUE(xglCreateRasterState);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateMsaaState:
+        {
+            struct_xglCreateMsaaState* pPacket = interpret_body_as_xglCreateMsaaState(packet);
+            XGL_MSAA_STATE_OBJECT state;
+            replayResult = m_xglFuncs.real_xglCreateMsaaState(remap(pPacket->device), pPacket->pCreateInfo, &state);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pState, &state);
+            }
+            CHECK_RETURN_VALUE(xglCreateMsaaState);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateColorBlendState:
+        {
+            struct_xglCreateColorBlendState* pPacket = interpret_body_as_xglCreateColorBlendState(packet);
+            XGL_COLOR_BLEND_STATE_OBJECT state;
+            replayResult = m_xglFuncs.real_xglCreateColorBlendState(remap(pPacket->device), pPacket->pCreateInfo, &state);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pState, &state);
+            }
+            CHECK_RETURN_VALUE(xglCreateColorBlendState);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateDepthStencilState:
+        {
+            struct_xglCreateDepthStencilState* pPacket = interpret_body_as_xglCreateDepthStencilState(packet);
+            XGL_DEPTH_STENCIL_STATE_OBJECT state;
+            replayResult = m_xglFuncs.real_xglCreateDepthStencilState(remap(pPacket->device), pPacket->pCreateInfo, &state);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pState, &state);
+            }
+            CHECK_RETURN_VALUE(xglCreateDepthStencilState);
+            break;
+        }
+        case GLV_TPI_XGL_xglCreateCommandBuffer:
+        {
+            struct_xglCreateCommandBuffer* pPacket = interpret_body_as_xglCreateCommandBuffer(packet);
+            XGL_CMD_BUFFER cmdBuffer;
+            replayResult = m_xglFuncs.real_xglCreateCommandBuffer(remap(pPacket->device), pPacket->pCreateInfo, &cmdBuffer);
+            if (replayResult == XGL_SUCCESS)
+            {
+                add_to_map(pPacket->pCmdBuffer, &cmdBuffer);
+            }
+            CHECK_RETURN_VALUE(xglCreateCommandBuffer);
+            break;
+        }
+        case GLV_TPI_XGL_xglBeginCommandBuffer:
+        {
+            struct_xglBeginCommandBuffer* pPacket = interpret_body_as_xglBeginCommandBuffer(packet);
+            replayResult = m_xglFuncs.real_xglBeginCommandBuffer(remap(pPacket->cmdBuffer), pPacket->flags);
+            CHECK_RETURN_VALUE(xglBeginCommandBuffer);
+            break;
+        }
+        case GLV_TPI_XGL_xglEndCommandBuffer:
+        {
+            struct_xglEndCommandBuffer* pPacket = interpret_body_as_xglEndCommandBuffer(packet);
+            replayResult = m_xglFuncs.real_xglEndCommandBuffer(remap(pPacket->cmdBuffer));
+            CHECK_RETURN_VALUE(xglEndCommandBuffer);
+            break;
+        }
+        case GLV_TPI_XGL_xglResetCommandBuffer:
+        {
+            struct_xglResetCommandBuffer* pPacket = interpret_body_as_xglResetCommandBuffer(packet);
+            replayResult = m_xglFuncs.real_xglResetCommandBuffer(remap(pPacket->cmdBuffer));
+            CHECK_RETURN_VALUE(xglResetCommandBuffer);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindPipeline:
+        {
+            struct_xglCmdBindPipeline* pPacket = interpret_body_as_xglCmdBindPipeline(packet);
+            m_xglFuncs.real_xglCmdBindPipeline(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, remap(pPacket->pipeline));
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindPipelineDelta:
+        {
+            struct_xglCmdBindPipelineDelta* pPacket = interpret_body_as_xglCmdBindPipelineDelta(packet);
+            m_xglFuncs.real_xglCmdBindPipelineDelta(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, remap(pPacket->delta));
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindStateObject:
+        {
+            struct_xglCmdBindStateObject* pPacket = interpret_body_as_xglCmdBindStateObject(packet);
+             m_xglFuncs.real_xglCmdBindStateObject(remap(pPacket->cmdBuffer), pPacket->stateBindPoint, remap(pPacket->state));
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindDescriptorSet:
+        {
+            struct_xglCmdBindDescriptorSet* pPacket = interpret_body_as_xglCmdBindDescriptorSet(packet);
+             m_xglFuncs.real_xglCmdBindDescriptorSet(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, pPacket->index, remap(pPacket->descriptorSet), pPacket->slotOffset);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindDynamicMemoryView:
+        {
+            struct_xglCmdBindDynamicMemoryView* pPacket = interpret_body_as_xglCmdBindDynamicMemoryView(packet);
+            XGL_MEMORY_VIEW_ATTACH_INFO memView;
+            memcpy(&memView, pPacket->pMemView, sizeof(XGL_MEMORY_VIEW_ATTACH_INFO));
+            memView.mem = remap(pPacket->pMemView->mem);
+             m_xglFuncs.real_xglCmdBindDynamicMemoryView(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, &memView);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindIndexData:
+        {
+            struct_xglCmdBindIndexData* pPacket = interpret_body_as_xglCmdBindIndexData(packet);
+             m_xglFuncs.real_xglCmdBindIndexData(remap(pPacket->cmdBuffer), remap(pPacket->mem), pPacket->offset, pPacket->indexType);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBindAttachments:
+        {
+            struct_xglCmdBindAttachments* pPacket = interpret_body_as_xglCmdBindAttachments(packet);
+            // adjust color targets
+            XGL_COLOR_ATTACHMENT_BIND_INFO* pColorAttachments = (XGL_COLOR_ATTACHMENT_BIND_INFO*)pPacket->pColorAttachments;
+            bool allocatedColorAttachments = false;
+            if (pColorAttachments != NULL)
+            {
+                allocatedColorAttachments = true;
+                pColorAttachments = GLV_NEW_ARRAY(XGL_COLOR_ATTACHMENT_BIND_INFO, pPacket->colorAttachmentCount);
+                memcpy(pColorAttachments, pPacket->pColorAttachments, sizeof(XGL_COLOR_ATTACHMENT_BIND_INFO) * pPacket->colorAttachmentCount);
+                for (XGL_UINT i = 0; i < pPacket->colorAttachmentCount; i++)
+                {
+                    pColorAttachments[i].view = remap(pPacket->pColorAttachments[i].view);
+                }
+            }
+
+            // adjust depth stencil target
+            const XGL_DEPTH_STENCIL_BIND_INFO* pDepthAttachment = pPacket->pDepthAttachment;
+            XGL_DEPTH_STENCIL_BIND_INFO depthTarget;
+            if (pDepthAttachment != NULL)
+            {
+                memcpy(&depthTarget, pPacket->pDepthAttachment, sizeof(XGL_DEPTH_STENCIL_BIND_INFO));
+                depthTarget.view = remap(pPacket->pDepthAttachment->view);
+                pDepthAttachment = &depthTarget;
+            }
+
+            // make call
+             m_xglFuncs.real_xglCmdBindAttachments(remap(pPacket->cmdBuffer), pPacket->colorAttachmentCount, pColorAttachments, pDepthAttachment);
+
+            // cleanup
+            if (allocatedColorAttachments)
+            {
+                GLV_DELETE((void*)pColorAttachments);
+            }
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdPrepareMemoryRegions:
+        {
+            struct_xglCmdPrepareMemoryRegions* pPacket = interpret_body_as_xglCmdPrepareMemoryRegions(packet);
+            // adjust transitions
+            XGL_MEMORY_STATE_TRANSITION* pStateTransitions = (XGL_MEMORY_STATE_TRANSITION*)pPacket->pStateTransitions;
+            bool allocatedMem = false;
+            if (pStateTransitions != NULL)
+            {
+                allocatedMem = true;
+                pStateTransitions = GLV_NEW_ARRAY(XGL_MEMORY_STATE_TRANSITION, pPacket->transitionCount);
+                memcpy(pStateTransitions, pPacket->pStateTransitions, sizeof(XGL_MEMORY_STATE_TRANSITION) * pPacket->transitionCount);
+                for (XGL_UINT i = 0; i < pPacket->transitionCount; i++)
+                {
+                    pStateTransitions[i].mem = remap(pPacket->pStateTransitions[i].mem);
+                }
+            }
+
+             m_xglFuncs.real_xglCmdPrepareMemoryRegions(remap(pPacket->cmdBuffer), pPacket->transitionCount, pStateTransitions);
+
+            // cleanup
+            if (allocatedMem)
+            {
+                GLV_DELETE((void*)pStateTransitions);
+            }
+
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdPrepareImages:
+        {
+            struct_xglCmdPrepareImages* pPacket = interpret_body_as_xglCmdPrepareImages(packet);
+
+            // adjust transitions
+            XGL_IMAGE_STATE_TRANSITION* pStateTransitions = (XGL_IMAGE_STATE_TRANSITION*)pPacket->pStateTransitions;
+            bool allocatedMem = false;
+            if (pStateTransitions != NULL)
+            {
+                allocatedMem = true;
+                pStateTransitions = GLV_NEW_ARRAY(XGL_IMAGE_STATE_TRANSITION, pPacket->transitionCount);
+                memcpy(pStateTransitions, pPacket->pStateTransitions, sizeof(XGL_IMAGE_STATE_TRANSITION) * pPacket->transitionCount);
+                for (XGL_UINT i = 0; i < pPacket->transitionCount; i++)
+                {
+                    pStateTransitions[i].image = remap(pPacket->pStateTransitions[i].image);
+                }
+            }
+
+             m_xglFuncs.real_xglCmdPrepareImages(remap(pPacket->cmdBuffer), pPacket->transitionCount, pStateTransitions);
+
+            // cleanup
+            if (allocatedMem)
+            {
+                GLV_DELETE((void*)pStateTransitions);
+            }
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdDraw:
+        {
+            struct_xglCmdDraw* pPacket = interpret_body_as_xglCmdDraw(packet);
+             m_xglFuncs.real_xglCmdDraw(remap(pPacket->cmdBuffer), pPacket->firstVertex, pPacket->vertexCount, pPacket->firstInstance, pPacket->instanceCount);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdDrawIndexed:
+        {
+            struct_xglCmdDrawIndexed* pPacket = interpret_body_as_xglCmdDrawIndexed(packet);
+             m_xglFuncs.real_xglCmdDrawIndexed(remap(pPacket->cmdBuffer), pPacket->firstIndex, pPacket->indexCount, pPacket->vertexOffset, pPacket->firstInstance, pPacket->instanceCount);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdDrawIndirect:
+        {
+            struct_xglCmdDrawIndirect* pPacket = interpret_body_as_xglCmdDrawIndirect(packet);
+             m_xglFuncs.real_xglCmdDrawIndirect(remap(pPacket->cmdBuffer), remap(pPacket->mem), pPacket->offset, pPacket->count, pPacket->stride);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdDrawIndexedIndirect:
+        {
+            struct_xglCmdDrawIndexedIndirect* pPacket = interpret_body_as_xglCmdDrawIndexedIndirect(packet);
+             m_xglFuncs.real_xglCmdDrawIndexedIndirect(remap(pPacket->cmdBuffer), remap(pPacket->mem), pPacket->offset, pPacket->count, pPacket->stride);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdDispatch:
+        {
+            struct_xglCmdDispatch* pPacket = interpret_body_as_xglCmdDispatch(packet);
+             m_xglFuncs.real_xglCmdDispatch(remap(pPacket->cmdBuffer), pPacket->x, pPacket->y, pPacket->z);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdDispatchIndirect:
+        {
+            struct_xglCmdDispatchIndirect* pPacket = interpret_body_as_xglCmdDispatchIndirect(packet);
+             m_xglFuncs.real_xglCmdDispatchIndirect(remap(pPacket->cmdBuffer), remap(pPacket->mem), pPacket->offset);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdCopyMemory:
+        {
+            struct_xglCmdCopyMemory* pPacket = interpret_body_as_xglCmdCopyMemory(packet);
+             m_xglFuncs.real_xglCmdCopyMemory(remap(pPacket->cmdBuffer), remap(pPacket->srcMem), remap(pPacket->destMem), pPacket->regionCount, pPacket->pRegions);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdCopyImage:
+        {
+            struct_xglCmdCopyImage* pPacket = interpret_body_as_xglCmdCopyImage(packet);
+             m_xglFuncs.real_xglCmdCopyImage(remap(pPacket->cmdBuffer), remap(pPacket->srcImage), remap(pPacket->destImage), pPacket->regionCount, pPacket->pRegions);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdCopyMemoryToImage:
+        {
+            struct_xglCmdCopyMemoryToImage* pPacket = interpret_body_as_xglCmdCopyMemoryToImage(packet);
+             m_xglFuncs.real_xglCmdCopyMemoryToImage(remap(pPacket->cmdBuffer), remap(pPacket->srcMem), remap(pPacket->destImage), pPacket->regionCount, pPacket->pRegions);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdCopyImageToMemory:
+        {
+            struct_xglCmdCopyImageToMemory* pPacket = interpret_body_as_xglCmdCopyImageToMemory(packet);
+             m_xglFuncs.real_xglCmdCopyImageToMemory(remap(pPacket->cmdBuffer), remap(pPacket->srcImage), remap(pPacket->destMem), pPacket->regionCount, pPacket->pRegions);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdCloneImageData:
+        {
+            struct_xglCmdCloneImageData* pPacket = interpret_body_as_xglCmdCloneImageData(packet);
+             m_xglFuncs.real_xglCmdCloneImageData(remap(pPacket->cmdBuffer), remap(pPacket->srcImage), pPacket->srcImageState, remap(pPacket->destImage), pPacket->destImageState);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdUpdateMemory:
+        {
+            struct_xglCmdUpdateMemory* pPacket = interpret_body_as_xglCmdUpdateMemory(packet);
+             m_xglFuncs.real_xglCmdUpdateMemory(remap(pPacket->cmdBuffer), remap(pPacket->destMem), pPacket->destOffset, pPacket->dataSize, pPacket->pData);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdFillMemory:
+        {
+            struct_xglCmdFillMemory* pPacket = interpret_body_as_xglCmdFillMemory(packet);
+             m_xglFuncs.real_xglCmdFillMemory(remap(pPacket->cmdBuffer), remap(pPacket->destMem), pPacket->destOffset, pPacket->fillSize, pPacket->data);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdClearColorImage:
+        {
+            struct_xglCmdClearColorImage* pPacket = interpret_body_as_xglCmdClearColorImage(packet);
+             m_xglFuncs.real_xglCmdClearColorImage(remap(pPacket->cmdBuffer), remap(pPacket->image), pPacket->color, pPacket->rangeCount, pPacket->pRanges);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdClearColorImageRaw:
+        {
+            struct_xglCmdClearColorImageRaw* pPacket = interpret_body_as_xglCmdClearColorImageRaw(packet);
+             m_xglFuncs.real_xglCmdClearColorImageRaw(remap(pPacket->cmdBuffer), remap(pPacket->image), pPacket->color, pPacket->rangeCount, pPacket->pRanges);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdClearDepthStencil:
+        {
+            struct_xglCmdClearDepthStencil* pPacket = interpret_body_as_xglCmdClearDepthStencil(packet);
+             m_xglFuncs.real_xglCmdClearDepthStencil(remap(pPacket->cmdBuffer), remap(pPacket->image), pPacket->depth, pPacket->stencil, pPacket->rangeCount, pPacket->pRanges);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdResolveImage:
+        {
+            struct_xglCmdResolveImage* pPacket = interpret_body_as_xglCmdResolveImage(packet);
+             m_xglFuncs.real_xglCmdResolveImage(remap(pPacket->cmdBuffer), remap(pPacket->srcImage), remap(pPacket->destImage), pPacket->rectCount, pPacket->pRects);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdSetEvent:
+        {
+            struct_xglCmdSetEvent* pPacket = interpret_body_as_xglCmdSetEvent(packet);
+             m_xglFuncs.real_xglCmdSetEvent(remap(pPacket->cmdBuffer), remap(pPacket->event));
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdResetEvent:
+        {
+            struct_xglCmdResetEvent* pPacket = interpret_body_as_xglCmdResetEvent(packet);
+             m_xglFuncs.real_xglCmdResetEvent(remap(pPacket->cmdBuffer), remap(pPacket->event));
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdMemoryAtomic:
+        {
+            struct_xglCmdMemoryAtomic* pPacket = interpret_body_as_xglCmdMemoryAtomic(packet);
+             m_xglFuncs.real_xglCmdMemoryAtomic(remap(pPacket->cmdBuffer), remap(pPacket->destMem), pPacket->destOffset, pPacket->srcData, pPacket->atomicOp);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdBeginQuery:
+        {
+            struct_xglCmdBeginQuery* pPacket = interpret_body_as_xglCmdBeginQuery(packet);
+             m_xglFuncs.real_xglCmdBeginQuery(remap(pPacket->cmdBuffer), remap(pPacket->queryPool), pPacket->slot, pPacket->flags);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdEndQuery:
+        {
+            struct_xglCmdEndQuery* pPacket = interpret_body_as_xglCmdEndQuery(packet);
+             m_xglFuncs.real_xglCmdEndQuery(remap(pPacket->cmdBuffer), remap(pPacket->queryPool), pPacket->slot);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdResetQueryPool:
+        {
+            struct_xglCmdResetQueryPool* pPacket = interpret_body_as_xglCmdResetQueryPool(packet);
+             m_xglFuncs.real_xglCmdResetQueryPool(remap(pPacket->cmdBuffer), remap(pPacket->queryPool), pPacket->startQuery, pPacket->queryCount);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdWriteTimestamp:
+        {
+            struct_xglCmdWriteTimestamp* pPacket = interpret_body_as_xglCmdWriteTimestamp(packet);
+             m_xglFuncs.real_xglCmdWriteTimestamp(remap(pPacket->cmdBuffer), pPacket->timestampType, remap(pPacket->destMem), pPacket->destOffset);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdInitAtomicCounters:
+        {
+            struct_xglCmdInitAtomicCounters* pPacket = interpret_body_as_xglCmdInitAtomicCounters(packet);
+             m_xglFuncs.real_xglCmdInitAtomicCounters(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, pPacket->startCounter, pPacket->counterCount, pPacket->pData);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdLoadAtomicCounters:
+        {
+            struct_xglCmdLoadAtomicCounters* pPacket = interpret_body_as_xglCmdLoadAtomicCounters(packet);
+             m_xglFuncs.real_xglCmdLoadAtomicCounters(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, pPacket->startCounter, pPacket->counterCount, pPacket->srcMem, pPacket->srcOffset);
+            break;
+        }
+        case GLV_TPI_XGL_xglCmdSaveAtomicCounters:
+        {
+            struct_xglCmdSaveAtomicCounters* pPacket = interpret_body_as_xglCmdSaveAtomicCounters(packet);
+             m_xglFuncs.real_xglCmdSaveAtomicCounters(remap(pPacket->cmdBuffer), pPacket->pipelineBindPoint, pPacket->startCounter, pPacket->counterCount, remap(pPacket->destMem), pPacket->destOffset);
+            break;
+        }
+
+        // xglDbg.h functions
+        case GLV_TPI_XGL_xglDbgSetValidationLevel:
+        {
+		struct_xglDbgSetValidationLevel *pPacket = interpret_body_as_xglDbgSetValidationLevel(packet);
+		replayResult = m_xglFuncs.real_xglDbgSetValidationLevel(remap(pPacket->device), pPacket->validationLevel);
+		CHECK_RETURN_VALUE(xglDbgSetValidationLevel);
+		break;
+        }
+        case GLV_TPI_XGL_xglDbgRegisterMsgCallback:
+        {
+		struct_xglDbgRegisterMsgCallback *pPacket = interpret_body_as_xglDbgRegisterMsgCallback(packet);
+		// just pass NULL since don't have replay pointer to app data
+		replayResult = m_xglFuncs.real_xglDbgRegisterMsgCallback(pPacket->pfnMsgCallback, NULL);
+		CHECK_RETURN_VALUE(xglDbgRegisterMsgCallback);
+		break;
+        }
+        case GLV_TPI_XGL_xglDbgUnregisterMsgCallback:
+        {
+		struct_xglDbgUnregisterMsgCallback *pPacket = interpret_body_as_xglDbgUnregisterMsgCallback(packet);
+		replayResult = m_xglFuncs.real_xglDbgUnregisterMsgCallback(pPacket->pfnMsgCallback);
+		CHECK_RETURN_VALUE(xglDbgUnregisterMsgCallback);
+		break;
+        }
+        case GLV_TPI_XGL_xglDbgSetMessageFilter:
+        {
+		struct_xglDbgSetMessageFilter *pPacket = interpret_body_as_xglDbgSetMessageFilter(packet);
+		replayResult = m_xglFuncs.real_xglDbgSetMessageFilter(remap(pPacket->device), pPacket->msgCode, pPacket->filter);
+		CHECK_RETURN_VALUE(xglDbgSetMessageFilter);
+		break;
+        }
+        case GLV_TPI_XGL_xglDbgSetObjectTag:
+        {
+		struct_xglDbgSetObjectTag *pPacket = interpret_body_as_xglDbgSetObjectTag(packet);
+		replayResult = m_xglFuncs.real_xglDbgSetObjectTag(remap(pPacket->object), pPacket->tagSize, pPacket->pTag);
+		CHECK_RETURN_VALUE(xglDbgSetObjectTag);
+		break;
+        }
+        case GLV_TPI_XGL_xglDbgSetGlobalOption:
+        {
+		struct_xglDbgSetGlobalOption *pPacket = interpret_body_as_xglDbgSetGlobalOption(packet);
+		replayResult = m_xglFuncs.real_xglDbgSetGlobalOption(pPacket->dbgOption, pPacket->dataSize, pPacket->pData);
+		CHECK_RETURN_VALUE(xglDbgSetGlobalOption);
+		break;
+        }
+        case GLV_TPI_XGL_xglDbgSetDeviceOption:
+        {
+		struct_xglDbgSetDeviceOption *pPacket = interpret_body_as_xglDbgSetDeviceOption(packet);
+		replayResult = m_xglFuncs.real_xglDbgSetDeviceOption(remap(pPacket->device), pPacket->dbgOption, pPacket->dataSize, pPacket->pData);
+		CHECK_RETURN_VALUE(xglDbgSetDeviceOption);
+		break;
+        }
+        case GLV_TPI_XGL_xglCmdDbgMarkerBegin:
+        {
+		struct_xglCmdDbgMarkerBegin *pPacket = interpret_body_as_xglCmdDbgMarkerBegin(packet);
+                m_xglFuncs.real_xglCmdDbgMarkerBegin(remap(pPacket->cmdBuffer), pPacket->pMarker);
+		break;
+        }
+        case GLV_TPI_XGL_xglCmdDbgMarkerEnd:
+        {
+		struct_xglCmdDbgMarkerEnd *pPacket = interpret_body_as_xglCmdDbgMarkerEnd(packet);
+                m_xglFuncs.real_xglCmdDbgMarkerEnd(remap(pPacket->cmdBuffer));
+		break;
+        }
+
+        // xglWsiX11Ext.h
+        case GLV_TPI_XGL_xglWsiX11AssociateConnection:
+        {
+            struct_xglWsiX11AssociateConnection *pPacket = interpret_body_as_xglWsiX11AssociateConnection(packet);
+            //associate with the replayers Wsi connection rather than tracers
+            replayResult = m_xglFuncs.real_xglWsiX11AssociateConnection(remap(pPacket->gpu), &(m_display->m_WsiConnection));
+            CHECK_RETURN_VALUE(xglWsiX11AssociateConnection);
+            break;
+        }
+        case GLV_TPI_XGL_xglWsiX11GetMSC:
+        {
+            struct_xglWsiX11GetMSC *pPacket = interpret_body_as_xglWsiX11GetMSC(packet);
+            replayResult = m_xglFuncs.real_xglWsiX11GetMSC(remap(pPacket->device), pPacket->crtc, pPacket->pMsc);
+            CHECK_RETURN_VALUE(xglWsiX11GetMSC);
+            break;
+        }
+        case GLV_TPI_XGL_xglWsiX11CreatePresentableImage:
+        {
+            struct_xglWsiX11CreatePresentableImage *pPacket = interpret_body_as_xglWsiX11CreatePresentableImage(packet);
+            XGL_IMAGE img;
+            XGL_GPU_MEMORY mem;
+            replayResult = m_xglFuncs.real_xglWsiX11CreatePresentableImage(remap(pPacket->device), pPacket->pCreateInfo, &img, &mem);
+            if (replayResult == XGL_SUCCESS)
+            {
+                if (pPacket->pImage != NULL)
+                    add_to_map(pPacket->pImage, &img);
+                if(pPacket->pMem != NULL)
+                    add_to_map(pPacket->pMem, &mem);
+            }
+            CHECK_RETURN_VALUE(xglWsiX11CreatePresentableImage);
+            break;
+        }
+        case GLV_TPI_XGL_xglWsiX11QueuePresent:
+        {
+            struct_xglWsiX11QueuePresent *pPacket = interpret_body_as_xglWsiX11QueuePresent(packet);
+            XGL_WSI_X11_PRESENT_INFO pInfo;
+            memcpy(&pInfo, pPacket->pPresentInfo, sizeof(XGL_WSI_X11_PRESENT_INFO));
+            pInfo.srcImage = remap(pPacket->pPresentInfo->srcImage);
+            // use replayers Xcb window
+            pInfo.destWindow = m_display->m_XcbWindow;
+            replayResult = m_xglFuncs.real_xglWsiX11QueuePresent(remap(pPacket->queue), &pInfo, remap(pPacket->fence));
+            CHECK_RETURN_VALUE(xglWsiX11QueuePresent);
+            break;
+        }
+        default:
+            glv_LogWarn("Unrecognized packet_id %u, skipping\n", packet->packet_id);
+            returnValue = glv_replay::GLV_REPLAY_INVALID_ID;
+            break;
+    }
+
+    return returnValue;
+}
+
diff --git a/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl_replay.h b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl_replay.h
new file mode 100644
index 0000000..7ff2e55
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvreplay_xgl/glvreplay_xgl_replay.h
@@ -0,0 +1,1314 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include <set>
+#include <map>
+#include <vector>
+#include <xcb/xcb.h>
+
+#include "glvreplay_window.h"
+#include "glvreplay_factory.h"
+#include "glv_trace_packet_identifiers.h"
+
+#include "xgl/inc/xgl.h"
+#include "xgl/inc/xglDbg.h"
+#include "xgl/inc/xglWsiX11Ext.h"
+
+class ApiReplay {
+public:
+    virtual ~ApiReplay() { }
+
+    virtual enum glv_replay::GLV_REPLAY_RESULT replay(glv_trace_packet_header * packet) = 0;
+    virtual int init(glv_replay::Display & disp) = 0;
+};
+
+class xglDisplay: public glv_replay::DisplayImp {
+friend class xglReplay;
+public:
+    xglDisplay();
+    ~xglDisplay();
+    int init(const unsigned int gpu_idx);
+    int set_window(glv_window_handle hWindow, unsigned int width, unsigned int height);
+    int create_window(const unsigned int width, const unsigned int height);
+    void resize_window(const unsigned int width, const unsigned int height);
+    void process_event();
+    // XGL_DEVICE get_device() { return m_dev[m_gpuIdx];}
+#if defined(WIN32)
+    HWND get_window_handle() { return m_windowHandle; }
+#endif
+private:
+    XGL_RESULT init_xgl(const unsigned int gpu_idx);
+    bool m_initedXGL;
+#if defined(WIN32)
+    HWND m_windowHandle;
+#elif defined(PLATFORM_LINUX)
+    XGL_WSI_X11_CONNECTION_INFO m_WsiConnection;
+    xcb_screen_t *m_pXcbScreen;
+    xcb_window_t m_XcbWindow;
+#endif
+    unsigned int m_windowWidth;
+    unsigned int m_windowHeight;
+#if 0
+    XGL_DEVICE m_dev[XGL_MAX_PHYSICAL_GPUS];
+    XGL_UINT32 m_gpuCount;
+    unsigned int m_gpuIdx;
+    XGL_PHYSICAL_GPU m_gpus[XGL_MAX_PHYSICAL_GPUS];
+    XGL_PHYSICAL_GPU_PROPERTIES m_gpuProps[XGL_MAX_PHYSICAL_GPUS];
+#endif
+    std::vector<XGL_CHAR *>m_extensions;
+};
+
+typedef struct _XGLAllocInfo {
+    XGL_GPU_SIZE size;
+    XGL_VOID *pData;
+} XGLAllocInfo;
+
+struct xglFuncs {
+    void init_funcs(void * libHandle);
+    void *m_libHandle;
+
+    typedef XGL_RESULT( XGLAPI * type_xglInitAndEnumerateGpus)(
+            const XGL_APPLICATION_INFO* pAppInfo,
+            const XGL_ALLOC_CALLBACKS*  pAllocCb,
+            XGL_UINT                    maxGpus,
+            XGL_UINT*                   pGpuCount,
+            XGL_PHYSICAL_GPU*           pGpus);
+    type_xglInitAndEnumerateGpus real_xglInitAndEnumerateGpus;
+    typedef XGL_RESULT( XGLAPI * type_xglGetGpuInfo)(
+            XGL_PHYSICAL_GPU            gpu,
+            XGL_PHYSICAL_GPU_INFO_TYPE  infoType,
+            XGL_SIZE*                   pDataSize,
+            XGL_VOID*                   pData);
+    type_xglGetGpuInfo real_xglGetGpuInfo;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateDevice)(
+            XGL_PHYSICAL_GPU              gpu,
+            const XGL_DEVICE_CREATE_INFO* pCreateInfo,
+            XGL_DEVICE*                   pDevice);
+    type_xglCreateDevice real_xglCreateDevice;
+    typedef XGL_RESULT( XGLAPI * type_xglDestroyDevice)(XGL_DEVICE device);
+    type_xglDestroyDevice real_xglDestroyDevice;
+    typedef XGL_RESULT( XGLAPI * type_xglGetExtensionSupport)(
+            XGL_PHYSICAL_GPU gpu,
+            const XGL_CHAR*  pExtName);
+    type_xglGetExtensionSupport real_xglGetExtensionSupport;
+    typedef XGL_RESULT( XGLAPI * type_xglGetDeviceQueue)(
+            XGL_DEVICE       device,
+            XGL_QUEUE_TYPE   queueType,
+            XGL_UINT         queueIndex,
+            XGL_QUEUE*       pQueue);
+    type_xglGetDeviceQueue real_xglGetDeviceQueue;
+    typedef XGL_RESULT( XGLAPI * type_xglQueueSubmit)(
+            XGL_QUEUE             queue,
+            XGL_UINT              cmdBufferCount,
+            const XGL_CMD_BUFFER* pCmdBuffers,
+            XGL_UINT              memRefCount,
+            const XGL_MEMORY_REF* pMemRefs,
+            XGL_FENCE             fence);
+    type_xglQueueSubmit real_xglQueueSubmit;
+    typedef XGL_RESULT( XGLAPI * type_xglQueueSetGlobalMemReferences)(
+            XGL_QUEUE             queue,
+            XGL_UINT              memRefCount,
+            const XGL_MEMORY_REF* pMemRefs);
+    type_xglQueueSetGlobalMemReferences real_xglQueueSetGlobalMemReferences;
+    typedef XGL_RESULT( XGLAPI * type_xglQueueWaitIdle)(XGL_QUEUE queue);
+    type_xglQueueWaitIdle real_xglQueueWaitIdle;
+    typedef XGL_RESULT( XGLAPI * type_xglDeviceWaitIdle)(XGL_DEVICE device);
+    type_xglDeviceWaitIdle real_xglDeviceWaitIdle;
+    typedef XGL_RESULT( XGLAPI * type_xglGetMemoryHeapCount)(
+            XGL_DEVICE  device,
+            XGL_UINT*   pCount);
+    type_xglGetMemoryHeapCount real_xglGetMemoryHeapCount;
+    typedef XGL_RESULT( XGLAPI * type_xglGetMemoryHeapInfo)(
+            XGL_DEVICE                  device,
+            XGL_UINT                    heapId,
+            XGL_MEMORY_HEAP_INFO_TYPE   infoType,
+            XGL_SIZE*                   pDataSize,
+            XGL_VOID*                   pData);
+    type_xglGetMemoryHeapInfo real_xglGetMemoryHeapInfo;
+    typedef XGL_RESULT( XGLAPI * type_xglAllocMemory)(
+            XGL_DEVICE                   device,
+            const XGL_MEMORY_ALLOC_INFO* pAllocInfo,
+            XGL_GPU_MEMORY*              pMem);
+    type_xglAllocMemory real_xglAllocMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglFreeMemory)(XGL_GPU_MEMORY mem);
+    type_xglFreeMemory real_xglFreeMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglSetMemoryPriority)(
+            XGL_GPU_MEMORY            mem,
+            XGL_MEMORY_PRIORITY       priority);
+    type_xglSetMemoryPriority real_xglSetMemoryPriority;
+    typedef XGL_RESULT( XGLAPI * type_xglMapMemory)(
+            XGL_GPU_MEMORY mem,
+            XGL_FLAGS      flags,                // Reserved
+            XGL_VOID**     ppData);
+    type_xglMapMemory real_xglMapMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglUnmapMemory)(XGL_GPU_MEMORY mem);
+    type_xglUnmapMemory real_xglUnmapMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglPinSystemMemory)(
+            XGL_DEVICE      device,
+            const XGL_VOID* pSysMem,
+            XGL_SIZE        memSize,
+            XGL_GPU_MEMORY* pMem);
+    type_xglPinSystemMemory real_xglPinSystemMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglRemapVirtualMemoryPages)(
+            XGL_DEVICE                            device,
+            XGL_UINT                              rangeCount,
+            const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pRanges,
+            XGL_UINT                              preWaitSemaphoreCount,
+            const XGL_QUEUE_SEMAPHORE*            pPreWaitSemaphores,
+            XGL_UINT                              postSignalSemaphoreCount,
+            const XGL_QUEUE_SEMAPHORE*            pPostSignalSemaphores);
+    type_xglRemapVirtualMemoryPages real_xglRemapVirtualMemoryPages;
+    typedef XGL_RESULT( XGLAPI * type_xglGetMultiGpuCompatibility)(
+            XGL_PHYSICAL_GPU            gpu0,
+            XGL_PHYSICAL_GPU            gpu1,
+            XGL_GPU_COMPATIBILITY_INFO* pInfo);
+    type_xglGetMultiGpuCompatibility real_xglGetMultiGpuCompatibility;
+    typedef XGL_RESULT( XGLAPI * type_xglOpenSharedMemory)(
+            XGL_DEVICE                  device,
+            const XGL_MEMORY_OPEN_INFO* pOpenInfo,
+            XGL_GPU_MEMORY*             pMem);
+    type_xglOpenSharedMemory real_xglOpenSharedMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglOpenSharedQueueSemaphore)(
+            XGL_DEVICE                           device,
+            const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pOpenInfo,
+            XGL_QUEUE_SEMAPHORE*                 pSemaphore);
+    type_xglOpenSharedQueueSemaphore real_xglOpenSharedQueueSemaphore;
+    typedef XGL_RESULT( XGLAPI * type_xglOpenPeerMemory)(
+            XGL_DEVICE                       device,
+            const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo,
+            XGL_GPU_MEMORY*                  pMem);
+    type_xglOpenPeerMemory real_xglOpenPeerMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglOpenPeerImage)(
+            XGL_DEVICE                      device,
+            const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo,
+            XGL_IMAGE*                      pImage,
+            XGL_GPU_MEMORY*                 pMem);
+    type_xglOpenPeerImage real_xglOpenPeerImage;
+    typedef XGL_RESULT( XGLAPI * type_xglDestroyObject)(XGL_OBJECT object);
+    type_xglDestroyObject real_xglDestroyObject;
+    typedef XGL_RESULT( XGLAPI * type_xglGetObjectInfo)(
+            XGL_BASE_OBJECT             object,
+            XGL_OBJECT_INFO_TYPE        infoType,
+            XGL_SIZE*                   pDataSize,
+            XGL_VOID*                   pData);
+    type_xglGetObjectInfo real_xglGetObjectInfo;
+    typedef XGL_RESULT( XGLAPI * type_xglBindObjectMemory)(
+            XGL_OBJECT     object,
+            XGL_GPU_MEMORY mem,
+            XGL_GPU_SIZE   offset);
+    type_xglBindObjectMemory real_xglBindObjectMemory;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateFence)(
+            XGL_DEVICE                   device,
+            const XGL_FENCE_CREATE_INFO* pCreateInfo,
+            XGL_FENCE*                   pFence);
+    type_xglCreateFence real_xglCreateFence;
+    typedef XGL_RESULT( XGLAPI * type_xglGetFenceStatus)(XGL_FENCE fence);
+    type_xglGetFenceStatus real_xglGetFenceStatus;
+    typedef XGL_RESULT( XGLAPI * type_xglWaitForFences)(
+            XGL_DEVICE       device,
+            XGL_UINT         fenceCount,
+            const XGL_FENCE* pFences,
+            XGL_BOOL         waitAll,
+            XGL_UINT64       timeout);
+    type_xglWaitForFences real_xglWaitForFences;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateQueueSemaphore)(
+            XGL_DEVICE                             device,
+            const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pCreateInfo,
+            XGL_QUEUE_SEMAPHORE*                   pSemaphore);
+    type_xglCreateQueueSemaphore real_xglCreateQueueSemaphore;
+    typedef XGL_RESULT( XGLAPI * type_xglSignalQueueSemaphore)(
+            XGL_QUEUE           queue,
+            XGL_QUEUE_SEMAPHORE semaphore);
+    type_xglSignalQueueSemaphore real_xglSignalQueueSemaphore;
+    typedef XGL_RESULT( XGLAPI * type_xglWaitQueueSemaphore)(
+            XGL_QUEUE           queue,
+            XGL_QUEUE_SEMAPHORE semaphore);
+    type_xglWaitQueueSemaphore real_xglWaitQueueSemaphore;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateEvent)(
+            XGL_DEVICE                   device,
+            const XGL_EVENT_CREATE_INFO* pCreateInfo,
+            XGL_EVENT*                   pEvent);
+    type_xglCreateEvent real_xglCreateEvent;
+    typedef XGL_RESULT( XGLAPI * type_xglGetEventStatus)(XGL_EVENT event);
+    type_xglGetEventStatus real_xglGetEventStatus;
+    typedef XGL_RESULT( XGLAPI * type_xglSetEvent)(XGL_EVENT event);
+    type_xglSetEvent real_xglSetEvent;
+    typedef XGL_RESULT( XGLAPI * type_xglResetEvent)(XGL_EVENT event);
+    type_xglResetEvent real_xglResetEvent;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateQueryPool)(
+            XGL_DEVICE                        device,
+            const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo,
+            XGL_QUERY_POOL*                   pQueryPool);
+    type_xglCreateQueryPool real_xglCreateQueryPool;
+    typedef XGL_RESULT( XGLAPI * type_xglGetQueryPoolResults)(
+            XGL_QUERY_POOL queryPool,
+            XGL_UINT       startQuery,
+            XGL_UINT       queryCount,
+            XGL_SIZE*      pDataSize,
+            XGL_VOID*      pData);
+    type_xglGetQueryPoolResults real_xglGetQueryPoolResults;
+    typedef XGL_RESULT( XGLAPI * type_xglGetFormatInfo)(
+            XGL_DEVICE             device,
+            XGL_FORMAT             format,
+            XGL_FORMAT_INFO_TYPE   infoType,
+            XGL_SIZE*              pDataSize,
+            XGL_VOID*              pData);
+    type_xglGetFormatInfo real_xglGetFormatInfo;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateImage)(
+            XGL_DEVICE                   device,
+            const XGL_IMAGE_CREATE_INFO* pCreateInfo,
+            XGL_IMAGE*                   pImage);
+    type_xglCreateImage real_xglCreateImage;
+    typedef XGL_RESULT( XGLAPI * type_xglGetImageSubresourceInfo)(
+            XGL_IMAGE                    image,
+            const XGL_IMAGE_SUBRESOURCE* pSubresource,
+            XGL_SUBRESOURCE_INFO_TYPE    infoType,
+            XGL_SIZE*                    pDataSize,
+            XGL_VOID*                    pData);
+    type_xglGetImageSubresourceInfo real_xglGetImageSubresourceInfo;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateImageView)(
+            XGL_DEVICE                        device,
+            const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo,
+            XGL_IMAGE_VIEW*                   pView);
+    type_xglCreateImageView real_xglCreateImageView;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateColorAttachmentView)(
+            XGL_DEVICE                                   device,
+            const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
+            XGL_COLOR_ATTACHMENT_VIEW*                   pView);
+    type_xglCreateColorAttachmentView real_xglCreateColorAttachmentView;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateDepthStencilView)(
+            XGL_DEVICE                                device,
+            const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo,
+            XGL_DEPTH_STENCIL_VIEW*                   pView);
+    type_xglCreateDepthStencilView real_xglCreateDepthStencilView;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateShader)(
+            XGL_DEVICE                    device,
+            const XGL_SHADER_CREATE_INFO* pCreateInfo,
+            XGL_SHADER*                   pShader);
+    type_xglCreateShader real_xglCreateShader;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateGraphicsPipeline)(
+            XGL_DEVICE                               device,
+            const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
+            XGL_PIPELINE*                            pPipeline);
+    type_xglCreateGraphicsPipeline real_xglCreateGraphicsPipeline;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateComputePipeline)(
+            XGL_DEVICE                              device,
+            const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
+            XGL_PIPELINE*                           pPipeline);
+    type_xglCreateComputePipeline real_xglCreateComputePipeline;
+    typedef XGL_RESULT( XGLAPI * type_xglStorePipeline)(
+            XGL_PIPELINE pipeline,
+            XGL_SIZE*    pDataSize,
+            XGL_VOID*    pData);
+    type_xglStorePipeline real_xglStorePipeline;
+    typedef XGL_RESULT( XGLAPI * type_xglLoadPipeline)(
+            XGL_DEVICE      device,
+            XGL_SIZE        dataSize,
+            const XGL_VOID* pData,
+            XGL_PIPELINE*   pPipeline);
+    type_xglLoadPipeline real_xglLoadPipeline;
+    typedef XGL_RESULT( XGLAPI * type_xglCreatePipelineDelta)(
+            XGL_DEVICE          device,
+	    XGL_PIPELINE        p1,
+	    XGL_PIPELINE        p2,
+	    XGL_PIPELINE_DELTA* delta);
+    type_xglCreatePipelineDelta real_xglCreatePipelineDelta;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateSampler)(
+            XGL_DEVICE                     device,
+            const XGL_SAMPLER_CREATE_INFO* pCreateInfo,
+            XGL_SAMPLER*                   pSampler);
+    type_xglCreateSampler real_xglCreateSampler;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateDescriptorSet)(
+            XGL_DEVICE                            device,
+            const XGL_DESCRIPTOR_SET_CREATE_INFO* pCreateInfo,
+            XGL_DESCRIPTOR_SET*                   pDescriptorSet);
+    type_xglCreateDescriptorSet real_xglCreateDescriptorSet;
+    typedef XGL_VOID( XGLAPI * type_xglBeginDescriptorSetUpdate)(XGL_DESCRIPTOR_SET descriptorSet);
+    type_xglBeginDescriptorSetUpdate real_xglBeginDescriptorSetUpdate;
+    typedef XGL_VOID( XGLAPI * type_xglEndDescriptorSetUpdate)(XGL_DESCRIPTOR_SET descriptorSet);
+    type_xglEndDescriptorSetUpdate real_xglEndDescriptorSetUpdate;
+    typedef XGL_VOID( XGLAPI * type_xglAttachSamplerDescriptors)(
+            XGL_DESCRIPTOR_SET descriptorSet,
+            XGL_UINT           startSlot,
+            XGL_UINT           slotCount,
+            const XGL_SAMPLER* pSamplers);
+    type_xglAttachSamplerDescriptors real_xglAttachSamplerDescriptors;
+    typedef XGL_VOID( XGLAPI * type_xglAttachImageViewDescriptors)(
+            XGL_DESCRIPTOR_SET                descriptorSet,
+            XGL_UINT                          startSlot,
+            XGL_UINT                          slotCount,
+            const XGL_IMAGE_VIEW_ATTACH_INFO* pImageViews);
+    type_xglAttachImageViewDescriptors real_xglAttachImageViewDescriptors;
+    typedef XGL_VOID( XGLAPI * type_xglAttachMemoryViewDescriptors)(
+            XGL_DESCRIPTOR_SET                 descriptorSet,
+            XGL_UINT                           startSlot,
+            XGL_UINT                           slotCount,
+            const XGL_MEMORY_VIEW_ATTACH_INFO* pMemViews);
+    type_xglAttachMemoryViewDescriptors real_xglAttachMemoryViewDescriptors;
+    typedef XGL_VOID( XGLAPI * type_xglAttachNestedDescriptors)(
+            XGL_DESCRIPTOR_SET                    descriptorSet,
+            XGL_UINT                              startSlot,
+            XGL_UINT                              slotCount,
+            const XGL_DESCRIPTOR_SET_ATTACH_INFO* pNestedDescriptorSets);
+    type_xglAttachNestedDescriptors real_xglAttachNestedDescriptors;
+    typedef XGL_VOID( XGLAPI * type_xglClearDescriptorSetSlots)(
+            XGL_DESCRIPTOR_SET descriptorSet,
+            XGL_UINT           startSlot,
+            XGL_UINT           slotCount);
+    type_xglClearDescriptorSetSlots real_xglClearDescriptorSetSlots;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateViewportState)(
+            XGL_DEVICE                            device,
+            const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
+            XGL_VIEWPORT_STATE_OBJECT*            pState);
+    type_xglCreateViewportState real_xglCreateViewportState;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateRasterState)(
+            XGL_DEVICE                          device,
+            const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
+            XGL_RASTER_STATE_OBJECT*            pState);
+    type_xglCreateRasterState real_xglCreateRasterState;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateMsaaState)(
+            XGL_DEVICE                        device,
+            const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
+            XGL_MSAA_STATE_OBJECT*            pState);
+    type_xglCreateMsaaState real_xglCreateMsaaState;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateColorBlendState)(
+            XGL_DEVICE                               device,
+            const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
+            XGL_COLOR_BLEND_STATE_OBJECT*            pState);
+    type_xglCreateColorBlendState real_xglCreateColorBlendState;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateDepthStencilState)(
+            XGL_DEVICE                                 device,
+            const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
+            XGL_DEPTH_STENCIL_STATE_OBJECT*            pState);
+    type_xglCreateDepthStencilState real_xglCreateDepthStencilState;
+    typedef XGL_RESULT( XGLAPI * type_xglCreateCommandBuffer)(
+            XGL_DEVICE                        device,
+            const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
+            XGL_CMD_BUFFER*                   pCmdBuffer);
+    type_xglCreateCommandBuffer real_xglCreateCommandBuffer;
+    typedef XGL_RESULT( XGLAPI * type_xglBeginCommandBuffer)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_FLAGS      flags);
+    type_xglBeginCommandBuffer real_xglBeginCommandBuffer;
+    typedef XGL_RESULT( XGLAPI * type_xglEndCommandBuffer)(XGL_CMD_BUFFER cmdBuffer);
+    type_xglEndCommandBuffer real_xglEndCommandBuffer;
+    typedef XGL_RESULT( XGLAPI * type_xglResetCommandBuffer)(XGL_CMD_BUFFER cmdBuffer);
+    type_xglResetCommandBuffer real_xglResetCommandBuffer;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindPipeline)(
+            XGL_CMD_BUFFER                cmdBuffer,
+            XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+            XGL_PIPELINE                  pipeline);
+    type_xglCmdBindPipeline real_xglCmdBindPipeline;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindPipelineDelta)(
+            XGL_CMD_BUFFER                cmdBuffer,
+            XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+            XGL_PIPELINE_DELTA            delta);
+    type_xglCmdBindPipelineDelta real_xglCmdBindPipelineDelta;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindStateObject)(
+            XGL_CMD_BUFFER               cmdBuffer,
+            XGL_STATE_BIND_POINT         stateBindPoint,
+            XGL_STATE_OBJECT             state);
+    type_xglCmdBindStateObject real_xglCmdBindStateObject;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindDescriptorSet)(
+            XGL_CMD_BUFFER                    cmdBuffer,
+            XGL_PIPELINE_BIND_POINT           pipelineBindPoint,
+            XGL_UINT                          index,
+            XGL_DESCRIPTOR_SET                descriptorSet,
+            XGL_UINT                          slotOffset);
+    type_xglCmdBindDescriptorSet real_xglCmdBindDescriptorSet;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindDynamicMemoryView)(
+            XGL_CMD_BUFFER                     cmdBuffer,
+            XGL_PIPELINE_BIND_POINT            pipelineBindPoint,
+            const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView);
+    type_xglCmdBindDynamicMemoryView real_xglCmdBindDynamicMemoryView;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindIndexData)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_GPU_MEMORY mem,
+            XGL_GPU_SIZE   offset,
+            XGL_INDEX_TYPE indexType);
+    type_xglCmdBindIndexData real_xglCmdBindIndexData;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBindAttachments)(
+            XGL_CMD_BUFFER                         cmdBuffer,
+            XGL_UINT                               colorTargetCount,
+            const XGL_COLOR_ATTACHMENT_BIND_INFO*  pColorTargets,
+            const XGL_DEPTH_STENCIL_BIND_INFO*     pDepthTarget);
+    type_xglCmdBindAttachments real_xglCmdBindAttachments;
+    typedef XGL_VOID( XGLAPI * type_xglCmdPrepareMemoryRegions)(
+            XGL_CMD_BUFFER                     cmdBuffer,
+            XGL_UINT                           transitionCount,
+            const XGL_MEMORY_STATE_TRANSITION* pStateTransitions);
+    type_xglCmdPrepareMemoryRegions real_xglCmdPrepareMemoryRegions;
+    typedef XGL_VOID( XGLAPI * type_xglCmdPrepareImages)(
+            XGL_CMD_BUFFER                    cmdBuffer,
+            XGL_UINT                          transitionCount,
+            const XGL_IMAGE_STATE_TRANSITION* pStateTransitions);
+    type_xglCmdPrepareImages real_xglCmdPrepareImages;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDraw)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_UINT       firstVertex,
+            XGL_UINT       vertexCount,
+            XGL_UINT       firstInstance,
+            XGL_UINT       instanceCount);
+    type_xglCmdDraw real_xglCmdDraw;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDrawIndexed)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_UINT       firstIndex,
+            XGL_UINT       indexCount,
+            XGL_INT        vertexOffset,
+            XGL_UINT       firstInstance,
+            XGL_UINT       instanceCount);
+    type_xglCmdDrawIndexed real_xglCmdDrawIndexed;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDrawIndirect)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_GPU_MEMORY mem,
+            XGL_GPU_SIZE   offset,
+            XGL_UINT32     count,
+            XGL_UINT32     stride);
+    type_xglCmdDrawIndirect real_xglCmdDrawIndirect;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDrawIndexedIndirect)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_GPU_MEMORY mem,
+            XGL_GPU_SIZE   offset,
+            XGL_UINT32     count,
+            XGL_UINT32     stride);
+    type_xglCmdDrawIndexedIndirect real_xglCmdDrawIndexedIndirect;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDispatch)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_UINT       x,
+            XGL_UINT       y,
+            XGL_UINT       z);
+    type_xglCmdDispatch real_xglCmdDispatch;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDispatchIndirect)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_GPU_MEMORY mem,
+            XGL_GPU_SIZE   offset);
+    type_xglCmdDispatchIndirect real_xglCmdDispatchIndirect;
+    typedef XGL_VOID( XGLAPI * type_xglCmdCopyMemory)(
+            XGL_CMD_BUFFER         cmdBuffer,
+            XGL_GPU_MEMORY         srcMem,
+            XGL_GPU_MEMORY         destMem,
+            XGL_UINT               regionCount,
+            const XGL_MEMORY_COPY* pRegions);
+    type_xglCmdCopyMemory real_xglCmdCopyMemory;
+    typedef XGL_VOID( XGLAPI * type_xglCmdCopyImage)(
+            XGL_CMD_BUFFER        cmdBuffer,
+            XGL_IMAGE             srcImage,
+            XGL_IMAGE             destImage,
+            XGL_UINT              regionCount,
+            const XGL_IMAGE_COPY* pRegions);
+    type_xglCmdCopyImage real_xglCmdCopyImage;
+    typedef XGL_VOID( XGLAPI * type_xglCmdCopyMemoryToImage)(
+            XGL_CMD_BUFFER               cmdBuffer,
+            XGL_GPU_MEMORY               srcMem,
+            XGL_IMAGE                    destImage,
+            XGL_UINT                     regionCount,
+            const XGL_MEMORY_IMAGE_COPY* pRegions);
+    type_xglCmdCopyMemoryToImage real_xglCmdCopyMemoryToImage;
+    typedef XGL_VOID( XGLAPI * type_xglCmdCopyImageToMemory)(
+            XGL_CMD_BUFFER               cmdBuffer,
+            XGL_IMAGE                    srcImage,
+            XGL_GPU_MEMORY               destMem,
+            XGL_UINT                     regionCount,
+            const XGL_MEMORY_IMAGE_COPY* pRegions);
+    type_xglCmdCopyImageToMemory real_xglCmdCopyImageToMemory;
+    typedef XGL_VOID( XGLAPI * type_xglCmdCloneImageData)(
+            XGL_CMD_BUFFER  cmdBuffer,
+            XGL_IMAGE       srcImage,
+            XGL_IMAGE_STATE srcImageState,
+            XGL_IMAGE       destImage,
+            XGL_IMAGE_STATE destImageState);
+    type_xglCmdCloneImageData real_xglCmdCloneImageData;
+    typedef XGL_VOID( XGLAPI * type_xglCmdUpdateMemory)(
+            XGL_CMD_BUFFER    cmdBuffer,
+            XGL_GPU_MEMORY    destMem,
+            XGL_GPU_SIZE      destOffset,
+            XGL_GPU_SIZE      dataSize,
+            const XGL_UINT32* pData);
+    type_xglCmdUpdateMemory real_xglCmdUpdateMemory;
+    typedef XGL_VOID( XGLAPI * type_xglCmdFillMemory)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_GPU_MEMORY destMem,
+            XGL_GPU_SIZE   destOffset,
+            XGL_GPU_SIZE   fillSize,
+            XGL_UINT32     data);
+    type_xglCmdFillMemory real_xglCmdFillMemory;
+    typedef XGL_VOID( XGLAPI * type_xglCmdClearColorImage)(
+            XGL_CMD_BUFFER                     cmdBuffer,
+            XGL_IMAGE                          image,
+            const XGL_FLOAT                    color[4],
+            XGL_UINT                           rangeCount,
+            const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges);
+    type_xglCmdClearColorImage real_xglCmdClearColorImage;
+    typedef XGL_VOID( XGLAPI * type_xglCmdClearColorImageRaw)(
+            XGL_CMD_BUFFER                     cmdBuffer,
+            XGL_IMAGE                          image,
+            const XGL_UINT32                   color[4],
+            XGL_UINT                           rangeCount,
+            const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges);
+    type_xglCmdClearColorImageRaw real_xglCmdClearColorImageRaw;
+    typedef XGL_VOID( XGLAPI * type_xglCmdClearDepthStencil)(
+            XGL_CMD_BUFFER                     cmdBuffer,
+            XGL_IMAGE                          image,
+            XGL_FLOAT                          depth,
+            XGL_UINT32                         stencil,
+            XGL_UINT                           rangeCount,
+            const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges);
+    type_xglCmdClearDepthStencil real_xglCmdClearDepthStencil;
+    typedef XGL_VOID( XGLAPI * type_xglCmdResolveImage)(
+            XGL_CMD_BUFFER           cmdBuffer,
+            XGL_IMAGE                srcImage,
+            XGL_IMAGE                destImage,
+            XGL_UINT                 rectCount,
+            const XGL_IMAGE_RESOLVE* pRects);
+    type_xglCmdResolveImage real_xglCmdResolveImage;
+    typedef XGL_VOID( XGLAPI * type_xglCmdSetEvent)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_EVENT      event);
+    type_xglCmdSetEvent real_xglCmdSetEvent;
+    typedef XGL_VOID( XGLAPI * type_xglCmdResetEvent)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_EVENT      event);
+    type_xglCmdResetEvent real_xglCmdResetEvent;
+    typedef XGL_VOID( XGLAPI * type_xglCmdMemoryAtomic)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_GPU_MEMORY destMem,
+            XGL_GPU_SIZE   destOffset,
+            XGL_UINT64     srcData,
+            XGL_ATOMIC_OP  atomicOp);
+    type_xglCmdMemoryAtomic real_xglCmdMemoryAtomic;
+    typedef XGL_VOID( XGLAPI * type_xglCmdBeginQuery)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_QUERY_POOL queryPool,
+            XGL_UINT       slot,
+            XGL_FLAGS      flags);
+    type_xglCmdBeginQuery real_xglCmdBeginQuery;
+    typedef XGL_VOID( XGLAPI * type_xglCmdEndQuery)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_QUERY_POOL queryPool,
+            XGL_UINT       slot);
+    type_xglCmdEndQuery real_xglCmdEndQuery;
+    typedef XGL_VOID( XGLAPI * type_xglCmdResetQueryPool)(
+            XGL_CMD_BUFFER cmdBuffer,
+            XGL_QUERY_POOL queryPool,
+            XGL_UINT       startQuery,
+            XGL_UINT       queryCount);
+    type_xglCmdResetQueryPool real_xglCmdResetQueryPool;
+    typedef XGL_VOID( XGLAPI * type_xglCmdWriteTimestamp)(
+            XGL_CMD_BUFFER           cmdBuffer,
+            XGL_TIMESTAMP_TYPE       timestampType,
+            XGL_GPU_MEMORY           destMem,
+            XGL_GPU_SIZE             destOffset);
+    type_xglCmdWriteTimestamp real_xglCmdWriteTimestamp;
+    typedef XGL_VOID( XGLAPI * type_xglCmdInitAtomicCounters)(
+            XGL_CMD_BUFFER                   cmdBuffer,
+            XGL_PIPELINE_BIND_POINT          pipelineBindPoint,
+            XGL_UINT                         startCounter,
+            XGL_UINT                         counterCount,
+            const XGL_UINT32*                pData);
+    type_xglCmdInitAtomicCounters real_xglCmdInitAtomicCounters;
+    typedef XGL_VOID( XGLAPI * type_xglCmdLoadAtomicCounters)(
+            XGL_CMD_BUFFER                cmdBuffer,
+            XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+            XGL_UINT                      startCounter,
+            XGL_UINT                      counterCount,
+            XGL_GPU_MEMORY                srcMem,
+            XGL_GPU_SIZE                  srcOffset);
+    type_xglCmdLoadAtomicCounters real_xglCmdLoadAtomicCounters;
+    typedef XGL_VOID( XGLAPI * type_xglCmdSaveAtomicCounters)(
+            XGL_CMD_BUFFER                cmdBuffer,
+            XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+            XGL_UINT                      startCounter,
+            XGL_UINT                      counterCount,
+            XGL_GPU_MEMORY                destMem,
+            XGL_GPU_SIZE                  destOffset);
+    type_xglCmdSaveAtomicCounters real_xglCmdSaveAtomicCounters;
+
+    // Debug entrypoints
+    typedef XGL_RESULT( XGLAPI * type_xglDbgSetValidationLevel)(
+            XGL_DEVICE             device,
+            XGL_VALIDATION_LEVEL   validationLevel);
+    type_xglDbgSetValidationLevel real_xglDbgSetValidationLevel;
+    typedef XGL_RESULT( XGLAPI * type_xglDbgRegisterMsgCallback)(
+            XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
+            XGL_VOID*                     pUserData);
+    type_xglDbgRegisterMsgCallback real_xglDbgRegisterMsgCallback;
+    typedef XGL_RESULT( XGLAPI * type_xglDbgUnregisterMsgCallback)(
+            XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback);
+    type_xglDbgUnregisterMsgCallback real_xglDbgUnregisterMsgCallback;
+    typedef XGL_RESULT( XGLAPI * type_xglDbgSetMessageFilter)(
+            XGL_DEVICE           device,
+            XGL_INT              msgCode,
+            XGL_DBG_MSG_FILTER   filter);
+    type_xglDbgSetMessageFilter real_xglDbgSetMessageFilter;
+    typedef XGL_RESULT( XGLAPI * type_xglDbgSetObjectTag)(
+            XGL_BASE_OBJECT object,
+            XGL_SIZE        tagSize,
+            const XGL_VOID* pTag);
+    type_xglDbgSetObjectTag real_xglDbgSetObjectTag;
+    typedef XGL_RESULT( XGLAPI * type_xglDbgSetGlobalOption)(
+            XGL_DBG_GLOBAL_OPTION        dbgOption,
+            XGL_SIZE                     dataSize,
+            const XGL_VOID*              pData);
+    type_xglDbgSetGlobalOption real_xglDbgSetGlobalOption;
+    typedef XGL_RESULT( XGLAPI * type_xglDbgSetDeviceOption)(
+            XGL_DEVICE                   device,
+            XGL_DBG_DEVICE_OPTION        dbgOption,
+            XGL_SIZE                     dataSize,
+            const XGL_VOID*              pData);
+    type_xglDbgSetDeviceOption real_xglDbgSetDeviceOption;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDbgMarkerBegin)(
+            XGL_CMD_BUFFER  cmdBuffer,
+            const XGL_CHAR* pMarker);
+    type_xglCmdDbgMarkerBegin real_xglCmdDbgMarkerBegin;
+    typedef XGL_VOID( XGLAPI * type_xglCmdDbgMarkerEnd)(
+            XGL_CMD_BUFFER  cmdBuffer);
+    type_xglCmdDbgMarkerEnd real_xglCmdDbgMarkerEnd;
+
+    //WsiX11Ext entrypoints
+    typedef XGL_RESULT (XGLAPI * type_xglWsiX11AssociateConnection)(
+            XGL_PHYSICAL_GPU                            gpu,
+            const XGL_WSI_X11_CONNECTION_INFO*          pConnectionInfo);
+    type_xglWsiX11AssociateConnection real_xglWsiX11AssociateConnection;
+    typedef XGL_RESULT (XGLAPI * type_xglWsiX11GetMSC)(
+            XGL_DEVICE                                  device,
+            xcb_randr_crtc_t                            crtc,
+            XGL_UINT64*                                 pMsc);
+    type_xglWsiX11GetMSC real_xglWsiX11GetMSC;
+    typedef XGL_RESULT (XGLAPI * type_xglWsiX11CreatePresentableImage)(
+            XGL_DEVICE                                  device,
+            const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
+            XGL_IMAGE*                                  pImage,
+            XGL_GPU_MEMORY*                             pMem);
+    type_xglWsiX11CreatePresentableImage real_xglWsiX11CreatePresentableImage;
+    typedef XGL_RESULT (XGLAPI * type_xglWsiX11QueuePresent)(
+            XGL_QUEUE                                   queue,
+            const XGL_WSI_X11_PRESENT_INFO*             pPresentInfo,
+            XGL_FENCE                                   fence);
+    type_xglWsiX11QueuePresent real_xglWsiX11QueuePresent;
+};
+
+class xglReplay : public ApiReplay {
+public:
+    ~xglReplay();
+    xglReplay(unsigned int debugLevel);
+
+    int init(glv_replay::Display & disp);
+    xglDisplay * get_display() {return m_display;}
+    glv_replay::GLV_REPLAY_RESULT replay(glv_trace_packet_header *packet);
+    glv_replay::GLV_REPLAY_RESULT handle_replay_errors(const char* entrypointName, const XGL_RESULT resCall, const XGL_RESULT resTrace, const glv_replay::GLV_REPLAY_RESULT resIn);
+private:
+    struct xglFuncs m_xglFuncs;
+    void copy_mem_remap_range_struct(XGL_VIRTUAL_MEMORY_REMAP_RANGE *outRange, const XGL_VIRTUAL_MEMORY_REMAP_RANGE *inRange);
+    unsigned int m_debugLevel;
+    xglDisplay *m_display;
+    XGL_MEMORY_HEAP_PROPERTIES m_heapProps[XGL_MAX_MEMORY_HEAPS];
+
+    std::map<XGL_GPU_MEMORY, XGLAllocInfo> m_mapData;
+    void add_entry_to_mapData(XGL_GPU_MEMORY handle, XGL_GPU_SIZE size)
+    {
+        XGLAllocInfo info;
+        info.pData = NULL;
+        info.size = size;
+        m_mapData.insert(std::pair<XGL_GPU_MEMORY, XGLAllocInfo>(handle, info));
+    }
+    void add_mapping_to_mapData(XGL_GPU_MEMORY handle, XGL_VOID *pData)
+    {
+        std::map<XGL_GPU_MEMORY,XGLAllocInfo>::iterator it = m_mapData.find(handle);
+        if (it == m_mapData.end())
+        {
+            glv_LogWarn("add_mapping_to_mapData() couldn't find entry\n");
+            return;
+        }
+
+        XGLAllocInfo &info = it->second;
+        if (info.pData != NULL)
+        {
+            glv_LogWarn("add_mapping_to_mapData() data already mapped overwrite old mapping\n");
+        }
+        info.pData = pData;
+    }
+    void rm_entry_from_mapData(XGL_GPU_MEMORY handle)
+    {
+        std::map<XGL_GPU_MEMORY,XGLAllocInfo>::iterator it = m_mapData.find(handle);
+        if (it == m_mapData.end())
+            return;
+        m_mapData.erase(it);
+    }
+    void rm_mapping_from_mapData(XGL_GPU_MEMORY handle, XGL_VOID* pData)
+    {
+        std::map<XGL_GPU_MEMORY,XGLAllocInfo>::iterator it = m_mapData.find(handle);
+
+        if (it == m_mapData.end())
+            return;
+
+        XGLAllocInfo &info = it->second;
+
+        if (!pData || !info.pData)
+        {
+            glv_LogWarn("rm_mapping_from_mapData() null src or dest pointers\n");
+            info.pData = NULL;
+            return;
+        }
+        memcpy(info.pData, pData, info.size);
+        info.pData = NULL;
+    }
+
+    std::map<XGL_PHYSICAL_GPU, XGL_PHYSICAL_GPU> m_gpus;
+    void add_to_map(XGL_PHYSICAL_GPU* pTraceGpu, XGL_PHYSICAL_GPU* pReplayGpu)
+    {
+        assert(pTraceGpu != NULL);
+        assert(pReplayGpu != NULL);
+        m_gpus[*pTraceGpu] = *pReplayGpu;
+    }
+
+    XGL_PHYSICAL_GPU remap(const XGL_PHYSICAL_GPU& gpu)
+    {
+        std::map<XGL_PHYSICAL_GPU, XGL_PHYSICAL_GPU>::const_iterator q = m_gpus.find(gpu);
+        return (q == m_gpus.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    void clear_all_map_handles()
+    {
+        m_gpus.clear();
+        m_devices.clear();
+        m_queues.clear();
+        m_memories.clear();
+        m_images.clear();
+        m_imageViews.clear();
+        m_colorTargetViews.clear();
+        m_depthStencilViews.clear();
+        m_shader.clear();
+        m_pipeline.clear();
+        m_pipelineDelta.clear();
+        m_sampler.clear();
+        m_descriptorSets.clear();
+        m_viewportStates.clear();
+        m_rasterStates.clear();
+        m_msaaStates.clear();
+        m_colorBlendStates.clear();
+        m_depthStencilStates.clear();
+        m_cmdBuffers.clear();
+        m_fences.clear();
+        m_queue_semaphores.clear();
+        m_events.clear();
+        m_queryPools.clear();
+        m_presentableImageSizes.clear();
+    }
+
+    std::map<XGL_DEVICE, XGL_DEVICE> m_devices;
+    void add_to_map(XGL_DEVICE* pTraceDevice, XGL_DEVICE* pReplayDevice)
+    {
+        assert(pTraceDevice != NULL);
+        assert(pReplayDevice != NULL);
+        m_devices[*pTraceDevice] = *pReplayDevice;
+    }
+    void rm_from_map(const XGL_DEVICE& deviceKey)
+    {
+        m_devices.erase(deviceKey);
+    }
+    XGL_DEVICE remap(const XGL_DEVICE& device)
+    {
+        std::map<XGL_DEVICE, XGL_DEVICE>::const_iterator q = m_devices.find(device);
+        return (q == m_devices.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_QUEUE, XGL_QUEUE> m_queues;
+    void add_to_map(XGL_QUEUE* pTraceQueue, XGL_QUEUE* pReplayQueue)
+    {
+        assert(pTraceQueue != NULL);
+        assert(pReplayQueue != NULL);
+        m_queues[*pTraceQueue] = *pReplayQueue;
+    }
+    // TODO how are queues individually removed from map???
+    XGL_QUEUE remap(const XGL_QUEUE& queue)
+    {
+        std::map<XGL_QUEUE, XGL_QUEUE>::const_iterator q = m_queues.find(queue);
+        return (q == m_queues.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_GPU_MEMORY, XGL_GPU_MEMORY> m_memories;
+    void add_to_map(XGL_GPU_MEMORY* pTraceMemory, XGL_GPU_MEMORY* pReplayMemory)
+    {
+        assert(pTraceMemory != NULL);
+        assert(pReplayMemory != NULL);
+        m_memories[*pTraceMemory] = *pReplayMemory;
+    }
+    void rm_from_map(const XGL_GPU_MEMORY &gpuMemKey)
+    {
+        m_memories.erase(gpuMemKey);
+    }
+    XGL_GPU_MEMORY remap(const XGL_GPU_MEMORY& memory)
+    {
+        std::map<XGL_GPU_MEMORY, XGL_GPU_MEMORY>::const_iterator m = m_memories.find(memory);
+        return (m == m_memories.end()) ? XGL_NULL_HANDLE : m->second;
+    }
+
+    std::map<XGL_IMAGE, XGL_IMAGE> m_images;
+    void add_to_map(XGL_IMAGE* pTraceImage, XGL_IMAGE* pReplayImage)
+    {
+        assert(pTraceImage != NULL);
+        assert(pReplayImage != NULL);
+        m_images[*pTraceImage] = *pReplayImage;
+    }
+    void rm_from_map(const XGL_IMAGE& image)
+    {
+        m_images.erase(image);
+    }
+    XGL_IMAGE remap(const XGL_IMAGE& image)
+    {
+        std::map<XGL_IMAGE, XGL_IMAGE>::const_iterator q = m_images.find(image);
+        return (q == m_images.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_IMAGE, XGL_EXTENT2D> m_presentableImageSizes;
+    void add_presentable_image_extents(const XGL_IMAGE* image, const XGL_EXTENT2D* extent)
+    {
+        assert(image != NULL);
+        assert(extent != NULL);
+        m_presentableImageSizes[*image] = *extent;
+    }
+
+    const XGL_EXTENT2D* get_presentable_image_extents(const XGL_IMAGE& image)
+    {
+        std::map<XGL_IMAGE, XGL_EXTENT2D>::const_iterator q = m_presentableImageSizes.find(image);
+        return (q == m_presentableImageSizes.end()) ? NULL : &(q->second);
+    }
+
+    std::map<XGL_IMAGE_VIEW, XGL_IMAGE_VIEW> m_imageViews;
+    void add_to_map(XGL_IMAGE_VIEW* pTraceImageView, XGL_IMAGE_VIEW* pReplayImageView)
+    {
+        assert(pTraceImageView != NULL);
+        assert(pReplayImageView != NULL);
+        m_imageViews[*pTraceImageView] = *pReplayImageView;
+    }
+    void rm_from_map(const XGL_IMAGE_VIEW& imageView)
+    {
+        m_imageViews.erase(imageView);
+    }
+    XGL_IMAGE_VIEW remap(const XGL_IMAGE_VIEW& imageView)
+    {
+        std::map<XGL_IMAGE_VIEW, XGL_IMAGE_VIEW>::const_iterator q = m_imageViews.find(imageView);
+        return (q == m_imageViews.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_COLOR_ATTACHMENT_VIEW, XGL_COLOR_ATTACHMENT_VIEW> m_colorTargetViews;
+    void add_to_map(XGL_COLOR_ATTACHMENT_VIEW* pTraceColorTargetView, XGL_COLOR_ATTACHMENT_VIEW* pReplayColorTargetView)
+    {
+        assert(pTraceColorTargetView != NULL);
+        assert(pReplayColorTargetView != NULL);
+        m_colorTargetViews[*pTraceColorTargetView] = *pReplayColorTargetView;
+    }
+    void rm_from_map(const XGL_COLOR_ATTACHMENT_VIEW& colorTargetView)
+    {
+        m_colorTargetViews.erase(colorTargetView);
+    }
+    XGL_COLOR_ATTACHMENT_VIEW remap(const XGL_COLOR_ATTACHMENT_VIEW& colorTargetView)
+    {
+        std::map<XGL_COLOR_ATTACHMENT_VIEW, XGL_COLOR_ATTACHMENT_VIEW>::const_iterator q = m_colorTargetViews.find(colorTargetView);
+        return (q == m_colorTargetViews.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_DEPTH_STENCIL_VIEW, XGL_DEPTH_STENCIL_VIEW> m_depthStencilViews;
+    void add_to_map(XGL_DEPTH_STENCIL_VIEW* pTraceDepthStencilView, XGL_DEPTH_STENCIL_VIEW* pReplayDepthStencilView)
+    {
+        assert(pTraceDepthStencilView != NULL);
+        assert(pReplayDepthStencilView != NULL);
+        m_depthStencilViews[*pTraceDepthStencilView] = *pReplayDepthStencilView;
+    }
+    void rm_from_map(const XGL_DEPTH_STENCIL_VIEW& depthStencilView)
+    {
+        m_depthStencilViews.erase(depthStencilView);
+    }
+    XGL_DEPTH_STENCIL_VIEW remap(const XGL_DEPTH_STENCIL_VIEW& depthStencilView)
+    {
+        std::map<XGL_DEPTH_STENCIL_VIEW, XGL_DEPTH_STENCIL_VIEW>::const_iterator q = m_depthStencilViews.find(depthStencilView);
+        return (q == m_depthStencilViews.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_SHADER, XGL_SHADER> m_shader;
+    void add_to_map(XGL_SHADER* pTraceShader, XGL_SHADER* pReplayShader)
+    {
+        assert(pTraceShader != NULL);
+        assert(pReplayShader != NULL);
+        m_shader[*pTraceShader] = *pReplayShader;
+    }
+    void rm_from_map(const XGL_SHADER& shader)
+    {
+        m_shader.erase(shader);
+    }
+    XGL_SHADER remap(const XGL_SHADER& shader)
+    {
+        std::map<XGL_SHADER, XGL_SHADER>::const_iterator q = m_shader.find(shader);
+        return (q == m_shader.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_PIPELINE, XGL_PIPELINE> m_pipeline;
+    void add_to_map(XGL_PIPELINE* pTracepipeline, XGL_PIPELINE* pReplaypipeline)
+    {
+        assert(pTracepipeline != NULL);
+        assert(pReplaypipeline != NULL);
+        m_pipeline[*pTracepipeline] = *pReplaypipeline;
+    }
+    void rm_from_map(const XGL_PIPELINE& pipeline)
+    {
+        m_pipeline.erase(pipeline);
+    }
+    XGL_PIPELINE remap(const XGL_PIPELINE& pipeline)
+    {
+        std::map<XGL_PIPELINE, XGL_PIPELINE>::const_iterator q = m_pipeline.find(pipeline);
+        return (q == m_pipeline.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_PIPELINE_DELTA, XGL_PIPELINE_DELTA> m_pipelineDelta;
+    void add_to_map(XGL_PIPELINE_DELTA* pTracepipedelta, XGL_PIPELINE_DELTA* pReplaypipedelta)
+    {
+        assert(pTracepipedelta != NULL);
+        assert(pReplaypipedelta != NULL);
+        m_pipelineDelta[*pTracepipedelta] = *pReplaypipedelta;
+    }
+    void rm_from_map(const XGL_PIPELINE_DELTA& pipedelta)
+    {
+        m_pipelineDelta.erase(pipedelta);
+    }
+    XGL_PIPELINE_DELTA remap(const XGL_PIPELINE_DELTA& pipedelta)
+    {
+        std::map<XGL_PIPELINE_DELTA, XGL_PIPELINE_DELTA>::const_iterator q = m_pipelineDelta.find(pipedelta);
+        return (q == m_pipelineDelta.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_SAMPLER, XGL_SAMPLER> m_sampler;
+    void add_to_map(XGL_SAMPLER* pTracesampler, XGL_SAMPLER* pReplaysampler)
+    {
+        assert(pTracesampler != NULL);
+        assert(pReplaysampler != NULL);
+        m_sampler[*pTracesampler] = *pReplaysampler;
+    }
+    void rm_from_map(const XGL_SAMPLER& sampler)
+    {
+        m_sampler.erase(sampler);
+    }
+    XGL_SAMPLER remap(const XGL_SAMPLER& sampler)
+    {
+        std::map<XGL_SAMPLER, XGL_SAMPLER>::const_iterator q = m_sampler.find(sampler);
+        return (q == m_sampler.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_DESCRIPTOR_SET, XGL_DESCRIPTOR_SET> m_descriptorSets;
+    void add_to_map(XGL_DESCRIPTOR_SET* pTraceSet, XGL_DESCRIPTOR_SET* pReplaySet)
+    {
+        assert(pTraceSet != NULL);
+        assert(pReplaySet != NULL);
+        m_descriptorSets[*pTraceSet] = *pReplaySet;
+    }
+    void rm_from_map(const XGL_DESCRIPTOR_SET& descriptorSet)
+    {
+        m_descriptorSets.erase(descriptorSet);
+    }
+    XGL_DESCRIPTOR_SET remap(const XGL_DESCRIPTOR_SET& descriptorSet)
+    {
+        std::map<XGL_DESCRIPTOR_SET, XGL_DESCRIPTOR_SET>::const_iterator q = m_descriptorSets.find(descriptorSet);
+        return (q == m_descriptorSets.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_VIEWPORT_STATE_OBJECT, XGL_VIEWPORT_STATE_OBJECT> m_viewportStates;
+    void add_to_map(XGL_VIEWPORT_STATE_OBJECT* pTraceState, XGL_VIEWPORT_STATE_OBJECT* pReplayState)
+    {
+        assert(pTraceState != NULL);
+        assert(pReplayState != NULL);
+        m_viewportStates[*pTraceState] = *pReplayState;
+    }
+    void rm_from_map(const XGL_VIEWPORT_STATE_OBJECT& state)
+    {
+        m_viewportStates.erase(state);
+    }
+    XGL_VIEWPORT_STATE_OBJECT remap(const XGL_VIEWPORT_STATE_OBJECT& state)
+    {
+        std::map<XGL_VIEWPORT_STATE_OBJECT, XGL_VIEWPORT_STATE_OBJECT>::const_iterator q = m_viewportStates.find(state);
+        return (q == m_viewportStates.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_RASTER_STATE_OBJECT, XGL_RASTER_STATE_OBJECT> m_rasterStates;
+    void add_to_map(XGL_RASTER_STATE_OBJECT* pTraceState, XGL_RASTER_STATE_OBJECT* pReplayState)
+    {
+        assert(pTraceState != NULL);
+        assert(pReplayState != NULL);
+        m_rasterStates[*pTraceState] = *pReplayState;
+    }
+    void rm_from_map(const XGL_RASTER_STATE_OBJECT& state)
+    {
+        m_rasterStates.erase(state);
+    }
+    XGL_RASTER_STATE_OBJECT remap(const XGL_RASTER_STATE_OBJECT& state)
+    {
+        std::map<XGL_RASTER_STATE_OBJECT, XGL_RASTER_STATE_OBJECT>::const_iterator q = m_rasterStates.find(state);
+        return (q == m_rasterStates.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_MSAA_STATE_OBJECT, XGL_MSAA_STATE_OBJECT> m_msaaStates;
+    void add_to_map(XGL_MSAA_STATE_OBJECT* pTraceState, XGL_MSAA_STATE_OBJECT* pReplayState)
+    {
+        assert(pTraceState != NULL);
+        assert(pReplayState != NULL);
+        m_msaaStates[*pTraceState] = *pReplayState;
+    }
+    void rm_from_map(const XGL_MSAA_STATE_OBJECT& state)
+    {
+        m_msaaStates.erase(state);
+    }
+    XGL_MSAA_STATE_OBJECT remap(const XGL_MSAA_STATE_OBJECT& state)
+    {
+        std::map<XGL_MSAA_STATE_OBJECT, XGL_MSAA_STATE_OBJECT>::const_iterator q = m_msaaStates.find(state);
+        return (q == m_msaaStates.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_COLOR_BLEND_STATE_OBJECT, XGL_COLOR_BLEND_STATE_OBJECT> m_colorBlendStates;
+    void add_to_map(XGL_COLOR_BLEND_STATE_OBJECT* pTraceState, XGL_COLOR_BLEND_STATE_OBJECT* pReplayState)
+    {
+        assert(pTraceState != NULL);
+        assert(pReplayState != NULL);
+        m_colorBlendStates[*pTraceState] = *pReplayState;
+    }
+    void rm_from_map(const XGL_COLOR_BLEND_STATE_OBJECT& state)
+    {
+        m_colorBlendStates.erase(state);
+    }
+    XGL_COLOR_BLEND_STATE_OBJECT remap(const XGL_COLOR_BLEND_STATE_OBJECT& state)
+    {
+        std::map<XGL_COLOR_BLEND_STATE_OBJECT, XGL_COLOR_BLEND_STATE_OBJECT>::const_iterator q = m_colorBlendStates.find(state);
+        return (q == m_colorBlendStates.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_DEPTH_STENCIL_STATE_OBJECT, XGL_DEPTH_STENCIL_STATE_OBJECT> m_depthStencilStates;
+    void add_to_map(XGL_DEPTH_STENCIL_STATE_OBJECT* pTraceState, XGL_DEPTH_STENCIL_STATE_OBJECT* pReplayState)
+    {
+        assert(pTraceState != NULL);
+        assert(pReplayState != NULL);
+        m_depthStencilStates[*pTraceState] = *pReplayState;
+    }
+    void rm_from_map(const XGL_DEPTH_STENCIL_STATE_OBJECT& state)
+    {
+        m_depthStencilStates.erase(state);
+    }
+    XGL_DEPTH_STENCIL_STATE_OBJECT remap(const XGL_DEPTH_STENCIL_STATE_OBJECT& state)
+    {
+        std::map<XGL_DEPTH_STENCIL_STATE_OBJECT, XGL_DEPTH_STENCIL_STATE_OBJECT>::const_iterator q = m_depthStencilStates.find(state);
+        return (q == m_depthStencilStates.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    XGL_STATE_OBJECT remap(const XGL_STATE_OBJECT& state)
+    {
+        /* includes: XGL_VIEWPORT_STATE_OBJECT, XGL_RASTER_STATE_OBJECT, XGL_MSAA_STATE_OBJECT
+         * XGL_COLOR_BLEND_STATE_OBJECT, XGL_DEPTH_STENCIL_STATE_OBJECT
+         */
+        XGL_STATE_OBJECT obj;
+        if ((obj = remap(static_cast <XGL_VIEWPORT_STATE_OBJECT> (state))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_RASTER_STATE_OBJECT> (state))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_MSAA_STATE_OBJECT> (state))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_COLOR_BLEND_STATE_OBJECT> (state))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_DEPTH_STENCIL_STATE_OBJECT> (state))) != XGL_NULL_HANDLE)
+            return obj;
+        return XGL_NULL_HANDLE;
+    }
+    void rm_from_map(const XGL_STATE_OBJECT& state)
+    {
+        rm_from_map(static_cast <XGL_VIEWPORT_STATE_OBJECT> (state));
+        rm_from_map(static_cast <XGL_RASTER_STATE_OBJECT> (state));
+        rm_from_map(static_cast <XGL_MSAA_STATE_OBJECT> (state));
+        rm_from_map(static_cast <XGL_COLOR_BLEND_STATE_OBJECT> (state));
+        rm_from_map(static_cast <XGL_DEPTH_STENCIL_STATE_OBJECT> (state));
+    }
+    std::map<XGL_CMD_BUFFER, XGL_CMD_BUFFER> m_cmdBuffers;
+    void add_to_map(XGL_CMD_BUFFER* pTraceCmdBuffer, XGL_CMD_BUFFER* pReplayCmdBuffer)
+    {
+        assert(pTraceCmdBuffer != NULL);
+        assert(pReplayCmdBuffer != NULL);
+        m_cmdBuffers[*pTraceCmdBuffer] = *pReplayCmdBuffer;
+    }
+    void rm_from_map(const XGL_CMD_BUFFER& cmdBuffer)
+    {
+        m_cmdBuffers.erase(cmdBuffer);
+    }
+    XGL_CMD_BUFFER remap(const XGL_CMD_BUFFER& cmdBuffer)
+    {
+        std::map<XGL_CMD_BUFFER, XGL_CMD_BUFFER>::const_iterator q = m_cmdBuffers.find(cmdBuffer);
+        return (q == m_cmdBuffers.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_FENCE, XGL_FENCE> m_fences;
+    void add_to_map(XGL_FENCE* pTraceFence, XGL_FENCE* pReplayFence)
+    {
+        assert(pTraceFence != NULL);
+        assert(pReplayFence != NULL);
+        m_fences[*pTraceFence] = *pReplayFence;
+    }
+    void rm_from_map(const XGL_FENCE& fence)
+    {
+        m_fences.erase(fence);
+    }
+    XGL_FENCE remap(const XGL_FENCE& fence)
+    {
+        std::map<XGL_FENCE, XGL_FENCE>::const_iterator q = m_fences.find(fence);
+        return (q == m_fences.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_QUEUE_SEMAPHORE, XGL_QUEUE_SEMAPHORE> m_queue_semaphores;
+    void add_to_map(XGL_QUEUE_SEMAPHORE* pTraceSema, XGL_QUEUE_SEMAPHORE* pReplaySema)
+    {
+        assert(pTraceSema != NULL);
+        assert(pReplaySema != NULL);
+        m_queue_semaphores[*pTraceSema] = *pReplaySema;
+    }
+    void rm_from_map(const XGL_QUEUE_SEMAPHORE& sema)
+    {
+        m_queue_semaphores.erase(sema);
+    }
+    XGL_QUEUE_SEMAPHORE remap(const XGL_QUEUE_SEMAPHORE& sema)
+    {
+        std::map<XGL_QUEUE_SEMAPHORE, XGL_QUEUE_SEMAPHORE>::const_iterator q = m_queue_semaphores.find(sema);
+        return (q == m_queue_semaphores.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_EVENT, XGL_EVENT> m_events;
+    void add_to_map(XGL_EVENT* pTraceEvent, XGL_EVENT* pReplayEvent)
+    {
+        assert(pTraceEvent != NULL);
+        assert(pReplayEvent != NULL);
+        m_events[*pTraceEvent] = *pReplayEvent;
+    }
+    void rm_from_map(const XGL_EVENT& event)
+    {
+        m_events.erase(event);
+    }
+    XGL_EVENT remap(const XGL_EVENT& event)
+    {
+        std::map<XGL_EVENT, XGL_EVENT>::const_iterator q = m_events.find(event);
+        return (q == m_events.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    std::map<XGL_QUERY_POOL, XGL_QUERY_POOL> m_queryPools;
+    void add_to_map(XGL_QUERY_POOL* pTracePool, XGL_QUERY_POOL* pReplayPool)
+    {
+        assert(pTracePool != NULL);
+        assert(pReplayPool != NULL);
+        m_queryPools[*pTracePool] = *pReplayPool;
+    }
+    void rm_from_map(const XGL_QUERY_POOL& queryPool)
+    {
+        m_queryPools.erase(queryPool);
+    }
+    XGL_QUERY_POOL remap(const XGL_QUERY_POOL& queryPool)
+    {
+        std::map<XGL_QUERY_POOL, XGL_QUERY_POOL>::const_iterator q = m_queryPools.find(queryPool);
+        return (q == m_queryPools.end()) ? XGL_NULL_HANDLE : q->second;
+    }
+
+    XGL_OBJECT remap(const XGL_OBJECT& object)
+    {
+        /*
+         * Includes: XGL_IMAGE, XGL_IMAGE_VIEW, XGL_COLOR_ATTACHMENT_VIEW, XGL_DEPTH_STENCIL_VIEW,
+         * XGL_SHADER, XGL_PIPELINE, XGL_PIPELINE_DELTA, XGL_SAMPLER, XGL_DESCRIPTOR_SET, XGL_STATE_OBJECT (plus subclasses),
+         * XGL_CMD_BUFFER, XGL_FENCE, XGL_QUEUE_SEMAPHORE, XGL_EVENT, XGL_QUERY_POOL
+         * XGL_WSI_WIN_DISPLAY
+         * XGL_BORDER_COLOR_PALETTE
+         */
+        XGL_OBJECT obj;
+        if ((obj = remap(static_cast <XGL_IMAGE> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_IMAGE_VIEW> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_COLOR_ATTACHMENT_VIEW> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_DEPTH_STENCIL_VIEW> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_SHADER> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_PIPELINE> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_PIPELINE_DELTA> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_SAMPLER> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_DESCRIPTOR_SET> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_STATE_OBJECT> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_CMD_BUFFER> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_FENCE> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_QUEUE_SEMAPHORE> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_EVENT> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_QUERY_POOL> (object))) != XGL_NULL_HANDLE)
+            return obj;
+
+        return XGL_NULL_HANDLE;
+    }
+
+    void rm_from_map(const XGL_OBJECT & objKey)
+    {
+        rm_from_map(static_cast <XGL_IMAGE> (objKey));
+        rm_from_map(static_cast <XGL_IMAGE_VIEW> (objKey));
+        rm_from_map(static_cast <XGL_COLOR_ATTACHMENT_VIEW> (objKey));
+        rm_from_map(static_cast <XGL_DEPTH_STENCIL_VIEW> (objKey));
+        rm_from_map(static_cast <XGL_SHADER> (objKey));
+        rm_from_map(static_cast <XGL_PIPELINE> (objKey));
+        rm_from_map(static_cast <XGL_PIPELINE_DELTA> (objKey));
+        rm_from_map(static_cast <XGL_SAMPLER> (objKey));
+        rm_from_map(static_cast <XGL_DESCRIPTOR_SET> (objKey));
+        rm_from_map(static_cast <XGL_STATE_OBJECT> (objKey));
+        rm_from_map(static_cast <XGL_CMD_BUFFER> (objKey));
+        rm_from_map(static_cast <XGL_FENCE> (objKey));
+        rm_from_map(static_cast <XGL_QUEUE_SEMAPHORE> (objKey));
+        rm_from_map(static_cast <XGL_EVENT> (objKey));
+        rm_from_map(static_cast <XGL_QUERY_POOL> (objKey));
+    }
+
+    XGL_BASE_OBJECT remap(const XGL_BASE_OBJECT& object)
+    {
+        XGL_BASE_OBJECT obj;
+
+        /*
+         * Includes: XGL_DEVICE, XGL_QUEUE, XGL_GPU_MEMORY, XGL_OBJECT
+         */
+        if ((obj = remap(static_cast <XGL_DEVICE> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_QUEUE> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_GPU_MEMORY> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        if ((obj = remap(static_cast <XGL_OBJECT> (object))) != XGL_NULL_HANDLE)
+            return obj;
+        return XGL_NULL_HANDLE;
+    }
+
+};
+
diff --git a/tools/glave/src/glv_extensions/glvtrace_gl_fps/CMakeLists.txt b/tools/glave/src/glv_extensions/glvtrace_gl_fps/CMakeLists.txt
new file mode 100644
index 0000000..e677727
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_gl_fps/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 2.8)
+
+# this project is only available on Windows
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+project(glvtrace_gl_fps)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glvtrace_gl_fps.c
+)
+
+set_source_files_properties( ${SRC_LIST} PROPERTIES LANGUAGE C)
+
+include_directories(
+    ${SRC_DIR}
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/glvtrace
+    ${SRC_DIR}/thirdparty
+)
+
+add_library(${PROJECT_NAME} SHARED ${SRC_LIST})
+
+target_link_libraries(${PROJECT_NAME} 
+    glvcommon
+    mhook
+)
+
+build_options_finalize()
+
+set_target_properties(glvtrace_gl_fps PROPERTIES LINKER_LANGUAGE C)
+
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
diff --git a/tools/glave/src/glv_extensions/glvtrace_gl_fps/glvtrace_gl_fps.c b/tools/glave/src/glv_extensions/glvtrace_gl_fps/glvtrace_gl_fps.c
new file mode 100644
index 0000000..e2fe1b7
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_gl_fps/glvtrace_gl_fps.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+// this tracer is really only valid on windows, so ifdef the entire file.
+#if defined(WIN32)
+
+#include <stdio.h>
+#include "glv_common.h"
+#include "glv_filelike.h"
+#include "glv_interconnect.h"
+#include "glv_trace_packet_identifiers.h"
+#include "mhook/mhook-lib/mhook.h"
+
+#pragma comment(lib, "opengl32.lib")
+
+// this is needed to be loaded by glvtrace
+GLVTRACER_EXPORT GLV_TRACER_ID GLVTRACER_STDCALL GLV_GetTracerId(void)
+{
+    return GLV_TID_GL_FPS;
+}
+
+// Pointers to real functions
+BOOL(APIENTRY * gReal_SwapBuffers)(HDC hdc) = SwapBuffers;
+
+BOOL g_bDisabled = FALSE;
+
+double g_frequency = 0.0;
+unsigned long long g_startTime = 0;
+unsigned long long g_frameCount = 0;
+
+BOOL APIENTRY hooked_SwapBuffers(HDC hdc)
+{
+    BOOL result = gReal_SwapBuffers(hdc);
+    unsigned long long difference;
+    double seconds;
+    LARGE_INTEGER tmp;
+    g_frameCount++;
+    QueryPerformanceCounter(&tmp);
+    difference = tmp.QuadPart - g_startTime;
+    seconds = (double)(difference) / g_frequency;
+    if (seconds > 1.0)
+    {
+        // it's been more than a second, report the frame rate
+        double frameRate = (double)(g_frameCount) / seconds;
+        glv_LogInfo("FPS: %f", frameRate);
+
+        // update start time and reset frame count
+        g_startTime = tmp.QuadPart;
+        g_frameCount = 0;
+    }
+
+    return result;
+}
+void AttachHooks()
+{
+    BOOL hookSuccess;
+    // If you need to debug startup, build with this set to true, then attach and change it to false.
+#ifdef _DEBUG
+    BOOL debugStartup = FALSE;
+    while (debugStartup);
+#endif
+
+    Mhook_Initialize();
+    Mhook_BeginMultiOperation(FALSE);
+    hookSuccess = TRUE;
+    if (gReal_SwapBuffers != NULL)
+    {
+        hookSuccess = Mhook_SetHook((PVOID*)&gReal_SwapBuffers, hooked_SwapBuffers);
+    }
+
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook SwapBuffers.\n");
+    }
+
+    Mhook_EndMultiOperation();
+}
+
+GLVTRACER_EXIT TrapExit(void)
+{
+    int i = 0;
+    ++i;
+}
+
+void DetachHooks()
+{
+    BOOL unhookSuccess = TRUE;
+    if (gReal_SwapBuffers != NULL)
+    {
+        unhookSuccess = Mhook_Unhook((PVOID*)&gReal_SwapBuffers);
+    }
+
+    if (!unhookSuccess)
+    {
+        glv_LogError("Failed to unhook SwapBuffers.\n");
+    }
+}
+
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                     )
+{
+    char exePath[MAX_PATH];
+    char* substr = ((sizeof(void*) == 4)? "glvtrace32.exe" : "glvtrace64.exe");
+    GetModuleFileName(NULL, exePath, MAX_PATH);
+    hModule;
+    lpReserved;
+
+    // only do the hooking and networking if the tracer is NOT being loaded by glvtrace
+    if (strstr(exePath, substr) == NULL)
+    {
+       switch (ul_reason_for_call)
+        {
+        case DLL_PROCESS_ATTACH:
+        {
+            LARGE_INTEGER tmp;
+            gMessageStream = glv_MessageStream_create(TRUE, "", GLV_BASE_PORT + GLV_TID_GL_FPS);
+
+            glv_trace_set_trace_file(glv_FileLike_create_msg(gMessageStream));
+            glv_tracelog_set_tracer_id(GLV_TID_GL_FPS);
+
+            glv_LogInfo("glvtrace_gl_fps loaded.");
+            if (QueryPerformanceFrequency(&tmp) == FALSE)
+            {
+                glv_LogError("QueryPerformanceFrequency failed, disabling tracer.");
+                g_bDisabled = TRUE;
+            }
+            else
+            {
+                g_frequency = (double)tmp.QuadPart;
+
+                QueryPerformanceCounter(&tmp);
+                g_startTime = tmp.QuadPart;
+
+                atexit(TrapExit);
+                AttachHooks();
+            }
+
+            break;
+        }
+        case DLL_PROCESS_DETACH:
+        {
+            if (!g_bDisabled)
+            {
+                DetachHooks();
+            }
+
+            GLV_DELETE(glv_trace_get_trace_file());
+            break;
+        }
+        default:
+            break;
+        }
+    }
+    return TRUE;
+}
+#endif
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/CMakeLists.txt b/tools/glave/src/glv_extensions/glvtrace_xgl/CMakeLists.txt
new file mode 100644
index 0000000..a79b8be
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/CMakeLists.txt
@@ -0,0 +1,61 @@
+cmake_minimum_required(VERSION 2.8)
+
+# this project is currently only available on Linux
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+
+project(glvtrace_xgl)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${SRC_DIR}/thirdparty/xgl/inc/)
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glvtrace_xgl.c
+    glvtrace_xgl_xgl.c
+    glvtrace_xgl_xgldbg.c
+    glvtrace_xgl_xglwsix11ext.c
+)
+
+set_source_files_properties( ${SRC_LIST} PROPERTIES LANGUAGE C)
+
+set (HDR_LIST
+    glvtrace_xgl_packet_id.h
+    glvtrace_xgl_xgl.h
+    glvtrace_xgl_xgl_structs.h
+    glvtrace_xgl_xgldbg.h
+    glvtrace_xgl_xgldbg_structs.h
+    glvtrace_xgl_xglwsix11ext.h
+    glvtrace_xgl_xglwsix11ext_structs.h
+)
+
+include_directories(
+    ${SRC_DIR}
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/glvtrace
+    ${SRC_DIR}/thirdparty
+)
+
+add_library(${PROJECT_NAME} SHARED ${SRC_LIST} ${HDR_LIST})
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+target_link_libraries(${PROJECT_NAME} 
+    glvcommon
+    ${SRC_DIR}/thirdparty/xgl/lib/libXGL.so.0
+    -shared
+    -ldl
+)
+endif()
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+target_link_libraries(${PROJECT_NAME} 
+    glvcommon
+    ${SRC_DIR}/thirdparty/xgl/lib/libXGL.dll
+)
+endif()
+
+build_options_finalize()
+
+set_target_properties(glvtrace_xgl PROPERTIES LINKER_LANGUAGE C)
+
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl.c b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl.c
new file mode 100644
index 0000000..0ba122c
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2014, Lunarg, Inc. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#include "glv_common.h"
+#include "glv_filelike.h"
+#include "glv_interconnect.h"
+#include "glvtrace_xgl_xgl.h"
+#include "glvtrace_xgl_xgldbg.h"
+#include "glvtrace_xgl_xglwsix11ext.h"
+
+// this is needed to be loaded by glvtrace
+GLVTRACER_EXPORT GLV_TRACER_ID GLVTRACER_STDCALL GLV_GetTracerId(void)
+{
+    return GLV_TID_XGL;
+}
+
+GLVTRACER_EXIT TrapExit(void)
+{
+    int i = 0;
+    ++i;
+}
+
+extern
+GLVTRACER_ENTRY _Load(void)
+{
+    // only do the hooking and networking if the tracer is NOT loaded by glvtrace
+    if (glv_is_loaded_into_glvtrace() == FALSE)
+    {
+        gMessageStream = glv_MessageStream_create(TRUE, "", GLV_BASE_PORT + GLV_TID_XGL);
+//        glv_tracelog_set_log_file(glv_FileLike_create_file(fopen("glv_log_traceside.txt","w")));
+        glv_tracelog_set_tracer_id(GLV_TID_XGL);
+        glv_LogInfo("glvtrace_xgl loaded into PID %d\n", glv_get_pid());
+        atexit(TrapExit);
+
+        // If you need to debug startup, build with this set to true, then attach and change it to false.
+    #ifdef _DEBUG
+        {
+        BOOL debugStartup = FALSE;
+        while (debugStartup);
+        }
+    #endif
+#ifndef PLATFORM_LINUX
+        AttachHooks();
+        AttachHooks_xgldbg();
+        AttachHooks_xglwsix11ext();
+#endif
+    }
+}
+
+GLVTRACER_LEAVE _Unload(void)
+{
+    // only do the hooking and networking if the tracer is NOT loaded by glvtrace
+    if (glv_is_loaded_into_glvtrace() == FALSE)
+    {
+        DetachHooks();
+        DetachHooks_xgldbg();
+        DetachHooks_xglwsix11ext();
+
+        glv_trace_packet_header* pHeader = glv_create_trace_packet(GLV_GetTracerId(), GLV_TPI_MARKER_TERMINATE_PROCESS, 0, 0);
+        glv_finalize_trace_packet(pHeader);
+        FileLike* pFileLike = glv_FileLike_create_msg(gMessageStream);
+        glv_write_trace_packet(pHeader, pFileLike);
+        glv_delete_trace_packet(&pHeader);
+        glv_free(pFileLike);
+
+        if (gMessageStream)
+            glv_MessageStream_destroy(&gMessageStream);
+
+    }
+    glv_tracelog_delete_log_file();
+}
+
+#if defined(WIN32)
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+                     )
+{
+    hModule;
+    lpReserved;
+
+    switch (ul_reason_for_call)
+    {
+    case DLL_PROCESS_ATTACH:
+    {
+        _Load();
+        break;
+    }
+    case DLL_PROCESS_DETACH:
+    {
+        _Unload();
+        break;
+    }
+    default:
+        break;
+    }
+    return TRUE;
+}
+#endif
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_packet_id.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_packet_id.h
new file mode 100644
index 0000000..b2c7010
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_packet_id.h
@@ -0,0 +1,175 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+#include "glv_trace_packet_utils.h"
+#include "glv_interconnect.h"
+
+#define SEND_ENTRYPOINT_ID(entrypoint) \
+    FileLike* pFile; \
+    pFile = glv_FileLike_create_msg(gMessageStream); \
+    glv_trace_set_trace_file(pFile); \
+    glv_TraceInfo(#entrypoint "\n");
+
+#define SEND_ENTRYPOINT_PARAMS(entrypoint, ...) \
+    FileLike* pFile; \
+    pFile = glv_FileLike_create_msg(gMessageStream); \
+    glv_trace_set_trace_file(pFile); \
+    glv_TraceInfo(entrypoint, __VA_ARGS__);
+
+#define CREATE_TRACE_PACKET(entrypoint, buffer_bytes_needed) \
+    pHeader = glv_create_trace_packet(GLV_TID_XGL, GLV_TPI_XGL_##entrypoint, sizeof(struct_##entrypoint), buffer_bytes_needed);
+
+#define FINISH_TRACE_PACKET() \
+    glv_finalize_trace_packet(pHeader); \
+    glv_write_trace_packet(pHeader, pFile); \
+    glv_delete_trace_packet(&pHeader); \
+    GLV_DELETE(pFile);
+
+enum GLV_TRACE_PACKET_ID_XGL
+{
+    // xgl.h
+    GLV_TPI_XGL_xglInitAndEnumerateGpus = GLV_TPI_BEGIN_API_HERE,
+    GLV_TPI_XGL_xglGetGpuInfo,
+    GLV_TPI_XGL_xglCreateDevice,
+    GLV_TPI_XGL_xglDestroyDevice,
+    GLV_TPI_XGL_xglGetExtensionSupport,
+    GLV_TPI_XGL_xglGetDeviceQueue,
+    GLV_TPI_XGL_xglQueueSubmit,
+    GLV_TPI_XGL_xglQueueSetGlobalMemReferences,
+    GLV_TPI_XGL_xglQueueWaitIdle,
+    GLV_TPI_XGL_xglDeviceWaitIdle,
+    GLV_TPI_XGL_xglGetMemoryHeapCount,
+    GLV_TPI_XGL_xglGetMemoryHeapInfo,
+    GLV_TPI_XGL_xglAllocMemory,
+    GLV_TPI_XGL_xglFreeMemory,
+    GLV_TPI_XGL_xglSetMemoryPriority,
+    GLV_TPI_XGL_xglMapMemory,
+    GLV_TPI_XGL_xglUnmapMemory,
+    GLV_TPI_XGL_xglPinSystemMemory,
+    GLV_TPI_XGL_xglRemapVirtualMemoryPages,
+    GLV_TPI_XGL_xglGetMultiGpuCompatibility,
+    GLV_TPI_XGL_xglOpenSharedMemory,
+    GLV_TPI_XGL_xglOpenSharedQueueSemaphore,
+    GLV_TPI_XGL_xglOpenPeerMemory,
+    GLV_TPI_XGL_xglOpenPeerImage,
+    GLV_TPI_XGL_xglDestroyObject,
+    GLV_TPI_XGL_xglGetObjectInfo,
+    GLV_TPI_XGL_xglBindObjectMemory,
+    GLV_TPI_XGL_xglCreateFence,
+    GLV_TPI_XGL_xglGetFenceStatus,
+    GLV_TPI_XGL_xglWaitForFences,
+    GLV_TPI_XGL_xglCreateQueueSemaphore,
+    GLV_TPI_XGL_xglSignalQueueSemaphore,
+    GLV_TPI_XGL_xglWaitQueueSemaphore,
+    GLV_TPI_XGL_xglCreateEvent,
+    GLV_TPI_XGL_xglGetEventStatus,
+    GLV_TPI_XGL_xglSetEvent,
+    GLV_TPI_XGL_xglResetEvent,
+    GLV_TPI_XGL_xglCreateQueryPool,
+    GLV_TPI_XGL_xglGetQueryPoolResults,
+    GLV_TPI_XGL_xglGetFormatInfo,
+    GLV_TPI_XGL_xglCreateImage,
+    GLV_TPI_XGL_xglGetImageSubresourceInfo,
+    GLV_TPI_XGL_xglCreateImageView,
+    GLV_TPI_XGL_xglCreateColorAttachmentView,
+    GLV_TPI_XGL_xglCreateDepthStencilView,
+    GLV_TPI_XGL_xglCreateShader,
+    GLV_TPI_XGL_xglCreateGraphicsPipeline,
+    GLV_TPI_XGL_xglCreateComputePipeline,
+    GLV_TPI_XGL_xglStorePipeline,
+    GLV_TPI_XGL_xglLoadPipeline,
+    GLV_TPI_XGL_xglCreatePipelineDelta,
+    GLV_TPI_XGL_xglCreateSampler,
+    GLV_TPI_XGL_xglCreateDescriptorSet,
+    GLV_TPI_XGL_xglBeginDescriptorSetUpdate,
+    GLV_TPI_XGL_xglEndDescriptorSetUpdate,
+    GLV_TPI_XGL_xglAttachSamplerDescriptors,
+    GLV_TPI_XGL_xglAttachImageViewDescriptors,
+    GLV_TPI_XGL_xglAttachMemoryViewDescriptors,
+    GLV_TPI_XGL_xglAttachNestedDescriptors,
+    GLV_TPI_XGL_xglClearDescriptorSetSlots,
+    GLV_TPI_XGL_xglCreateViewportState,
+    GLV_TPI_XGL_xglCreateRasterState,
+    GLV_TPI_XGL_xglCreateMsaaState,
+    GLV_TPI_XGL_xglCreateColorBlendState,
+    GLV_TPI_XGL_xglCreateDepthStencilState,
+    GLV_TPI_XGL_xglCreateCommandBuffer,
+    GLV_TPI_XGL_xglBeginCommandBuffer,
+    GLV_TPI_XGL_xglEndCommandBuffer,
+    GLV_TPI_XGL_xglResetCommandBuffer,
+    GLV_TPI_XGL_xglCmdBindPipeline,
+    GLV_TPI_XGL_xglCmdBindPipelineDelta,
+    GLV_TPI_XGL_xglCmdBindStateObject,
+    GLV_TPI_XGL_xglCmdBindDescriptorSet,
+    GLV_TPI_XGL_xglCmdBindDynamicMemoryView,
+    GLV_TPI_XGL_xglCmdBindIndexData,
+    GLV_TPI_XGL_xglCmdBindAttachments,
+    GLV_TPI_XGL_xglCmdPrepareMemoryRegions,
+    GLV_TPI_XGL_xglCmdPrepareImages,
+    GLV_TPI_XGL_xglCmdDraw,
+    GLV_TPI_XGL_xglCmdDrawIndexed,
+    GLV_TPI_XGL_xglCmdDrawIndirect,
+    GLV_TPI_XGL_xglCmdDrawIndexedIndirect,
+    GLV_TPI_XGL_xglCmdDispatch,
+    GLV_TPI_XGL_xglCmdDispatchIndirect,
+    GLV_TPI_XGL_xglCmdCopyMemory,
+    GLV_TPI_XGL_xglCmdCopyImage,
+    GLV_TPI_XGL_xglCmdCopyMemoryToImage,
+    GLV_TPI_XGL_xglCmdCopyImageToMemory,
+    GLV_TPI_XGL_xglCmdCloneImageData,
+    GLV_TPI_XGL_xglCmdUpdateMemory,
+    GLV_TPI_XGL_xglCmdFillMemory,
+    GLV_TPI_XGL_xglCmdClearColorImage,
+    GLV_TPI_XGL_xglCmdClearColorImageRaw,
+    GLV_TPI_XGL_xglCmdClearDepthStencil,
+    GLV_TPI_XGL_xglCmdResolveImage,
+    GLV_TPI_XGL_xglCmdSetEvent,
+    GLV_TPI_XGL_xglCmdResetEvent,
+    GLV_TPI_XGL_xglCmdMemoryAtomic,
+    GLV_TPI_XGL_xglCmdBeginQuery,
+    GLV_TPI_XGL_xglCmdEndQuery,
+    GLV_TPI_XGL_xglCmdResetQueryPool,
+    GLV_TPI_XGL_xglCmdWriteTimestamp,
+    GLV_TPI_XGL_xglCmdInitAtomicCounters,
+    GLV_TPI_XGL_xglCmdLoadAtomicCounters,
+    GLV_TPI_XGL_xglCmdSaveAtomicCounters,
+
+    // xglDbg.h
+    GLV_TPI_XGL_xglDbgSetValidationLevel,
+    GLV_TPI_XGL_xglDbgRegisterMsgCallback,
+    GLV_TPI_XGL_xglDbgUnregisterMsgCallback,
+    GLV_TPI_XGL_xglDbgSetMessageFilter,
+    GLV_TPI_XGL_xglDbgSetObjectTag,
+    GLV_TPI_XGL_xglDbgSetGlobalOption,
+    GLV_TPI_XGL_xglDbgSetDeviceOption,
+    GLV_TPI_XGL_xglCmdDbgMarkerBegin,
+    GLV_TPI_XGL_xglCmdDbgMarkerEnd,
+
+    //xglWsiX11Ext.h
+    GLV_TPI_XGL_xglWsiX11AssociateConnection,
+    GLV_TPI_XGL_xglWsiX11GetMSC,
+    GLV_TPI_XGL_xglWsiX11CreatePresentableImage,
+    GLV_TPI_XGL_xglWsiX11QueuePresent,
+};
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl.c b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl.c
new file mode 100644
index 0000000..c885b42
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl.c
@@ -0,0 +1,3575 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glv_platform.h"
+#include "glv_common.h"
+#include "glvtrace_xgl_xgl.h"
+#include "glvtrace_xgl_xgldbg.h"
+#include "glvtrace_xgl_xglwsix11ext.h"
+#include "glv_interconnect.h"
+#include "glv_filelike.h"
+#ifdef WIN32
+#include "mhook/mhook-lib/mhook.h"
+#endif
+#include "glv_trace_packet_utils.h"
+#include <stdio.h>
+
+
+static XGL_RESULT( XGLAPI * real_xglInitAndEnumerateGpus)(
+    const XGL_APPLICATION_INFO* pAppInfo,
+    const XGL_ALLOC_CALLBACKS*  pAllocCb,
+    XGL_UINT                    maxGpus,
+    XGL_UINT*                   pGpuCount,
+    XGL_PHYSICAL_GPU*           pGpus) = xglInitAndEnumerateGpus;
+
+static XGL_RESULT( XGLAPI * real_xglGetGpuInfo)(
+    XGL_PHYSICAL_GPU            gpu,
+    XGL_PHYSICAL_GPU_INFO_TYPE  infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData) = xglGetGpuInfo;
+
+static XGL_RESULT( XGLAPI * real_xglCreateDevice)(
+    XGL_PHYSICAL_GPU              gpu,
+    const XGL_DEVICE_CREATE_INFO* pCreateInfo,
+    XGL_DEVICE*                   pDevice) = xglCreateDevice;
+
+static XGL_RESULT( XGLAPI * real_xglDestroyDevice)(
+    XGL_DEVICE device) = xglDestroyDevice;
+
+static XGL_RESULT( XGLAPI * real_xglGetExtensionSupport)(
+    XGL_PHYSICAL_GPU gpu,
+    const XGL_CHAR*  pExtName) = xglGetExtensionSupport;
+
+static XGL_RESULT( XGLAPI * real_xglGetDeviceQueue)(
+    XGL_DEVICE       device,
+    XGL_QUEUE_TYPE   queueType,
+    XGL_UINT         queueIndex,
+    XGL_QUEUE*       pQueue) = xglGetDeviceQueue;
+
+static XGL_RESULT( XGLAPI * real_xglQueueSubmit)(
+    XGL_QUEUE             queue,
+    XGL_UINT              cmdBufferCount,
+    const XGL_CMD_BUFFER* pCmdBuffers,
+    XGL_UINT              memRefCount,
+    const XGL_MEMORY_REF* pMemRefs,
+    XGL_FENCE             fence) = xglQueueSubmit;
+
+static XGL_RESULT( XGLAPI * real_xglQueueSetGlobalMemReferences)(
+    XGL_QUEUE             queue,
+    XGL_UINT              memRefCount,
+    const XGL_MEMORY_REF* pMemRefs) = xglQueueSetGlobalMemReferences;
+
+static XGL_RESULT( XGLAPI * real_xglQueueWaitIdle)(
+    XGL_QUEUE queue) = xglQueueWaitIdle;
+
+static XGL_RESULT( XGLAPI * real_xglDeviceWaitIdle)(
+    XGL_DEVICE device) = xglDeviceWaitIdle;
+
+static XGL_RESULT( XGLAPI * real_xglGetMemoryHeapCount)(
+    XGL_DEVICE  device,
+    XGL_UINT*   pCount) = xglGetMemoryHeapCount;
+
+static XGL_RESULT( XGLAPI * real_xglGetMemoryHeapInfo)(
+    XGL_DEVICE                  device,
+    XGL_UINT                    heapId,
+    XGL_MEMORY_HEAP_INFO_TYPE   infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData) = xglGetMemoryHeapInfo;
+
+static XGL_RESULT( XGLAPI * real_xglAllocMemory)(
+    XGL_DEVICE                   device,
+    const XGL_MEMORY_ALLOC_INFO* pAllocInfo,
+    XGL_GPU_MEMORY*              pMem) = xglAllocMemory;
+
+static XGL_RESULT( XGLAPI * real_xglFreeMemory)(
+    XGL_GPU_MEMORY mem) = xglFreeMemory;
+
+static XGL_RESULT( XGLAPI * real_xglSetMemoryPriority)(
+    XGL_GPU_MEMORY            mem,
+    XGL_MEMORY_PRIORITY       priority) = xglSetMemoryPriority;
+
+static XGL_RESULT( XGLAPI * real_xglMapMemory)(
+    XGL_GPU_MEMORY mem,
+    XGL_FLAGS      flags,                // Reserved
+    XGL_VOID**     ppData) = xglMapMemory;
+
+static XGL_RESULT( XGLAPI * real_xglUnmapMemory)(
+    XGL_GPU_MEMORY mem) = xglUnmapMemory;
+
+static XGL_RESULT( XGLAPI * real_xglPinSystemMemory)(
+    XGL_DEVICE      device,
+    const XGL_VOID* pSysMem,
+    XGL_SIZE        memSize,
+    XGL_GPU_MEMORY* pMem) = xglPinSystemMemory;
+
+static XGL_RESULT( XGLAPI * real_xglRemapVirtualMemoryPages)(
+    XGL_DEVICE                            device,
+    XGL_UINT                              rangeCount,
+    const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pRanges,
+    XGL_UINT                              preWaitSemaphoreCount,
+    const XGL_QUEUE_SEMAPHORE*            pPreWaitSemaphores,
+    XGL_UINT                              postSignalSemaphoreCount,
+    const XGL_QUEUE_SEMAPHORE*            pPostSignalSemaphores) = xglRemapVirtualMemoryPages;
+
+static XGL_RESULT( XGLAPI * real_xglGetMultiGpuCompatibility)(
+    XGL_PHYSICAL_GPU            gpu0,
+    XGL_PHYSICAL_GPU            gpu1,
+    XGL_GPU_COMPATIBILITY_INFO* pInfo) = xglGetMultiGpuCompatibility;
+
+static XGL_RESULT( XGLAPI * real_xglOpenSharedMemory)(
+    XGL_DEVICE                  device,
+    const XGL_MEMORY_OPEN_INFO* pOpenInfo,
+    XGL_GPU_MEMORY*             pMem) = xglOpenSharedMemory;
+
+static XGL_RESULT( XGLAPI * real_xglOpenSharedQueueSemaphore)(
+    XGL_DEVICE                           device,
+    const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pOpenInfo,
+    XGL_QUEUE_SEMAPHORE*                 pSemaphore) = xglOpenSharedQueueSemaphore;
+
+static XGL_RESULT( XGLAPI * real_xglOpenPeerMemory)(
+    XGL_DEVICE                       device,
+    const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo,
+    XGL_GPU_MEMORY*                  pMem) = xglOpenPeerMemory;
+
+static XGL_RESULT( XGLAPI * real_xglOpenPeerImage)(
+    XGL_DEVICE                      device,
+    const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo,
+    XGL_IMAGE*                      pImage,
+    XGL_GPU_MEMORY*                 pMem) = xglOpenPeerImage;
+
+static XGL_RESULT( XGLAPI * real_xglDestroyObject)(
+    XGL_OBJECT object) = xglDestroyObject;
+
+static XGL_RESULT( XGLAPI * real_xglGetObjectInfo)(
+    XGL_BASE_OBJECT             object,
+    XGL_OBJECT_INFO_TYPE        infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData) = xglGetObjectInfo;
+
+static XGL_RESULT( XGLAPI * real_xglBindObjectMemory)(
+    XGL_OBJECT     object,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset) = xglBindObjectMemory;
+
+static XGL_RESULT( XGLAPI * real_xglCreateFence)(
+    XGL_DEVICE                   device,
+    const XGL_FENCE_CREATE_INFO* pCreateInfo,
+    XGL_FENCE*                   pFence) = xglCreateFence;
+
+static XGL_RESULT( XGLAPI * real_xglGetFenceStatus)(
+    XGL_FENCE fence) = xglGetFenceStatus;
+
+static XGL_RESULT( XGLAPI * real_xglWaitForFences)(
+    XGL_DEVICE       device,
+    XGL_UINT         fenceCount,
+    const XGL_FENCE* pFences,
+    XGL_BOOL         waitAll,
+    XGL_UINT64       timeout) = xglWaitForFences;
+
+static XGL_RESULT( XGLAPI * real_xglCreateQueueSemaphore)(
+    XGL_DEVICE                             device,
+    const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pCreateInfo,
+    XGL_QUEUE_SEMAPHORE*                   pSemaphore) = xglCreateQueueSemaphore;
+
+static XGL_RESULT( XGLAPI * real_xglSignalQueueSemaphore)(
+    XGL_QUEUE           queue,
+    XGL_QUEUE_SEMAPHORE semaphore) = xglSignalQueueSemaphore;
+
+static XGL_RESULT( XGLAPI * real_xglWaitQueueSemaphore)(
+    XGL_QUEUE           queue,
+    XGL_QUEUE_SEMAPHORE semaphore) = xglWaitQueueSemaphore;
+
+static XGL_RESULT( XGLAPI * real_xglCreateEvent)(
+    XGL_DEVICE                   device,
+    const XGL_EVENT_CREATE_INFO* pCreateInfo,
+    XGL_EVENT*                   pEvent) = xglCreateEvent;
+
+static XGL_RESULT( XGLAPI * real_xglGetEventStatus)(
+    XGL_EVENT event) = xglGetEventStatus;
+
+static XGL_RESULT( XGLAPI * real_xglSetEvent)(
+    XGL_EVENT event) = xglSetEvent;
+
+static XGL_RESULT( XGLAPI * real_xglResetEvent)(
+    XGL_EVENT event) = xglResetEvent;
+
+static XGL_RESULT( XGLAPI * real_xglCreateQueryPool)(
+    XGL_DEVICE                        device,
+    const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo,
+    XGL_QUERY_POOL*                   pQueryPool) = xglCreateQueryPool;
+
+static XGL_RESULT( XGLAPI * real_xglGetQueryPoolResults)(
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       startQuery,
+    XGL_UINT       queryCount,
+    XGL_SIZE*      pDataSize,
+    XGL_VOID*      pData) = xglGetQueryPoolResults;
+
+static XGL_RESULT( XGLAPI * real_xglGetFormatInfo)(
+    XGL_DEVICE             device,
+    XGL_FORMAT             format,
+    XGL_FORMAT_INFO_TYPE   infoType,
+    XGL_SIZE*              pDataSize,
+    XGL_VOID*              pData) = xglGetFormatInfo;
+
+static XGL_RESULT( XGLAPI * real_xglCreateImage)(
+    XGL_DEVICE                   device,
+    const XGL_IMAGE_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE*                   pImage) = xglCreateImage;
+
+static XGL_RESULT( XGLAPI * real_xglGetImageSubresourceInfo)(
+    XGL_IMAGE                    image,
+    const XGL_IMAGE_SUBRESOURCE* pSubresource,
+    XGL_SUBRESOURCE_INFO_TYPE    infoType,
+    XGL_SIZE*                    pDataSize,
+    XGL_VOID*                    pData) = xglGetImageSubresourceInfo;
+
+static XGL_RESULT( XGLAPI * real_xglCreateImageView)(
+    XGL_DEVICE                        device,
+    const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE_VIEW*                   pView) = xglCreateImageView;
+
+static XGL_RESULT( XGLAPI * real_xglCreateColorAttachmentView)(
+    XGL_DEVICE                                   device,
+    const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_COLOR_ATTACHMENT_VIEW*                   pView) = xglCreateColorAttachmentView;
+
+static XGL_RESULT( XGLAPI * real_xglCreateDepthStencilView)(
+    XGL_DEVICE                                device,
+    const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_DEPTH_STENCIL_VIEW*                   pView) = xglCreateDepthStencilView;
+
+static XGL_RESULT( XGLAPI * real_xglCreateShader)(
+    XGL_DEVICE                    device,
+    const XGL_SHADER_CREATE_INFO* pCreateInfo,
+    XGL_SHADER*                   pShader) = xglCreateShader;
+
+static XGL_RESULT( XGLAPI * real_xglCreateGraphicsPipeline)(
+    XGL_DEVICE                               device,
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
+    XGL_PIPELINE*                            pPipeline) = xglCreateGraphicsPipeline;
+
+static XGL_RESULT( XGLAPI * real_xglCreateComputePipeline)(
+    XGL_DEVICE                              device,
+    const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
+    XGL_PIPELINE*                           pPipeline) = xglCreateComputePipeline;
+
+static XGL_RESULT( XGLAPI * real_xglStorePipeline)(
+    XGL_PIPELINE pipeline,
+    XGL_SIZE*    pDataSize,
+    XGL_VOID*    pData) = xglStorePipeline;
+
+static XGL_RESULT( XGLAPI * real_xglLoadPipeline)(
+    XGL_DEVICE      device,
+    XGL_SIZE        dataSize,
+    const XGL_VOID* pData,
+    XGL_PIPELINE*   pPipeline) = xglLoadPipeline;
+
+static XGL_RESULT( XGLAPI * real_xglCreatePipelineDelta)(
+    XGL_DEVICE      device,
+    XGL_PIPELINE    p1,
+    XGL_PIPELINE    p2,
+    XGL_PIPELINE_DELTA*   delta) = xglCreatePipelineDelta;
+
+static XGL_RESULT( XGLAPI * real_xglCreateSampler)(
+    XGL_DEVICE                     device,
+    const XGL_SAMPLER_CREATE_INFO* pCreateInfo,
+    XGL_SAMPLER*                   pSampler) = xglCreateSampler;
+
+static XGL_RESULT( XGLAPI * real_xglCreateDescriptorSet)(
+    XGL_DEVICE                            device,
+    const XGL_DESCRIPTOR_SET_CREATE_INFO* pCreateInfo,
+    XGL_DESCRIPTOR_SET*                   pDescriptorSet) = xglCreateDescriptorSet;
+
+
+static XGL_VOID( XGLAPI * real_xglBeginDescriptorSetUpdate)(
+    XGL_DESCRIPTOR_SET descriptorSet) = xglBeginDescriptorSetUpdate;
+
+static XGL_VOID( XGLAPI * real_xglEndDescriptorSetUpdate)(
+    XGL_DESCRIPTOR_SET descriptorSet) = xglEndDescriptorSetUpdate;
+
+static XGL_VOID( XGLAPI * real_xglAttachSamplerDescriptors)(
+    XGL_DESCRIPTOR_SET descriptorSet,
+    XGL_UINT           startSlot,
+    XGL_UINT           slotCount,
+    const XGL_SAMPLER* pSamplers) = xglAttachSamplerDescriptors;
+
+static XGL_VOID( XGLAPI * real_xglAttachImageViewDescriptors)(
+    XGL_DESCRIPTOR_SET                descriptorSet,
+    XGL_UINT                          startSlot,
+    XGL_UINT                          slotCount,
+    const XGL_IMAGE_VIEW_ATTACH_INFO* pImageViews) = xglAttachImageViewDescriptors;
+
+static XGL_VOID( XGLAPI * real_xglAttachMemoryViewDescriptors)(
+    XGL_DESCRIPTOR_SET                 descriptorSet,
+    XGL_UINT                           startSlot,
+    XGL_UINT                           slotCount,
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemViews) = xglAttachMemoryViewDescriptors;
+
+static XGL_VOID( XGLAPI * real_xglAttachNestedDescriptors)(
+    XGL_DESCRIPTOR_SET                    descriptorSet,
+    XGL_UINT                              startSlot,
+    XGL_UINT                              slotCount,
+    const XGL_DESCRIPTOR_SET_ATTACH_INFO* pNestedDescriptorSets) = xglAttachNestedDescriptors;
+
+static XGL_VOID( XGLAPI * real_xglClearDescriptorSetSlots)(
+    XGL_DESCRIPTOR_SET descriptorSet,
+    XGL_UINT           startSlot,
+    XGL_UINT           slotCount) = xglClearDescriptorSetSlots;
+
+static XGL_RESULT( XGLAPI * real_xglCreateViewportState)(
+    XGL_DEVICE                            device,
+    const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
+    XGL_VIEWPORT_STATE_OBJECT*            pState) = xglCreateViewportState;
+
+static XGL_RESULT( XGLAPI * real_xglCreateRasterState)(
+    XGL_DEVICE                          device,
+    const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
+    XGL_RASTER_STATE_OBJECT*            pState) = xglCreateRasterState;
+
+static XGL_RESULT( XGLAPI * real_xglCreateMsaaState)(
+    XGL_DEVICE                        device,
+    const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
+    XGL_MSAA_STATE_OBJECT*            pState) = xglCreateMsaaState;
+
+static XGL_RESULT( XGLAPI * real_xglCreateColorBlendState)(
+    XGL_DEVICE                               device,
+    const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
+    XGL_COLOR_BLEND_STATE_OBJECT*            pState) = xglCreateColorBlendState;
+
+static XGL_RESULT( XGLAPI * real_xglCreateDepthStencilState)(
+    XGL_DEVICE                                 device,
+    const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
+    XGL_DEPTH_STENCIL_STATE_OBJECT*            pState) = xglCreateDepthStencilState;
+
+static XGL_RESULT( XGLAPI * real_xglCreateCommandBuffer)(
+    XGL_DEVICE                        device,
+    const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
+    XGL_CMD_BUFFER*                   pCmdBuffer) = xglCreateCommandBuffer;
+
+static XGL_RESULT( XGLAPI * real_xglBeginCommandBuffer)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_FLAGS      flags) = xglBeginCommandBuffer;               // XGL_CMD_BUFFER_BUILD_FLAGS
+
+static XGL_RESULT( XGLAPI * real_xglEndCommandBuffer)(
+    XGL_CMD_BUFFER cmdBuffer) = xglEndCommandBuffer;
+
+static XGL_RESULT( XGLAPI * real_xglResetCommandBuffer)(
+    XGL_CMD_BUFFER cmdBuffer) = xglResetCommandBuffer;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindPipeline)(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_PIPELINE                  pipeline) = xglCmdBindPipeline;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindPipelineDelta)(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_PIPELINE_DELTA            delta) = xglCmdBindPipelineDelta;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindStateObject)(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_STATE_BIND_POINT         stateBindPoint,
+    XGL_STATE_OBJECT             state) = xglCmdBindStateObject;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindDescriptorSet)(
+    XGL_CMD_BUFFER                    cmdBuffer,
+    XGL_PIPELINE_BIND_POINT           pipelineBindPoint,
+    XGL_UINT                          index,
+    XGL_DESCRIPTOR_SET                descriptorSet,
+    XGL_UINT                          slotOffset) = xglCmdBindDescriptorSet;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindDynamicMemoryView)(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_PIPELINE_BIND_POINT            pipelineBindPoint,
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView) = xglCmdBindDynamicMemoryView;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindIndexData)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_INDEX_TYPE indexType) = xglCmdBindIndexData;
+
+static XGL_VOID( XGLAPI * real_xglCmdBindAttachments)(
+    XGL_CMD_BUFFER                         cmdBuffer,
+    XGL_UINT                               colorTargetCount,
+    const XGL_COLOR_ATTACHMENT_BIND_INFO*  pColorTargets,
+    const XGL_DEPTH_STENCIL_BIND_INFO*     pDepthTarget) = xglCmdBindAttachments;
+
+static XGL_VOID( XGLAPI * real_xglCmdPrepareMemoryRegions)(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_UINT                           transitionCount,
+    const XGL_MEMORY_STATE_TRANSITION* pStateTransitions) = xglCmdPrepareMemoryRegions;
+
+static XGL_VOID( XGLAPI * real_xglCmdPrepareImages)(
+    XGL_CMD_BUFFER                    cmdBuffer,
+    XGL_UINT                          transitionCount,
+    const XGL_IMAGE_STATE_TRANSITION* pStateTransitions) = xglCmdPrepareImages;
+
+static XGL_VOID( XGLAPI * real_xglCmdDraw)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       firstVertex,
+    XGL_UINT       vertexCount,
+    XGL_UINT       firstInstance,
+    XGL_UINT       instanceCount) = xglCmdDraw;
+
+static XGL_VOID( XGLAPI * real_xglCmdDrawIndexed)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       firstIndex,
+    XGL_UINT       indexCount,
+    XGL_INT        vertexOffset,
+    XGL_UINT       firstInstance,
+    XGL_UINT       instanceCount) = xglCmdDrawIndexed;
+
+static XGL_VOID( XGLAPI * real_xglCmdDrawIndirect)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_UINT32     count,
+    XGL_UINT32     stride) = xglCmdDrawIndirect;
+
+static XGL_VOID( XGLAPI * real_xglCmdDrawIndexedIndirect)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_UINT32     count,
+    XGL_UINT32     stride) = xglCmdDrawIndexedIndirect;
+
+static XGL_VOID( XGLAPI * real_xglCmdDispatch)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       x,
+    XGL_UINT       y,
+    XGL_UINT       z) = xglCmdDispatch;
+
+static XGL_VOID( XGLAPI * real_xglCmdDispatchIndirect)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset) = xglCmdDispatchIndirect;
+
+static XGL_VOID( XGLAPI * real_xglCmdCopyMemory)(
+    XGL_CMD_BUFFER         cmdBuffer,
+    XGL_GPU_MEMORY         srcMem,
+    XGL_GPU_MEMORY         destMem,
+    XGL_UINT               regionCount,
+    const XGL_MEMORY_COPY* pRegions) = xglCmdCopyMemory;
+
+static XGL_VOID( XGLAPI * real_xglCmdCopyImage)(
+    XGL_CMD_BUFFER        cmdBuffer,
+    XGL_IMAGE             srcImage,
+    XGL_IMAGE             destImage,
+    XGL_UINT              regionCount,
+    const XGL_IMAGE_COPY* pRegions) = xglCmdCopyImage;
+
+static XGL_VOID( XGLAPI * real_xglCmdCopyMemoryToImage)(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_GPU_MEMORY               srcMem,
+    XGL_IMAGE                    destImage,
+    XGL_UINT                     regionCount,
+    const XGL_MEMORY_IMAGE_COPY* pRegions) = xglCmdCopyMemoryToImage;
+
+static XGL_VOID( XGLAPI * real_xglCmdCopyImageToMemory)(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_IMAGE                    srcImage,
+    XGL_GPU_MEMORY               destMem,
+    XGL_UINT                     regionCount,
+    const XGL_MEMORY_IMAGE_COPY* pRegions) = xglCmdCopyImageToMemory;
+
+static XGL_VOID( XGLAPI * real_xglCmdCloneImageData)(
+    XGL_CMD_BUFFER  cmdBuffer,
+    XGL_IMAGE       srcImage,
+    XGL_IMAGE_STATE srcImageState,
+    XGL_IMAGE       destImage,
+    XGL_IMAGE_STATE destImageState) = xglCmdCloneImageData;
+
+static XGL_VOID( XGLAPI * real_xglCmdUpdateMemory)(
+    XGL_CMD_BUFFER    cmdBuffer,
+    XGL_GPU_MEMORY    destMem,
+    XGL_GPU_SIZE      destOffset,
+    XGL_GPU_SIZE      dataSize,
+    const XGL_UINT32* pData) = xglCmdUpdateMemory;
+
+static XGL_VOID( XGLAPI * real_xglCmdFillMemory)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY destMem,
+    XGL_GPU_SIZE   destOffset,
+    XGL_GPU_SIZE   fillSize,
+    XGL_UINT32     data) = xglCmdFillMemory;
+
+static XGL_VOID( XGLAPI * real_xglCmdClearColorImage)(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    const XGL_FLOAT                    color[4],
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges) = xglCmdClearColorImage;
+
+static XGL_VOID( XGLAPI * real_xglCmdClearColorImageRaw)(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    const XGL_UINT32                   color[4],
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges) = xglCmdClearColorImageRaw;
+
+static XGL_VOID( XGLAPI * real_xglCmdClearDepthStencil)(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    XGL_FLOAT                          depth,
+    XGL_UINT32                         stencil,
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges) = xglCmdClearDepthStencil;
+
+static XGL_VOID( XGLAPI * real_xglCmdResolveImage)(
+    XGL_CMD_BUFFER           cmdBuffer,
+    XGL_IMAGE                srcImage,
+    XGL_IMAGE                destImage,
+    XGL_UINT                 rectCount,
+    const XGL_IMAGE_RESOLVE* pRects) = xglCmdResolveImage;
+
+static XGL_VOID( XGLAPI * real_xglCmdSetEvent)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_EVENT      event) = xglCmdSetEvent;
+
+static XGL_VOID( XGLAPI * real_xglCmdResetEvent)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_EVENT      event) = xglCmdResetEvent;
+
+static XGL_VOID( XGLAPI * real_xglCmdMemoryAtomic)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY destMem,
+    XGL_GPU_SIZE   destOffset,
+    XGL_UINT64     srcData,
+    XGL_ATOMIC_OP  atomicOp) = xglCmdMemoryAtomic;
+
+static XGL_VOID( XGLAPI * real_xglCmdBeginQuery)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       slot,
+    XGL_FLAGS      flags) = xglCmdBeginQuery;
+
+static XGL_VOID( XGLAPI * real_xglCmdEndQuery)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       slot) = xglCmdEndQuery;
+
+static XGL_VOID( XGLAPI * real_xglCmdResetQueryPool)(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       startQuery,
+    XGL_UINT       queryCount) = xglCmdResetQueryPool;
+
+static XGL_VOID( XGLAPI * real_xglCmdWriteTimestamp)(
+    XGL_CMD_BUFFER           cmdBuffer,
+    XGL_TIMESTAMP_TYPE       timestampType,
+    XGL_GPU_MEMORY           destMem,
+    XGL_GPU_SIZE             destOffset) = xglCmdWriteTimestamp;
+
+static XGL_VOID( XGLAPI * real_xglCmdInitAtomicCounters)(
+    XGL_CMD_BUFFER                   cmdBuffer,
+    XGL_PIPELINE_BIND_POINT          pipelineBindPoint,
+    XGL_UINT                         startCounter,
+    XGL_UINT                         counterCount,
+    const XGL_UINT32*                pData) = xglCmdInitAtomicCounters;
+
+static XGL_VOID( XGLAPI * real_xglCmdLoadAtomicCounters)(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_UINT                      startCounter,
+    XGL_UINT                      counterCount,
+    XGL_GPU_MEMORY                srcMem,
+    XGL_GPU_SIZE                  srcOffset) = xglCmdLoadAtomicCounters;
+
+static XGL_VOID( XGLAPI * real_xglCmdSaveAtomicCounters)(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_UINT                      startCounter,
+    XGL_UINT                      counterCount,
+    XGL_GPU_MEMORY                destMem,
+    XGL_GPU_SIZE                  destOffset) = xglCmdSaveAtomicCounters;
+
+static BOOL isHooked = FALSE;
+
+void AttachHooks()
+{
+    BOOL hookSuccess = TRUE;
+#if defined(WIN32)
+    Mhook_BeginMultiOperation(FALSE);
+    if (real_xglInitAndEnumerateGpus != NULL)
+    {
+        isHooked = TRUE;
+        hookSuccess = Mhook_SetHook((PVOID*)&real_xglInitAndEnumerateGpus, hooked_xglInitAndEnumerateGpus);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetGpuInfo, hooked_xglGetGpuInfo);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateDevice, hooked_xglCreateDevice);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDestroyDevice, hooked_xglDestroyDevice);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetExtensionSupport, hooked_xglGetExtensionSupport);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetDeviceQueue, hooked_xglGetDeviceQueue);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglQueueSubmit, hooked_xglQueueSubmit);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglQueueSetGlobalMemReferences, hooked_xglQueueSetGlobalMemReferences);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglQueueWaitIdle, hooked_xglQueueWaitIdle);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDeviceWaitIdle, hooked_xglDeviceWaitIdle);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetMemoryHeapCount, hooked_xglGetMemoryHeapCount);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetMemoryHeapInfo, hooked_xglGetMemoryHeapInfo);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglAllocMemory, hooked_xglAllocMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglFreeMemory, hooked_xglFreeMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglSetMemoryPriority, hooked_xglSetMemoryPriority);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglMapMemory, hooked_xglMapMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglUnmapMemory, hooked_xglUnmapMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglPinSystemMemory, hooked_xglPinSystemMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglRemapVirtualMemoryPages, hooked_xglRemapVirtualMemoryPages);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetMultiGpuCompatibility, hooked_xglGetMultiGpuCompatibility);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglOpenSharedMemory, hooked_xglOpenSharedMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglOpenSharedQueueSemaphore, hooked_xglOpenSharedQueueSemaphore);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglOpenPeerMemory, hooked_xglOpenPeerMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglOpenPeerImage, hooked_xglOpenPeerImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDestroyObject, hooked_xglDestroyObject);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetObjectInfo, hooked_xglGetObjectInfo);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglBindObjectMemory, hooked_xglBindObjectMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateFence, hooked_xglCreateFence);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetFenceStatus, hooked_xglGetFenceStatus);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglWaitForFences, hooked_xglWaitForFences);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateQueueSemaphore, hooked_xglCreateQueueSemaphore);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglSignalQueueSemaphore, hooked_xglSignalQueueSemaphore);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglWaitQueueSemaphore, hooked_xglWaitQueueSemaphore);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateEvent, hooked_xglCreateEvent);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetEventStatus, hooked_xglGetEventStatus);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglSetEvent, hooked_xglSetEvent);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglResetEvent, hooked_xglResetEvent);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateQueryPool, hooked_xglCreateQueryPool);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetQueryPoolResults, hooked_xglGetQueryPoolResults);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetFormatInfo, hooked_xglGetFormatInfo);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateImage, hooked_xglCreateImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglGetImageSubresourceInfo, hooked_xglGetImageSubresourceInfo);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateImageView, hooked_xglCreateImageView);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateColorAttachmentView, hooked_xglCreateColorAttachmentView);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateDepthStencilView, hooked_xglCreateDepthStencilView);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateShader, hooked_xglCreateShader);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateGraphicsPipeline, hooked_xglCreateGraphicsPipeline);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateComputePipeline, hooked_xglCreateComputePipeline);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglStorePipeline, hooked_xglStorePipeline);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglLoadPipeline, hooked_xglLoadPipeline);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreatePipelineDelta, hooked_xglCreatePipelineDelta);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateSampler, hooked_xglCreateSampler);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateDescriptorSet, hooked_xglCreateDescriptorSet);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglBeginDescriptorSetUpdate, hooked_xglBeginDescriptorSetUpdate);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglEndDescriptorSetUpdate, hooked_xglEndDescriptorSetUpdate);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglAttachSamplerDescriptors, hooked_xglAttachSamplerDescriptors);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglAttachImageViewDescriptors, hooked_xglAttachImageViewDescriptors);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglAttachMemoryViewDescriptors, hooked_xglAttachMemoryViewDescriptors);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglAttachNestedDescriptors, hooked_xglAttachNestedDescriptors);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglClearDescriptorSetSlots, hooked_xglClearDescriptorSetSlots);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateViewportState, hooked_xglCreateViewportState);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateRasterState, hooked_xglCreateRasterState);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateMsaaState, hooked_xglCreateMsaaState);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateColorBlendState, hooked_xglCreateColorBlendState);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateDepthStencilState, hooked_xglCreateDepthStencilState);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCreateCommandBuffer, hooked_xglCreateCommandBuffer);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglBeginCommandBuffer, hooked_xglBeginCommandBuffer);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglEndCommandBuffer, hooked_xglEndCommandBuffer);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglResetCommandBuffer, hooked_xglResetCommandBuffer);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindPipeline, hooked_xglCmdBindPipeline);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindPipelineDelta, hooked_xglCmdBindPipelineDelta);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindStateObject, hooked_xglCmdBindStateObject);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindDescriptorSet, hooked_xglCmdBindDescriptorSet);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindDynamicMemoryView, hooked_xglCmdBindDynamicMemoryView);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindIndexData, hooked_xglCmdBindIndexData);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBindAttachments, hooked_xglCmdBindAttachments);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdPrepareMemoryRegions, hooked_xglCmdPrepareMemoryRegions);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdPrepareImages, hooked_xglCmdPrepareImages);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDraw, hooked_xglCmdDraw);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDrawIndexed, hooked_xglCmdDrawIndexed);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDrawIndirect, hooked_xglCmdDrawIndirect);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDrawIndexedIndirect, hooked_xglCmdDrawIndexedIndirect);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDispatch, hooked_xglCmdDispatch);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDispatchIndirect, hooked_xglCmdDispatchIndirect);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdCopyMemory, hooked_xglCmdCopyMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdCopyImage, hooked_xglCmdCopyImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdCopyMemoryToImage, hooked_xglCmdCopyMemoryToImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdCopyImageToMemory, hooked_xglCmdCopyImageToMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdCloneImageData, hooked_xglCmdCloneImageData);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdUpdateMemory, hooked_xglCmdUpdateMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdFillMemory, hooked_xglCmdFillMemory);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdClearColorImage, hooked_xglCmdClearColorImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdClearColorImageRaw, hooked_xglCmdClearColorImageRaw);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdClearDepthStencil, hooked_xglCmdClearDepthStencil);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdResolveImage, hooked_xglCmdResolveImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdSetEvent, hooked_xglCmdSetEvent);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdResetEvent, hooked_xglCmdResetEvent);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdMemoryAtomic, hooked_xglCmdMemoryAtomic);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdBeginQuery, hooked_xglCmdBeginQuery);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdEndQuery, hooked_xglCmdEndQuery);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdResetQueryPool, hooked_xglCmdResetQueryPool);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdWriteTimestamp, hooked_xglCmdWriteTimestamp);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdInitAtomicCounters, hooked_xglCmdInitAtomicCounters);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdLoadAtomicCounters, hooked_xglCmdLoadAtomicCounters);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdSaveAtomicCounters, hooked_xglCmdSaveAtomicCounters);
+    }
+
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook XGL.");
+    }
+
+    Mhook_EndMultiOperation();
+
+#elif defined(__linux__)
+    if (real_xglInitAndEnumerateGpus == xglInitAndEnumerateGpus)
+        hookSuccess = glv_platform_get_next_lib_sym((PVOID*)&real_xglInitAndEnumerateGpus,"xglInitAndEnumerateGpus");
+    isHooked = TRUE;
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetGpuInfo, "xglGetGpuInfo");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateDevice, "xglCreateDevice");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDestroyDevice, "xglDestroyDevice");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetExtensionSupport, "xglGetExtensionSupport");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetDeviceQueue, "xglGetDeviceQueue");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglQueueSubmit, "xglQueueSubmit");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglQueueSetGlobalMemReferences, "xglQueueSetGlobalMemReferences");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglQueueWaitIdle, "xglQueueWaitIdle");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDeviceWaitIdle, "xglDeviceWaitIdle");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetMemoryHeapCount, "xglGetMemoryHeapCount");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetMemoryHeapInfo, "xglGetMemoryHeapInfo");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglAllocMemory, "xglAllocMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglFreeMemory, "xglFreeMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglSetMemoryPriority, "xglSetMemoryPriority");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglMapMemory, "xglMapMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglUnmapMemory, "xglUnmapMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglPinSystemMemory, "xglPinSystemMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglRemapVirtualMemoryPages, "xglRemapVirtualMemoryPages");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetMultiGpuCompatibility, "xglGetMultiGpuCompatibility");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglOpenSharedMemory, "xglOpenSharedMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglOpenSharedQueueSemaphore, "xglOpenSharedQueueSemaphore");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglOpenPeerMemory, "xglOpenPeerMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglOpenPeerImage, "xglOpenPeerImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDestroyObject, "xglDestroyObject");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetObjectInfo, "xglGetObjectInfo");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglBindObjectMemory, "xglBindObjectMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateFence, "xglCreateFence");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetFenceStatus, "xglGetFenceStatus");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglWaitForFences, "xglWaitForFences");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateQueueSemaphore, "xglCreateQueueSemaphore");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglSignalQueueSemaphore, "xglSignalQueueSemaphore");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglWaitQueueSemaphore, "xglWaitQueueSemaphore");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateEvent, "xglCreateEvent");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetEventStatus, "xglGetEventStatus");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglSetEvent, "xglSetEvent");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglResetEvent, "xglResetEvent");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateQueryPool, "xglCreateQueryPool");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetQueryPoolResults, "xglGetQueryPoolResults");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetFormatInfo, "xglGetFormatInfo");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateImage, "xglCreateImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglGetImageSubresourceInfo, "xglGetImageSubresourceInfo");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateImageView, "xglCreateImageView");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateColorAttachmentView, "xglCreateColorAttachmentView");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateDepthStencilView, "xglCreateDepthStencilView");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateShader, "xglCreateShader");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateGraphicsPipeline, "xglCreateGraphicsPipeline");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateComputePipeline, "xglCreateComputePipeline");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglStorePipeline, "xglStorePipeline");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglLoadPipeline, "xglLoadPipeline");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreatePipelineDelta, "xglCreatePipelineDelta");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateSampler, "xglCreateSampler");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateDescriptorSet, "xglCreateDescriptorSet");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglBeginDescriptorSetUpdate, "xglBeginDescriptorSetUpdate");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglEndDescriptorSetUpdate, "xglEndDescriptorSetUpdate");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglAttachSamplerDescriptors, "xglAttachSamplerDescriptors");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglAttachImageViewDescriptors, "xglAttachImageViewDescriptors");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglAttachMemoryViewDescriptors, "xglAttachMemoryViewDescriptors");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglAttachNestedDescriptors, "xglAttachNestedDescriptors");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglClearDescriptorSetSlots, "xglClearDescriptorSetSlots");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateViewportState, "xglCreateViewportState");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateRasterState, "xglCreateRasterState");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateMsaaState, "xglCreateMsaaState");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateColorBlendState, "xglCreateColorBlendState");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateDepthStencilState, "xglCreateDepthStencilState");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCreateCommandBuffer, "xglCreateCommandBuffer");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglBeginCommandBuffer, "xglBeginCommandBuffer");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglEndCommandBuffer, "xglEndCommandBuffer");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglResetCommandBuffer, "xglResetCommandBuffer");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindPipeline, "xglCmdBindPipeline");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindPipelineDelta, "xglCmdBindPipelineDelta");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindStateObject, "xglCmdBindStateObject");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindDescriptorSet, "xglCmdBindDescriptorSet");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindDynamicMemoryView, "xglCmdBindDynamicMemoryView");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindIndexData, "xglCmdBindIndexData");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBindAttachments, "xglCmdBindAttachments");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdPrepareMemoryRegions, "xglCmdPrepareMemoryRegions");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdPrepareImages, "xglCmdPrepareImages");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDraw, "xglCmdDraw");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDrawIndexed, "xglCmdDrawIndexed");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDrawIndirect, "xglCmdDrawIndirect");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDrawIndexedIndirect, "xglCmdDrawIndexedIndirect");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDispatch, "xglCmdDispatch");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDispatchIndirect, "xglCmdDispatchIndirect");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdCopyMemory, "xglCmdCopyMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdCopyImage, "xglCmdCopyImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdCopyMemoryToImage, "xglCmdCopyMemoryToImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdCopyImageToMemory, "xglCmdCopyImageToMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdCloneImageData, "xglCmdCloneImageData");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdUpdateMemory, "xglCmdUpdateMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdFillMemory, "xglCmdFillMemory");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdClearColorImage, "xglCmdClearColorImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdClearColorImageRaw, "xglCmdClearColorImageRaw");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdClearDepthStencil, "xglCmdClearDepthStencil");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdResolveImage, "xglCmdResolveImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdSetEvent, "xglCmdSetEvent");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdResetEvent, "xglCmdResetEvent");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdMemoryAtomic, "xglCmdMemoryAtomic");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdBeginQuery, "xglCmdBeginQuery");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdEndQuery, "xglCmdEndQuery");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdResetQueryPool, "xglCmdResetQueryPool");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdWriteTimestamp, "xglCmdWriteTimestamp");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdInitAtomicCounters, "xglCmdInitAtomicCounters");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdLoadAtomicCounters, "xglCmdLoadAtomicCounters");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdSaveAtomicCounters, "xglCmdSaveAtomicCounters");
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook XGL.");
+    }
+
+#endif
+}
+
+void DetachHooks()
+{
+#ifdef __linux__
+    return;
+#elif defined(WIN32)
+    BOOL unhookSuccess = TRUE;
+    if (real_xglGetGpuInfo != NULL)
+    {
+        unhookSuccess = Mhook_Unhook((PVOID*)&real_xglInitAndEnumerateGpus);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetGpuInfo);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateDevice);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDestroyDevice);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetExtensionSupport);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetDeviceQueue);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglQueueSubmit);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglQueueSetGlobalMemReferences);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglQueueWaitIdle);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDeviceWaitIdle);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetMemoryHeapCount);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetMemoryHeapInfo);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglAllocMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglFreeMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglSetMemoryPriority);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglMapMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglUnmapMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglPinSystemMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglRemapVirtualMemoryPages);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetMultiGpuCompatibility);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglOpenSharedMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglOpenSharedQueueSemaphore);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglOpenPeerMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglOpenPeerImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDestroyObject);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetObjectInfo);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglBindObjectMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateFence);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetFenceStatus);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglWaitForFences);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateQueueSemaphore);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglSignalQueueSemaphore);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglWaitQueueSemaphore);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateEvent);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetEventStatus);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglSetEvent);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglResetEvent);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateQueryPool);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetQueryPoolResults);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetFormatInfo);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglGetImageSubresourceInfo);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateImageView);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateColorAttachmentView);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateDepthStencilView);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateShader);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateGraphicsPipeline);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateComputePipeline);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglStorePipeline);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglLoadPipeline);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreatePipelineDelta);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateSampler);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateDescriptorSet);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglBeginDescriptorSetUpdate);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglEndDescriptorSetUpdate);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglAttachSamplerDescriptors);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglAttachImageViewDescriptors);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglAttachMemoryViewDescriptors);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglAttachNestedDescriptors);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglClearDescriptorSetSlots);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateViewportState);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateRasterState);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateMsaaState);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateColorBlendState);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateDepthStencilState);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCreateCommandBuffer);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglBeginCommandBuffer);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglEndCommandBuffer);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglResetCommandBuffer);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindPipeline);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindPipelineDelta);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindStateObject);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindDescriptorSet);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindDynamicMemoryView);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindIndexData);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBindAttachments);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdPrepareMemoryRegions);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdPrepareImages);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDraw);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDrawIndexed);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDrawIndirect);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDrawIndexedIndirect);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDispatch);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDispatchIndirect);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdCopyMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdCopyImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdCopyMemoryToImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdCopyImageToMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdCloneImageData);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdUpdateMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdFillMemory);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdClearColorImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdClearColorImageRaw);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdClearDepthStencil);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdResolveImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdSetEvent);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdResetEvent);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdMemoryAtomic);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdBeginQuery);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdEndQuery);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdResetQueryPool);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdWriteTimestamp);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdInitAtomicCounters);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdLoadAtomicCounters);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdSaveAtomicCounters);
+    }
+    isHooked = FALSE;
+
+    if (!unhookSuccess)
+    {
+        glv_LogError("Failed to unhook XGL.");
+    }
+#endif
+}
+
+// GPU initialization
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglInitAndEnumerateGpus(
+    const XGL_APPLICATION_INFO* pAppInfo,
+    const XGL_ALLOC_CALLBACKS*  pAllocCb,
+    XGL_UINT                    maxGpus,
+    XGL_UINT*                   pGpuCount,
+    XGL_PHYSICAL_GPU*           pGpus)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    uint64_t startTime;
+    struct_xglInitAndEnumerateGpus* pPacket;
+    SEND_ENTRYPOINT_ID(xglInitAndEnumerateGpus);
+
+    if (real_xglInitAndEnumerateGpus == xglInitAndEnumerateGpus)
+    {
+        glv_platform_get_next_lib_sym((void **) &real_xglInitAndEnumerateGpus,"xglInitAndEnumerateGpus");
+    }
+    startTime = glv_get_time();
+    result = real_xglInitAndEnumerateGpus(pAppInfo, pAllocCb, maxGpus, pGpuCount, pGpus);
+
+    // since we don't know how many gpus will be found must  create trace packet after calling xglInit
+    CREATE_TRACE_PACKET(xglInitAndEnumerateGpus, calc_size_XGL_APPLICATION_INFO(pAppInfo) + ((pAllocCb == NULL) ? 0 :sizeof(XGL_ALLOC_CALLBACKS))
+        + sizeof(XGL_UINT) + ((pGpus && pGpuCount) ? *pGpuCount * sizeof(XGL_PHYSICAL_GPU) : 0));
+    pHeader->entrypoint_begin_time = startTime;
+    if (isHooked == FALSE) {
+        AttachHooks();
+        AttachHooks_xgldbg();
+        AttachHooks_xglwsix11ext();
+    }
+    pPacket = interpret_body_as_xglInitAndEnumerateGpus(pHeader);
+    add_XGL_APPLICATION_INFO_to_packet(pHeader, (XGL_APPLICATION_INFO**)&(pPacket->pAppInfo), pAppInfo);
+    if (pAllocCb) {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pAllocCb), sizeof(XGL_ALLOC_CALLBACKS), pAllocCb);
+        glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pAllocCb));
+    }
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pGpuCount), sizeof(XGL_UINT), pGpuCount);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pGpuCount));
+    if (pGpuCount && pGpus)
+    {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pGpus), sizeof(XGL_PHYSICAL_GPU) * *pGpuCount, pGpus);
+        glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pGpus));
+    }
+    pPacket->maxGpus = maxGpus;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetGpuInfo(
+    XGL_PHYSICAL_GPU                   gpu,
+    XGL_PHYSICAL_GPU_INFO_TYPE         infoType,
+    XGL_SIZE*                          pDataSize,
+    XGL_VOID*                          pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetGpuInfo* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetGpuInfo);
+    CREATE_TRACE_PACKET(xglGetGpuInfo, ((pDataSize != NULL)? sizeof(XGL_SIZE) : 0) + ((pDataSize != NULL && pData != NULL) ? *pDataSize : 0));
+    result = real_xglGetGpuInfo(gpu, infoType, pDataSize, pData);
+    pPacket = interpret_body_as_xglGetGpuInfo(pHeader);
+    pPacket->gpu = gpu;
+    pPacket->infoType = infoType;
+    pPacket->result = result;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+    if (pData && pDataSize)
+    {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), *pDataSize, pData);
+        glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    }
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Device functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateDevice(
+    XGL_PHYSICAL_GPU              gpu,
+    const XGL_DEVICE_CREATE_INFO* pCreateInfo,
+    XGL_DEVICE*                   pDevice)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateDevice* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateDevice);
+    CREATE_TRACE_PACKET(xglCreateDevice, calc_size_XGL_DEVICE_CREATE_INFO(pCreateInfo) + sizeof(XGL_DEVICE));
+    result = real_xglCreateDevice(gpu, pCreateInfo, pDevice);
+    pPacket = interpret_body_as_xglCreateDevice(pHeader);
+    pPacket->gpu = gpu;
+    add_XGL_DEVICE_CREATE_INFO_to_packet(pHeader, (XGL_DEVICE_CREATE_INFO**) &(pPacket->pCreateInfo), pCreateInfo);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDevice), sizeof(XGL_DEVICE), pDevice);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDevice));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDestroyDevice(
+    XGL_DEVICE device)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDestroyDevice* pPacket;
+    SEND_ENTRYPOINT_ID(xglDestroyDevice);
+    CREATE_TRACE_PACKET(xglDestroyDevice, 0);
+    result = real_xglDestroyDevice(device);
+    pPacket = interpret_body_as_xglDestroyDevice(pHeader);
+    pPacket->device = device;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Extension discovery functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetExtensionSupport(
+    XGL_PHYSICAL_GPU gpu,
+    const XGL_CHAR*  pExtName)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetExtensionSupport* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetExtensionSupport);
+    CREATE_TRACE_PACKET(xglGetExtensionSupport, strlen((const char *)pExtName) + 1);
+    result = real_xglGetExtensionSupport(gpu, pExtName);
+    pPacket = interpret_body_as_xglGetExtensionSupport(pHeader);
+    pPacket->gpu = gpu;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pExtName), strlen((const char *)pExtName) + 1, pExtName);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pExtName));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Queue functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetDeviceQueue(
+    XGL_DEVICE       device,
+    XGL_QUEUE_TYPE   queueType,
+    XGL_UINT         queueIndex,
+    XGL_QUEUE*       pQueue)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetDeviceQueue* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetDeviceQueue);
+    CREATE_TRACE_PACKET(xglGetDeviceQueue, sizeof(XGL_QUEUE));
+    result = real_xglGetDeviceQueue(device, queueType, queueIndex, pQueue);
+    pPacket = interpret_body_as_xglGetDeviceQueue(pHeader);
+    pPacket->device = device;
+    pPacket->queueType = queueType;
+    pPacket->queueIndex = queueIndex;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pQueue), sizeof(XGL_QUEUE), pQueue);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pQueue));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglQueueSubmit(
+    XGL_QUEUE             queue,
+    XGL_UINT              cmdBufferCount,
+    const XGL_CMD_BUFFER* pCmdBuffers,
+    XGL_UINT              memRefCount,
+    const XGL_MEMORY_REF* pMemRefs,
+    XGL_FENCE             fence)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglQueueSubmit* pPacket;
+    SEND_ENTRYPOINT_ID(xglQueueSubmit);
+    CREATE_TRACE_PACKET(xglQueueSubmit, cmdBufferCount*sizeof(XGL_CMD_BUFFER) + memRefCount*sizeof(XGL_MEMORY_REF));
+    result = real_xglQueueSubmit(queue, cmdBufferCount, pCmdBuffers, memRefCount, pMemRefs, fence);
+    pPacket = interpret_body_as_xglQueueSubmit(pHeader);
+    pPacket->queue = queue;
+    pPacket->cmdBufferCount = cmdBufferCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCmdBuffers), cmdBufferCount*sizeof(XGL_CMD_BUFFER), pCmdBuffers);
+    pPacket->memRefCount = memRefCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMemRefs), memRefCount*sizeof(XGL_MEMORY_REF), pMemRefs);
+    pPacket->fence = fence;
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCmdBuffers));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMemRefs));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglQueueSetGlobalMemReferences(
+    XGL_QUEUE             queue,
+    XGL_UINT              memRefCount,
+    const XGL_MEMORY_REF* pMemRefs)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglQueueSetGlobalMemReferences* pPacket;
+    SEND_ENTRYPOINT_ID(xglQueueSetGlobalMemReferences);
+    CREATE_TRACE_PACKET(xglQueueSetGlobalMemReferences, memRefCount*sizeof(XGL_MEMORY_REF));
+    result = real_xglQueueSetGlobalMemReferences(queue, memRefCount, pMemRefs);
+    pPacket = interpret_body_as_xglQueueSetGlobalMemReferences(pHeader);
+    pPacket->queue = queue;
+    pPacket->memRefCount = memRefCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMemRefs), memRefCount*sizeof(XGL_MEMORY_REF), pMemRefs);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMemRefs));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglQueueWaitIdle(
+    XGL_QUEUE queue)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglQueueWaitIdle* pPacket;
+    SEND_ENTRYPOINT_ID(xglQueueWaitIdle);
+    CREATE_TRACE_PACKET(xglQueueWaitIdle, 0);
+    result = real_xglQueueWaitIdle(queue);
+    pPacket = interpret_body_as_xglQueueWaitIdle(pHeader);
+    pPacket->queue = queue;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDeviceWaitIdle(
+    XGL_DEVICE device)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDeviceWaitIdle* pPacket;
+    SEND_ENTRYPOINT_ID(xglDeviceWaitIdle);
+    CREATE_TRACE_PACKET(xglDeviceWaitIdle, 0);
+    result = real_xglDeviceWaitIdle(device);
+    pPacket = interpret_body_as_xglDeviceWaitIdle(pHeader);
+    pPacket->device = device;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Support for shadowing CPU mapped memory
+typedef struct _XGLAllocInfo {
+    XGL_GPU_SIZE   size;
+    XGL_GPU_MEMORY handle;
+    XGL_VOID       *pData;
+    BOOL           valid;
+} XGLAllocInfo;
+typedef struct _XGLMemInfo {
+    unsigned int numEntrys;
+    XGLAllocInfo *pEntrys;
+    XGLAllocInfo *pLastMapped;
+    unsigned int capacity;
+} XGLMemInfo;
+
+static XGLMemInfo mInfo = {0, NULL, NULL, 0};
+
+static void init_mem_info_entrys(XGLAllocInfo *ptr, const unsigned int num)
+{
+    unsigned int i;
+    for (i = 0; i < num; i++)
+    {
+        XGLAllocInfo *entry = ptr + i;
+        entry->pData = NULL;
+        entry->size  = 0;
+        entry->handle = NULL;
+        entry->valid = FALSE;
+    }
+}
+
+static void init_mem_info()
+{
+    mInfo.numEntrys = 0;
+    mInfo.capacity = 1024;
+    mInfo.pLastMapped = NULL;
+
+    mInfo.pEntrys = GLV_NEW_ARRAY(XGLAllocInfo, mInfo.capacity);
+
+    if (mInfo.pEntrys == NULL)
+        glv_LogError("init_mem_info()  malloc failed\n");
+    else
+        init_mem_info_entrys(mInfo.pEntrys, mInfo.capacity);
+}
+
+static void delete_mem_info()
+{
+    GLV_DELETE(mInfo.pEntrys);
+    mInfo.pEntrys = NULL;
+    mInfo.numEntrys = 0;
+    mInfo.capacity = 0;
+    mInfo.pLastMapped = NULL;
+}
+
+static XGLAllocInfo * get_mem_info_entry()
+{
+    unsigned int i;
+    XGLAllocInfo *entry;
+    if (mInfo.numEntrys > mInfo.capacity)
+    {
+        glv_LogError("get_mem_info_entry() bad internal state numEntrys\n");
+        return NULL;
+    }
+
+    if (mInfo.numEntrys == mInfo.capacity)
+    {  // grow the array 2x
+        mInfo.capacity *= 2;
+        mInfo.pEntrys = (XGLAllocInfo *) GLV_REALLOC(mInfo.pEntrys, mInfo.capacity * sizeof(XGLAllocInfo));
+        //init the newly added entrys
+        init_mem_info_entrys(mInfo.pEntrys + mInfo.capacity / 2, mInfo.capacity / 2);
+    }
+
+    assert(mInfo.numEntrys < mInfo.capacity);
+    entry = mInfo.pEntrys;
+    for (i = 0; i < mInfo.capacity; i++)
+    {
+        if ((entry + i)->valid == FALSE)
+            return entry + i;
+    }
+
+    glv_LogError("get_mem_info_entry() didn't find an entry\n");
+    return NULL;
+}
+
+static XGLAllocInfo * find_mem_info_entry(const XGL_GPU_MEMORY handle)
+{
+    XGLAllocInfo *entry = mInfo.pEntrys;
+    unsigned int i;
+    if (mInfo.pLastMapped && mInfo.pLastMapped->handle == handle && mInfo.pLastMapped->valid)
+        return mInfo.pLastMapped;
+    for (i = 0; i < mInfo.numEntrys; i++)
+    {
+        if ((entry + i)->valid && (handle == (entry + i)->handle))
+            return entry + i;
+    }
+
+    return NULL;
+}
+
+static void add_new_handle_to_mem_info(const XGL_GPU_MEMORY handle, XGL_GPU_SIZE size, XGL_VOID *pData)
+{
+    XGLAllocInfo *entry;
+
+    if (mInfo.capacity == 0)
+        init_mem_info();
+
+    entry = get_mem_info_entry();
+    if (entry)
+    {
+        entry->valid = TRUE;
+        entry->handle = handle;
+        entry->size = size;
+        entry->pData = pData;   // NOTE: xglFreeMemory will free this mem, so no malloc()
+        mInfo.numEntrys++;
+    }
+}
+
+static void add_data_to_mem_info(const XGL_GPU_MEMORY handle, XGL_VOID *pData)
+{
+    XGLAllocInfo *entry = find_mem_info_entry(handle);
+
+    if (entry)
+    {
+        entry->pData = pData;
+    }
+    mInfo.pLastMapped = entry;
+}
+
+static void rm_handle_from_mem_info(const XGL_GPU_MEMORY handle)
+{
+    XGLAllocInfo *entry = find_mem_info_entry(handle);
+
+    if (entry)
+    {
+        entry->valid = FALSE;
+        entry->pData = NULL;
+        entry->size = 0;
+        entry->handle = NULL;
+
+        mInfo.numEntrys--;
+        if (entry == mInfo.pLastMapped)
+            mInfo.pLastMapped = NULL;
+        if (mInfo.numEntrys == 0)
+            delete_mem_info();
+    }
+}
+
+// Memory functions
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetMemoryHeapCount(
+    XGL_DEVICE  device,
+    XGL_UINT*   pCount)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetMemoryHeapCount* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetMemoryHeapCount);
+    CREATE_TRACE_PACKET(xglGetMemoryHeapCount, sizeof(XGL_UINT));
+    result = real_xglGetMemoryHeapCount(device, pCount);
+    pPacket = interpret_body_as_xglGetMemoryHeapCount(pHeader);
+    pPacket->device = device;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCount), sizeof(XGL_UINT), pCount);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCount));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetMemoryHeapInfo(
+    XGL_DEVICE                  device,
+    XGL_UINT                    heapId,
+    XGL_MEMORY_HEAP_INFO_TYPE   infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetMemoryHeapInfo* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetMemoryHeapInfo);
+    CREATE_TRACE_PACKET(xglGetMemoryHeapInfo, ((pDataSize != NULL) ? sizeof(XGL_SIZE) : 0) + ((pDataSize != NULL && pData != NULL)? *pDataSize : 0));
+    result = real_xglGetMemoryHeapInfo(device, heapId, infoType, pDataSize, pData);
+    pPacket = interpret_body_as_xglGetMemoryHeapInfo(pHeader);
+    pPacket->device = device;
+    pPacket->heapId = heapId;
+    pPacket->infoType = infoType;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), (pDataSize != NULL && pData != NULL)? *pDataSize : 0, pData);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglAllocMemory(
+    XGL_DEVICE                   device,
+    const XGL_MEMORY_ALLOC_INFO* pAllocInfo,
+    XGL_GPU_MEMORY*              pMem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglAllocMemory* pPacket;
+    SEND_ENTRYPOINT_PARAMS("xglAllocMemory(device %p, AllocInfo (size %d, align %d, flags %d), pMem %p)\n",
+        device, pAllocInfo->allocationSize, pAllocInfo->alignment, pAllocInfo->flags, pMem);
+    CREATE_TRACE_PACKET(xglAllocMemory, sizeof(XGL_MEMORY_ALLOC_INFO) + sizeof(XGL_GPU_MEMORY));
+    result = real_xglAllocMemory(device, pAllocInfo, pMem);
+    pPacket = interpret_body_as_xglAllocMemory(pHeader);
+    pPacket->device = device;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pAllocInfo), sizeof(XGL_MEMORY_ALLOC_INFO), pAllocInfo);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMem), sizeof(XGL_GPU_MEMORY), pMem);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader,(void**)&(pPacket->pAllocInfo));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMem));
+    FINISH_TRACE_PACKET();
+    add_new_handle_to_mem_info(*pMem, pAllocInfo->allocationSize, NULL);
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglFreeMemory(
+    XGL_GPU_MEMORY mem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglFreeMemory* pPacket;
+    SEND_ENTRYPOINT_PARAMS("xglFreeMemory( mem %p)\n", mem);
+    CREATE_TRACE_PACKET(xglFreeMemory, 0);
+    result = real_xglFreeMemory(mem);
+    pPacket = interpret_body_as_xglFreeMemory(pHeader);
+    pPacket->mem = mem;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    rm_handle_from_mem_info(mem);
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglSetMemoryPriority(
+    XGL_GPU_MEMORY mem,
+    XGL_MEMORY_PRIORITY       priority)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglSetMemoryPriority* pPacket;
+    SEND_ENTRYPOINT_ID(xglSetMemoryPriority);
+    CREATE_TRACE_PACKET(xglSetMemoryPriority, 0);
+    result = real_xglSetMemoryPriority(mem, priority);
+    pPacket = interpret_body_as_xglSetMemoryPriority(pHeader);
+    pPacket->mem = mem;
+    pPacket->priority = priority;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglMapMemory(
+    XGL_GPU_MEMORY mem,
+    XGL_FLAGS      flags,                // Reserved
+    XGL_VOID**     ppData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglMapMemory* pPacket;
+    SEND_ENTRYPOINT_PARAMS("xglMapMemory(mem %p, flags %u, ppData %p)\n", mem, flags, ppData);
+    CREATE_TRACE_PACKET(xglMapMemory, sizeof(XGL_VOID*));
+    result = real_xglMapMemory(mem, flags, ppData);
+    pPacket = interpret_body_as_xglMapMemory(pHeader);
+    pPacket->mem = mem;
+    pPacket->flags = flags;
+    if (ppData != NULL)
+    {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->ppData), sizeof(XGL_VOID*), *ppData);
+        glv_finalize_buffer_address(pHeader, (void**)&(pPacket->ppData));
+        add_data_to_mem_info(mem, *ppData);
+    }
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglUnmapMemory(
+    XGL_GPU_MEMORY mem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglUnmapMemory* pPacket;
+    XGLAllocInfo *entry;
+    SEND_ENTRYPOINT_PARAMS("xglUnmapMemory(mem %p)\n", mem);
+    // insert into packet the data that was written by CPU between the xglMapMemory call and here
+    // Note must do this prior to the real xglUnMap() or else may get a FAULT
+    entry = find_mem_info_entry(mem);
+    CREATE_TRACE_PACKET(xglUnmapMemory, (entry) ? entry->size : 0);
+    pPacket = interpret_body_as_xglUnmapMemory(pHeader);
+
+    if (entry)
+    {
+        assert(entry->handle == mem);
+        glv_add_buffer_to_trace_packet(pHeader, (void**) &(pPacket->pData), entry->size, entry->pData);
+        glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+        entry->pData = NULL;
+    }
+    result = real_xglUnmapMemory(mem);
+    pPacket->mem = mem;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglPinSystemMemory(
+    XGL_DEVICE      device,
+    const XGL_VOID* pSysMem,
+    XGL_SIZE        memSize,
+    XGL_GPU_MEMORY* pMem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglPinSystemMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglPinSystemMemory);
+    CREATE_TRACE_PACKET(xglPinSystemMemory, sizeof(XGL_GPU_MEMORY));
+    result = real_xglPinSystemMemory(device, pSysMem, memSize, pMem);
+    pPacket = interpret_body_as_xglPinSystemMemory(pHeader);
+    pPacket->device = device;
+    pPacket->pSysMem = pSysMem;
+    pPacket->memSize = memSize;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMem), sizeof(XGL_GPU_MEMORY), pMem);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMem));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglRemapVirtualMemoryPages(
+    XGL_DEVICE                            device,
+    XGL_UINT                              rangeCount,
+    const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pRanges,
+    XGL_UINT                              preWaitSemaphoreCount,
+    const XGL_QUEUE_SEMAPHORE*            pPreWaitSemaphores,
+    XGL_UINT                              postSignalSemaphoreCount,
+    const XGL_QUEUE_SEMAPHORE*            pPostSignalSemaphores)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglRemapVirtualMemoryPages* pPacket;
+    SEND_ENTRYPOINT_ID(xglRemapVirtualMemoryPages);
+    CREATE_TRACE_PACKET(xglRemapVirtualMemoryPages, rangeCount*sizeof(XGL_VIRTUAL_MEMORY_REMAP_RANGE) + preWaitSemaphoreCount*sizeof(XGL_QUEUE_SEMAPHORE) + postSignalSemaphoreCount*sizeof(XGL_QUEUE_SEMAPHORE));
+    result = real_xglRemapVirtualMemoryPages(device, rangeCount, pRanges, preWaitSemaphoreCount, pPreWaitSemaphores, postSignalSemaphoreCount, pPostSignalSemaphores);
+    pPacket = interpret_body_as_xglRemapVirtualMemoryPages(pHeader);
+    pPacket->device = device;
+    pPacket->rangeCount = rangeCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRanges), rangeCount*sizeof(XGL_VIRTUAL_MEMORY_REMAP_RANGE), pRanges);
+    pPacket->preWaitSemaphoreCount = preWaitSemaphoreCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pPreWaitSemaphores), preWaitSemaphoreCount*sizeof(XGL_QUEUE_SEMAPHORE), pPreWaitSemaphores);
+    pPacket->postSignalSemaphoreCount = postSignalSemaphoreCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pPostSignalSemaphores), postSignalSemaphoreCount*sizeof(XGL_QUEUE_SEMAPHORE), pPostSignalSemaphores);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRanges));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pPreWaitSemaphores));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pPostSignalSemaphores));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Multi-device functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetMultiGpuCompatibility(
+    XGL_PHYSICAL_GPU            gpu0,
+    XGL_PHYSICAL_GPU            gpu1,
+    XGL_GPU_COMPATIBILITY_INFO* pInfo)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetMultiGpuCompatibility* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetMultiGpuCompatibility);
+    CREATE_TRACE_PACKET(xglGetMultiGpuCompatibility, sizeof(XGL_GPU_COMPATIBILITY_INFO));
+    result = real_xglGetMultiGpuCompatibility(gpu0, gpu1, pInfo);
+    pPacket = interpret_body_as_xglGetMultiGpuCompatibility(pHeader);
+    pPacket->gpu0 = gpu0;
+    pPacket->gpu1 = gpu1;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pInfo), sizeof(XGL_GPU_COMPATIBILITY_INFO), pInfo);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pInfo));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglOpenSharedMemory(
+    XGL_DEVICE                  device,
+    const XGL_MEMORY_OPEN_INFO* pOpenInfo,
+    XGL_GPU_MEMORY*             pMem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglOpenSharedMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglOpenSharedMemory);
+    CREATE_TRACE_PACKET(xglOpenSharedMemory, sizeof(XGL_MEMORY_OPEN_INFO) + sizeof(XGL_GPU_MEMORY));
+    result = real_xglOpenSharedMemory(device, pOpenInfo, pMem);
+    pPacket = interpret_body_as_xglOpenSharedMemory(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pOpenInfo), sizeof(XGL_MEMORY_OPEN_INFO), pOpenInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMem), sizeof(XGL_GPU_MEMORY), pMem);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pOpenInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMem));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglOpenSharedQueueSemaphore(
+    XGL_DEVICE                           device,
+    const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pOpenInfo,
+    XGL_QUEUE_SEMAPHORE*                 pSemaphore)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglOpenSharedQueueSemaphore* pPacket;
+    SEND_ENTRYPOINT_ID(xglOpenSharedQueueSemaphore);
+    CREATE_TRACE_PACKET(xglOpenSharedQueueSemaphore, sizeof(XGL_QUEUE_SEMAPHORE_OPEN_INFO) + sizeof(XGL_QUEUE_SEMAPHORE));
+    result = real_xglOpenSharedQueueSemaphore(device, pOpenInfo, pSemaphore);
+    pPacket = interpret_body_as_xglOpenSharedQueueSemaphore(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pOpenInfo), sizeof(XGL_QUEUE_SEMAPHORE_OPEN_INFO), pOpenInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pSemaphore), sizeof(XGL_QUEUE_SEMAPHORE), pSemaphore);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pOpenInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pSemaphore));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglOpenPeerMemory(
+    XGL_DEVICE                       device,
+    const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo,
+    XGL_GPU_MEMORY*                  pMem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglOpenPeerMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglOpenPeerMemory);
+    CREATE_TRACE_PACKET(xglOpenPeerMemory, sizeof(XGL_PEER_MEMORY_OPEN_INFO) + sizeof(XGL_GPU_MEMORY));
+    result = real_xglOpenPeerMemory(device, pOpenInfo, pMem);
+    pPacket = interpret_body_as_xglOpenPeerMemory(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pOpenInfo), sizeof(XGL_PEER_MEMORY_OPEN_INFO), pOpenInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMem), sizeof(XGL_GPU_MEMORY), pMem);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pOpenInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMem));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglOpenPeerImage(
+    XGL_DEVICE                      device,
+    const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo,
+    XGL_IMAGE*                      pImage,
+    XGL_GPU_MEMORY*                 pMem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglOpenPeerImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglOpenPeerImage);
+    CREATE_TRACE_PACKET(xglOpenPeerImage, sizeof(XGL_PEER_IMAGE_OPEN_INFO) + sizeof(XGL_IMAGE) + sizeof(XGL_GPU_MEMORY));
+    result = real_xglOpenPeerImage(device, pOpenInfo, pImage, pMem);
+    pPacket = interpret_body_as_xglOpenPeerImage(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pOpenInfo), sizeof(XGL_PEER_IMAGE_OPEN_INFO), pOpenInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pImage), sizeof(XGL_IMAGE), pImage);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMem), sizeof(XGL_GPU_MEMORY), pMem);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pOpenInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pImage));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMem));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Generic API object functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDestroyObject(
+    XGL_OBJECT object)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDestroyObject* pPacket;
+    SEND_ENTRYPOINT_ID(xglDestroyObject);
+    CREATE_TRACE_PACKET(xglDestroyObject, 0);
+    result = real_xglDestroyObject(object);
+    pPacket = interpret_body_as_xglDestroyObject(pHeader);
+    pPacket->object = object;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetObjectInfo(
+    XGL_BASE_OBJECT             object,
+    XGL_OBJECT_INFO_TYPE        infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetObjectInfo* pPacket;
+    uint64_t startTime;
+    SEND_ENTRYPOINT_ID(xglGetObjectInfo);
+    startTime = glv_get_time();
+    result = real_xglGetObjectInfo(object, infoType, pDataSize, pData);
+    // since don't know the size of *pDataSize potentially until after the call create trace packet post call
+    CREATE_TRACE_PACKET(xglGetObjectInfo, ((pDataSize != NULL) ? sizeof(XGL_SIZE) : 0) + ((pDataSize != NULL)? *pDataSize : 0));
+    pHeader->entrypoint_begin_time = startTime;
+    pPacket = interpret_body_as_xglGetObjectInfo(pHeader);
+    pPacket->object = object;
+	pPacket->infoType = infoType;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+    if (pDataSize && pData)
+    {
+	    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), *pDataSize, pData);
+        glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    }
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglBindObjectMemory(
+    XGL_OBJECT     object,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglBindObjectMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglBindObjectMemory);
+    CREATE_TRACE_PACKET(xglBindObjectMemory, 0);
+    result = real_xglBindObjectMemory(object, mem, offset);
+    pPacket = interpret_body_as_xglBindObjectMemory(pHeader);
+    pPacket->object = object;
+    pPacket->mem = mem;
+    pPacket->offset = offset;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Fence functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateFence(
+    XGL_DEVICE                   device,
+    const XGL_FENCE_CREATE_INFO* pCreateInfo,
+    XGL_FENCE*                   pFence)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateFence* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateFence);
+    CREATE_TRACE_PACKET(xglCreateFence, sizeof(XGL_FENCE_CREATE_INFO) + sizeof(XGL_FENCE));
+    result = real_xglCreateFence(device, pCreateInfo, pFence);
+    pPacket = interpret_body_as_xglCreateFence(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_FENCE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pFence), sizeof(XGL_FENCE), pFence);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pFence));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetFenceStatus(
+    XGL_FENCE fence)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetFenceStatus* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetFenceStatus);
+    CREATE_TRACE_PACKET(xglGetFenceStatus, 0);
+    result = real_xglGetFenceStatus(fence);
+    pPacket = interpret_body_as_xglGetFenceStatus(pHeader);
+    pPacket->fence = fence;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglWaitForFences(
+    XGL_DEVICE       device,
+    XGL_UINT         fenceCount,
+    const XGL_FENCE* pFences,
+    XGL_BOOL         waitAll,
+    XGL_UINT64       timeout)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglWaitForFences* pPacket;
+    SEND_ENTRYPOINT_ID(xglWaitForFences);
+    CREATE_TRACE_PACKET(xglWaitForFences, fenceCount*sizeof(XGL_FENCE));
+    result = real_xglWaitForFences(device, fenceCount, pFences, waitAll, timeout);
+    pPacket = interpret_body_as_xglWaitForFences(pHeader);
+    pPacket->device = device;
+    pPacket->fenceCount = fenceCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pFences), fenceCount*sizeof(XGL_FENCE), pFences);
+    pPacket->waitAll = waitAll;
+    pPacket->timeout = timeout;
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pFences));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Queue semaphore functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateQueueSemaphore(
+    XGL_DEVICE                             device,
+    const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pCreateInfo,
+    XGL_QUEUE_SEMAPHORE*                   pSemaphore)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateQueueSemaphore* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateQueueSemaphore);
+    CREATE_TRACE_PACKET(xglCreateQueueSemaphore, sizeof(XGL_QUEUE_SEMAPHORE_CREATE_INFO) + sizeof(XGL_QUEUE_SEMAPHORE));
+    result = real_xglCreateQueueSemaphore(device, pCreateInfo, pSemaphore);
+    pPacket = interpret_body_as_xglCreateQueueSemaphore(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_QUEUE_SEMAPHORE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pSemaphore), sizeof(XGL_QUEUE_SEMAPHORE), pSemaphore);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pSemaphore));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglSignalQueueSemaphore(
+    XGL_QUEUE           queue,
+    XGL_QUEUE_SEMAPHORE semaphore)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglSignalQueueSemaphore* pPacket;
+    SEND_ENTRYPOINT_ID(xglSignalQueueSemaphore);
+    CREATE_TRACE_PACKET(xglSignalQueueSemaphore, 0);
+    result = real_xglSignalQueueSemaphore(queue, semaphore);
+    pPacket = interpret_body_as_xglSignalQueueSemaphore(pHeader);
+    pPacket->queue = queue;
+    pPacket->semaphore = semaphore;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglWaitQueueSemaphore(
+    XGL_QUEUE           queue,
+    XGL_QUEUE_SEMAPHORE semaphore)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglWaitQueueSemaphore* pPacket;
+    SEND_ENTRYPOINT_ID(xglWaitQueueSemaphore);
+    CREATE_TRACE_PACKET(xglWaitQueueSemaphore, 0);
+    result = real_xglWaitQueueSemaphore(queue, semaphore);
+    pPacket = interpret_body_as_xglWaitQueueSemaphore(pHeader);
+    pPacket->queue = queue;
+    pPacket->semaphore = semaphore;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Event functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateEvent(
+    XGL_DEVICE                   device,
+    const XGL_EVENT_CREATE_INFO* pCreateInfo,
+    XGL_EVENT*                   pEvent)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateEvent* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateEvent);
+    CREATE_TRACE_PACKET(xglCreateEvent, sizeof(XGL_EVENT_CREATE_INFO) + sizeof(XGL_EVENT));
+    result = real_xglCreateEvent(device, pCreateInfo, pEvent);
+    pPacket = interpret_body_as_xglCreateEvent(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_EVENT_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pEvent), sizeof(XGL_EVENT), pEvent);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pEvent));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetEventStatus(
+    XGL_EVENT event)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetEventStatus* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetEventStatus);
+    CREATE_TRACE_PACKET(xglGetEventStatus, 0);
+    result = real_xglGetEventStatus(event);
+    pPacket = interpret_body_as_xglGetEventStatus(pHeader);
+    pPacket->event = event;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglSetEvent(
+    XGL_EVENT event)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglSetEvent* pPacket;
+    SEND_ENTRYPOINT_ID(xglSetEvent);
+    CREATE_TRACE_PACKET(xglSetEvent, 0);
+    result = real_xglSetEvent(event);
+    pPacket = interpret_body_as_xglSetEvent(pHeader);
+    pPacket->event = event;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglResetEvent(
+    XGL_EVENT event)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglResetEvent* pPacket;
+    SEND_ENTRYPOINT_ID(xglResetEvent);
+    CREATE_TRACE_PACKET(xglResetEvent, 0);
+    result = real_xglResetEvent(event);
+    pPacket = interpret_body_as_xglResetEvent(pHeader);
+    pPacket->event = event;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Query functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateQueryPool(
+    XGL_DEVICE                        device,
+    const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo,
+    XGL_QUERY_POOL*                   pQueryPool)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateQueryPool* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateQueryPool);
+    CREATE_TRACE_PACKET(xglCreateQueryPool, sizeof(XGL_QUERY_POOL) + sizeof(XGL_QUERY_POOL_CREATE_INFO));
+    result = real_xglCreateQueryPool(device, pCreateInfo, pQueryPool);
+    pPacket = interpret_body_as_xglCreateQueryPool(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_QUERY_POOL_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pQueryPool), sizeof(XGL_QUERY_POOL), pQueryPool);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pQueryPool));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetQueryPoolResults(
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       startQuery,
+    XGL_UINT       queryCount,
+    XGL_SIZE*      pDataSize,
+    XGL_VOID*      pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetQueryPoolResults* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetQueryPoolResults);
+    CREATE_TRACE_PACKET(xglGetQueryPoolResults, ((pDataSize != NULL ) ? sizeof(XGL_SIZE) : 0) + ((pDataSize != NULL && pData != NULL) ? *pDataSize : 0));
+    result = real_xglGetQueryPoolResults(queryPool, startQuery, queryCount, pDataSize, pData);
+    pPacket = interpret_body_as_xglGetQueryPoolResults(pHeader);
+    pPacket->queryPool = queryPool;
+    pPacket->startQuery = startQuery;
+    pPacket->queryCount = queryCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), (pDataSize != NULL && pData != NULL) ? *pDataSize : 0, pData);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Format capabilities
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetFormatInfo(
+    XGL_DEVICE             device,
+    XGL_FORMAT             format,
+    XGL_FORMAT_INFO_TYPE   infoType,
+    XGL_SIZE*              pDataSize,
+    XGL_VOID*              pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetFormatInfo* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetFormatInfo);
+    CREATE_TRACE_PACKET(xglGetFormatInfo, ((pDataSize != NULL ) ? sizeof(XGL_SIZE) : 0) + ((pDataSize != NULL && pData != NULL) ? *pDataSize : 0));
+    result = real_xglGetFormatInfo(device, format, infoType, pDataSize, pData);
+    pPacket = interpret_body_as_xglGetFormatInfo(pHeader);
+    pPacket->device = device;
+    pPacket->format = format;
+    pPacket->infoType = infoType;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), (pDataSize != NULL && pData != NULL) ? *pDataSize : 0, pData);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Image functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateImage(
+    XGL_DEVICE                   device,
+    const XGL_IMAGE_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE*                   pImage)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateImage);
+    CREATE_TRACE_PACKET(xglCreateImage, sizeof(XGL_IMAGE_CREATE_INFO) + sizeof(XGL_IMAGE));
+    result = real_xglCreateImage(device, pCreateInfo, pImage);
+    pPacket = interpret_body_as_xglCreateImage(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_IMAGE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pImage), sizeof(XGL_IMAGE), pImage);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pImage));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglGetImageSubresourceInfo(
+    XGL_IMAGE                    image,
+    const XGL_IMAGE_SUBRESOURCE* pSubresource,
+    XGL_SUBRESOURCE_INFO_TYPE    infoType,
+    XGL_SIZE*                    pDataSize,
+    XGL_VOID*                    pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglGetImageSubresourceInfo* pPacket;
+    SEND_ENTRYPOINT_ID(xglGetImageSubresourceInfo);
+    CREATE_TRACE_PACKET(xglGetImageSubresourceInfo, ((pSubresource != NULL) ? sizeof(XGL_IMAGE_SUBRESOURCE) : 0) + ((pDataSize != NULL ) ? sizeof(XGL_SIZE) : 0) + ((pDataSize != NULL && pData != NULL) ? *pDataSize : 0));
+    result = real_xglGetImageSubresourceInfo(image, pSubresource, infoType, pDataSize, pData);
+    pPacket = interpret_body_as_xglGetImageSubresourceInfo(pHeader);
+    pPacket->image = image;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pSubresource), sizeof(XGL_IMAGE_SUBRESOURCE), pSubresource);
+    pPacket->infoType = infoType;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), (pDataSize != NULL && pData != NULL) ? *pDataSize : 0, pData);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pSubresource));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Image view functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateImageView(
+    XGL_DEVICE                        device,
+    const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE_VIEW*                   pView)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateImageView* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateImageView);
+    CREATE_TRACE_PACKET(xglCreateImageView, sizeof(XGL_IMAGE_VIEW_CREATE_INFO) + sizeof(XGL_IMAGE_VIEW));
+    result = real_xglCreateImageView(device, pCreateInfo, pView);
+    pPacket = interpret_body_as_xglCreateImageView(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_IMAGE_VIEW_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pView), sizeof(XGL_IMAGE_VIEW), pView);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pView));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateColorAttachmentView(
+    XGL_DEVICE                               device,
+    const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_COLOR_ATTACHMENT_VIEW*                   pView)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateColorAttachmentView* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateColorAttachmentView);
+    CREATE_TRACE_PACKET(xglCreateColorAttachmentView, sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO)+sizeof(XGL_COLOR_ATTACHMENT_VIEW));
+    result = real_xglCreateColorAttachmentView(device, pCreateInfo, pView);
+    pPacket = interpret_body_as_xglCreateColorAttachmentView(pHeader);
+    pPacket->device = device;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO), pCreateInfo);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pView), sizeof(XGL_COLOR_ATTACHMENT_VIEW), pView);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pView));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateDepthStencilView(
+    XGL_DEVICE                                device,
+    const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_DEPTH_STENCIL_VIEW*                   pView)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateDepthStencilView* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateDepthStencilView);
+    CREATE_TRACE_PACKET(xglCreateDepthStencilView, sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO) + sizeof(XGL_DEPTH_STENCIL_VIEW));
+    result = real_xglCreateDepthStencilView(device, pCreateInfo, pView);
+    pPacket = interpret_body_as_xglCreateDepthStencilView(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_DEPTH_STENCIL_VIEW_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pView), sizeof(XGL_DEPTH_STENCIL_VIEW), pView);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pView));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Shader functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateShader(
+    XGL_DEVICE                    device,
+    const XGL_SHADER_CREATE_INFO* pCreateInfo,
+    XGL_SHADER*                   pShader)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateShader* pPacket;
+    size_t shaderCodeSize;
+    SEND_ENTRYPOINT_ID(xglCreateShader);
+    shaderCodeSize = (pCreateInfo != NULL) ? pCreateInfo->codeSize : 0;
+    CREATE_TRACE_PACKET(xglCreateShader, sizeof(XGL_SHADER_CREATE_INFO) + sizeof(XGL_SHADER) + shaderCodeSize);
+    result = real_xglCreateShader(device, pCreateInfo, pShader);
+    pPacket = interpret_body_as_xglCreateShader(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_SHADER_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo->pCode), shaderCodeSize, pCreateInfo->pCode);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pShader), sizeof(XGL_SHADER), pShader);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo->pCode));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pShader));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Pipeline functions
+
+static size_t calculate_pipeline_shader_size(const XGL_PIPELINE_SHADER* shader)
+{
+    size_t size = 0;
+    XGL_UINT i, j;
+    
+    size += sizeof(XGL_PIPELINE_SHADER);
+    // descriptor sets
+    for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)
+    {
+        for (j = 0; j < shader->descriptorSetMapping[i].descriptorCount; j++)
+        {
+            size += sizeof(XGL_DESCRIPTOR_SLOT_INFO);
+            if (shader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)
+            {
+                size += sizeof(XGL_DESCRIPTOR_SET_MAPPING);
+            }
+        }
+    }
+
+    // constant buffers
+    if (shader->linkConstBufferCount > 0 && shader->pLinkConstBufferInfo != NULL)
+    {
+        XGL_UINT i;
+        for (i = 0; i < shader->linkConstBufferCount; i++)
+        {
+            size += sizeof(XGL_LINK_CONST_BUFFER);
+            size += shader->pLinkConstBufferInfo[i].bufferSize;
+        }
+    }
+    return size;
+}
+
+static void add_pipeline_shader_to_trace_packet(glv_trace_packet_header* pHeader, XGL_PIPELINE_SHADER* packetShader, const XGL_PIPELINE_SHADER* paramShader)
+{
+    XGL_UINT i, j;
+    // descriptor sets
+    for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)
+    {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo), sizeof(XGL_DESCRIPTOR_SLOT_INFO)* paramShader->descriptorSetMapping[i].descriptorCount, paramShader->descriptorSetMapping[i].pDescriptorInfo);
+        for (j = 0; j < paramShader->descriptorSetMapping[i].descriptorCount; j++)
+        {
+            if (paramShader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)
+            {
+                glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet), sizeof(XGL_DESCRIPTOR_SET_MAPPING), paramShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet);
+            }
+        }
+        packetShader->descriptorSetMapping[i].descriptorCount = paramShader->descriptorSetMapping[i].descriptorCount;
+    }
+
+    // constant buffers
+    if (paramShader->linkConstBufferCount > 0 && paramShader->pLinkConstBufferInfo != NULL)
+    {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->pLinkConstBufferInfo), sizeof(XGL_LINK_CONST_BUFFER) * paramShader->linkConstBufferCount, paramShader->pLinkConstBufferInfo);
+        for (i = 0; i < paramShader->linkConstBufferCount; i++)
+        {
+            glv_add_buffer_to_trace_packet(pHeader, (void**)&(packetShader->pLinkConstBufferInfo[i].pBufferData), packetShader->pLinkConstBufferInfo[i].bufferSize, paramShader->pLinkConstBufferInfo[i].pBufferData);
+        }
+    }
+}
+
+static void finalize_pipeline_shader_address(glv_trace_packet_header* pHeader, const XGL_PIPELINE_SHADER* packetShader)
+{
+    XGL_UINT i, j;
+    // descriptor sets
+    for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)
+    {
+        for (j = 0; j < packetShader->descriptorSetMapping[i].descriptorCount; j++)
+        {
+            if (packetShader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)
+            {
+                glv_finalize_buffer_address(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet));
+            }
+        }
+        glv_finalize_buffer_address(pHeader, (void**)&(packetShader->descriptorSetMapping[i].pDescriptorInfo));
+    }
+
+    // constant buffers
+    if (packetShader->linkConstBufferCount > 0 && packetShader->pLinkConstBufferInfo != NULL)
+    {
+        for (i = 0; i < packetShader->linkConstBufferCount; i++)
+        {
+            glv_finalize_buffer_address(pHeader, (void**)&(packetShader->pLinkConstBufferInfo[i].pBufferData));
+        }
+        glv_finalize_buffer_address(pHeader, (void**)&(packetShader->pLinkConstBufferInfo));
+    }
+}
+
+static size_t calculate_pipeline_state_size(const XGL_VOID* pState)
+{
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pNext = pState;
+    size_t totalStateSize = 0;
+    while (pNext)
+    {
+        switch (pNext->sType)
+        {
+            //case XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO:
+            //    totalStateSize += sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO);
+            //    break;
+            case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
+                totalStateSize += sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO);
+                break;
+            case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
+                totalStateSize += sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO);
+                break;
+            case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
+                totalStateSize += sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO);
+                break;
+            case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
+                totalStateSize += sizeof(XGL_PIPELINE_DB_STATE_CREATE_INFO);
+                break;
+            case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
+                totalStateSize += sizeof(XGL_PIPELINE_CB_STATE);
+                break;
+            case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
+            {
+                const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pShaderStage = (const XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pNext;
+                totalStateSize += (sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO) + calculate_pipeline_shader_size(&pShaderStage->shader));
+                break;
+            }
+            //case XGL_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO:
+            //    totalStateSize += sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO);
+            //   break;
+            default:
+                assert(0);
+        }
+        pNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO*)pNext->pNext;
+    }
+    return totalStateSize;
+}
+
+static void add_pipeline_state_to_trace_packet(glv_trace_packet_header* pHeader, XGL_VOID** ppOut, const XGL_VOID* pIn)
+{
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pInNow = pIn;
+    XGL_GRAPHICS_PIPELINE_CREATE_INFO** ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)ppOut;
+    while (pInNow != NULL)
+    {
+        XGL_GRAPHICS_PIPELINE_CREATE_INFO** ppOutNow = ppOutNext;
+        ppOutNext = NULL;
+
+        switch (pInNow->sType)
+        {
+            case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
+            {
+                glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_IA_STATE_CREATE_INFO), pInNow);
+                ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;
+                glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));
+                break;
+            }
+            case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
+            {
+                glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_TESS_STATE_CREATE_INFO), pInNow);
+                ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;
+                glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));
+                break;
+            }
+            case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
+            {
+                glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_RS_STATE_CREATE_INFO), pInNow);
+                ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;
+                glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));
+                break;
+            }
+            case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
+            {
+                glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_DB_STATE_CREATE_INFO), pInNow);
+                ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;
+                glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));
+                break;
+            }
+            case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
+            {
+                glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_CB_STATE), pInNow);
+                ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;
+                glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));
+                break;
+            }
+            case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
+            {
+                XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pPacket = NULL;
+                XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pInPacket = NULL;
+                glv_add_buffer_to_trace_packet(pHeader, (void**)(ppOutNow), sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO), pInNow);
+                pPacket = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*) *ppOutNow;
+                pInPacket = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*) pInNow;
+                add_pipeline_shader_to_trace_packet(pHeader, &pPacket->shader, &pInPacket->shader);
+                finalize_pipeline_shader_address(pHeader, &pPacket->shader);
+                ppOutNext = (XGL_GRAPHICS_PIPELINE_CREATE_INFO**)&(*ppOutNow)->pNext;
+                glv_finalize_buffer_address(pHeader, (void**)(ppOutNow));
+                break;
+            }
+            default:
+                assert(!"Encountered an unexpected type in pipeline state list");
+        }
+        pInNow = (XGL_GRAPHICS_PIPELINE_CREATE_INFO*)pInNow->pNext;
+    }
+    return;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateGraphicsPipeline(
+    XGL_DEVICE                               device,
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
+    XGL_PIPELINE*                            pPipeline)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    size_t stateSize;
+    struct_xglCreateGraphicsPipeline* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateGraphicsPipeline);
+    stateSize = calculate_pipeline_state_size(pCreateInfo->pNext);
+    CREATE_TRACE_PACKET(xglCreateGraphicsPipeline, sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO) + sizeof(XGL_PIPELINE) + stateSize);
+    result = real_xglCreateGraphicsPipeline(device, pCreateInfo, pPipeline);
+    pPacket = interpret_body_as_xglCreateGraphicsPipeline(pHeader);
+    pPacket->device = device;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_GRAPHICS_PIPELINE_CREATE_INFO), pCreateInfo);
+    add_pipeline_state_to_trace_packet(pHeader, (XGL_VOID**)&pPacket->pCreateInfo->pNext, pCreateInfo->pNext);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pPipeline), sizeof(XGL_PIPELINE), pPipeline);
+    pPacket->result = result;
+    // finalize the addresses in the pipeline state list is done in add_pipeline_state_to_trace_packet()
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pPipeline));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateComputePipeline(
+    XGL_DEVICE                              device,
+    const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
+    XGL_PIPELINE*                           pPipeline)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    size_t stateSize;
+    struct_xglCreateComputePipeline* pPacket = NULL;
+    SEND_ENTRYPOINT_ID(xglCreateComputePipeline);
+    stateSize = calculate_pipeline_state_size(pCreateInfo->pNext);
+    CREATE_TRACE_PACKET(xglCreateComputePipeline, sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO) + sizeof(XGL_PIPELINE) + stateSize + calculate_pipeline_shader_size(&pCreateInfo->cs));
+    result = real_xglCreateComputePipeline(device, pCreateInfo, pPipeline);
+    pPacket = interpret_body_as_xglCreateComputePipeline(pHeader);
+    pPacket->device = device;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_COMPUTE_PIPELINE_CREATE_INFO), pCreateInfo);
+    add_pipeline_state_to_trace_packet(pHeader, (XGL_VOID**)&(pPacket->pCreateInfo->pNext), pCreateInfo->pNext);
+    add_pipeline_shader_to_trace_packet(pHeader, (XGL_PIPELINE_SHADER*)&pPacket->pCreateInfo->cs, &pCreateInfo->cs);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pPipeline), sizeof(XGL_PIPELINE), pPipeline);
+    pPacket->result = result;
+    // finalize the addresses in the pipeline state list is done in add_pipeline_state_to_trace_packet()
+    finalize_pipeline_shader_address(pHeader, &pPacket->pCreateInfo->cs);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pPipeline));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglStorePipeline(
+    XGL_PIPELINE pipeline,
+    XGL_SIZE*    pDataSize,
+    XGL_VOID*    pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglStorePipeline* pPacket;
+    SEND_ENTRYPOINT_ID(xglStorePipeline);
+    CREATE_TRACE_PACKET(xglStorePipeline, sizeof(XGL_SIZE) + ((pDataSize != NULL) ? *pDataSize : 0));
+    result = real_xglStorePipeline(pipeline, pDataSize, pData);
+    pPacket = interpret_body_as_xglStorePipeline(pHeader);
+    pPacket->pipeline = pipeline;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDataSize), sizeof(XGL_SIZE), pDataSize);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), (pDataSize != NULL) ? *pDataSize : 0, pData);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDataSize));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglLoadPipeline(
+    XGL_DEVICE      device,
+    XGL_SIZE        dataSize,
+    const XGL_VOID* pData,
+    XGL_PIPELINE*   pPipeline)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglLoadPipeline* pPacket;
+    SEND_ENTRYPOINT_ID(xglLoadPipeline);
+    CREATE_TRACE_PACKET(xglLoadPipeline, dataSize + sizeof(XGL_PIPELINE));
+    result = real_xglLoadPipeline(device, dataSize, pData, pPipeline);
+    pPacket = interpret_body_as_xglLoadPipeline(pHeader);
+    pPacket->device = device;
+    pPacket->dataSize = dataSize;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), dataSize, pData);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pPipeline), sizeof(XGL_PIPELINE), pPipeline);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pPipeline));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreatePipelineDelta(
+    XGL_DEVICE      device,
+    XGL_PIPELINE    p1,
+    XGL_PIPELINE    p2,
+    XGL_PIPELINE_DELTA* delta)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreatePipelineDelta* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreatePipelineDelta);
+    CREATE_TRACE_PACKET(xglCreatePipelineDelta, sizeof(XGL_PIPELINE_DELTA));
+    result = real_xglCreatePipelineDelta(device, p1, p2, delta);
+    pPacket = interpret_body_as_xglCreatePipelineDelta(pHeader);
+    pPacket->device = device;
+    pPacket->p1 = p1;
+    pPacket->p2 = p2;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->delta), sizeof(XGL_PIPELINE_DELTA), delta);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->delta));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Sampler functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateSampler(
+    XGL_DEVICE                     device,
+    const XGL_SAMPLER_CREATE_INFO* pCreateInfo,
+    XGL_SAMPLER*                   pSampler)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateSampler* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateSampler);
+    CREATE_TRACE_PACKET(xglCreateSampler, sizeof(XGL_SAMPLER_CREATE_INFO) + sizeof(XGL_SAMPLER));
+    result = real_xglCreateSampler(device, pCreateInfo, pSampler);
+    pPacket = interpret_body_as_xglCreateSampler(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_SAMPLER_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pSampler), sizeof(XGL_SAMPLER), pSampler);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pSampler));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Descriptor set functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateDescriptorSet(
+    XGL_DEVICE                            device,
+    const XGL_DESCRIPTOR_SET_CREATE_INFO* pCreateInfo,
+    XGL_DESCRIPTOR_SET*                   pDescriptorSet)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateDescriptorSet* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateDescriptorSet);
+    CREATE_TRACE_PACKET(xglCreateDescriptorSet, sizeof(XGL_DESCRIPTOR_SET_CREATE_INFO) + sizeof(XGL_DESCRIPTOR_SET));
+    result = real_xglCreateDescriptorSet(device, pCreateInfo, pDescriptorSet);
+    pPacket = interpret_body_as_xglCreateDescriptorSet(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_DESCRIPTOR_SET_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDescriptorSet), sizeof(XGL_DESCRIPTOR_SET), pDescriptorSet);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDescriptorSet));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglBeginDescriptorSetUpdate(
+    XGL_DESCRIPTOR_SET descriptorSet)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglBeginDescriptorSetUpdate* pPacket;
+    SEND_ENTRYPOINT_ID(xglBeginDescriptorSetUpdate);
+    CREATE_TRACE_PACKET(xglBeginDescriptorSetUpdate, 0);
+    real_xglBeginDescriptorSetUpdate(descriptorSet);
+    pPacket = interpret_body_as_xglBeginDescriptorSetUpdate(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglEndDescriptorSetUpdate(
+    XGL_DESCRIPTOR_SET descriptorSet)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglEndDescriptorSetUpdate* pPacket;
+    SEND_ENTRYPOINT_ID(xglEndDescriptorSetUpdate);
+    CREATE_TRACE_PACKET(xglEndDescriptorSetUpdate, 0);
+    real_xglEndDescriptorSetUpdate(descriptorSet);
+    pPacket = interpret_body_as_xglEndDescriptorSetUpdate(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglAttachSamplerDescriptors(
+    XGL_DESCRIPTOR_SET descriptorSet,
+    XGL_UINT           startSlot,
+    XGL_UINT           slotCount,
+    const XGL_SAMPLER* pSamplers)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglAttachSamplerDescriptors* pPacket;
+    SEND_ENTRYPOINT_ID(xglAttachSamplerDescriptors);
+    CREATE_TRACE_PACKET(xglAttachSamplerDescriptors, slotCount*sizeof(XGL_SAMPLER));
+    real_xglAttachSamplerDescriptors(descriptorSet, startSlot, slotCount, pSamplers);
+    pPacket = interpret_body_as_xglAttachSamplerDescriptors(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    pPacket->startSlot = startSlot;
+	pPacket->slotCount = slotCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pSamplers), slotCount*sizeof(XGL_SAMPLER), pSamplers);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pSamplers));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglAttachImageViewDescriptors(
+    XGL_DESCRIPTOR_SET                descriptorSet,
+    XGL_UINT                          startSlot,
+    XGL_UINT                          slotCount,
+    const XGL_IMAGE_VIEW_ATTACH_INFO* pImageViews)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglAttachImageViewDescriptors* pPacket;
+    SEND_ENTRYPOINT_ID(xglAttachImageViewDescriptors);
+    CREATE_TRACE_PACKET(xglAttachImageViewDescriptors, slotCount*sizeof(XGL_IMAGE_VIEW_ATTACH_INFO));
+    real_xglAttachImageViewDescriptors(descriptorSet, startSlot, slotCount, pImageViews);
+    pPacket = interpret_body_as_xglAttachImageViewDescriptors(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    pPacket->startSlot = startSlot;
+	pPacket->slotCount = slotCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pImageViews), slotCount*sizeof(XGL_IMAGE_VIEW_ATTACH_INFO), pImageViews);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pImageViews));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglAttachMemoryViewDescriptors(
+    XGL_DESCRIPTOR_SET                 descriptorSet,
+    XGL_UINT                           startSlot,
+    XGL_UINT                           slotCount,
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemViews)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglAttachMemoryViewDescriptors* pPacket;
+    SEND_ENTRYPOINT_ID(xglAttachMemoryViewDescriptors);
+    CREATE_TRACE_PACKET(xglAttachMemoryViewDescriptors, slotCount*sizeof(XGL_MEMORY_VIEW_ATTACH_INFO));
+    real_xglAttachMemoryViewDescriptors(descriptorSet, startSlot, slotCount, pMemViews);
+    pPacket = interpret_body_as_xglAttachMemoryViewDescriptors(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    pPacket->startSlot = startSlot;
+	pPacket->slotCount = slotCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMemViews), slotCount*sizeof(XGL_MEMORY_VIEW_ATTACH_INFO), pMemViews);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMemViews));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglAttachNestedDescriptors(
+    XGL_DESCRIPTOR_SET                    descriptorSet,
+    XGL_UINT                              startSlot,
+    XGL_UINT                              slotCount,
+    const XGL_DESCRIPTOR_SET_ATTACH_INFO* pNestedDescriptorSets)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglAttachNestedDescriptors* pPacket;
+    SEND_ENTRYPOINT_ID(xglAttachNestedDescriptors);
+    CREATE_TRACE_PACKET(xglAttachNestedDescriptors, slotCount*sizeof(XGL_DESCRIPTOR_SET_ATTACH_INFO));
+    real_xglAttachNestedDescriptors(descriptorSet, startSlot, slotCount, pNestedDescriptorSets);
+    pPacket = interpret_body_as_xglAttachNestedDescriptors(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    pPacket->startSlot = startSlot;
+	pPacket->slotCount = slotCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pNestedDescriptorSets), slotCount*sizeof(XGL_DESCRIPTOR_SET_ATTACH_INFO), pNestedDescriptorSets);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pNestedDescriptorSets));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglClearDescriptorSetSlots(
+    XGL_DESCRIPTOR_SET descriptorSet,
+    XGL_UINT           startSlot,
+    XGL_UINT           slotCount)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglClearDescriptorSetSlots* pPacket;
+    SEND_ENTRYPOINT_ID(xglClearDescriptorSetSlots);
+    CREATE_TRACE_PACKET(xglClearDescriptorSetSlots, 0);
+    real_xglClearDescriptorSetSlots(descriptorSet, startSlot, slotCount);
+    pPacket = interpret_body_as_xglClearDescriptorSetSlots(pHeader);
+    pPacket->descriptorSet = descriptorSet;
+    pPacket->startSlot = startSlot;
+    pPacket->slotCount = slotCount;
+    FINISH_TRACE_PACKET();
+}
+
+// State object functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateViewportState(
+    XGL_DEVICE                            device,
+    const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
+    XGL_VIEWPORT_STATE_OBJECT*            pState)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateViewportState* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateViewportState);
+    CREATE_TRACE_PACKET(xglCreateViewportState, sizeof(XGL_VIEWPORT_STATE_CREATE_INFO) + sizeof(XGL_VIEWPORT_STATE_OBJECT));
+    result = real_xglCreateViewportState(device, pCreateInfo, pState);
+    pPacket = interpret_body_as_xglCreateViewportState(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_VIEWPORT_STATE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pState), sizeof(XGL_VIEWPORT_STATE_OBJECT), pState);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pState));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateRasterState(
+    XGL_DEVICE                          device,
+    const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
+    XGL_RASTER_STATE_OBJECT*            pState)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateRasterState* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateRasterState);
+    CREATE_TRACE_PACKET(xglCreateRasterState, sizeof(XGL_RASTER_STATE_CREATE_INFO) + sizeof(XGL_RASTER_STATE_OBJECT));
+    result = real_xglCreateRasterState(device, pCreateInfo, pState);
+    pPacket = interpret_body_as_xglCreateRasterState(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_RASTER_STATE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pState), sizeof(XGL_RASTER_STATE_OBJECT), pState);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pState));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateMsaaState(
+    XGL_DEVICE                        device,
+    const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
+    XGL_MSAA_STATE_OBJECT*            pState)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateMsaaState* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateMsaaState);
+    CREATE_TRACE_PACKET(xglCreateMsaaState, sizeof(XGL_MSAA_STATE_CREATE_INFO) + sizeof(XGL_MSAA_STATE_OBJECT));
+    result = real_xglCreateMsaaState(device, pCreateInfo, pState);
+    pPacket = interpret_body_as_xglCreateMsaaState(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_MSAA_STATE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pState), sizeof(XGL_MSAA_STATE_OBJECT), pState);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pState));
+	FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateColorBlendState(
+    XGL_DEVICE                               device,
+    const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
+    XGL_COLOR_BLEND_STATE_OBJECT*            pState)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateColorBlendState* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateColorBlendState);
+    CREATE_TRACE_PACKET(xglCreateColorBlendState, sizeof(XGL_COLOR_BLEND_STATE_CREATE_INFO) + sizeof(XGL_COLOR_BLEND_STATE_OBJECT));
+    result = real_xglCreateColorBlendState(device, pCreateInfo, pState);
+    pPacket = interpret_body_as_xglCreateColorBlendState(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_COLOR_BLEND_STATE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pState), sizeof(XGL_COLOR_BLEND_STATE_OBJECT), pState);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pState));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateDepthStencilState(
+    XGL_DEVICE                                 device,
+    const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
+    XGL_DEPTH_STENCIL_STATE_OBJECT*            pState)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateDepthStencilState* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateDepthStencilState);
+    CREATE_TRACE_PACKET(xglCreateDepthStencilState, sizeof(XGL_DEPTH_STENCIL_STATE_CREATE_INFO) + sizeof(XGL_DEPTH_STENCIL_STATE_OBJECT));
+    result = real_xglCreateDepthStencilState(device, pCreateInfo, pState);
+    pPacket = interpret_body_as_xglCreateDepthStencilState(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_DEPTH_STENCIL_STATE_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pState), sizeof(XGL_DEPTH_STENCIL_STATE_OBJECT), pState);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pState));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+// Command buffer functions
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglCreateCommandBuffer(
+    XGL_DEVICE                        device,
+    const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
+    XGL_CMD_BUFFER*                   pCmdBuffer)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglCreateCommandBuffer* pPacket;
+    SEND_ENTRYPOINT_ID(xglCreateCommandBuffer);
+    CREATE_TRACE_PACKET(xglCreateCommandBuffer, sizeof(XGL_CMD_BUFFER_CREATE_INFO) + sizeof(XGL_CMD_BUFFER));
+    result = real_xglCreateCommandBuffer(device, pCreateInfo, pCmdBuffer);
+    pPacket = interpret_body_as_xglCreateCommandBuffer(pHeader);
+    pPacket->device = device;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_CMD_BUFFER_CREATE_INFO), pCreateInfo);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCmdBuffer), sizeof(XGL_CMD_BUFFER), pCmdBuffer);
+    pPacket->result = result;
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCmdBuffer));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglBeginCommandBuffer(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_FLAGS      flags)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglBeginCommandBuffer* pPacket;
+    SEND_ENTRYPOINT_ID(xglBeginCommandBuffer);
+    CREATE_TRACE_PACKET(xglBeginCommandBuffer, 0);
+    result = real_xglBeginCommandBuffer(cmdBuffer, flags);
+    pPacket = interpret_body_as_xglBeginCommandBuffer(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->flags = flags;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglEndCommandBuffer(
+    XGL_CMD_BUFFER cmdBuffer)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglEndCommandBuffer* pPacket;
+    SEND_ENTRYPOINT_ID(xglEndCommandBuffer);
+    CREATE_TRACE_PACKET(xglEndCommandBuffer, 0);
+    result = real_xglEndCommandBuffer(cmdBuffer);
+    pPacket = interpret_body_as_xglEndCommandBuffer(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglResetCommandBuffer(
+    XGL_CMD_BUFFER cmdBuffer)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglResetCommandBuffer* pPacket;
+    SEND_ENTRYPOINT_ID(xglResetCommandBuffer);
+    CREATE_TRACE_PACKET(xglResetCommandBuffer, 0);
+    result = real_xglResetCommandBuffer(cmdBuffer);
+    pPacket = interpret_body_as_xglResetCommandBuffer(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->result = result;
+    return result;
+}
+
+// Command buffer building functions
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindPipeline(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_PIPELINE                  pipeline)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindPipeline* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindPipeline);
+    CREATE_TRACE_PACKET(xglCmdBindPipeline, 0);
+    real_xglCmdBindPipeline(cmdBuffer, pipelineBindPoint, pipeline);
+    pPacket = interpret_body_as_xglCmdBindPipeline(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+    pPacket->pipeline = pipeline;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindPipelineDelta(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_PIPELINE_DELTA            delta)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindPipelineDelta* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindPipelineDelta);
+    CREATE_TRACE_PACKET(xglCmdBindPipelineDelta, 0);
+    real_xglCmdBindPipelineDelta(cmdBuffer, pipelineBindPoint, delta);
+    pPacket = interpret_body_as_xglCmdBindPipelineDelta(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+    pPacket->delta = delta;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindStateObject(
+    XGL_CMD_BUFFER                   cmdBuffer,
+    XGL_STATE_BIND_POINT             stateBindPoint,
+    XGL_STATE_OBJECT                 state)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindStateObject* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindStateObject);
+    CREATE_TRACE_PACKET(xglCmdBindStateObject, 0);
+    real_xglCmdBindStateObject(cmdBuffer, stateBindPoint, state);
+    pPacket = interpret_body_as_xglCmdBindStateObject(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->stateBindPoint = stateBindPoint;
+    pPacket->state = state;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindDescriptorSet(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_PIPELINE_BIND_POINT            pipelineBindPoint,
+    XGL_UINT                           index,
+    XGL_DESCRIPTOR_SET                 descriptorSet,
+    XGL_UINT                           slotOffset)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindDescriptorSet* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindDescriptorSet);
+    CREATE_TRACE_PACKET(xglCmdBindDescriptorSet, 0);
+    real_xglCmdBindDescriptorSet(cmdBuffer, pipelineBindPoint, index, descriptorSet, slotOffset);
+    pPacket = interpret_body_as_xglCmdBindDescriptorSet(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+    pPacket->index = index;
+    pPacket->descriptorSet = descriptorSet;
+    pPacket->slotOffset = slotOffset;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindDynamicMemoryView(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_PIPELINE_BIND_POINT            pipelineBindPoint,
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindDynamicMemoryView* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindDynamicMemoryView);
+    CREATE_TRACE_PACKET(xglCmdBindDynamicMemoryView, sizeof(XGL_MEMORY_VIEW_ATTACH_INFO));
+    real_xglCmdBindDynamicMemoryView(cmdBuffer, pipelineBindPoint, pMemView);
+    pPacket = interpret_body_as_xglCmdBindDynamicMemoryView(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMemView), sizeof(XGL_MEMORY_VIEW_ATTACH_INFO), pMemView);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMemView));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindIndexData(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_INDEX_TYPE indexType)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindIndexData* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindIndexData);
+    CREATE_TRACE_PACKET(xglCmdBindIndexData, 0);
+    real_xglCmdBindIndexData(cmdBuffer, mem, offset, indexType);
+    pPacket = interpret_body_as_xglCmdBindIndexData(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->mem = mem;
+    pPacket->offset = offset;
+    pPacket->indexType = indexType;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBindAttachments(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_UINT                           colorAttachmentCount,
+    const XGL_COLOR_ATTACHMENT_BIND_INFO*  pColorAttachments,
+    const XGL_DEPTH_STENCIL_BIND_INFO* pDepthAttachment)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBindAttachments* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBindAttachments);
+    CREATE_TRACE_PACKET(xglCmdBindAttachments, colorAttachmentCount*sizeof(XGL_COLOR_ATTACHMENT_BIND_INFO)+((pDepthAttachment != NULL) ? sizeof(XGL_DEPTH_STENCIL_BIND_INFO) : 0));
+    real_xglCmdBindAttachments(cmdBuffer, colorAttachmentCount, pColorAttachments, pDepthAttachment);
+    pPacket = interpret_body_as_xglCmdBindAttachments(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->colorAttachmentCount = colorAttachmentCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pColorAttachments), colorAttachmentCount*sizeof(XGL_COLOR_ATTACHMENT_BIND_INFO), pColorAttachments);
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pDepthAttachment), sizeof(XGL_DEPTH_STENCIL_BIND_INFO), pDepthAttachment);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pColorAttachments));
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pDepthAttachment));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdPrepareMemoryRegions(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_UINT                           transitionCount,
+    const XGL_MEMORY_STATE_TRANSITION* pStateTransitions)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdPrepareMemoryRegions* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdPrepareMemoryRegions);
+    CREATE_TRACE_PACKET(xglCmdPrepareMemoryRegions, transitionCount*sizeof(XGL_MEMORY_STATE_TRANSITION));
+    real_xglCmdPrepareMemoryRegions(cmdBuffer, transitionCount, pStateTransitions);
+    pPacket = interpret_body_as_xglCmdPrepareMemoryRegions(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->transitionCount = transitionCount;
+	glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pStateTransitions), transitionCount*sizeof(XGL_MEMORY_STATE_TRANSITION), pStateTransitions);
+	glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pStateTransitions));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdPrepareImages(
+    XGL_CMD_BUFFER                    cmdBuffer,
+    XGL_UINT                          transitionCount,
+    const XGL_IMAGE_STATE_TRANSITION* pStateTransitions)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdPrepareImages* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdPrepareImages);
+    CREATE_TRACE_PACKET(xglCmdPrepareImages, transitionCount*sizeof(XGL_IMAGE_STATE_TRANSITION));
+    real_xglCmdPrepareImages(cmdBuffer, transitionCount, pStateTransitions);
+    pPacket = interpret_body_as_xglCmdPrepareImages(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->transitionCount = transitionCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pStateTransitions), transitionCount*sizeof(XGL_IMAGE_STATE_TRANSITION), pStateTransitions);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pStateTransitions));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDraw(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       firstVertex,
+    XGL_UINT       vertexCount,
+    XGL_UINT       firstInstance,
+    XGL_UINT       instanceCount)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDraw* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDraw);
+    CREATE_TRACE_PACKET(xglCmdDraw, 0);
+    real_xglCmdDraw(cmdBuffer, firstVertex, vertexCount, firstInstance, instanceCount);
+    pPacket = interpret_body_as_xglCmdDraw(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->firstVertex = firstVertex;
+    pPacket->vertexCount = vertexCount;
+    pPacket->firstInstance = firstInstance;
+    pPacket->instanceCount = instanceCount;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDrawIndexed(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       firstIndex,
+    XGL_UINT       indexCount,
+    XGL_INT        vertexOffset,
+    XGL_UINT       firstInstance,
+    XGL_UINT       instanceCount)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDrawIndexed* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDrawIndexed);
+    CREATE_TRACE_PACKET(xglCmdDrawIndexed, 0);
+    real_xglCmdDrawIndexed(cmdBuffer, firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
+    pPacket = interpret_body_as_xglCmdDrawIndexed(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->firstIndex = firstIndex;
+    pPacket->indexCount = indexCount;
+    pPacket->vertexOffset = vertexOffset;
+    pPacket->firstInstance = firstInstance;
+    pPacket->instanceCount = instanceCount;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDrawIndirect(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_UINT32     count,
+    XGL_UINT32     stride)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDrawIndirect* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDrawIndirect);
+    CREATE_TRACE_PACKET(xglCmdDrawIndirect, 0);
+    real_xglCmdDrawIndirect(cmdBuffer, mem, offset, count, stride);
+    pPacket = interpret_body_as_xglCmdDrawIndirect(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->mem = mem;
+    pPacket->offset = offset;
+    pPacket->count = count;
+    pPacket->stride = stride;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDrawIndexedIndirect(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_UINT32     count,
+    XGL_UINT32     stride)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDrawIndexedIndirect* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDrawIndexedIndirect);
+    CREATE_TRACE_PACKET(xglCmdDrawIndexedIndirect, 0);
+    real_xglCmdDrawIndexedIndirect(cmdBuffer, mem, offset, count, stride);
+    pPacket = interpret_body_as_xglCmdDrawIndexedIndirect(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->mem = mem;
+    pPacket->offset = offset;
+    pPacket->count = count;
+    pPacket->stride = stride;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDispatch(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       x,
+    XGL_UINT       y,
+    XGL_UINT       z)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDispatch* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDispatch);
+    CREATE_TRACE_PACKET(xglCmdDispatch, 0);
+    real_xglCmdDispatch(cmdBuffer, x, y, z);
+    pPacket = interpret_body_as_xglCmdDispatch(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->x = x;
+    pPacket->y = y;
+    pPacket->z = z;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDispatchIndirect(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDispatchIndirect* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDispatchIndirect);
+    CREATE_TRACE_PACKET(xglCmdDispatchIndirect, 0);
+    real_xglCmdDispatchIndirect(cmdBuffer, mem, offset);
+    pPacket = interpret_body_as_xglCmdDispatchIndirect(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->mem = mem;
+    pPacket->offset = offset;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdCopyMemory(
+    XGL_CMD_BUFFER         cmdBuffer,
+    XGL_GPU_MEMORY         srcMem,
+    XGL_GPU_MEMORY         destMem,
+    XGL_UINT               regionCount,
+    const XGL_MEMORY_COPY* pRegions)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdCopyMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdCopyMemory);
+    CREATE_TRACE_PACKET(xglCmdCopyMemory, regionCount*sizeof(XGL_MEMORY_COPY));
+    real_xglCmdCopyMemory(cmdBuffer, srcMem, destMem, regionCount, pRegions);
+    pPacket = interpret_body_as_xglCmdCopyMemory(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->srcMem = srcMem;
+    pPacket->destMem = destMem;
+    pPacket->regionCount = regionCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRegions), regionCount*sizeof(XGL_MEMORY_COPY), pRegions);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRegions));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdCopyImage(
+    XGL_CMD_BUFFER        cmdBuffer,
+    XGL_IMAGE             srcImage,
+    XGL_IMAGE             destImage,
+    XGL_UINT              regionCount,
+    const XGL_IMAGE_COPY* pRegions)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdCopyImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdCopyImage);
+    CREATE_TRACE_PACKET(xglCmdCopyImage, regionCount*sizeof(XGL_MEMORY_IMAGE_COPY));
+    real_xglCmdCopyImage(cmdBuffer, srcImage, destImage, regionCount, pRegions);
+    pPacket = interpret_body_as_xglCmdCopyImage(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->srcImage = srcImage;
+    pPacket->destImage = destImage;
+    pPacket->regionCount = regionCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRegions), regionCount*sizeof(XGL_MEMORY_IMAGE_COPY), pRegions);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRegions));    FINISH_TRACE_PACKET();
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdCopyMemoryToImage(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_GPU_MEMORY               srcMem,
+    XGL_IMAGE                    destImage,
+    XGL_UINT                     regionCount,
+    const XGL_MEMORY_IMAGE_COPY* pRegions)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdCopyMemoryToImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdCopyMemoryToImage);
+    CREATE_TRACE_PACKET(xglCmdCopyMemoryToImage, regionCount*sizeof(XGL_MEMORY_IMAGE_COPY));
+    real_xglCmdCopyMemoryToImage(cmdBuffer, srcMem, destImage, regionCount, pRegions);
+    pPacket = interpret_body_as_xglCmdCopyMemoryToImage(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->srcMem = srcMem;
+    pPacket->destImage = destImage;
+    pPacket->regionCount = regionCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRegions), regionCount*sizeof(XGL_MEMORY_IMAGE_COPY), pRegions);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRegions));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdCopyImageToMemory(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_IMAGE                    srcImage,
+    XGL_GPU_MEMORY               destMem,
+    XGL_UINT                     regionCount,
+    const XGL_MEMORY_IMAGE_COPY* pRegions)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdCopyImageToMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdCopyImageToMemory);
+    CREATE_TRACE_PACKET(xglCmdCopyImageToMemory, regionCount*sizeof(XGL_MEMORY_IMAGE_COPY));
+    real_xglCmdCopyImageToMemory(cmdBuffer, srcImage, destMem, regionCount, pRegions);
+    pPacket = interpret_body_as_xglCmdCopyImageToMemory(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->srcImage = srcImage;
+    pPacket->destMem = destMem;
+    pPacket->regionCount = regionCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRegions), regionCount*sizeof(XGL_MEMORY_IMAGE_COPY), pRegions);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRegions));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdCloneImageData(
+    XGL_CMD_BUFFER  cmdBuffer,
+    XGL_IMAGE       srcImage,
+    XGL_IMAGE_STATE srcImageState,
+    XGL_IMAGE       destImage,
+    XGL_IMAGE_STATE destImageState)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdCloneImageData* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdCloneImageData);
+    CREATE_TRACE_PACKET(xglCmdCloneImageData, 0);
+    real_xglCmdCloneImageData(cmdBuffer, srcImage, srcImageState, destImage, destImageState);
+    pPacket = interpret_body_as_xglCmdCloneImageData(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->srcImage = srcImage;
+    pPacket->srcImageState = srcImageState;
+    pPacket->destImage = destImage;
+    pPacket->destImageState = destImageState;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdUpdateMemory(
+    XGL_CMD_BUFFER    cmdBuffer,
+    XGL_GPU_MEMORY    destMem,
+    XGL_GPU_SIZE      destOffset,
+    XGL_GPU_SIZE      dataSize,
+    const XGL_UINT32* pData)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdUpdateMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdUpdateMemory);
+    CREATE_TRACE_PACKET(xglCmdUpdateMemory, dataSize);
+    real_xglCmdUpdateMemory(cmdBuffer, destMem, destOffset, dataSize, pData);
+    pPacket = interpret_body_as_xglCmdUpdateMemory(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->destMem = destMem;
+    pPacket->destOffset = destOffset;
+    pPacket->dataSize = dataSize;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), dataSize, pData);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdFillMemory(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY destMem,
+    XGL_GPU_SIZE   destOffset,
+    XGL_GPU_SIZE   fillSize,
+    XGL_UINT32     data)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdFillMemory* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdFillMemory);
+    CREATE_TRACE_PACKET(xglCmdFillMemory, 0);
+    real_xglCmdFillMemory(cmdBuffer, destMem, destOffset, fillSize, data);
+    pPacket = interpret_body_as_xglCmdFillMemory(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->destMem = destMem;
+    pPacket->destOffset = destOffset;
+    pPacket->fillSize = fillSize;
+    pPacket->data = data;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdClearColorImage(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    const XGL_FLOAT                    color[4],
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdClearColorImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdClearColorImage);
+    CREATE_TRACE_PACKET(xglCmdClearColorImage, rangeCount*sizeof(XGL_IMAGE_SUBRESOURCE_RANGE));
+    real_xglCmdClearColorImage(cmdBuffer, image, color, rangeCount, pRanges);
+    pPacket = interpret_body_as_xglCmdClearColorImage(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->image = image;
+    memcpy((void*)pPacket->color, color, 4 * sizeof(XGL_UINT32));
+    pPacket->rangeCount = rangeCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRanges), rangeCount*sizeof(XGL_IMAGE_SUBRESOURCE_RANGE), pRanges);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRanges));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdClearColorImageRaw(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    const XGL_UINT32                   color[4],
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdClearColorImageRaw* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdClearColorImageRaw);
+    CREATE_TRACE_PACKET(xglCmdClearColorImageRaw, rangeCount*sizeof(XGL_IMAGE_SUBRESOURCE_RANGE));
+    real_xglCmdClearColorImageRaw(cmdBuffer, image, color, rangeCount, pRanges);
+    pPacket = interpret_body_as_xglCmdClearColorImageRaw(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->image = image;
+    memcpy((void*)pPacket->color, color, 4 * sizeof(XGL_UINT32));
+    pPacket->rangeCount = rangeCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRanges), rangeCount*sizeof(XGL_IMAGE_SUBRESOURCE_RANGE), pRanges);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRanges));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdClearDepthStencil(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    XGL_FLOAT                          depth,
+    XGL_UINT32                          stencil,
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdClearDepthStencil* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdClearDepthStencil);
+    CREATE_TRACE_PACKET(xglCmdClearDepthStencil, rangeCount*sizeof(XGL_IMAGE_SUBRESOURCE_RANGE));
+    real_xglCmdClearDepthStencil(cmdBuffer, image, depth, stencil, rangeCount, pRanges);
+    pPacket = interpret_body_as_xglCmdClearDepthStencil(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->image = image;
+    pPacket->depth = depth;
+    pPacket->stencil = stencil;
+    pPacket->rangeCount = rangeCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRanges), rangeCount*sizeof(XGL_IMAGE_SUBRESOURCE_RANGE), pRanges);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRanges));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdResolveImage(
+    XGL_CMD_BUFFER           cmdBuffer,
+    XGL_IMAGE                srcImage,
+    XGL_IMAGE                destImage,
+    XGL_UINT                 rectCount,
+    const XGL_IMAGE_RESOLVE* pRects)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdResolveImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdResolveImage);
+    CREATE_TRACE_PACKET(xglCmdResolveImage, rectCount*sizeof(XGL_IMAGE_RESOLVE));
+    real_xglCmdResolveImage(cmdBuffer, srcImage, destImage, rectCount, pRects);
+    pPacket = interpret_body_as_xglCmdResolveImage(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->srcImage = srcImage;
+    pPacket->destImage = destImage;
+    pPacket->rectCount = rectCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pRects), rectCount*sizeof(XGL_IMAGE_RESOLVE), pRects);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pRects));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdSetEvent(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_EVENT      event)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdSetEvent* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdSetEvent);
+    CREATE_TRACE_PACKET(xglCmdSetEvent, 0);
+    real_xglCmdSetEvent(cmdBuffer, event);
+    pPacket = interpret_body_as_xglCmdSetEvent(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->event = event;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdResetEvent(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_EVENT      event)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdResetEvent* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdResetEvent);
+    CREATE_TRACE_PACKET(xglCmdResetEvent, 0);
+    real_xglCmdResetEvent(cmdBuffer, event);
+    pPacket = interpret_body_as_xglCmdResetEvent(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->event = event;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdMemoryAtomic(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY destMem,
+    XGL_GPU_SIZE   destOffset,
+    XGL_UINT64     srcData,
+    XGL_ATOMIC_OP  atomicOp)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdMemoryAtomic* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdMemoryAtomic);
+    CREATE_TRACE_PACKET(xglCmdMemoryAtomic, 0);
+    real_xglCmdMemoryAtomic(cmdBuffer, destMem, destOffset, srcData, atomicOp);
+    pPacket = interpret_body_as_xglCmdMemoryAtomic(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->destMem = destMem;
+    pPacket->destOffset = destOffset;
+    pPacket->srcData = srcData;
+    pPacket->atomicOp = atomicOp;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdBeginQuery(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       slot,
+    XGL_FLAGS      flags)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdBeginQuery* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdBeginQuery);
+    CREATE_TRACE_PACKET(xglCmdBeginQuery, 0);
+    real_xglCmdBeginQuery(cmdBuffer, queryPool, slot, flags);
+    pPacket = interpret_body_as_xglCmdBeginQuery(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->queryPool = queryPool;
+    pPacket->slot = slot;
+    pPacket->flags = flags;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdEndQuery(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       slot)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdEndQuery* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdEndQuery);
+    CREATE_TRACE_PACKET(xglCmdEndQuery, 0);
+    real_xglCmdEndQuery(cmdBuffer, queryPool, slot);
+    pPacket = interpret_body_as_xglCmdEndQuery(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->queryPool = queryPool;
+    pPacket->slot = slot;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdResetQueryPool(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       startQuery,
+    XGL_UINT       queryCount)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdResetQueryPool* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdResetQueryPool);
+    CREATE_TRACE_PACKET(xglCmdResetQueryPool, 0);
+    real_xglCmdResetQueryPool(cmdBuffer, queryPool, startQuery, queryCount);
+    pPacket = interpret_body_as_xglCmdResetQueryPool(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->queryPool = queryPool;
+    pPacket->startQuery = startQuery;
+    pPacket->queryCount = queryCount;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdWriteTimestamp(
+    XGL_CMD_BUFFER           cmdBuffer,
+    XGL_TIMESTAMP_TYPE       timestampType,
+    XGL_GPU_MEMORY           destMem,
+    XGL_GPU_SIZE             destOffset)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdWriteTimestamp* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdWriteTimestamp);
+    CREATE_TRACE_PACKET(xglCmdWriteTimestamp, 0);
+    real_xglCmdWriteTimestamp(cmdBuffer, timestampType, destMem, destOffset);
+    pPacket = interpret_body_as_xglCmdWriteTimestamp(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->timestampType = timestampType;
+    pPacket->destMem = destMem;
+    pPacket->destOffset = destOffset;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdInitAtomicCounters(
+    XGL_CMD_BUFFER                   cmdBuffer,
+    XGL_PIPELINE_BIND_POINT          pipelineBindPoint,
+    XGL_UINT                         startCounter,
+    XGL_UINT                         counterCount,
+    const XGL_UINT32*                pData)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdInitAtomicCounters* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdInitAtomicCounters);
+    CREATE_TRACE_PACKET(xglCmdInitAtomicCounters, counterCount*sizeof(XGL_UINT32));
+    real_xglCmdInitAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, pData);
+    pPacket = interpret_body_as_xglCmdInitAtomicCounters(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+    pPacket->startCounter = startCounter;
+    pPacket->counterCount = counterCount;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), counterCount*sizeof(XGL_UINT32), pData);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdLoadAtomicCounters(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_UINT                      startCounter,
+    XGL_UINT                      counterCount,
+    XGL_GPU_MEMORY                srcMem,
+    XGL_GPU_SIZE                  srcOffset)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdLoadAtomicCounters* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdLoadAtomicCounters);
+    CREATE_TRACE_PACKET(xglCmdLoadAtomicCounters, 0);
+    real_xglCmdLoadAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, srcMem, srcOffset);
+    pPacket = interpret_body_as_xglCmdLoadAtomicCounters(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+    pPacket->startCounter = startCounter;
+    pPacket->counterCount = counterCount;
+    pPacket->srcMem = srcMem;
+    pPacket->srcOffset = srcOffset;
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdSaveAtomicCounters(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_UINT                      startCounter,
+    XGL_UINT                      counterCount,
+    XGL_GPU_MEMORY                destMem,
+    XGL_GPU_SIZE                  destOffset)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdSaveAtomicCounters* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdSaveAtomicCounters);
+    CREATE_TRACE_PACKET(xglCmdSaveAtomicCounters, 0);
+    real_xglCmdSaveAtomicCounters(cmdBuffer, pipelineBindPoint, startCounter, counterCount, destMem, destOffset);
+    pPacket = interpret_body_as_xglCmdSaveAtomicCounters(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    pPacket->pipelineBindPoint = pipelineBindPoint;
+    pPacket->startCounter = startCounter;
+    pPacket->counterCount = counterCount;
+    pPacket->destMem = destMem;
+    pPacket->destOffset = destOffset;
+    FINISH_TRACE_PACKET();
+}
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl.h
new file mode 100644
index 0000000..a8eff4d
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl.h
@@ -0,0 +1,826 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glvtrace_xgl_xgl_structs.h"
+#include "glvtrace_xgl_packet_id.h"
+
+void AttachHooks();
+void DetachHooks();
+
+// Pointers to real functions and declarations of hooked functions
+#ifdef WIN32
+#define __HOOKED_xglInitAndEnumerateGpus hooked_xglInitAndEnumerateGpus
+#define __HOOKED_xglGetGpuInfo hooked_xglGetGpuInfo
+#define __HOOKED_xglCreateDevice hooked_xglCreateDevice
+#define __HOOKED_xglDestroyDevice hooked_xglDestroyDevice
+#define __HOOKED_xglGetExtensionSupport hooked_xglGetExtensionSupport
+#define __HOOKED_xglGetDeviceQueue hooked_xglGetDeviceQueue
+#define __HOOKED_xglQueueSubmit hooked_xglQueueSubmit
+#define __HOOKED_xglQueueSetGlobalMemReferences hooked_xglQueueSetGlobalMemReferences
+#define __HOOKED_xglQueueWaitIdle hooked_xglQueueWaitIdle
+#define __HOOKED_xglDeviceWaitIdle hooked_xglDeviceWaitIdle
+#define __HOOKED_xglGetMemoryHeapCount hooked_xglGetMemoryHeapCount
+#define __HOOKED_xglGetMemoryHeapInfo hooked_xglGetMemoryHeapInfo
+#define __HOOKED_xglAllocMemory hooked_xglAllocMemory
+#define __HOOKED_xglFreeMemory hooked_xglFreeMemory
+#define __HOOKED_xglSetMemoryPriority hooked_xglSetMemoryPriority
+#define __HOOKED_xglMapMemory hooked_xglMapMemory
+#define __HOOKED_xglUnmapMemory hooked_xglUnmapMemory
+#define __HOOKED_xglPinSystemMemory hooked_xglPinSystemMemory
+#define __HOOKED_xglRemapVirtualMemoryPages hooked_xglRemapVirtualMemoryPages
+#define __HOOKED_xglGetMultiGpuCompatibility hooked_xglGetMultiGpuCompatibility
+#define __HOOKED_xglOpenSharedMemory hooked_xglOpenSharedMemory
+#define __HOOKED_xglOpenSharedQueueSemaphore hooked_xglOpenSharedQueueSemaphore
+#define __HOOKED_xglOpenPeerMemory hooked_xglOpenPeerMemory
+#define __HOOKED_xglOpenPeerImage hooked_xglOpenPeerImage
+#define __HOOKED_xglDestroyObject hooked_xglDestroyObject
+#define __HOOKED_xglGetObjectInfo hooked_xglGetObjectInfo
+#define __HOOKED_xglBindObjectMemory hooked_xglBindObjectMemory
+#define __HOOKED_xglCreateFence hooked_xglCreateFence
+#define __HOOKED_xglGetFenceStatus hooked_xglGetFenceStatus
+#define __HOOKED_xglWaitForFences hooked_xglWaitForFences
+#define __HOOKED_xglCreateQueueSemaphore hooked_xglCreateQueueSemaphore
+#define __HOOKED_xglSignalQueueSemaphore hooked_xglSignalQueueSemaphore
+#define __HOOKED_xglWaitQueueSemaphore hooked_xglWaitQueueSemaphore
+#define __HOOKED_xglCreateEvent hooked_xglCreateEvent
+#define __HOOKED_xglGetEventStatus hooked_xglGetEventStatus
+#define __HOOKED_xglSetEvent hooked_xglSetEvent
+#define __HOOKED_xglResetEvent hooked_xglResetEvent
+#define __HOOKED_xglCreateQueryPool hooked_xglCreateQueryPool
+#define __HOOKED_xglGetQueryPoolResults hooked_xglGetQueryPoolResults
+#define __HOOKED_xglGetFormatInfo hooked_xglGetFormatInfo
+#define __HOOKED_xglCreateImage hooked_xglCreateImage
+#define __HOOKED_xglGetImageSubresourceInfo hooked_xglGetImageSubresourceInfo
+#define __HOOKED_xglCreateImageView hooked_xglCreateImageView
+#define __HOOKED_xglCreateColorAttachmentView hooked_xglCreateColorAttachmentView
+#define __HOOKED_xglCreateDepthStencilView hooked_xglCreateDepthStencilView
+#define __HOOKED_xglCreateShader hooked_xglCreateShader
+#define __HOOKED_xglCreateGraphicsPipeline hooked_xglCreateGraphicsPipeline
+#define __HOOKED_xglCreateComputePipeline hooked_xglCreateComputePipeline
+#define __HOOKED_xglStorePipeline hooked_xglStorePipeline
+#define __HOOKED_xglLoadPipeline hooked_xglLoadPipeline
+#define __HOOKED_xglCreateSampler hooked_xglCreateSampler
+#define __HOOKED_xglCreateDescriptorSet hooked_xglCreateDescriptorSet
+#define __HOOKED_xglBeginDescriptorSetUpdate hooked_xglBeginDescriptorSetUpdate
+#define __HOOKED_xglEndDescriptorSetUpdate hooked_xglEndDescriptorSetUpdate
+#define __HOOKED_xglAttachSamplerDescriptors hooked_xglAttachSamplerDescriptors
+#define __HOOKED_xglAttachImageViewDescriptors hooked_xglAttachImageViewDescriptors
+#define __HOOKED_xglAttachMemoryViewDescriptors hooked_xglAttachMemoryViewDescriptors
+#define __HOOKED_xglAttachNestedDescriptors hooked_xglAttachNestedDescriptors
+#define __HOOKED_xglClearDescriptorSetSlots hooked_xglClearDescriptorSetSlots
+#define __HOOKED_xglCreateViewportState hooked_xglCreateViewportState
+#define __HOOKED_xglCreateRasterState hooked_xglCreateRasterState
+#define __HOOKED_xglCreateMsaaState hooked_xglCreateMsaaState
+#define __HOOKED_xglCreateColorBlendState hooked_xglCreateColorBlendState
+#define __HOOKED_xglCreateDepthStencilState hooked_xglCreateDepthStencilState
+#define __HOOKED_xglCreateCommandBuffer hooked_xglCreateCommandBuffer
+#define __HOOKED_xglBeginCommandBuffer hooked_xglBeginCommandBuffer
+#define __HOOKED_xglEndCommandBuffer hooked_xglEndCommandBuffer
+#define __HOOKED_xglResetCommandBuffer hooked_xglResetCommandBuffer
+#define __HOOKED_xglCmdBindPipeline hooked_xglCmdBindPipeline
+#define __HOOKED_xglCmdBindStateObject hooked_xglCmdBindStateObject
+#define __HOOKED_xglCmdBindDescriptorSet hooked_xglCmdBindDescriptorSet
+#define __HOOKED_xglCmdBindDynamicMemoryView hooked_xglCmdBindDynamicMemoryView
+#define __HOOKED_xglCmdBindIndexData hooked_xglCmdBindIndexData
+#define __HOOKED_xglCmdBindAttachments hooked_xglCmdBindAttachments
+#define __HOOKED_xglCmdPrepareMemoryRegions hooked_xglCmdPrepareMemoryRegions
+#define __HOOKED_xglCmdPrepareImages hooked_xglCmdPrepareImages
+#define __HOOKED_xglCmdDraw hooked_xglCmdDraw
+#define __HOOKED_xglCmdDrawIndexed hooked_xglCmdDrawIndexed
+#define __HOOKED_xglCmdDrawIndirect hooked_xglCmdDrawIndirect
+#define __HOOKED_xglCmdDrawIndexedIndirect hooked_xglCmdDrawIndexedIndirect
+#define __HOOKED_xglCmdDispatch hooked_xglCmdDispatch
+#define __HOOKED_xglCmdDispatchIndirect hooked_xglCmdDispatchIndirect
+#define __HOOKED_xglCmdCopyMemory hooked_xglCmdCopyMemory
+#define __HOOKED_xglCmdCopyImage hooked_xglCmdCopyImage
+#define __HOOKED_xglCmdCopyMemoryToImage hooked_xglCmdCopyMemoryToImage
+#define __HOOKED_xglCmdCopyImageToMemory hooked_xglCmdCopyImageToMemory
+#define __HOOKED_xglCmdCloneImageData hooked_xglCmdCloneImageData
+#define __HOOKED_xglCmdUpdateMemory hooked_xglCmdUpdateMemory
+#define __HOOKED_xglCmdFillMemory hooked_xglCmdFillMemory
+#define __HOOKED_xglCmdClearColorImage hooked_xglCmdClearColorImage
+#define __HOOKED_xglCmdClearColorImageRaw hooked_xglCmdClearColorImageRaw
+#define __HOOKED_xglCmdClearDepthStencil hooked_xglCmdClearDepthStencil
+#define __HOOKED_xglCmdResolveImage hooked_xglCmdResolveImage
+#define __HOOKED_xglCmdSetEvent hooked_xglCmdSetEvent
+#define __HOOKED_xglCmdResetEvent hooked_xglCmdResetEvent
+#define __HOOKED_xglCmdMemoryAtomic hooked_xglCmdMemoryAtomic
+#define __HOOKED_xglCmdBeginQuery hooked_xglCmdBeginQuery
+#define __HOOKED_xglCmdEndQuery hooked_xglCmdEndQuery
+#define __HOOKED_xglCmdResetQueryPool hooked_xglCmdResetQueryPool
+#define __HOOKED_xglCmdWriteTimestamp hooked_xglCmdWriteTimestamp
+#define __HOOKED_xglCmdInitAtomicCounters hooked_xglCmdInitAtomicCounters
+#define __HOOKED_xglCmdLoadAtomicCounters hooked_xglCmdLoadAtomicCounters
+#define __HOOKED_xglCmdSaveAtomicCounters hooked_xglCmdSaveAtomicCounters
+
+#elif defined(__linux__)
+#define __HOOKED_xglInitAndEnumerateGpus xglInitAndEnumerateGpus
+#define __HOOKED_xglGetGpuInfo xglGetGpuInfo
+#define __HOOKED_xglCreateDevice xglCreateDevice
+#define __HOOKED_xglDestroyDevice xglDestroyDevice
+#define __HOOKED_xglGetExtensionSupport xglGetExtensionSupport
+#define __HOOKED_xglGetDeviceQueue xglGetDeviceQueue
+#define __HOOKED_xglQueueSubmit xglQueueSubmit
+#define __HOOKED_xglQueueSetGlobalMemReferences xglQueueSetGlobalMemReferences
+#define __HOOKED_xglQueueWaitIdle xglQueueWaitIdle
+#define __HOOKED_xglDeviceWaitIdle xglDeviceWaitIdle
+#define __HOOKED_xglGetMemoryHeapCount xglGetMemoryHeapCount
+#define __HOOKED_xglGetMemoryHeapInfo xglGetMemoryHeapInfo
+#define __HOOKED_xglAllocMemory xglAllocMemory
+#define __HOOKED_xglFreeMemory xglFreeMemory
+#define __HOOKED_xglSetMemoryPriority xglSetMemoryPriority
+#define __HOOKED_xglMapMemory xglMapMemory
+#define __HOOKED_xglUnmapMemory xglUnmapMemory
+#define __HOOKED_xglPinSystemMemory xglPinSystemMemory
+#define __HOOKED_xglRemapVirtualMemoryPages xglRemapVirtualMemoryPages
+#define __HOOKED_xglGetMultiGpuCompatibility xglGetMultiGpuCompatibility
+#define __HOOKED_xglOpenSharedMemory xglOpenSharedMemory
+#define __HOOKED_xglOpenSharedQueueSemaphore xglOpenSharedQueueSemaphore
+#define __HOOKED_xglOpenPeerMemory xglOpenPeerMemory
+#define __HOOKED_xglOpenPeerImage xglOpenPeerImage
+#define __HOOKED_xglDestroyObject xglDestroyObject
+#define __HOOKED_xglGetObjectInfo xglGetObjectInfo
+#define __HOOKED_xglBindObjectMemory xglBindObjectMemory
+#define __HOOKED_xglCreateFence xglCreateFence
+#define __HOOKED_xglGetFenceStatus xglGetFenceStatus
+#define __HOOKED_xglWaitForFences xglWaitForFences
+#define __HOOKED_xglCreateQueueSemaphore xglCreateQueueSemaphore
+#define __HOOKED_xglSignalQueueSemaphore xglSignalQueueSemaphore
+#define __HOOKED_xglWaitQueueSemaphore xglWaitQueueSemaphore
+#define __HOOKED_xglCreateEvent xglCreateEvent
+#define __HOOKED_xglGetEventStatus xglGetEventStatus
+#define __HOOKED_xglSetEvent xglSetEvent
+#define __HOOKED_xglResetEvent xglResetEvent
+#define __HOOKED_xglCreateQueryPool xglCreateQueryPool
+#define __HOOKED_xglGetQueryPoolResults xglGetQueryPoolResults
+#define __HOOKED_xglGetFormatInfo xglGetFormatInfo
+#define __HOOKED_xglCreateImage xglCreateImage
+#define __HOOKED_xglGetImageSubresourceInfo xglGetImageSubresourceInfo
+#define __HOOKED_xglCreateImageView xglCreateImageView
+#define __HOOKED_xglCreateColorAttachmentView xglCreateColorAttachmentView
+#define __HOOKED_xglCreateDepthStencilView xglCreateDepthStencilView
+#define __HOOKED_xglCreateShader xglCreateShader
+#define __HOOKED_xglCreateGraphicsPipeline xglCreateGraphicsPipeline
+#define __HOOKED_xglCreateComputePipeline xglCreateComputePipeline
+#define __HOOKED_xglStorePipeline xglStorePipeline
+#define __HOOKED_xglLoadPipeline xglLoadPipeline
+#define __HOOKED_xglCreateSampler xglCreateSampler
+#define __HOOKED_xglCreateDescriptorSet xglCreateDescriptorSet
+#define __HOOKED_xglBeginDescriptorSetUpdate xglBeginDescriptorSetUpdate
+#define __HOOKED_xglEndDescriptorSetUpdate xglEndDescriptorSetUpdate
+#define __HOOKED_xglAttachSamplerDescriptors xglAttachSamplerDescriptors
+#define __HOOKED_xglAttachImageViewDescriptors xglAttachImageViewDescriptors
+#define __HOOKED_xglAttachMemoryViewDescriptors xglAttachMemoryViewDescriptors
+#define __HOOKED_xglAttachNestedDescriptors xglAttachNestedDescriptors
+#define __HOOKED_xglClearDescriptorSetSlots xglClearDescriptorSetSlots
+#define __HOOKED_xglCreateViewportState xglCreateViewportState
+#define __HOOKED_xglCreateRasterState xglCreateRasterState
+#define __HOOKED_xglCreateMsaaState xglCreateMsaaState
+#define __HOOKED_xglCreateColorBlendState xglCreateColorBlendState
+#define __HOOKED_xglCreateDepthStencilState xglCreateDepthStencilState
+#define __HOOKED_xglCreateCommandBuffer xglCreateCommandBuffer
+#define __HOOKED_xglBeginCommandBuffer xglBeginCommandBuffer
+#define __HOOKED_xglEndCommandBuffer xglEndCommandBuffer
+#define __HOOKED_xglResetCommandBuffer xglResetCommandBuffer
+#define __HOOKED_xglCmdBindPipeline xglCmdBindPipeline
+#define __HOOKED_xglCmdBindStateObject xglCmdBindStateObject
+#define __HOOKED_xglCmdBindDescriptorSet xglCmdBindDescriptorSet
+#define __HOOKED_xglCmdBindDynamicMemoryView xglCmdBindDynamicMemoryView
+#define __HOOKED_xglCmdBindIndexData xglCmdBindIndexData
+#define __HOOKED_xglCmdBindAttachments xglCmdBindAttachments
+#define __HOOKED_xglCmdPrepareMemoryRegions xglCmdPrepareMemoryRegions
+#define __HOOKED_xglCmdPrepareImages xglCmdPrepareImages
+#define __HOOKED_xglCmdDraw xglCmdDraw
+#define __HOOKED_xglCmdDrawIndexed xglCmdDrawIndexed
+#define __HOOKED_xglCmdDrawIndirect xglCmdDrawIndirect
+#define __HOOKED_xglCmdDrawIndexedIndirect xglCmdDrawIndexedIndirect
+#define __HOOKED_xglCmdDispatch xglCmdDispatch
+#define __HOOKED_xglCmdDispatchIndirect xglCmdDispatchIndirect
+#define __HOOKED_xglCmdCopyMemory xglCmdCopyMemory
+#define __HOOKED_xglCmdCopyImage xglCmdCopyImage
+#define __HOOKED_xglCmdCopyMemoryToImage xglCmdCopyMemoryToImage
+#define __HOOKED_xglCmdCopyImageToMemory xglCmdCopyImageToMemory
+#define __HOOKED_xglCmdCloneImageData xglCmdCloneImageData
+#define __HOOKED_xglCmdUpdateMemory xglCmdUpdateMemory
+#define __HOOKED_xglCmdFillMemory xglCmdFillMemory
+#define __HOOKED_xglCmdClearColorImage xglCmdClearColorImage
+#define __HOOKED_xglCmdClearColorImageRaw xglCmdClearColorImageRaw
+#define __HOOKED_xglCmdClearDepthStencil xglCmdClearDepthStencil
+#define __HOOKED_xglCmdResolveImage xglCmdResolveImage
+#define __HOOKED_xglCmdSetEvent xglCmdSetEvent
+#define __HOOKED_xglCmdResetEvent xglCmdResetEvent
+#define __HOOKED_xglCmdMemoryAtomic xglCmdMemoryAtomic
+#define __HOOKED_xglCmdBeginQuery xglCmdBeginQuery
+#define __HOOKED_xglCmdEndQuery xglCmdEndQuery
+#define __HOOKED_xglCmdResetQueryPool xglCmdResetQueryPool
+#define __HOOKED_xglCmdWriteTimestamp xglCmdWriteTimestamp
+#define __HOOKED_xglCmdInitAtomicCounters xglCmdInitAtomicCounters
+#define __HOOKED_xglCmdLoadAtomicCounters xglCmdLoadAtomicCounters
+#define __HOOKED_xglCmdSaveAtomicCounters xglCmdSaveAtomicCounters
+#endif
+
+// GPU initialization
+
+XGL_RESULT XGLAPI __HOOKED_xglInitAndEnumerateGpus(
+    const XGL_APPLICATION_INFO* pAppInfo,
+    const XGL_ALLOC_CALLBACKS*  pAllocCb,
+    XGL_UINT                    maxGpus,
+    XGL_UINT*                   pGpuCount,
+    XGL_PHYSICAL_GPU*           pGpus);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetGpuInfo(
+    XGL_PHYSICAL_GPU            gpu,
+    XGL_PHYSICAL_GPU_INFO_TYPE  infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData);
+
+// Device functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateDevice(
+    XGL_PHYSICAL_GPU              gpu,
+    const XGL_DEVICE_CREATE_INFO* pCreateInfo,
+    XGL_DEVICE*                   pDevice);
+
+XGL_RESULT XGLAPI __HOOKED_xglDestroyDevice(
+    XGL_DEVICE device);
+
+// Extension discovery functions
+XGL_RESULT XGLAPI __HOOKED_xglGetExtensionSupport(
+    XGL_PHYSICAL_GPU gpu,
+    const XGL_CHAR*  pExtName);
+
+// Queue functions
+
+XGL_RESULT XGLAPI __HOOKED_xglGetDeviceQueue(
+    XGL_DEVICE       device,
+    XGL_QUEUE_TYPE   queueType,
+    XGL_UINT         queueIndex,
+    XGL_QUEUE*       pQueue);
+
+XGL_RESULT XGLAPI __HOOKED_xglQueueSubmit(
+    XGL_QUEUE             queue,
+    XGL_UINT              cmdBufferCount,
+    const XGL_CMD_BUFFER* pCmdBuffers,
+    XGL_UINT              memRefCount,
+    const XGL_MEMORY_REF* pMemRefs,
+    XGL_FENCE             fence);
+
+XGL_RESULT XGLAPI __HOOKED_xglQueueSetGlobalMemReferences(
+    XGL_QUEUE             queue,
+    XGL_UINT              memRefCount,
+    const XGL_MEMORY_REF* pMemRefs);
+
+XGL_RESULT XGLAPI __HOOKED_xglQueueWaitIdle(
+    XGL_QUEUE queue);
+
+XGL_RESULT XGLAPI __HOOKED_xglDeviceWaitIdle(
+    XGL_DEVICE device);
+
+// Memory functions
+XGL_RESULT XGLAPI __HOOKED_xglGetMemoryHeapCount(
+    XGL_DEVICE  device,
+    XGL_UINT*   pCount);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetMemoryHeapInfo(
+    XGL_DEVICE                  device,
+    XGL_UINT                    heapId,
+    XGL_MEMORY_HEAP_INFO_TYPE   infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData);
+
+XGL_RESULT XGLAPI __HOOKED_xglAllocMemory(
+    XGL_DEVICE                   device,
+    const XGL_MEMORY_ALLOC_INFO* pAllocInfo,
+    XGL_GPU_MEMORY*              pMem);
+
+XGL_RESULT XGLAPI __HOOKED_xglFreeMemory(
+    XGL_GPU_MEMORY mem);
+
+XGL_RESULT XGLAPI __HOOKED_xglSetMemoryPriority(
+    XGL_GPU_MEMORY            mem,
+    XGL_MEMORY_PRIORITY       priority);
+
+XGL_RESULT XGLAPI __HOOKED_xglMapMemory(
+    XGL_GPU_MEMORY mem,
+    XGL_FLAGS      flags,                // Reserved
+    XGL_VOID**     ppData);
+
+XGL_RESULT XGLAPI __HOOKED_xglUnmapMemory(
+    XGL_GPU_MEMORY mem);
+
+XGL_RESULT XGLAPI __HOOKED_xglPinSystemMemory(
+    XGL_DEVICE      device,
+    const XGL_VOID* pSysMem,
+    XGL_SIZE        memSize,
+    XGL_GPU_MEMORY* pMem);
+
+XGL_RESULT XGLAPI __HOOKED_xglRemapVirtualMemoryPages(
+    XGL_DEVICE                            device,
+    XGL_UINT                              rangeCount,
+    const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pRanges,
+    XGL_UINT                              preWaitSemaphoreCount,
+    const XGL_QUEUE_SEMAPHORE*            pPreWaitSemaphores,
+    XGL_UINT                              postSignalSemaphoreCount,
+    const XGL_QUEUE_SEMAPHORE*            pPostSignalSemaphores);
+
+// Multi-device functions
+XGL_RESULT XGLAPI __HOOKED_xglGetMultiGpuCompatibility(
+    XGL_PHYSICAL_GPU            gpu0,
+    XGL_PHYSICAL_GPU            gpu1,
+    XGL_GPU_COMPATIBILITY_INFO* pInfo);
+
+XGL_RESULT XGLAPI __HOOKED_xglOpenSharedMemory(
+    XGL_DEVICE                  device,
+    const XGL_MEMORY_OPEN_INFO* pOpenInfo,
+    XGL_GPU_MEMORY*             pMem);
+
+XGL_RESULT XGLAPI __HOOKED_xglOpenSharedQueueSemaphore(
+    XGL_DEVICE                           device,
+    const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pOpenInfo,
+    XGL_QUEUE_SEMAPHORE*                 pSemaphore);
+
+XGL_RESULT XGLAPI __HOOKED_xglOpenPeerMemory(
+    XGL_DEVICE                       device,
+    const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo,
+    XGL_GPU_MEMORY*                  pMem);
+
+XGL_RESULT XGLAPI __HOOKED_xglOpenPeerImage(
+    XGL_DEVICE                      device,
+    const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo,
+    XGL_IMAGE*                      pImage,
+    XGL_GPU_MEMORY*                 pMem);
+
+// Generic API object functions
+
+XGL_RESULT XGLAPI __HOOKED_xglDestroyObject(
+    XGL_OBJECT object);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetObjectInfo(
+    XGL_BASE_OBJECT             object,
+    XGL_OBJECT_INFO_TYPE        infoType,
+    XGL_SIZE*                   pDataSize,
+    XGL_VOID*                   pData);
+
+XGL_RESULT XGLAPI __HOOKED_xglBindObjectMemory(
+    XGL_OBJECT     object,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset);
+
+// Fence functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateFence(
+    XGL_DEVICE                   device,
+    const XGL_FENCE_CREATE_INFO* pCreateInfo,
+    XGL_FENCE*                   pFence);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetFenceStatus(
+    XGL_FENCE fence);
+
+XGL_RESULT XGLAPI __HOOKED_xglWaitForFences(
+    XGL_DEVICE       device,
+    XGL_UINT         fenceCount,
+    const XGL_FENCE* pFences,
+    XGL_BOOL         waitAll,
+    XGL_UINT64       timeout);
+
+// Queue semaphore functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateQueueSemaphore(
+    XGL_DEVICE                             device,
+    const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pCreateInfo,
+    XGL_QUEUE_SEMAPHORE*                   pSemaphore);
+
+XGL_RESULT XGLAPI __HOOKED_xglSignalQueueSemaphore(
+    XGL_QUEUE           queue,
+    XGL_QUEUE_SEMAPHORE semaphore);
+
+XGL_RESULT XGLAPI __HOOKED_xglWaitQueueSemaphore(
+    XGL_QUEUE           queue,
+    XGL_QUEUE_SEMAPHORE semaphore);
+
+// Event functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateEvent(
+    XGL_DEVICE                   device,
+    const XGL_EVENT_CREATE_INFO* pCreateInfo,
+    XGL_EVENT*                   pEvent);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetEventStatus(
+    XGL_EVENT event);
+
+XGL_RESULT XGLAPI __HOOKED_xglSetEvent(
+    XGL_EVENT event);
+
+XGL_RESULT XGLAPI __HOOKED_xglResetEvent(
+    XGL_EVENT event);
+
+// Query functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateQueryPool(
+    XGL_DEVICE                        device,
+    const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo,
+    XGL_QUERY_POOL*                   pQueryPool);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetQueryPoolResults(
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       startQuery,
+    XGL_UINT       queryCount,
+    XGL_SIZE*      pDataSize,
+    XGL_VOID*      pData);
+
+// Format capabilities
+
+XGL_RESULT XGLAPI __HOOKED_xglGetFormatInfo(
+    XGL_DEVICE             device,
+    XGL_FORMAT             format,
+    XGL_FORMAT_INFO_TYPE   infoType,
+    XGL_SIZE*              pDataSize,
+    XGL_VOID*              pData);
+
+// Image functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateImage(
+    XGL_DEVICE                   device,
+    const XGL_IMAGE_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE*                   pImage);
+
+XGL_RESULT XGLAPI __HOOKED_xglGetImageSubresourceInfo(
+    XGL_IMAGE                    image,
+    const XGL_IMAGE_SUBRESOURCE* pSubresource,
+    XGL_SUBRESOURCE_INFO_TYPE    infoType,
+    XGL_SIZE*                    pDataSize,
+    XGL_VOID*                    pData);
+
+// Image view functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateImageView(
+    XGL_DEVICE                        device,
+    const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE_VIEW*                   pView);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateColorAttachmentView(
+    XGL_DEVICE                                   device,
+    const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_COLOR_ATTACHMENT_VIEW*                   pView);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateDepthStencilView(
+    XGL_DEVICE                                device,
+    const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo,
+    XGL_DEPTH_STENCIL_VIEW*                   pView);
+
+// Shader functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateShader(
+    XGL_DEVICE                    device,
+    const XGL_SHADER_CREATE_INFO* pCreateInfo,
+    XGL_SHADER*                   pShader);
+
+// Pipeline functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateGraphicsPipeline(
+    XGL_DEVICE                               device,
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo,
+    XGL_PIPELINE*                            pPipeline);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateComputePipeline(
+    XGL_DEVICE                              device,
+    const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo,
+    XGL_PIPELINE*                           pPipeline);
+
+XGL_RESULT XGLAPI __HOOKED_xglStorePipeline(
+    XGL_PIPELINE pipeline,
+    XGL_SIZE*    pDataSize,
+    XGL_VOID*    pData);
+
+XGL_RESULT XGLAPI __HOOKED_xglLoadPipeline(
+    XGL_DEVICE      device,
+    XGL_SIZE        dataSize,
+    const XGL_VOID* pData,
+    XGL_PIPELINE*   pPipeline);
+
+// Sampler functions
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateSampler(
+    XGL_DEVICE                     device,
+    const XGL_SAMPLER_CREATE_INFO* pCreateInfo,
+    XGL_SAMPLER*                   pSampler);
+
+// Descriptor set functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateDescriptorSet(
+    XGL_DEVICE                            device,
+    const XGL_DESCRIPTOR_SET_CREATE_INFO* pCreateInfo,
+    XGL_DESCRIPTOR_SET*                   pDescriptorSet);
+
+XGL_VOID XGLAPI __HOOKED_xglBeginDescriptorSetUpdate(
+    XGL_DESCRIPTOR_SET descriptorSet);
+
+XGL_VOID XGLAPI __HOOKED_xglEndDescriptorSetUpdate(
+    XGL_DESCRIPTOR_SET descriptorSet);
+
+XGL_VOID XGLAPI __HOOKED_xglAttachSamplerDescriptors(
+    XGL_DESCRIPTOR_SET descriptorSet,
+    XGL_UINT           startSlot,
+    XGL_UINT           slotCount,
+    const XGL_SAMPLER* pSamplers);
+
+XGL_VOID XGLAPI __HOOKED_xglAttachImageViewDescriptors(
+    XGL_DESCRIPTOR_SET                descriptorSet,
+    XGL_UINT                          startSlot,
+    XGL_UINT                          slotCount,
+    const XGL_IMAGE_VIEW_ATTACH_INFO* pImageViews);
+
+XGL_VOID XGLAPI __HOOKED_xglAttachMemoryViewDescriptors(
+    XGL_DESCRIPTOR_SET                 descriptorSet,
+    XGL_UINT                           startSlot,
+    XGL_UINT                           slotCount,
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemViews);
+
+XGL_VOID XGLAPI __HOOKED_xglAttachNestedDescriptors(
+    XGL_DESCRIPTOR_SET                    descriptorSet,
+    XGL_UINT                              startSlot,
+    XGL_UINT                              slotCount,
+    const XGL_DESCRIPTOR_SET_ATTACH_INFO* pNestedDescriptorSets);
+
+XGL_VOID XGLAPI __HOOKED_xglClearDescriptorSetSlots(
+    XGL_DESCRIPTOR_SET descriptorSet,
+    XGL_UINT           startSlot,
+    XGL_UINT           slotCount);
+
+// State object functions
+XGL_RESULT XGLAPI __HOOKED_xglCreateViewportState(
+    XGL_DEVICE                            device,
+    const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo,
+    XGL_VIEWPORT_STATE_OBJECT*            pState);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateRasterState(
+    XGL_DEVICE                          device,
+    const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo,
+    XGL_RASTER_STATE_OBJECT*            pState);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateMsaaState(
+    XGL_DEVICE                        device,
+    const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo,
+    XGL_MSAA_STATE_OBJECT*            pState);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateColorBlendState(
+    XGL_DEVICE                               device,
+    const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo,
+    XGL_COLOR_BLEND_STATE_OBJECT*            pState);
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateDepthStencilState(
+    XGL_DEVICE                                 device,
+    const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo,
+    XGL_DEPTH_STENCIL_STATE_OBJECT*            pState);
+
+// Command buffer functions
+
+XGL_RESULT XGLAPI __HOOKED_xglCreateCommandBuffer(
+    XGL_DEVICE                        device,
+    const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo,
+    XGL_CMD_BUFFER*                   pCmdBuffer);
+
+XGL_RESULT XGLAPI __HOOKED_xglBeginCommandBuffer(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_FLAGS      flags);               // XGL_CMD_BUFFER_BUILD_FLAGS
+
+XGL_RESULT XGLAPI __HOOKED_xglEndCommandBuffer(
+    XGL_CMD_BUFFER cmdBuffer);
+
+XGL_RESULT XGLAPI __HOOKED_xglResetCommandBuffer(
+    XGL_CMD_BUFFER cmdBuffer);
+
+// Command buffer building functions
+XGL_VOID XGLAPI __HOOKED_xglCmdBindPipeline(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_PIPELINE                  pipeline);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdBindStateObject(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_STATE_BIND_POINT         stateBindPoint,
+    XGL_STATE_OBJECT             state);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdBindDescriptorSet(
+    XGL_CMD_BUFFER                    cmdBuffer,
+    XGL_PIPELINE_BIND_POINT           pipelineBindPoint,
+    XGL_UINT                          index,
+    XGL_DESCRIPTOR_SET                descriptorSet,
+    XGL_UINT                          slotOffset);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdBindDynamicMemoryView(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_PIPELINE_BIND_POINT            pipelineBindPoint,
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdBindIndexData(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_INDEX_TYPE indexType);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdBindAttachments(
+    XGL_CMD_BUFFER                         cmdBuffer,
+    XGL_UINT                               colorTargetCount,
+    const XGL_COLOR_ATTACHMENT_BIND_INFO*  pColorTargets,
+    const XGL_DEPTH_STENCIL_BIND_INFO*     pDepthTarget);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdPrepareMemoryRegions(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_UINT                           transitionCount,
+    const XGL_MEMORY_STATE_TRANSITION* pStateTransitions);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdPrepareImages(
+    XGL_CMD_BUFFER                    cmdBuffer,
+    XGL_UINT                          transitionCount,
+    const XGL_IMAGE_STATE_TRANSITION* pStateTransitions);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDraw(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       firstVertex,
+    XGL_UINT       vertexCount,
+    XGL_UINT       firstInstance,
+    XGL_UINT       instanceCount);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDrawIndexed(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       firstIndex,
+    XGL_UINT       indexCount,
+    XGL_INT        vertexOffset,
+    XGL_UINT       firstInstance,
+    XGL_UINT       instanceCount);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDrawIndirect(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_UINT32     count,
+    XGL_UINT32     stride);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDrawIndexedIndirect(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset,
+    XGL_UINT32     count,
+    XGL_UINT32     stride);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDispatch(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_UINT       x,
+    XGL_UINT       y,
+    XGL_UINT       z);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDispatchIndirect(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY mem,
+    XGL_GPU_SIZE   offset);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdCopyMemory(
+    XGL_CMD_BUFFER         cmdBuffer,
+    XGL_GPU_MEMORY         srcMem,
+    XGL_GPU_MEMORY         destMem,
+    XGL_UINT               regionCount,
+    const XGL_MEMORY_COPY* pRegions);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdCopyImage(
+    XGL_CMD_BUFFER        cmdBuffer,
+    XGL_IMAGE             srcImage,
+    XGL_IMAGE             destImage,
+    XGL_UINT              regionCount,
+    const XGL_IMAGE_COPY* pRegions);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdCopyMemoryToImage(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_GPU_MEMORY               srcMem,
+    XGL_IMAGE                    destImage,
+    XGL_UINT                     regionCount,
+    const XGL_MEMORY_IMAGE_COPY* pRegions);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdCopyImageToMemory(
+    XGL_CMD_BUFFER               cmdBuffer,
+    XGL_IMAGE                    srcImage,
+    XGL_GPU_MEMORY               destMem,
+    XGL_UINT                     regionCount,
+    const XGL_MEMORY_IMAGE_COPY* pRegions);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdCloneImageData(
+    XGL_CMD_BUFFER  cmdBuffer,
+    XGL_IMAGE       srcImage,
+    XGL_IMAGE_STATE srcImageState,
+    XGL_IMAGE       destImage,
+    XGL_IMAGE_STATE destImageState);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdUpdateMemory(
+    XGL_CMD_BUFFER    cmdBuffer,
+    XGL_GPU_MEMORY    destMem,
+    XGL_GPU_SIZE      destOffset,
+    XGL_GPU_SIZE      dataSize,
+    const XGL_UINT32* pData);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdFillMemory(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY destMem,
+    XGL_GPU_SIZE   destOffset,
+    XGL_GPU_SIZE   fillSize,
+    XGL_UINT32     data);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdClearColorImage(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    const XGL_FLOAT                    color[4],
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdClearColorImageRaw(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    const XGL_UINT32                   color[4],
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdClearDepthStencil(
+    XGL_CMD_BUFFER                     cmdBuffer,
+    XGL_IMAGE                          image,
+    XGL_FLOAT                          depth,
+    XGL_UINT32                          stencil,
+    XGL_UINT                           rangeCount,
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdResolveImage(
+    XGL_CMD_BUFFER           cmdBuffer,
+    XGL_IMAGE                srcImage,
+    XGL_IMAGE                destImage,
+    XGL_UINT                 rectCount,
+    const XGL_IMAGE_RESOLVE* pRects);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdSetEvent(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_EVENT      event);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdResetEvent(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_EVENT      event);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdMemoryAtomic(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_GPU_MEMORY destMem,
+    XGL_GPU_SIZE   destOffset,
+    XGL_UINT64     srcData,
+    XGL_ATOMIC_OP  atomicOp);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdBeginQuery(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       slot,
+    XGL_FLAGS      flags);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdEndQuery(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       slot);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdResetQueryPool(
+    XGL_CMD_BUFFER cmdBuffer,
+    XGL_QUERY_POOL queryPool,
+    XGL_UINT       startQuery,
+    XGL_UINT       queryCount);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdWriteTimestamp(
+    XGL_CMD_BUFFER           cmdBuffer,
+    XGL_TIMESTAMP_TYPE       timestampType,
+    XGL_GPU_MEMORY           destMem,
+    XGL_GPU_SIZE             destOffset);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdInitAtomicCounters(
+    XGL_CMD_BUFFER                   cmdBuffer,
+    XGL_PIPELINE_BIND_POINT          pipelineBindPoint,
+    XGL_UINT                         startCounter,
+    XGL_UINT                         counterCount,
+    const XGL_UINT32*                pData);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdLoadAtomicCounters(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_UINT                      startCounter,
+    XGL_UINT                      counterCount,
+    XGL_GPU_MEMORY                srcMem,
+    XGL_GPU_SIZE                  srcOffset);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdSaveAtomicCounters(
+    XGL_CMD_BUFFER                cmdBuffer,
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint,
+    XGL_UINT                      startCounter,
+    XGL_UINT                      counterCount,
+    XGL_GPU_MEMORY                destMem,
+    XGL_GPU_SIZE                  destOffset);
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl_structs.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl_structs.h
new file mode 100644
index 0000000..3fba90e
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgl_structs.h
@@ -0,0 +1,2008 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "xgl/inc/xgl.h"
+#include "glv_trace_packet_utils.h"
+
+static const char* string_XGL_RESULT(XGL_RESULT result)
+{
+    switch ((XGL_RESULT)result)
+    {
+    // Return codes for successful operation execution
+    case XGL_SUCCESS:
+        return "XGL_SUCCESS";
+    case XGL_UNSUPPORTED:
+        return "XGL_UNSUPPORTED";
+    case XGL_NOT_READY:
+        return "XGL_NOT_READY";
+    case XGL_TIMEOUT:
+        return "XGL_TIMEOUT";
+    case XGL_EVENT_SET:
+        return "XGL_EVENT_SET";
+    case XGL_EVENT_RESET:
+        return "XGL_EVENT_RESET";
+    // Error codes
+    case XGL_ERROR_UNKNOWN:
+        return "XGL_ERROR_UNKNOWN";
+    case XGL_ERROR_UNAVAILABLE:
+        return "XGL_ERROR_UNAVAILABLE";
+    case XGL_ERROR_INITIALIZATION_FAILED:
+        return "XGL_ERROR_INITIALIZATION_FAILED";
+    case XGL_ERROR_OUT_OF_MEMORY:
+        return "XGL_ERROR_OUT_OF_MEMORY";
+    case XGL_ERROR_OUT_OF_GPU_MEMORY:
+        return "XGL_ERROR_OUT_OF_GPU_MEMORY";
+    case XGL_ERROR_DEVICE_ALREADY_CREATED:
+        return "XGL_ERROR_DEVICE_ALREADY_CREATED";
+    case XGL_ERROR_DEVICE_LOST:
+        return "XGL_ERROR_DEVICE_LOST";
+    case XGL_ERROR_INVALID_POINTER:
+        return "XGL_ERROR_INVALID_POINTER";
+    case XGL_ERROR_INVALID_VALUE:
+        return "XGL_ERROR_INVALID_VALUE";
+    case XGL_ERROR_INVALID_HANDLE:
+        return "XGL_ERROR_INVALID_HANDLE";
+    case XGL_ERROR_INVALID_ORDINAL:
+        return "XGL_ERROR_INVALID_ORDINAL";
+    case XGL_ERROR_INVALID_MEMORY_SIZE:
+        return "XGL_ERROR_INVALID_MEMORY_SIZE";
+    case XGL_ERROR_INVALID_EXTENSION:
+        return "XGL_ERROR_INVALID_EXTENSION";
+    case XGL_ERROR_INVALID_FLAGS:
+        return "XGL_ERROR_INVALID_FLAGS";
+    case XGL_ERROR_INVALID_ALIGNMENT:
+        return "XGL_ERROR_INVALID_ALIGNMENT";
+    case XGL_ERROR_INVALID_FORMAT:
+        return "XGL_ERROR_INVALID_FORMAT";
+    case XGL_ERROR_INVALID_IMAGE:
+        return "XGL_ERROR_INVALID_IMAGE";
+    case XGL_ERROR_INVALID_DESCRIPTOR_SET_DATA:
+        return "XGL_ERROR_INVALID_DESCRIPTOR_SET_DATA";
+    case XGL_ERROR_INVALID_QUEUE_TYPE:
+        return "XGL_ERROR_INVALID_QUEUE_TYPE";
+    case XGL_ERROR_INVALID_OBJECT_TYPE:
+        return "XGL_ERROR_INVALID_OBJECT_TYPE";
+    case XGL_ERROR_UNSUPPORTED_SHADER_IL_VERSION:
+        return "XGL_ERROR_UNSUPPORTED_SHADER_IL_VERSION";
+    case XGL_ERROR_BAD_SHADER_CODE:
+        return "XGL_ERROR_BAD_SHADER_CODE";
+    case XGL_ERROR_BAD_PIPELINE_DATA:
+        return "XGL_ERROR_BAD_PIPELINE_DATA";
+    case XGL_ERROR_TOO_MANY_MEMORY_REFERENCES:
+        return "XGL_ERROR_TOO_MANY_MEMORY_REFERENCES";
+    case XGL_ERROR_NOT_MAPPABLE:
+        return "XGL_ERROR_NOT_MAPPABLE";
+    case XGL_ERROR_MEMORY_MAP_FAILED:
+        return "XGL_ERROR_MEMORY_MAP_FAILED";
+    case XGL_ERROR_MEMORY_UNMAP_FAILED:
+        return "XGL_ERROR_MEMORY_UNMAP_FAILED";
+    case XGL_ERROR_INCOMPATIBLE_DEVICE:
+        return "XGL_ERROR_INCOMPATIBLE_DEVICE";
+    case XGL_ERROR_INCOMPATIBLE_DRIVER:
+        return "XGL_ERROR_INCOMPATIBLE_DRIVER";
+    case XGL_ERROR_INCOMPLETE_COMMAND_BUFFER:
+        return "XGL_ERROR_INCOMPLETE_COMMAND_BUFFER";
+    case XGL_ERROR_BUILDING_COMMAND_BUFFER:
+        return "XGL_ERROR_BUILDING_COMMAND_BUFFER";
+    case XGL_ERROR_MEMORY_NOT_BOUND:
+        return "XGL_ERROR_MEMORY_NOT_BOUND";
+    case XGL_ERROR_INCOMPATIBLE_QUEUE:
+        return "XGL_ERROR_INCOMPATIBLE_QUEUE";
+    case XGL_ERROR_NOT_SHAREABLE:
+        return "XGL_ERROR_NOT_SHAREABLE";
+    }
+    return "Unhandled XGL_RESULT";
+}
+
+//=============================================================================
+static uint64_t calc_size_XGL_APPLICATION_INFO(const XGL_APPLICATION_INFO* pStruct)
+{
+    return ((pStruct == NULL) ? 0 : sizeof(XGL_APPLICATION_INFO)) + strlen((const char *)pStruct->pAppName) + 1 + strlen((const char *)pStruct->pEngineName) + 1;
+}
+
+static void add_XGL_APPLICATION_INFO_to_packet(glv_trace_packet_header*  pHeader, XGL_APPLICATION_INFO** ppStruct, const XGL_APPLICATION_INFO *pInStruct)
+{
+    glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(XGL_APPLICATION_INFO), pInStruct);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pAppName), strlen((const char *)pInStruct->pAppName) + 1, (const char *)pInStruct->pAppName);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&((*ppStruct)->pEngineName), strlen((const char *)pInStruct->pEngineName) + 1, (const char *)pInStruct->pEngineName);
+    glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pAppName));
+    glv_finalize_buffer_address(pHeader, (void**)&((*ppStruct)->pEngineName));
+    glv_finalize_buffer_address(pHeader, (void**)&*ppStruct);
+};
+
+//=============================================================================
+
+static uint64_t calc_size_XGL_DEVICE_CREATE_INFO(const XGL_DEVICE_CREATE_INFO* pStruct)
+{
+    uint64_t total_size_ppEnabledExtensionNames = pStruct->extensionCount * sizeof(XGL_CHAR *);
+    uint32_t i;
+    for (i = 0; i < pStruct->extensionCount; i++)
+    {
+        total_size_ppEnabledExtensionNames += strlen((const char *)pStruct->ppEnabledExtensionNames[i]) + 1;
+    }
+
+    return sizeof(XGL_DEVICE_CREATE_INFO) + (pStruct->queueRecordCount*sizeof(XGL_DEVICE_CREATE_INFO)) + total_size_ppEnabledExtensionNames;
+}
+
+static void add_XGL_DEVICE_CREATE_INFO_to_packet(glv_trace_packet_header*  pHeader, XGL_DEVICE_CREATE_INFO** ppStruct, const XGL_DEVICE_CREATE_INFO *pInStruct)
+{
+    uint32_t i;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)ppStruct, sizeof(XGL_DEVICE_CREATE_INFO), pInStruct);
+
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(*ppStruct)->pRequestedQueues, pInStruct->queueRecordCount*sizeof(XGL_DEVICE_CREATE_INFO), pInStruct->pRequestedQueues);
+    glv_finalize_buffer_address(pHeader, (void**)&(*ppStruct)->pRequestedQueues);
+
+    if (pInStruct->extensionCount > 0) 
+    {
+        glv_add_buffer_to_trace_packet(pHeader, (void**)(&(*ppStruct)->ppEnabledExtensionNames), pInStruct->extensionCount * sizeof(XGL_CHAR *), pInStruct->ppEnabledExtensionNames);
+        for (i = 0; i < pInStruct->extensionCount; i++)
+        {
+
+            glv_add_buffer_to_trace_packet(pHeader, (void**)(&((*ppStruct)->ppEnabledExtensionNames[i])), strlen((const char *)pInStruct->ppEnabledExtensionNames[i]) + 1, (const char *)pInStruct->ppEnabledExtensionNames[i]);
+            glv_finalize_buffer_address(pHeader, (void**)(&((*ppStruct)->ppEnabledExtensionNames[i])));
+        }
+        glv_finalize_buffer_address(pHeader, (void **)&(*ppStruct)->ppEnabledExtensionNames);
+    }
+    glv_finalize_buffer_address(pHeader, (void**)ppStruct);
+}
+
+static XGL_DEVICE_CREATE_INFO* intepret_XGL_DEVICE_CREATE_INFO(glv_trace_packet_header*  pHeader, intptr_t ptr_variable)
+{
+    XGL_DEVICE_CREATE_INFO* pXGL_DEVICE_CREATE_INFO = (XGL_DEVICE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)ptr_variable);
+
+    if (pXGL_DEVICE_CREATE_INFO != NULL)
+    {
+        pXGL_DEVICE_CREATE_INFO->pRequestedQueues = (const XGL_DEVICE_QUEUE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pXGL_DEVICE_CREATE_INFO->pRequestedQueues);
+
+        if (pXGL_DEVICE_CREATE_INFO->extensionCount > 0)
+        {
+            const XGL_CHAR** pNames;
+            uint32_t i;
+            pXGL_DEVICE_CREATE_INFO->ppEnabledExtensionNames = (const XGL_CHAR *const*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pXGL_DEVICE_CREATE_INFO->ppEnabledExtensionNames);
+            pNames = (const XGL_CHAR**)pXGL_DEVICE_CREATE_INFO->ppEnabledExtensionNames;
+            for (i = 0; i < pXGL_DEVICE_CREATE_INFO->extensionCount; i++)
+            {
+                pNames[i] = (const XGL_CHAR*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)(pXGL_DEVICE_CREATE_INFO->ppEnabledExtensionNames[i]));
+            }
+        }
+    }
+
+    return pXGL_DEVICE_CREATE_INFO;
+}
+
+//=============================================================================
+// entrypoints
+
+typedef struct struct_xglInitAndEnumerateGpus {
+    glv_trace_packet_header*    header;
+    const XGL_APPLICATION_INFO* pAppInfo;
+    const XGL_ALLOC_CALLBACKS*  pAllocCb;
+    XGL_UINT                    maxGpus;
+    XGL_UINT*                   pGpuCount;
+    XGL_PHYSICAL_GPU*           pGpus;
+    XGL_RESULT                  result;
+} struct_xglInitAndEnumerateGpus;
+
+static struct_xglInitAndEnumerateGpus* interpret_body_as_xglInitAndEnumerateGpus(glv_trace_packet_header*  pHeader)
+{
+    struct_xglInitAndEnumerateGpus* pPacket = (struct_xglInitAndEnumerateGpus*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pAppInfo = (const XGL_APPLICATION_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAppInfo);
+    if (pPacket->pAppInfo != NULL)
+    {
+        XGL_APPLICATION_INFO* pInfo = (XGL_APPLICATION_INFO*)pPacket->pAppInfo;
+        pInfo->pAppName = (const XGL_CHAR*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAppInfo->pAppName);
+        pInfo->pEngineName = (const XGL_CHAR*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAppInfo->pEngineName);
+    }
+    pPacket->pAllocCb = (const XGL_ALLOC_CALLBACKS*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAllocCb);
+    pPacket->pGpuCount = (XGL_UINT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pGpuCount);
+    pPacket->pGpus = (XGL_PHYSICAL_GPU*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pGpus);
+    return pPacket;
+}
+
+typedef struct struct_xglGetGpuInfo {
+    glv_trace_packet_header*           header;
+    XGL_PHYSICAL_GPU                   gpu;
+    XGL_PHYSICAL_GPU_INFO_TYPE         infoType;
+    XGL_SIZE*                          pDataSize;
+    XGL_VOID*                          pData;
+    XGL_RESULT                         result;
+} struct_xglGetGpuInfo;
+
+static struct_xglGetGpuInfo* interpret_body_as_xglGetGpuInfo(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetGpuInfo* pPacket = (struct_xglGetGpuInfo*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+// Device functions
+
+typedef struct struct_xglCreateDevice {
+    glv_trace_packet_header*      header;
+    XGL_PHYSICAL_GPU              gpu;
+    const XGL_DEVICE_CREATE_INFO* pCreateInfo;
+    XGL_DEVICE*                   pDevice;
+    XGL_RESULT                    result;
+} struct_xglCreateDevice;
+
+static struct_xglCreateDevice* interpret_body_as_xglCreateDevice(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateDevice* pPacket = (struct_xglCreateDevice*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = intepret_XGL_DEVICE_CREATE_INFO(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pDevice = (XGL_DEVICE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDevice);
+    return pPacket;
+}
+
+typedef struct struct_xglDestroyDevice {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                device;
+    XGL_RESULT                result;
+} struct_xglDestroyDevice;
+
+static struct_xglDestroyDevice* interpret_body_as_xglDestroyDevice(glv_trace_packet_header*  pHeader)
+{
+    struct_xglDestroyDevice* pPacket = (struct_xglDestroyDevice*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// Extension discovery functions
+
+typedef struct struct_xglGetExtensionSupport {
+    glv_trace_packet_header*  header;
+    XGL_PHYSICAL_GPU          gpu;
+    const XGL_CHAR*           pExtName;
+    XGL_RESULT                result;
+} struct_xglGetExtensionSupport;
+
+static struct_xglGetExtensionSupport* interpret_body_as_xglGetExtensionSupport(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetExtensionSupport* pPacket = (struct_xglGetExtensionSupport*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pExtName = (const XGL_CHAR*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pExtName);
+    return pPacket;
+}
+
+// Queue functions
+
+typedef struct struct_xglGetDeviceQueue {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                device;
+    XGL_QUEUE_TYPE            queueType;
+    XGL_UINT                  queueIndex;
+    XGL_QUEUE*                pQueue;
+    XGL_RESULT                result;
+} struct_xglGetDeviceQueue;
+
+static struct_xglGetDeviceQueue* interpret_body_as_xglGetDeviceQueue(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetDeviceQueue* pPacket = (struct_xglGetDeviceQueue*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pQueue = (XGL_QUEUE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pQueue);
+    return pPacket;
+}
+
+typedef struct struct_xglQueueSubmit {
+    glv_trace_packet_header* header;
+    XGL_QUEUE                queue;
+    XGL_UINT                 cmdBufferCount;
+    const XGL_CMD_BUFFER*    pCmdBuffers;
+    XGL_UINT                 memRefCount;
+    const XGL_MEMORY_REF*    pMemRefs;
+    XGL_FENCE                fence;
+    XGL_RESULT               result;
+} struct_xglQueueSubmit;
+
+static struct_xglQueueSubmit* interpret_body_as_xglQueueSubmit(glv_trace_packet_header*  pHeader)
+{
+    struct_xglQueueSubmit* pPacket = (struct_xglQueueSubmit*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCmdBuffers = (const XGL_CMD_BUFFER*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCmdBuffers);
+    pPacket->pMemRefs = (const XGL_MEMORY_REF*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMemRefs);
+    return pPacket;
+}
+
+typedef struct struct_xglQueueSetGlobalMemReferences {
+    glv_trace_packet_header*  header;
+    XGL_QUEUE                 queue;
+    XGL_UINT                  memRefCount;
+    const XGL_MEMORY_REF*     pMemRefs;
+    XGL_RESULT                result;
+} struct_xglQueueSetGlobalMemReferences;
+
+static struct_xglQueueSetGlobalMemReferences* interpret_body_as_xglQueueSetGlobalMemReferences(glv_trace_packet_header*  pHeader)
+{
+    struct_xglQueueSetGlobalMemReferences* pPacket = (struct_xglQueueSetGlobalMemReferences*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pMemRefs = (const XGL_MEMORY_REF*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMemRefs);
+    return pPacket;
+}
+
+typedef struct struct_xglQueueWaitIdle {
+    glv_trace_packet_header*  header;
+    XGL_QUEUE queue;
+    XGL_RESULT result;
+} struct_xglQueueWaitIdle;
+
+static struct_xglQueueWaitIdle* interpret_body_as_xglQueueWaitIdle(glv_trace_packet_header*  pHeader)
+{
+    struct_xglQueueWaitIdle* pPacket = (struct_xglQueueWaitIdle*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglDeviceWaitIdle {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE device;
+    XGL_RESULT result;
+} struct_xglDeviceWaitIdle;
+
+static struct_xglDeviceWaitIdle* interpret_body_as_xglDeviceWaitIdle(glv_trace_packet_header*  pHeader)
+{
+    struct_xglDeviceWaitIdle* pPacket = (struct_xglDeviceWaitIdle*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// Memory functions
+
+typedef struct struct_xglGetMemoryHeapCount {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE  device;
+    XGL_UINT*   pCount;
+    XGL_RESULT result;
+} struct_xglGetMemoryHeapCount;
+
+static struct_xglGetMemoryHeapCount* interpret_body_as_xglGetMemoryHeapCount(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetMemoryHeapCount* pPacket = (struct_xglGetMemoryHeapCount*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCount = (XGL_UINT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCount);
+    return pPacket;
+}
+
+typedef struct struct_xglGetMemoryHeapInfo {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE device;
+    XGL_UINT   heapId;
+    XGL_MEMORY_HEAP_INFO_TYPE   infoType;
+    XGL_SIZE*  pDataSize;
+    XGL_VOID*  pData;
+    XGL_RESULT result;
+} struct_xglGetMemoryHeapInfo;
+
+static struct_xglGetMemoryHeapInfo* interpret_body_as_xglGetMemoryHeapInfo(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetMemoryHeapInfo* pPacket = (struct_xglGetMemoryHeapInfo*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglAllocMemory {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                   device;
+    const XGL_MEMORY_ALLOC_INFO* pAllocInfo;
+    XGL_GPU_MEMORY*              pMem;
+    XGL_RESULT result;
+} struct_xglAllocMemory;
+
+static struct_xglAllocMemory* interpret_body_as_xglAllocMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglAllocMemory* pPacket = (struct_xglAllocMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pAllocInfo = (const XGL_MEMORY_ALLOC_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pAllocInfo);
+    pPacket->pMem = (XGL_GPU_MEMORY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMem);
+    return pPacket;
+}
+
+typedef struct struct_xglFreeMemory {
+    glv_trace_packet_header*  header;
+    XGL_GPU_MEMORY mem;
+    XGL_RESULT result;
+} struct_xglFreeMemory;
+
+static struct_xglFreeMemory* interpret_body_as_xglFreeMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglFreeMemory* pPacket = (struct_xglFreeMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglSetMemoryPriority {
+    glv_trace_packet_header*  header;
+    XGL_GPU_MEMORY mem;
+    XGL_MEMORY_PRIORITY       priority;
+    XGL_RESULT result;
+} struct_xglSetMemoryPriority;
+
+static struct_xglSetMemoryPriority* interpret_body_as_xglSetMemoryPriority(glv_trace_packet_header*  pHeader)
+{
+    struct_xglSetMemoryPriority* pPacket = (struct_xglSetMemoryPriority*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglMapMemory {
+    glv_trace_packet_header*  header;
+    XGL_GPU_MEMORY mem;
+    XGL_FLAGS      flags;                // Reserved
+    XGL_VOID**     ppData;
+    XGL_RESULT result;
+} struct_xglMapMemory;
+
+static struct_xglMapMemory* interpret_body_as_xglMapMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglMapMemory* pPacket = (struct_xglMapMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->ppData = (XGL_VOID**)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->ppData);
+    return pPacket;
+}
+
+typedef struct struct_xglUnmapMemory {
+    glv_trace_packet_header*  header;
+    XGL_GPU_MEMORY mem;
+    XGL_VOID *pData;  //Data CPU potentially wrote into
+    XGL_RESULT result;
+} struct_xglUnmapMemory;
+
+static struct_xglUnmapMemory* interpret_body_as_xglUnmapMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglUnmapMemory* pPacket = (struct_xglUnmapMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pData = (XGL_VOID *)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglPinSystemMemory {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE      device;
+    const XGL_VOID* pSysMem;
+    XGL_SIZE        memSize;
+    XGL_GPU_MEMORY* pMem;
+    XGL_RESULT result;
+} struct_xglPinSystemMemory;
+
+static struct_xglPinSystemMemory* interpret_body_as_xglPinSystemMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglPinSystemMemory* pPacket = (struct_xglPinSystemMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pSysMem = (const XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pSysMem);
+    pPacket->pMem = (XGL_GPU_MEMORY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMem);
+    return pPacket;
+}
+
+typedef struct struct_xglRemapVirtualMemoryPages {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                            device;
+    XGL_UINT                              rangeCount;
+    const XGL_VIRTUAL_MEMORY_REMAP_RANGE* pRanges;
+    XGL_UINT                              preWaitSemaphoreCount;
+    const XGL_QUEUE_SEMAPHORE*            pPreWaitSemaphores;
+    XGL_UINT                              postSignalSemaphoreCount;
+    const XGL_QUEUE_SEMAPHORE*            pPostSignalSemaphores;
+    XGL_RESULT result;
+} struct_xglRemapVirtualMemoryPages;
+
+static struct_xglRemapVirtualMemoryPages* interpret_body_as_xglRemapVirtualMemoryPages(glv_trace_packet_header*  pHeader)
+{
+    struct_xglRemapVirtualMemoryPages* pPacket = (struct_xglRemapVirtualMemoryPages*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRanges = (const XGL_VIRTUAL_MEMORY_REMAP_RANGE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRanges);
+    pPacket->pPreWaitSemaphores = (const XGL_QUEUE_SEMAPHORE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pPreWaitSemaphores);
+    pPacket->pPostSignalSemaphores = (const XGL_QUEUE_SEMAPHORE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pPostSignalSemaphores);
+    return pPacket;
+}
+
+// Multi-device functions
+
+typedef struct struct_xglGetMultiGpuCompatibility {
+    glv_trace_packet_header*  header;
+    XGL_PHYSICAL_GPU            gpu0;
+    XGL_PHYSICAL_GPU            gpu1;
+    XGL_GPU_COMPATIBILITY_INFO* pInfo;
+    XGL_RESULT result;
+} struct_xglGetMultiGpuCompatibility;
+
+static struct_xglGetMultiGpuCompatibility* interpret_body_as_xglGetMultiGpuCompatibility(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetMultiGpuCompatibility* pPacket = (struct_xglGetMultiGpuCompatibility*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pInfo = (XGL_GPU_COMPATIBILITY_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pInfo);
+    return pPacket;
+}
+
+typedef struct struct_xglOpenSharedMemory {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                  device;
+    const XGL_MEMORY_OPEN_INFO* pOpenInfo;
+    XGL_GPU_MEMORY*             pMem;
+    XGL_RESULT result;
+} struct_xglOpenSharedMemory;
+
+static struct_xglOpenSharedMemory* interpret_body_as_xglOpenSharedMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglOpenSharedMemory* pPacket = (struct_xglOpenSharedMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pOpenInfo = (const XGL_MEMORY_OPEN_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pOpenInfo);
+    pPacket->pMem = (XGL_GPU_MEMORY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMem);
+    return pPacket;
+}
+
+typedef struct struct_xglOpenSharedQueueSemaphore {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                           device;
+    const XGL_QUEUE_SEMAPHORE_OPEN_INFO* pOpenInfo;
+    XGL_QUEUE_SEMAPHORE*                 pSemaphore;
+    XGL_RESULT result;
+} struct_xglOpenSharedQueueSemaphore;
+
+static struct_xglOpenSharedQueueSemaphore* interpret_body_as_xglOpenSharedQueueSemaphore(glv_trace_packet_header*  pHeader)
+{
+    struct_xglOpenSharedQueueSemaphore* pPacket = (struct_xglOpenSharedQueueSemaphore*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pOpenInfo = (const XGL_QUEUE_SEMAPHORE_OPEN_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pOpenInfo);
+    pPacket->pSemaphore = (XGL_QUEUE_SEMAPHORE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pSemaphore);
+    return pPacket;
+}
+
+typedef struct struct_xglOpenPeerMemory {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                       device;
+    const XGL_PEER_MEMORY_OPEN_INFO* pOpenInfo;
+    XGL_GPU_MEMORY*                  pMem;
+    XGL_RESULT result;
+} struct_xglOpenPeerMemory;
+
+static struct_xglOpenPeerMemory* interpret_body_as_xglOpenPeerMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglOpenPeerMemory* pPacket = (struct_xglOpenPeerMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pOpenInfo = (const XGL_PEER_MEMORY_OPEN_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pOpenInfo);
+    return pPacket;
+}
+
+typedef struct struct_xglOpenPeerImage {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                      device;
+    const XGL_PEER_IMAGE_OPEN_INFO* pOpenInfo;
+    XGL_IMAGE*                      pImage;
+    XGL_GPU_MEMORY*                 pMem;
+    XGL_RESULT result;
+} struct_xglOpenPeerImage;
+
+static struct_xglOpenPeerImage* interpret_body_as_xglOpenPeerImage(glv_trace_packet_header*  pHeader)
+{
+    struct_xglOpenPeerImage* pPacket = (struct_xglOpenPeerImage*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pOpenInfo = (const XGL_PEER_IMAGE_OPEN_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pOpenInfo);
+    return pPacket;
+}
+
+// Generic API object functions
+
+typedef struct struct_xglDestroyObject {
+    glv_trace_packet_header*  header;
+    XGL_OBJECT object;
+    XGL_RESULT result;
+} struct_xglDestroyObject;
+
+static struct_xglDestroyObject* interpret_body_as_xglDestroyObject(glv_trace_packet_header*  pHeader)
+{
+    struct_xglDestroyObject* pPacket = (struct_xglDestroyObject*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglGetObjectInfo {
+    glv_trace_packet_header*  header;
+    XGL_BASE_OBJECT object;
+    XGL_OBJECT_INFO_TYPE        infoType;
+    XGL_SIZE*       pDataSize;
+    XGL_VOID*       pData;
+    XGL_RESULT result;
+} struct_xglGetObjectInfo;
+
+static struct_xglGetObjectInfo* interpret_body_as_xglGetObjectInfo(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetObjectInfo* pPacket = (struct_xglGetObjectInfo*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglBindObjectMemory {
+    glv_trace_packet_header*  header;
+    XGL_OBJECT     object;
+    XGL_GPU_MEMORY mem;
+    XGL_GPU_SIZE   offset;
+    XGL_RESULT result;
+} struct_xglBindObjectMemory;
+
+static struct_xglBindObjectMemory* interpret_body_as_xglBindObjectMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglBindObjectMemory* pPacket = (struct_xglBindObjectMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// Fence functions
+
+typedef struct struct_xglCreateFence {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                   device;
+    const XGL_FENCE_CREATE_INFO* pCreateInfo;
+    XGL_FENCE*                   pFence;
+    XGL_RESULT result;
+} struct_xglCreateFence;
+
+static struct_xglCreateFence* interpret_body_as_xglCreateFence(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateFence* pPacket = (struct_xglCreateFence*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (XGL_FENCE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pFence = (XGL_FENCE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pFence);
+    return pPacket;
+}
+
+typedef struct struct_xglGetFenceStatus {
+    glv_trace_packet_header*  header;
+    XGL_FENCE fence;
+    XGL_RESULT result;
+} struct_xglGetFenceStatus;
+
+static struct_xglGetFenceStatus* interpret_body_as_xglGetFenceStatus(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetFenceStatus* pPacket = (struct_xglGetFenceStatus*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglWaitForFences {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE       device;
+    XGL_UINT         fenceCount;
+    const XGL_FENCE* pFences;
+    XGL_BOOL         waitAll;
+    XGL_UINT64       timeout;
+    XGL_RESULT result;
+} struct_xglWaitForFences;
+
+static struct_xglWaitForFences* interpret_body_as_xglWaitForFences(glv_trace_packet_header*  pHeader)
+{
+    struct_xglWaitForFences* pPacket = (struct_xglWaitForFences*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pFences = (const XGL_FENCE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pFences);
+    return pPacket;
+}
+
+// Queue semaphore functions
+
+typedef struct struct_xglCreateQueueSemaphore {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                             device;
+    const XGL_QUEUE_SEMAPHORE_CREATE_INFO* pCreateInfo;
+    XGL_QUEUE_SEMAPHORE*                   pSemaphore;
+    XGL_RESULT result;
+} struct_xglCreateQueueSemaphore;
+
+static struct_xglCreateQueueSemaphore* interpret_body_as_xglCreateQueueSemaphore(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateQueueSemaphore* pPacket = (struct_xglCreateQueueSemaphore*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_QUEUE_SEMAPHORE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pSemaphore = (XGL_QUEUE_SEMAPHORE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pSemaphore);
+    return pPacket;
+}
+
+typedef struct struct_xglSignalQueueSemaphore {
+    glv_trace_packet_header*  header;
+    XGL_QUEUE queue;
+    XGL_QUEUE_SEMAPHORE semaphore;
+    XGL_RESULT result;
+} struct_xglSignalQueueSemaphore;
+
+static struct_xglSignalQueueSemaphore* interpret_body_as_xglSignalQueueSemaphore(glv_trace_packet_header*  pHeader)
+{
+    struct_xglSignalQueueSemaphore* pPacket = (struct_xglSignalQueueSemaphore*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglWaitQueueSemaphore {
+    glv_trace_packet_header*  header;
+    XGL_QUEUE queue;
+    XGL_QUEUE_SEMAPHORE semaphore;
+    XGL_RESULT result;
+} struct_xglWaitQueueSemaphore;
+
+static struct_xglWaitQueueSemaphore* interpret_body_as_xglWaitQueueSemaphore(glv_trace_packet_header*  pHeader)
+{
+    struct_xglWaitQueueSemaphore* pPacket = (struct_xglWaitQueueSemaphore*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// Event functions
+
+typedef struct struct_xglCreateEvent {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                   device;
+    const XGL_EVENT_CREATE_INFO* pCreateInfo;
+    XGL_EVENT*                   pEvent;
+    XGL_RESULT result;
+} struct_xglCreateEvent;
+
+static struct_xglCreateEvent* interpret_body_as_xglCreateEvent(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateEvent* pPacket = (struct_xglCreateEvent*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_EVENT_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pEvent = (XGL_EVENT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pEvent);
+    return pPacket;
+}
+
+typedef struct struct_xglGetEventStatus {
+    glv_trace_packet_header*  header;
+    XGL_EVENT event;
+    XGL_RESULT result;
+} struct_xglGetEventStatus;
+
+static struct_xglGetEventStatus* interpret_body_as_xglGetEventStatus(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetEventStatus* pPacket = (struct_xglGetEventStatus*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglSetEvent {
+    glv_trace_packet_header*  header;
+    XGL_EVENT event;
+    XGL_RESULT result;
+} struct_xglSetEvent;
+
+static struct_xglSetEvent* interpret_body_as_xglSetEvent(glv_trace_packet_header*  pHeader)
+{
+    struct_xglSetEvent* pPacket = (struct_xglSetEvent*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglResetEvent {
+    glv_trace_packet_header*  header;
+    XGL_EVENT event;
+    XGL_RESULT result;
+} struct_xglResetEvent;
+
+static struct_xglResetEvent* interpret_body_as_xglResetEvent(glv_trace_packet_header*  pHeader)
+{
+    struct_xglResetEvent* pPacket = (struct_xglResetEvent*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// Query functions
+
+typedef struct struct_xglCreateQueryPool {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                        device;
+    const XGL_QUERY_POOL_CREATE_INFO* pCreateInfo;
+    XGL_QUERY_POOL*                   pQueryPool;
+    XGL_RESULT result;
+} struct_xglCreateQueryPool;
+
+static struct_xglCreateQueryPool* interpret_body_as_xglCreateQueryPool(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateQueryPool* pPacket = (struct_xglCreateQueryPool*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_QUERY_POOL_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pQueryPool = (XGL_QUERY_POOL*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pQueryPool);
+    return pPacket;
+}
+
+typedef struct struct_xglGetQueryPoolResults {
+    glv_trace_packet_header*  header;
+    XGL_QUERY_POOL queryPool;
+    XGL_UINT       startQuery;
+    XGL_UINT       queryCount;
+    XGL_SIZE*      pDataSize;
+    XGL_VOID*      pData;
+    XGL_RESULT result;
+} struct_xglGetQueryPoolResults;
+
+static struct_xglGetQueryPoolResults* interpret_body_as_xglGetQueryPoolResults(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetQueryPoolResults* pPacket = (struct_xglGetQueryPoolResults*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+// Format capabilities
+
+typedef struct struct_xglGetFormatInfo {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE device;
+    XGL_FORMAT format;
+    XGL_FORMAT_INFO_TYPE   infoType;
+    XGL_SIZE*  pDataSize;
+    XGL_VOID*  pData;
+    XGL_RESULT result;
+} struct_xglGetFormatInfo;
+
+static struct_xglGetFormatInfo* interpret_body_as_xglGetFormatInfo(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetFormatInfo* pPacket = (struct_xglGetFormatInfo*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+// Image functions
+
+typedef struct struct_xglCreateImage {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                   device;
+    const XGL_IMAGE_CREATE_INFO* pCreateInfo;
+    XGL_IMAGE*                   pImage;
+    XGL_RESULT result;
+} struct_xglCreateImage;
+
+static struct_xglCreateImage* interpret_body_as_xglCreateImage(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateImage* pPacket = (struct_xglCreateImage*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_IMAGE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pImage = (XGL_IMAGE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pImage);
+    return pPacket;
+}
+
+typedef struct struct_xglGetImageSubresourceInfo {
+    glv_trace_packet_header*  header;
+    XGL_IMAGE                    image;
+    const XGL_IMAGE_SUBRESOURCE* pSubresource;
+    XGL_SUBRESOURCE_INFO_TYPE    infoType;
+    XGL_SIZE*                    pDataSize;
+    XGL_VOID*                    pData;
+    XGL_RESULT result;
+} struct_xglGetImageSubresourceInfo;
+
+static struct_xglGetImageSubresourceInfo* interpret_body_as_xglGetImageSubresourceInfo(glv_trace_packet_header*  pHeader)
+{
+    struct_xglGetImageSubresourceInfo* pPacket = (struct_xglGetImageSubresourceInfo*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pSubresource = (const XGL_IMAGE_SUBRESOURCE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pSubresource);
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+// Image view functions
+
+typedef struct struct_xglCreateImageView {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                        device;
+    const XGL_IMAGE_VIEW_CREATE_INFO* pCreateInfo;
+    XGL_IMAGE_VIEW*                   pView;
+    XGL_RESULT result;
+} struct_xglCreateImageView;
+
+static struct_xglCreateImageView* interpret_body_as_xglCreateImageView(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateImageView* pPacket = (struct_xglCreateImageView*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_IMAGE_VIEW_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pView = (XGL_IMAGE_VIEW*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pView);
+    return pPacket;
+}
+
+typedef struct struct_xglCreateColorAttachmentView {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                               device;
+    const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO* pCreateInfo;
+    XGL_COLOR_ATTACHMENT_VIEW*                   pView;
+    XGL_RESULT result;
+} struct_xglCreateColorAttachmentView;
+
+static struct_xglCreateColorAttachmentView* interpret_body_as_xglCreateColorAttachmentView(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateColorAttachmentView* pPacket = (struct_xglCreateColorAttachmentView*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_COLOR_ATTACHMENT_VIEW_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pView = (XGL_COLOR_ATTACHMENT_VIEW*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pView);
+    return pPacket;
+}
+
+typedef struct struct_xglCreateDepthStencilView {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                                device;
+    const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO* pCreateInfo;
+    XGL_DEPTH_STENCIL_VIEW*                   pView;
+    XGL_RESULT result;
+} struct_xglCreateDepthStencilView;
+
+static struct_xglCreateDepthStencilView* interpret_body_as_xglCreateDepthStencilView(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateDepthStencilView* pPacket = (struct_xglCreateDepthStencilView*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_DEPTH_STENCIL_VIEW_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pView = (XGL_DEPTH_STENCIL_VIEW*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pView);
+    return pPacket;
+}
+
+// Shader functions
+
+typedef struct struct_xglCreateShader {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                    device;
+    const XGL_SHADER_CREATE_INFO* pCreateInfo;
+    XGL_SHADER*                   pShader;
+    XGL_RESULT result;
+} struct_xglCreateShader;
+
+static struct_xglCreateShader* interpret_body_as_xglCreateShader(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateShader* pPacket = (struct_xglCreateShader*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_SHADER_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pShader = (XGL_SHADER*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pShader);
+    if (pPacket->pCreateInfo != NULL)
+    {
+        XGL_SHADER_CREATE_INFO* pInfo = (XGL_SHADER_CREATE_INFO*)pPacket->pCreateInfo;
+        pInfo->pCode = glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pCode);
+    }
+    return pPacket;
+}
+
+// Pipeline functions
+
+typedef struct struct_xglCreateGraphicsPipeline {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                               device;
+    const XGL_GRAPHICS_PIPELINE_CREATE_INFO* pCreateInfo;
+    XGL_PIPELINE*                            pPipeline;
+    XGL_RESULT result;
+} struct_xglCreateGraphicsPipeline;
+
+static void interpret_pipeline_shader(glv_trace_packet_header*  pHeader, XGL_PIPELINE_SHADER* pShader)
+{
+    XGL_UINT i, j;
+    if (pShader != NULL)
+    {
+        // descriptor sets
+        // TODO: need to ensure XGL_MAX_DESCRIPTOR_SETS is equal in replay as it was at trace time - meta data
+        for (i = 0; i < XGL_MAX_DESCRIPTOR_SETS; i++)
+        {
+            pShader->descriptorSetMapping[i].pDescriptorInfo = (const XGL_DESCRIPTOR_SLOT_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->descriptorSetMapping[i].pDescriptorInfo);
+            for (j = 0; j < pShader->descriptorSetMapping[i].descriptorCount; j++)
+            {
+                if (pShader->descriptorSetMapping[i].pDescriptorInfo[j].slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET)
+                {
+                    XGL_DESCRIPTOR_SLOT_INFO* pInfo = (XGL_DESCRIPTOR_SLOT_INFO*)pShader->descriptorSetMapping[i].pDescriptorInfo;
+                    pInfo[j].pNextLevelSet = (const XGL_DESCRIPTOR_SET_MAPPING*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->descriptorSetMapping[i].pDescriptorInfo[j].pNextLevelSet);
+                }
+            }
+        }
+
+        // constant buffers
+        if (pShader->linkConstBufferCount > 0)
+        {
+            XGL_UINT i;
+            pShader->pLinkConstBufferInfo = (const XGL_LINK_CONST_BUFFER*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pLinkConstBufferInfo);
+            for (i = 0; i < pShader->linkConstBufferCount; i++)
+            {
+                XGL_LINK_CONST_BUFFER* pBuffer = (XGL_LINK_CONST_BUFFER*)pShader->pLinkConstBufferInfo;
+                pBuffer[i].pBufferData = (const XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pShader->pLinkConstBufferInfo[i].pBufferData);
+            }
+        }
+    }
+}
+
+static struct_xglCreateGraphicsPipeline* interpret_body_as_xglCreateGraphicsPipeline(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateGraphicsPipeline* pPacket = (struct_xglCreateGraphicsPipeline*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pPipeline = (XGL_PIPELINE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pPipeline);
+    pPacket->pCreateInfo = (const XGL_GRAPHICS_PIPELINE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+
+    if (pPacket->pCreateInfo != NULL)
+    {
+        assert(pPacket->pCreateInfo->sType == XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
+
+        // need to make a non-const pointer to the pointer so that we can properly change the original pointer to the interpretted one
+        XGL_VOID** ppNextVoidPtr = (XGL_VOID**)&pPacket->pCreateInfo->pNext;
+        *ppNextVoidPtr = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo->pNext);
+
+        XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* pNext = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pPacket->pCreateInfo->pNext;
+        while ((NULL != pNext) && (XGL_NULL_HANDLE != pNext))
+        {
+            switch(pNext->sType)
+            {
+                case XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO:
+                case XGL_STRUCTURE_TYPE_PIPELINE_TESS_STATE_CREATE_INFO:
+                case XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO:
+                case XGL_STRUCTURE_TYPE_PIPELINE_DB_STATE_CREATE_INFO:
+                case XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO:
+                {
+                    XGL_VOID** ppNextVoidPtr = (XGL_VOID**)&pNext->pNext;
+                    *ppNextVoidPtr = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pNext);
+                    break;
+                }
+                case XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO:
+                {
+                    XGL_VOID** ppNextVoidPtr = (XGL_VOID**)&pNext->pNext;
+                    *ppNextVoidPtr = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pNext->pNext);
+
+                    interpret_pipeline_shader(pHeader, &pNext->shader);
+
+                    break;
+                }
+                default:
+                    assert(!"Encountered an unexpected type in pipeline state list");
+            }
+
+            pNext = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*)pNext->pNext;
+        }
+    }
+    return pPacket;
+}
+
+typedef struct struct_xglCreateComputePipeline {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                              device;
+    const XGL_COMPUTE_PIPELINE_CREATE_INFO* pCreateInfo;
+    XGL_PIPELINE*                           pPipeline;
+    XGL_RESULT result;
+} struct_xglCreateComputePipeline;
+
+static struct_xglCreateComputePipeline* interpret_body_as_xglCreateComputePipeline(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateComputePipeline* pPacket = (struct_xglCreateComputePipeline*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_COMPUTE_PIPELINE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    if (pPacket->pCreateInfo != NULL)
+    {
+        interpret_pipeline_shader(pHeader, (XGL_PIPELINE_SHADER*)(&pPacket->pCreateInfo->cs));
+    }
+    pPacket->pPipeline = (XGL_PIPELINE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pPipeline);
+    return pPacket;
+}
+
+typedef struct struct_xglStorePipeline {
+    glv_trace_packet_header*  header;
+    XGL_PIPELINE pipeline;
+    XGL_SIZE*    pDataSize;
+    XGL_VOID*    pData;
+    XGL_RESULT result;
+} struct_xglStorePipeline;
+
+static struct_xglStorePipeline* interpret_body_as_xglStorePipeline(glv_trace_packet_header*  pHeader)
+{
+    struct_xglStorePipeline* pPacket = (struct_xglStorePipeline*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pDataSize = (XGL_SIZE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDataSize);
+    pPacket->pData = (XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglLoadPipeline {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE      device;
+    XGL_SIZE        dataSize;
+    const XGL_VOID* pData;
+    XGL_PIPELINE*   pPipeline;
+    XGL_RESULT result;
+} struct_xglLoadPipeline;
+
+static struct_xglLoadPipeline* interpret_body_as_xglLoadPipeline(glv_trace_packet_header*  pHeader)
+{
+    struct_xglLoadPipeline* pPacket = (struct_xglLoadPipeline*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pData = (const XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    pPacket->pPipeline = (XGL_PIPELINE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pPipeline);
+    return pPacket;
+}
+typedef struct struct_xglCreatePipelineDelta {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE   device;
+    XGL_PIPELINE p1;
+    XGL_PIPELINE p2;
+    XGL_PIPELINE_DELTA* delta;
+    XGL_RESULT result;
+} struct_xglCreatePipelineDelta;
+
+static struct_xglCreatePipelineDelta* interpret_body_as_xglCreatePipelineDelta(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreatePipelineDelta* pPacket = (struct_xglCreatePipelineDelta*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->delta = (XGL_PIPELINE_DELTA*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->delta);
+    return pPacket;
+}
+
+// Sampler functions
+
+typedef struct struct_xglCreateSampler {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                     device;
+    const XGL_SAMPLER_CREATE_INFO* pCreateInfo;
+    XGL_SAMPLER*                   pSampler;
+    XGL_RESULT result;
+} struct_xglCreateSampler;
+
+static struct_xglCreateSampler* interpret_body_as_xglCreateSampler(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateSampler* pPacket = (struct_xglCreateSampler*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_SAMPLER_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pSampler = (XGL_SAMPLER*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pSampler);
+    return pPacket;
+}
+
+// Descriptor set functions
+
+typedef struct struct_xglCreateDescriptorSet {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                            device;
+    const XGL_DESCRIPTOR_SET_CREATE_INFO* pCreateInfo;
+    XGL_DESCRIPTOR_SET*                   pDescriptorSet;
+    XGL_RESULT result;
+} struct_xglCreateDescriptorSet;
+
+static struct_xglCreateDescriptorSet* interpret_body_as_xglCreateDescriptorSet(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateDescriptorSet* pPacket = (struct_xglCreateDescriptorSet*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_DESCRIPTOR_SET_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pDescriptorSet = (XGL_DESCRIPTOR_SET*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDescriptorSet);
+    return pPacket;
+}
+
+typedef struct struct_xglBeginDescriptorSetUpdate {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET descriptorSet;
+} struct_xglBeginDescriptorSetUpdate;
+
+static struct_xglBeginDescriptorSetUpdate* interpret_body_as_xglBeginDescriptorSetUpdate(glv_trace_packet_header*  pHeader)
+{
+    struct_xglBeginDescriptorSetUpdate* pPacket = (struct_xglBeginDescriptorSetUpdate*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglEndDescriptorSetUpdate {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET descriptorSet;
+} struct_xglEndDescriptorSetUpdate;
+
+static struct_xglEndDescriptorSetUpdate* interpret_body_as_xglEndDescriptorSetUpdate(glv_trace_packet_header*  pHeader)
+{
+    struct_xglEndDescriptorSetUpdate* pPacket = (struct_xglEndDescriptorSetUpdate*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglAttachSamplerDescriptors {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET descriptorSet;
+    XGL_UINT           startSlot;
+    XGL_UINT           slotCount;
+    const XGL_SAMPLER* pSamplers;
+} struct_xglAttachSamplerDescriptors;
+
+static struct_xglAttachSamplerDescriptors* interpret_body_as_xglAttachSamplerDescriptors(glv_trace_packet_header*  pHeader)
+{
+    struct_xglAttachSamplerDescriptors* pPacket = (struct_xglAttachSamplerDescriptors*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pSamplers = (const XGL_SAMPLER*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pSamplers);
+    return pPacket;
+}
+
+typedef struct struct_xglAttachImageViewDescriptors {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET                descriptorSet;
+    XGL_UINT                          startSlot;
+    XGL_UINT                          slotCount;
+    const XGL_IMAGE_VIEW_ATTACH_INFO* pImageViews;
+} struct_xglAttachImageViewDescriptors;
+
+static struct_xglAttachImageViewDescriptors* interpret_body_as_xglAttachImageViewDescriptors(glv_trace_packet_header*  pHeader)
+{
+    struct_xglAttachImageViewDescriptors* pPacket = (struct_xglAttachImageViewDescriptors*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pImageViews = (const XGL_IMAGE_VIEW_ATTACH_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pImageViews);
+    return pPacket;
+}
+
+typedef struct struct_xglAttachMemoryViewDescriptors {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET                 descriptorSet;
+    XGL_UINT                           startSlot;
+    XGL_UINT                           slotCount;
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemViews;
+} struct_xglAttachMemoryViewDescriptors;
+
+static struct_xglAttachMemoryViewDescriptors* interpret_body_as_xglAttachMemoryViewDescriptors(glv_trace_packet_header*  pHeader)
+{
+    struct_xglAttachMemoryViewDescriptors* pPacket = (struct_xglAttachMemoryViewDescriptors*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pMemViews = (const XGL_MEMORY_VIEW_ATTACH_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMemViews);
+    return pPacket;
+}
+
+typedef struct struct_xglAttachNestedDescriptors {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET                    descriptorSet;
+    XGL_UINT                              startSlot;
+    XGL_UINT                              slotCount;
+    const XGL_DESCRIPTOR_SET_ATTACH_INFO* pNestedDescriptorSets;
+} struct_xglAttachNestedDescriptors;
+
+static struct_xglAttachNestedDescriptors* interpret_body_as_xglAttachNestedDescriptors(glv_trace_packet_header*  pHeader)
+{
+    struct_xglAttachNestedDescriptors* pPacket = (struct_xglAttachNestedDescriptors*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pNestedDescriptorSets = (const XGL_DESCRIPTOR_SET_ATTACH_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pNestedDescriptorSets);
+    return pPacket;
+}
+
+typedef struct struct_xglClearDescriptorSetSlots {
+    glv_trace_packet_header*  header;
+    XGL_DESCRIPTOR_SET descriptorSet;
+    XGL_UINT           startSlot;
+    XGL_UINT           slotCount;
+} struct_xglClearDescriptorSetSlots;
+
+static struct_xglClearDescriptorSetSlots* interpret_body_as_xglClearDescriptorSetSlots(glv_trace_packet_header*  pHeader)
+{
+    struct_xglClearDescriptorSetSlots* pPacket = (struct_xglClearDescriptorSetSlots*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// State object functions
+
+typedef struct struct_xglCreateViewportState {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                            device;
+    const XGL_VIEWPORT_STATE_CREATE_INFO* pCreateInfo;
+    XGL_VIEWPORT_STATE_OBJECT*            pState;
+    XGL_RESULT result;
+} struct_xglCreateViewportState;
+
+static struct_xglCreateViewportState* interpret_body_as_xglCreateViewportState(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateViewportState* pPacket = (struct_xglCreateViewportState*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_VIEWPORT_STATE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pState = (XGL_VIEWPORT_STATE_OBJECT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pState);
+    return pPacket;
+}
+
+typedef struct struct_xglCreateRasterState {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                          device;
+    const XGL_RASTER_STATE_CREATE_INFO* pCreateInfo;
+    XGL_RASTER_STATE_OBJECT*            pState;
+    XGL_RESULT result;
+} struct_xglCreateRasterState;
+
+static struct_xglCreateRasterState* interpret_body_as_xglCreateRasterState(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateRasterState* pPacket = (struct_xglCreateRasterState*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_RASTER_STATE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pState = (XGL_RASTER_STATE_OBJECT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pState);
+    return pPacket;
+}
+
+typedef struct struct_xglCreateMsaaState {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                        device;
+    const XGL_MSAA_STATE_CREATE_INFO* pCreateInfo;
+    XGL_MSAA_STATE_OBJECT*            pState;
+    XGL_RESULT result;
+} struct_xglCreateMsaaState;
+
+static struct_xglCreateMsaaState* interpret_body_as_xglCreateMsaaState(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateMsaaState* pPacket = (struct_xglCreateMsaaState*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_MSAA_STATE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pState = (XGL_MSAA_STATE_OBJECT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pState);
+    return pPacket;
+}
+
+typedef struct struct_xglCreateColorBlendState {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                               device;
+    const XGL_COLOR_BLEND_STATE_CREATE_INFO* pCreateInfo;
+    XGL_COLOR_BLEND_STATE_OBJECT*            pState;
+    XGL_RESULT result;
+} struct_xglCreateColorBlendState;
+
+static struct_xglCreateColorBlendState* interpret_body_as_xglCreateColorBlendState(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateColorBlendState* pPacket = (struct_xglCreateColorBlendState*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_COLOR_BLEND_STATE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pState = (XGL_COLOR_BLEND_STATE_OBJECT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pState);
+    return pPacket;
+}
+
+typedef struct struct_xglCreateDepthStencilState {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                                 device;
+    const XGL_DEPTH_STENCIL_STATE_CREATE_INFO* pCreateInfo;
+    XGL_DEPTH_STENCIL_STATE_OBJECT*            pState;
+    XGL_RESULT result;
+} struct_xglCreateDepthStencilState;
+
+static struct_xglCreateDepthStencilState* interpret_body_as_xglCreateDepthStencilState(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateDepthStencilState* pPacket = (struct_xglCreateDepthStencilState*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_DEPTH_STENCIL_STATE_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pState = (XGL_DEPTH_STENCIL_STATE_OBJECT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pState);
+    return pPacket;
+}
+
+// Command buffer functions
+
+typedef struct struct_xglCreateCommandBuffer {
+    glv_trace_packet_header*  header;
+    XGL_DEVICE                        device;
+    const XGL_CMD_BUFFER_CREATE_INFO* pCreateInfo;
+    XGL_CMD_BUFFER*                   pCmdBuffer;
+    XGL_RESULT result;
+} struct_xglCreateCommandBuffer;
+
+static struct_xglCreateCommandBuffer* interpret_body_as_xglCreateCommandBuffer(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCreateCommandBuffer* pPacket = (struct_xglCreateCommandBuffer*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pCreateInfo = (const XGL_CMD_BUFFER_CREATE_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pCmdBuffer = (XGL_CMD_BUFFER*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCmdBuffer);
+    return pPacket;
+}
+
+typedef struct struct_xglBeginCommandBuffer {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_FLAGS      flags;               // XGL_CMD_BUFFER_BUILD_FLAG
+    XGL_RESULT result;
+} struct_xglBeginCommandBuffer;
+
+static struct_xglBeginCommandBuffer* interpret_body_as_xglBeginCommandBuffer(glv_trace_packet_header*  pHeader)
+{
+    struct_xglBeginCommandBuffer* pPacket = (struct_xglBeginCommandBuffer*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglEndCommandBuffer {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_RESULT result;
+} struct_xglEndCommandBuffer;
+
+static struct_xglEndCommandBuffer* interpret_body_as_xglEndCommandBuffer(glv_trace_packet_header*  pHeader)
+{
+    struct_xglEndCommandBuffer* pPacket = (struct_xglEndCommandBuffer*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglResetCommandBuffer {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_RESULT result;
+} struct_xglResetCommandBuffer;
+
+static struct_xglResetCommandBuffer* interpret_body_as_xglResetCommandBuffer(glv_trace_packet_header*  pHeader)
+{
+    struct_xglResetCommandBuffer* pPacket = (struct_xglResetCommandBuffer*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+// Command buffer building functions
+
+typedef struct struct_xglCmdBindPipeline {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint;
+    XGL_PIPELINE   pipeline;
+} struct_xglCmdBindPipeline;
+
+static struct_xglCmdBindPipeline* interpret_body_as_xglCmdBindPipeline(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindPipeline* pPacket = (struct_xglCmdBindPipeline*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBindPipelineDelta {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint;
+    XGL_PIPELINE_DELTA   delta;
+} struct_xglCmdBindPipelineDelta;
+
+static struct_xglCmdBindPipelineDelta* interpret_body_as_xglCmdBindPipelineDelta(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindPipelineDelta* pPacket = (struct_xglCmdBindPipelineDelta*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBindStateObject {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER   cmdBuffer;
+    XGL_STATE_BIND_POINT         stateBindPoint;
+    XGL_STATE_OBJECT state;
+} struct_xglCmdBindStateObject;
+
+static struct_xglCmdBindStateObject* interpret_body_as_xglCmdBindStateObject(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindStateObject* pPacket = (struct_xglCmdBindStateObject*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBindDescriptorSet {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER     cmdBuffer;
+    XGL_PIPELINE_BIND_POINT           pipelineBindPoint;
+    XGL_UINT           index;
+    XGL_DESCRIPTOR_SET descriptorSet;
+    XGL_UINT           slotOffset;
+} struct_xglCmdBindDescriptorSet;
+
+static struct_xglCmdBindDescriptorSet* interpret_body_as_xglCmdBindDescriptorSet(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindDescriptorSet* pPacket = (struct_xglCmdBindDescriptorSet*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBindDynamicMemoryView {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                     cmdBuffer;
+    XGL_PIPELINE_BIND_POINT                           pipelineBindPoint;
+    const XGL_MEMORY_VIEW_ATTACH_INFO* pMemView;
+} struct_xglCmdBindDynamicMemoryView;
+
+static struct_xglCmdBindDynamicMemoryView* interpret_body_as_xglCmdBindDynamicMemoryView(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindDynamicMemoryView* pPacket = (struct_xglCmdBindDynamicMemoryView*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pMemView = (const XGL_MEMORY_VIEW_ATTACH_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMemView);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBindIndexData {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_GPU_MEMORY mem;
+    XGL_GPU_SIZE   offset;
+    XGL_INDEX_TYPE       indexType;
+} struct_xglCmdBindIndexData;
+
+static struct_xglCmdBindIndexData* interpret_body_as_xglCmdBindIndexData(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindIndexData* pPacket = (struct_xglCmdBindIndexData*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBindAttachments {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                     cmdBuffer;
+    XGL_UINT                           colorAttachmentCount;
+    const XGL_COLOR_ATTACHMENT_BIND_INFO*  pColorAttachments;
+    const XGL_DEPTH_STENCIL_BIND_INFO* pDepthAttachment;
+} struct_xglCmdBindAttachments;
+
+static struct_xglCmdBindAttachments* interpret_body_as_xglCmdBindAttachments(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBindAttachments* pPacket = (struct_xglCmdBindAttachments*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pColorAttachments = (const XGL_COLOR_ATTACHMENT_BIND_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pColorAttachments);
+    pPacket->pDepthAttachment = (const XGL_DEPTH_STENCIL_BIND_INFO*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pDepthAttachment);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdPrepareMemoryRegions {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                     cmdBuffer;
+    XGL_UINT                           transitionCount;
+    const XGL_MEMORY_STATE_TRANSITION* pStateTransitions;
+} struct_xglCmdPrepareMemoryRegions;
+
+static struct_xglCmdPrepareMemoryRegions* interpret_body_as_xglCmdPrepareMemoryRegions(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdPrepareMemoryRegions* pPacket = (struct_xglCmdPrepareMemoryRegions*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pStateTransitions = (const XGL_MEMORY_STATE_TRANSITION*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pStateTransitions);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdPrepareImages {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                    cmdBuffer;
+    XGL_UINT                          transitionCount;
+    const XGL_IMAGE_STATE_TRANSITION* pStateTransitions;
+} struct_xglCmdPrepareImages;
+
+static struct_xglCmdPrepareImages* interpret_body_as_xglCmdPrepareImages(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdPrepareImages* pPacket = (struct_xglCmdPrepareImages*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pStateTransitions = (const XGL_IMAGE_STATE_TRANSITION*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pStateTransitions);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDraw {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_UINT       firstVertex;
+    XGL_UINT       vertexCount;
+    XGL_UINT       firstInstance;
+    XGL_UINT       instanceCount;
+} struct_xglCmdDraw;
+
+static struct_xglCmdDraw* interpret_body_as_xglCmdDraw(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdDraw* pPacket = (struct_xglCmdDraw*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDrawIndexed {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_UINT       firstIndex;
+    XGL_UINT       indexCount;
+    XGL_INT        vertexOffset;
+    XGL_UINT       firstInstance;
+    XGL_UINT       instanceCount;
+} struct_xglCmdDrawIndexed;
+
+static struct_xglCmdDrawIndexed* interpret_body_as_xglCmdDrawIndexed(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdDrawIndexed* pPacket = (struct_xglCmdDrawIndexed*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDrawIndirect {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_GPU_MEMORY mem;
+    XGL_GPU_SIZE   offset;
+    XGL_UINT32     count;
+    XGL_UINT32     stride;
+} struct_xglCmdDrawIndirect;
+
+static struct_xglCmdDrawIndirect* interpret_body_as_xglCmdDrawIndirect(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdDrawIndirect* pPacket = (struct_xglCmdDrawIndirect*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDrawIndexedIndirect {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_GPU_MEMORY mem;
+    XGL_GPU_SIZE   offset;
+    XGL_UINT32     count;
+    XGL_UINT32     stride;
+} struct_xglCmdDrawIndexedIndirect;
+
+static struct_xglCmdDrawIndexedIndirect* interpret_body_as_xglCmdDrawIndexedIndirect(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdDrawIndexedIndirect* pPacket = (struct_xglCmdDrawIndexedIndirect*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDispatch {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_UINT       x;
+    XGL_UINT       y;
+    XGL_UINT       z;
+} struct_xglCmdDispatch;
+
+static struct_xglCmdDispatch* interpret_body_as_xglCmdDispatch(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdDispatch* pPacket = (struct_xglCmdDispatch*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDispatchIndirect {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_GPU_MEMORY mem;
+    XGL_GPU_SIZE   offset;
+} struct_xglCmdDispatchIndirect;
+
+static struct_xglCmdDispatchIndirect* interpret_body_as_xglCmdDispatchIndirect(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdDispatchIndirect* pPacket = (struct_xglCmdDispatchIndirect*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdCopyMemory {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER         cmdBuffer;
+    XGL_GPU_MEMORY         srcMem;
+    XGL_GPU_MEMORY         destMem;
+    XGL_UINT               regionCount;
+    const XGL_MEMORY_COPY* pRegions;
+} struct_xglCmdCopyMemory;
+
+static struct_xglCmdCopyMemory* interpret_body_as_xglCmdCopyMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdCopyMemory* pPacket = (struct_xglCmdCopyMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRegions = (const XGL_MEMORY_COPY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRegions);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdCopyImage {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER        cmdBuffer;
+    XGL_IMAGE             srcImage;
+    XGL_IMAGE             destImage;
+    XGL_UINT              regionCount;
+    const XGL_IMAGE_COPY* pRegions;
+} struct_xglCmdCopyImage;
+
+static struct_xglCmdCopyImage* interpret_body_as_xglCmdCopyImage(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdCopyImage* pPacket = (struct_xglCmdCopyImage*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRegions = (const XGL_IMAGE_COPY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRegions);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdCopyMemoryToImage {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER               cmdBuffer;
+    XGL_GPU_MEMORY               srcMem;
+    XGL_IMAGE                    destImage;
+    XGL_UINT                     regionCount;
+    const XGL_MEMORY_IMAGE_COPY* pRegions;
+} struct_xglCmdCopyMemoryToImage;
+
+static struct_xglCmdCopyMemoryToImage* interpret_body_as_xglCmdCopyMemoryToImage(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdCopyMemoryToImage* pPacket = (struct_xglCmdCopyMemoryToImage*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRegions = (const XGL_MEMORY_IMAGE_COPY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRegions);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdCopyImageToMemory {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER               cmdBuffer;
+    XGL_IMAGE                    srcImage;
+    XGL_GPU_MEMORY               destMem;
+    XGL_UINT                     regionCount;
+    const XGL_MEMORY_IMAGE_COPY* pRegions;
+} struct_xglCmdCopyImageToMemory;
+
+static struct_xglCmdCopyImageToMemory* interpret_body_as_xglCmdCopyImageToMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdCopyImageToMemory* pPacket = (struct_xglCmdCopyImageToMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRegions = (const XGL_MEMORY_IMAGE_COPY*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRegions);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdCloneImageData {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER  cmdBuffer;
+    XGL_IMAGE       srcImage;
+    XGL_IMAGE_STATE        srcImageState;
+    XGL_IMAGE       destImage;
+    XGL_IMAGE_STATE        destImageState;
+} struct_xglCmdCloneImageData;
+
+static struct_xglCmdCloneImageData* interpret_body_as_xglCmdCloneImageData(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdCloneImageData* pPacket = (struct_xglCmdCloneImageData*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdUpdateMemory {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER    cmdBuffer;
+    XGL_GPU_MEMORY    destMem;
+    XGL_GPU_SIZE      destOffset;
+    XGL_GPU_SIZE      dataSize;
+    const XGL_UINT32* pData;
+} struct_xglCmdUpdateMemory;
+
+static struct_xglCmdUpdateMemory* interpret_body_as_xglCmdUpdateMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdUpdateMemory* pPacket = (struct_xglCmdUpdateMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pData = (const XGL_UINT32*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdFillMemory {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_GPU_MEMORY destMem;
+    XGL_GPU_SIZE   destOffset;
+    XGL_GPU_SIZE   fillSize;
+    XGL_UINT32     data;
+} struct_xglCmdFillMemory;
+
+static struct_xglCmdFillMemory* interpret_body_as_xglCmdFillMemory(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdFillMemory* pPacket = (struct_xglCmdFillMemory*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdClearColorImage {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                     cmdBuffer;
+    XGL_IMAGE                          image;
+    const XGL_FLOAT                    color[4];
+    XGL_UINT                           rangeCount;
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges;
+} struct_xglCmdClearColorImage;
+
+static struct_xglCmdClearColorImage* interpret_body_as_xglCmdClearColorImage(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdClearColorImage* pPacket = (struct_xglCmdClearColorImage*)pHeader->pBody;
+    pPacket->header = pHeader;
+//    pPacket->color = (const XGL_FLOAT*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->color);
+    pPacket->pRanges = (const XGL_IMAGE_SUBRESOURCE_RANGE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRanges);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdClearColorImageRaw {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                     cmdBuffer;
+    XGL_IMAGE                          image;
+    const XGL_UINT32                   color[4];
+    XGL_UINT                           rangeCount;
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges;
+} struct_xglCmdClearColorImageRaw;
+
+static struct_xglCmdClearColorImageRaw* interpret_body_as_xglCmdClearColorImageRaw(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdClearColorImageRaw* pPacket = (struct_xglCmdClearColorImageRaw*)pHeader->pBody;
+    pPacket->header = pHeader;
+//    pPacket->color = (const XGL_UINT32*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->color);
+    pPacket->pRanges = (const XGL_IMAGE_SUBRESOURCE_RANGE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRanges);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdClearDepthStencil {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER                     cmdBuffer;
+    XGL_IMAGE                          image;
+    XGL_FLOAT                          depth;
+    XGL_UINT8                          stencil;
+    XGL_UINT                           rangeCount;
+    const XGL_IMAGE_SUBRESOURCE_RANGE* pRanges;
+} struct_xglCmdClearDepthStencil;
+
+static struct_xglCmdClearDepthStencil* interpret_body_as_xglCmdClearDepthStencil(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdClearDepthStencil* pPacket = (struct_xglCmdClearDepthStencil*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRanges = (const XGL_IMAGE_SUBRESOURCE_RANGE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRanges);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdResolveImage {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER           cmdBuffer;
+    XGL_IMAGE                srcImage;
+    XGL_IMAGE                destImage;
+    XGL_UINT                 rectCount;
+    const XGL_IMAGE_RESOLVE* pRects;
+} struct_xglCmdResolveImage;
+
+static struct_xglCmdResolveImage* interpret_body_as_xglCmdResolveImage(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdResolveImage* pPacket = (struct_xglCmdResolveImage*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pRects = (const XGL_IMAGE_RESOLVE*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pRects);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdSetEvent {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_EVENT      event;
+} struct_xglCmdSetEvent;
+
+static struct_xglCmdSetEvent* interpret_body_as_xglCmdSetEvent(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdSetEvent* pPacket = (struct_xglCmdSetEvent*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdResetEvent {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_EVENT      event;
+} struct_xglCmdResetEvent;
+
+static struct_xglCmdResetEvent* interpret_body_as_xglCmdResetEvent(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdResetEvent* pPacket = (struct_xglCmdResetEvent*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdMemoryAtomic {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_GPU_MEMORY destMem;
+    XGL_GPU_SIZE   destOffset;
+    XGL_UINT64     srcData;
+    XGL_ATOMIC_OP atomicOp;
+} struct_xglCmdMemoryAtomic;
+
+static struct_xglCmdMemoryAtomic* interpret_body_as_xglCmdMemoryAtomic(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdMemoryAtomic* pPacket = (struct_xglCmdMemoryAtomic*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdBeginQuery {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_QUERY_POOL queryPool;
+    XGL_UINT       slot;
+    XGL_FLAGS      flags;
+} struct_xglCmdBeginQuery;
+
+static struct_xglCmdBeginQuery* interpret_body_as_xglCmdBeginQuery(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdBeginQuery* pPacket = (struct_xglCmdBeginQuery*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdEndQuery {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_QUERY_POOL queryPool;
+    XGL_UINT       slot;
+} struct_xglCmdEndQuery;
+
+static struct_xglCmdEndQuery* interpret_body_as_xglCmdEndQuery(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdEndQuery* pPacket = (struct_xglCmdEndQuery*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdResetQueryPool {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_QUERY_POOL queryPool;
+    XGL_UINT       startQuery;
+    XGL_UINT       queryCount;
+} struct_xglCmdResetQueryPool;
+
+static struct_xglCmdResetQueryPool* interpret_body_as_xglCmdResetQueryPool(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdResetQueryPool* pPacket = (struct_xglCmdResetQueryPool*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdWriteTimestamp {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_TIMESTAMP_TYPE       timestampType;
+    XGL_GPU_MEMORY destMem;
+    XGL_GPU_SIZE   destOffset;
+} struct_xglCmdWriteTimestamp;
+
+static struct_xglCmdWriteTimestamp* interpret_body_as_xglCmdWriteTimestamp(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdWriteTimestamp* pPacket = (struct_xglCmdWriteTimestamp*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdInitAtomicCounters {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER    cmdBuffer;
+    XGL_PIPELINE_BIND_POINT          pipelineBindPoint;
+    XGL_UINT          startCounter;
+    XGL_UINT          counterCount;
+    const XGL_UINT32* pData;
+} struct_xglCmdInitAtomicCounters;
+
+static struct_xglCmdInitAtomicCounters* interpret_body_as_xglCmdInitAtomicCounters(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdInitAtomicCounters* pPacket = (struct_xglCmdInitAtomicCounters*)pHeader->pBody;
+    pPacket->header = pHeader;
+    pPacket->pData = (const XGL_UINT32*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdLoadAtomicCounters {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint;
+    XGL_UINT       startCounter;
+    XGL_UINT       counterCount;
+    XGL_GPU_MEMORY srcMem;
+    XGL_GPU_SIZE   srcOffset;
+} struct_xglCmdLoadAtomicCounters;
+
+static struct_xglCmdLoadAtomicCounters* interpret_body_as_xglCmdLoadAtomicCounters(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdLoadAtomicCounters* pPacket = (struct_xglCmdLoadAtomicCounters*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglCmdSaveAtomicCounters {
+    glv_trace_packet_header*  header;
+    XGL_CMD_BUFFER cmdBuffer;
+    XGL_PIPELINE_BIND_POINT       pipelineBindPoint;
+    XGL_UINT       startCounter;
+    XGL_UINT       counterCount;
+    XGL_GPU_MEMORY destMem;
+    XGL_GPU_SIZE   destOffset;
+} struct_xglCmdSaveAtomicCounters;
+
+static struct_xglCmdSaveAtomicCounters* interpret_body_as_xglCmdSaveAtomicCounters(glv_trace_packet_header*  pHeader)
+{
+    struct_xglCmdSaveAtomicCounters* pPacket = (struct_xglCmdSaveAtomicCounters*)pHeader->pBody;
+    pPacket->header = pHeader;
+    return pPacket;
+}
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg.c b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg.c
new file mode 100644
index 0000000..01839b6
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg.c
@@ -0,0 +1,307 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glv_platform.h"
+#include "glvtrace_xgl_xgldbg.h"
+#include "glvtrace_xgl_xgldbg_structs.h"
+#include "glvtrace_xgl_packet_id.h"
+#include "glv_common.h"
+#ifdef WIN32
+#include "mhook/mhook-lib/mhook.h"
+#endif
+
+// ======================== Pointers to real functions ========================
+static XGL_RESULT( XGLAPI * real_xglDbgSetValidationLevel)(
+    XGL_DEVICE             device,
+    XGL_VALIDATION_LEVEL   validationLevel) = xglDbgSetValidationLevel;
+
+static XGL_RESULT( XGLAPI * real_xglDbgRegisterMsgCallback)(
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
+    XGL_VOID*                     pUserData) = xglDbgRegisterMsgCallback;
+
+static XGL_RESULT( XGLAPI * real_xglDbgUnregisterMsgCallback)(
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback) = xglDbgUnregisterMsgCallback;
+
+static XGL_RESULT( XGLAPI * real_xglDbgSetMessageFilter)(
+    XGL_DEVICE           device,
+    XGL_INT              msgCode,
+    XGL_DBG_MSG_FILTER   filter) = xglDbgSetMessageFilter;
+
+static XGL_RESULT( XGLAPI * real_xglDbgSetObjectTag)(
+    XGL_BASE_OBJECT object,
+    XGL_SIZE        tagSize,
+    const XGL_VOID* pTag) = xglDbgSetObjectTag;
+
+static XGL_RESULT( XGLAPI * real_xglDbgSetGlobalOption)(
+    XGL_DBG_GLOBAL_OPTION        dbgOption,
+    XGL_SIZE                     dataSize,
+    const XGL_VOID*              pData) = xglDbgSetGlobalOption;
+
+static XGL_RESULT( XGLAPI * real_xglDbgSetDeviceOption)(
+    XGL_DEVICE                   device,
+    XGL_DBG_DEVICE_OPTION        dbgOption,
+    XGL_SIZE                     dataSize,
+    const XGL_VOID*              pData) = xglDbgSetDeviceOption;
+
+static XGL_VOID( XGLAPI * real_xglCmdDbgMarkerBegin)(
+    XGL_CMD_BUFFER  cmdBuffer,
+    const XGL_CHAR* pMarker) = xglCmdDbgMarkerBegin;
+
+static XGL_VOID( XGLAPI * real_xglCmdDbgMarkerEnd)(
+    XGL_CMD_BUFFER  cmdBuffer) = xglCmdDbgMarkerEnd;
+
+void AttachHooks_xgldbg()
+{
+    BOOL hookSuccess = TRUE;
+#if defined(WIN32)
+    Mhook_BeginMultiOperation(FALSE);
+    if (real_xglDbgSetValidationLevel != NULL)
+    {
+        hookSuccess = Mhook_SetHook((PVOID*)&real_xglDbgSetValidationLevel, hooked_xglDbgSetValidationLevel);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDbgRegisterMsgCallback, hooked_xglDbgRegisterMsgCallback);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDbgUnregisterMsgCallback, hooked_xglDbgUnregisterMsgCallback);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDbgSetMessageFilter, hooked_xglDbgSetMessageFilter);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDbgSetObjectTag, hooked_xglDbgSetObjectTag);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDbgSetGlobalOption, hooked_xglDbgSetGlobalOption);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglDbgSetDeviceOption, hooked_xglDbgSetDeviceOption);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDbgMarkerBegin, hooked_xglCmdDbgMarkerBegin);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglCmdDbgMarkerEnd, hooked_xglCmdDbgMarkerEnd);
+    }
+
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook XGLDbg.");
+    }
+
+    Mhook_EndMultiOperation();
+#elif defined(__linux__)
+    hookSuccess = glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgSetValidationLevel, "xglDbgSetValidationLevel");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgRegisterMsgCallback, "xglDbgRegisterMsgCallback");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgUnregisterMsgCallback, "xglDbgUnregisterMsgCallback");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgSetMessageFilter, "xglDbgSetMessageFilter");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgSetObjectTag, "xglDbgSetObjectTag");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgSetGlobalOption,"xglDbgSetGlobalOption");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglDbgSetDeviceOption, "xglDbgSetDeviceOption");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDbgMarkerBegin, "xglCmdDbgMarkerBegin");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglCmdDbgMarkerEnd, "xglCmdDbgMarkerEnd");
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook XGLDbg.");
+    }
+#endif
+}
+
+void DetachHooks_xgldbg()
+{
+ 
+#ifdef WIN32
+    BOOL unhookSuccess = TRUE;
+
+    if (real_xglDbgSetValidationLevel != NULL)
+    {
+        unhookSuccess = Mhook_Unhook((PVOID*)&real_xglDbgSetValidationLevel);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDbgRegisterMsgCallback);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDbgUnregisterMsgCallback);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDbgSetMessageFilter);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDbgSetObjectTag);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDbgSetGlobalOption);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglDbgSetDeviceOption);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDbgMarkerBegin);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglCmdDbgMarkerEnd);
+    }
+    
+    if (!unhookSuccess)
+    {
+        glv_LogError("Failed to unhook XGLDbg.");
+    }
+#elif defined(__linux__)
+    return;
+#endif
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgSetValidationLevel(
+    XGL_DEVICE             device,
+    XGL_VALIDATION_LEVEL   validationLevel)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgSetValidationLevel* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgSetValidationLevel);
+    CREATE_TRACE_PACKET(xglDbgSetValidationLevel, 0);
+    result = real_xglDbgSetValidationLevel(device, validationLevel);
+    pPacket = interpret_body_as_xglDbgSetValidationLevel(pHeader);
+    pPacket->device = device;
+    pPacket->validationLevel = validationLevel;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgRegisterMsgCallback(
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
+    XGL_VOID*                     pUserData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgRegisterMsgCallback* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgRegisterMsgCallback);
+    CREATE_TRACE_PACKET(xglDbgRegisterMsgCallback, 0);
+    result = real_xglDbgRegisterMsgCallback(pfnMsgCallback, pUserData);
+    pPacket = interpret_body_as_xglDbgRegisterMsgCallback(pHeader);
+    pPacket->pfnMsgCallback = pfnMsgCallback;
+    pPacket->pUserData = pUserData;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgUnregisterMsgCallback(
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgUnregisterMsgCallback* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgUnregisterMsgCallback);
+    CREATE_TRACE_PACKET(xglDbgUnregisterMsgCallback, 0);
+    result = real_xglDbgUnregisterMsgCallback(pfnMsgCallback);
+    pPacket = interpret_body_as_xglDbgUnregisterMsgCallback(pHeader);
+    pPacket->pfnMsgCallback = pfnMsgCallback;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgSetMessageFilter(
+    XGL_DEVICE           device,
+    XGL_INT              msgCode,
+    XGL_DBG_MSG_FILTER   filter)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgSetMessageFilter* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgSetMessageFilter);
+    CREATE_TRACE_PACKET(xglDbgSetMessageFilter, 0);
+    result = real_xglDbgSetMessageFilter(device, msgCode, filter);
+    pPacket = interpret_body_as_xglDbgSetMessageFilter(pHeader);
+    pPacket->device = device;
+    pPacket->msgCode = msgCode;
+    pPacket->filter = filter;
+    pPacket->result = result;
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgSetObjectTag(
+    XGL_BASE_OBJECT object,
+    XGL_SIZE        tagSize,
+    const XGL_VOID* pTag)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgSetObjectTag* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgSetObjectTag);
+    CREATE_TRACE_PACKET(xglDbgSetObjectTag, tagSize);
+    result = real_xglDbgSetObjectTag(object, tagSize, pTag);
+    pPacket = interpret_body_as_xglDbgSetObjectTag(pHeader);
+    pPacket->object = object;
+    pPacket->tagSize = tagSize;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pTag), tagSize, pTag);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pTag));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgSetGlobalOption(
+    XGL_DBG_GLOBAL_OPTION        dbgOption,
+    XGL_SIZE                     dataSize,
+    const XGL_VOID*              pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgSetGlobalOption* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgSetGlobalOption);
+    CREATE_TRACE_PACKET(xglDbgSetGlobalOption, dataSize);
+    result = real_xglDbgSetGlobalOption(dbgOption, dataSize, pData);
+    pPacket = interpret_body_as_xglDbgSetGlobalOption(pHeader);
+    pPacket->dbgOption = dbgOption;
+    pPacket->dataSize = dataSize;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), dataSize, pData);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglDbgSetDeviceOption(
+    XGL_DEVICE                   device,
+    XGL_DBG_DEVICE_OPTION        dbgOption,
+    XGL_SIZE                     dataSize,
+    const XGL_VOID*              pData)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglDbgSetDeviceOption* pPacket;
+    SEND_ENTRYPOINT_ID(xglDbgSetDeviceOption);
+    CREATE_TRACE_PACKET(xglDbgSetDeviceOption, dataSize);
+    result = real_xglDbgSetDeviceOption(device, dbgOption, dataSize, pData);
+    pPacket = interpret_body_as_xglDbgSetDeviceOption(pHeader);
+    pPacket->device = device;
+    pPacket->dbgOption = dbgOption;
+    pPacket->dataSize = dataSize;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pData), dataSize, pData);
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pData));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDbgMarkerBegin(
+    XGL_CMD_BUFFER  cmdBuffer,
+    const XGL_CHAR* pMarker)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDbgMarkerBegin* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDbgMarkerBegin);
+    CREATE_TRACE_PACKET(xglCmdDbgMarkerBegin, strlen((const char *)pMarker) + 1);
+    real_xglCmdDbgMarkerBegin(cmdBuffer, pMarker);
+    pPacket = interpret_body_as_xglCmdDbgMarkerBegin(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMarker), strlen((const char *)pMarker) + 1, pMarker);
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMarker));
+    FINISH_TRACE_PACKET();
+}
+
+GLVTRACER_EXPORT XGL_VOID XGLAPI __HOOKED_xglCmdDbgMarkerEnd(
+    XGL_CMD_BUFFER  cmdBuffer)
+{
+    glv_trace_packet_header* pHeader;
+    struct_xglCmdDbgMarkerEnd* pPacket;
+    SEND_ENTRYPOINT_ID(xglCmdDbgMarkerEnd);
+    CREATE_TRACE_PACKET(xglCmdDbgMarkerEnd, 0);
+    real_xglCmdDbgMarkerEnd(cmdBuffer);
+    pPacket = interpret_body_as_xglCmdDbgMarkerEnd(pHeader);
+    pPacket->cmdBuffer = cmdBuffer;
+    FINISH_TRACE_PACKET();
+}
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg.h
new file mode 100644
index 0000000..e38cb1d
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg.h
@@ -0,0 +1,93 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "xgl/inc/xgl.h"
+#include "xgl/inc/xglDbg.h"
+
+void AttachHooks_xgldbg();
+void DetachHooks_xgldbg();
+
+#ifdef WIN32
+#define __HOOKED_xglDbgSetValidationLevel hooked_xglDbgSetValidationLevel
+#define __HOOKED_xglDbgRegisterMsgCallback hooked_xglDbgRegisterMsgCallback
+#define __HOOKED_xglDbgUnregisterMsgCallback hooked_xglDbgUnregisterMsgCallback
+#define __HOOKED_xglDbgSetMessageFilter hooked_xglDbgSetMessageFilter
+#define __HOOKED_xglDbgSetObjectTag hooked_xglDbgSetObjectTag
+#define __HOOKED_xglDbgSetGlobalOption hooked_xglDbgSetGlobalOption
+#define __HOOKED_xglDbgSetDeviceOption hooked_xglDbgSetDeviceOption
+#define __HOOKED_xglCmdDbgMarkerBegin hooked_xglCmdDbgMarkerBegin
+#define __HOOKED_xglCmdDbgMarkerEnd hooked_xglCmdDbgMarkerEnd
+#elif defined(__linux__)
+#define __HOOKED_xglDbgSetValidationLevel xglDbgSetValidationLevel
+#define __HOOKED_xglDbgRegisterMsgCallback xglDbgRegisterMsgCallback
+#define __HOOKED_xglDbgUnregisterMsgCallback xglDbgUnregisterMsgCallback
+#define __HOOKED_xglDbgSetMessageFilter xglDbgSetMessageFilter
+#define __HOOKED_xglDbgSetObjectTag xglDbgSetObjectTag
+#define __HOOKED_xglDbgSetGlobalOption xglDbgSetGlobalOption
+#define __HOOKED_xglDbgSetDeviceOption xglDbgSetDeviceOption
+#define __HOOKED_xglCmdDbgMarkerBegin xglCmdDbgMarkerBegin
+#define __HOOKED_xglCmdDbgMarkerEnd xglCmdDbgMarkerEnd
+#endif
+
+//================== hooked function declarations =============================
+XGL_RESULT XGLAPI __HOOKED_xglDbgSetValidationLevel(
+    XGL_DEVICE             device,
+    XGL_VALIDATION_LEVEL   validationLevel);
+
+XGL_RESULT XGLAPI __HOOKED_xglDbgRegisterMsgCallback(
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback,
+    XGL_VOID*                     pUserData);
+
+XGL_RESULT XGLAPI __HOOKED_xglDbgUnregisterMsgCallback(
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback);
+
+XGL_RESULT XGLAPI __HOOKED_xglDbgSetMessageFilter(
+    XGL_DEVICE           device,
+    XGL_INT              msgCode,
+    XGL_DBG_MSG_FILTER   filter);
+
+XGL_RESULT XGLAPI __HOOKED_xglDbgSetObjectTag(
+    XGL_BASE_OBJECT object,
+    XGL_SIZE        tagSize,
+    const XGL_VOID* pTag);
+
+XGL_RESULT XGLAPI __HOOKED_xglDbgSetGlobalOption(
+    XGL_DBG_GLOBAL_OPTION        dbgOption,
+    XGL_SIZE                     dataSize,
+    const XGL_VOID*              pData);
+
+XGL_RESULT XGLAPI __HOOKED_xglDbgSetDeviceOption(
+    XGL_DEVICE      device,
+    XGL_DBG_DEVICE_OPTION        dbgOption,
+    XGL_SIZE                     dataSize,
+    const XGL_VOID*              pData);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDbgMarkerBegin(
+    XGL_CMD_BUFFER  cmdBuffer,
+    const XGL_CHAR* pMarker);
+
+XGL_VOID XGLAPI __HOOKED_xglCmdDbgMarkerEnd(
+    XGL_CMD_BUFFER  cmdBuffer);
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg_structs.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg_structs.h
new file mode 100644
index 0000000..5f0ef88
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xgldbg_structs.h
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "xgl/inc/xglDbg.h"
+#include "glv_trace_packet_utils.h"
+
+//=============================================================================
+// entrypoints
+
+typedef struct struct_xglDbgSetValidationLevel {
+    glv_trace_packet_header* pHeader;
+    XGL_DEVICE device;
+    XGL_VALIDATION_LEVEL   validationLevel;
+    XGL_RESULT result;
+} struct_xglDbgSetValidationLevel;
+
+static struct_xglDbgSetValidationLevel* interpret_body_as_xglDbgSetValidationLevel(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgSetValidationLevel* pPacket = (struct_xglDbgSetValidationLevel*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglDbgRegisterMsgCallback{
+    glv_trace_packet_header* pHeader;
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback;
+    XGL_VOID*                     pUserData;
+    XGL_RESULT result;
+} struct_xglDbgRegisterMsgCallback;
+
+static struct_xglDbgRegisterMsgCallback* interpret_body_as_xglDbgRegisterMsgCallback(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgRegisterMsgCallback* pPacket = (struct_xglDbgRegisterMsgCallback*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglDbgUnregisterMsgCallback{
+    glv_trace_packet_header* pHeader;
+    XGL_DBG_MSG_CALLBACK_FUNCTION pfnMsgCallback;
+    XGL_RESULT result;
+} struct_xglDbgUnregisterMsgCallback;
+
+static struct_xglDbgUnregisterMsgCallback* interpret_body_as_xglDbgUnregisterMsgCallback(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgUnregisterMsgCallback* pPacket = (struct_xglDbgUnregisterMsgCallback*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglDbgSetMessageFilter{
+    glv_trace_packet_header* pHeader;
+    XGL_DEVICE               device;
+    XGL_INT                  msgCode;
+    XGL_DBG_MSG_FILTER       filter;
+    XGL_RESULT               result;
+} struct_xglDbgSetMessageFilter;
+
+static struct_xglDbgSetMessageFilter* interpret_body_as_xglDbgSetMessageFilter(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgSetMessageFilter* pPacket = (struct_xglDbgSetMessageFilter*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    return pPacket;
+}
+
+typedef struct struct_xglDbgSetObjectTag{
+    glv_trace_packet_header* pHeader;
+    XGL_BASE_OBJECT object;
+    XGL_SIZE        tagSize;
+    const XGL_VOID* pTag;
+    XGL_RESULT result;
+} struct_xglDbgSetObjectTag;
+
+static struct_xglDbgSetObjectTag* interpret_body_as_xglDbgSetObjectTag(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgSetObjectTag* pPacket = (struct_xglDbgSetObjectTag*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pTag = (const XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pTag);
+    return pPacket;
+}
+
+typedef struct struct_xglDbgSetGlobalOption{
+    glv_trace_packet_header* pHeader;
+    XGL_DBG_GLOBAL_OPTION    dbgOption;
+    XGL_SIZE                 dataSize;
+    const XGL_VOID*          pData;
+    XGL_RESULT               result;
+} struct_xglDbgSetGlobalOption;
+
+static struct_xglDbgSetGlobalOption* interpret_body_as_xglDbgSetGlobalOption(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgSetGlobalOption* pPacket = (struct_xglDbgSetGlobalOption*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pData = (const XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglDbgSetDeviceOption{
+    glv_trace_packet_header* pHeader;
+    XGL_DEVICE               device;
+    XGL_DBG_DEVICE_OPTION    dbgOption;
+    XGL_SIZE                 dataSize;
+    const XGL_VOID*          pData;
+    XGL_RESULT               result;
+} struct_xglDbgSetDeviceOption;
+
+static struct_xglDbgSetDeviceOption* interpret_body_as_xglDbgSetDeviceOption(glv_trace_packet_header* pHeader)
+{
+    struct_xglDbgSetDeviceOption* pPacket = (struct_xglDbgSetDeviceOption*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pData = (const XGL_VOID*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pData);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDbgMarkerBegin{
+    glv_trace_packet_header* pHeader;
+    XGL_CMD_BUFFER  cmdBuffer;
+    const XGL_CHAR* pMarker;
+} struct_xglCmdDbgMarkerBegin;
+
+static struct_xglCmdDbgMarkerBegin* interpret_body_as_xglCmdDbgMarkerBegin(glv_trace_packet_header* pHeader)
+{
+    struct_xglCmdDbgMarkerBegin* pPacket = (struct_xglCmdDbgMarkerBegin*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pMarker = (const XGL_CHAR*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMarker);
+    return pPacket;
+}
+
+typedef struct struct_xglCmdDbgMarkerEnd{
+    glv_trace_packet_header* pHeader;
+    XGL_CMD_BUFFER  cmdBuffer;
+} struct_xglCmdDbgMarkerEnd;
+
+static struct_xglCmdDbgMarkerEnd* interpret_body_as_xglCmdDbgMarkerEnd(glv_trace_packet_header* pHeader)
+{
+    struct_xglCmdDbgMarkerEnd* pPacket = (struct_xglCmdDbgMarkerEnd*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    return pPacket;
+}
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext.c b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext.c
new file mode 100644
index 0000000..1b250a8
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2014, Lunarg, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+#include "glv_platform.h"
+#include "glvtrace_xgl_xglwsix11ext.h"
+#include "glvtrace_xgl_xglwsix11ext_structs.h"
+#include "glvtrace_xgl_packet_id.h"
+#include "glv_common.h"
+#ifdef WIN32
+#include "mhook/mhook-lib/mhook.h"
+#endif
+
+// ======================== Pointers to real functions ========================
+static XGL_RESULT ( XGLAPI * real_xglWsiX11AssociateConnection)(
+    XGL_PHYSICAL_GPU                            gpu,
+    const XGL_WSI_X11_CONNECTION_INFO*          pConnectionInfo) = xglWsiX11AssociateConnection;
+
+static XGL_RESULT ( XGLAPI * real_xglWsiX11GetMSC)(
+    XGL_DEVICE                                  device,
+    xcb_randr_crtc_t                            crtc,
+    XGL_UINT64*                                 pMsc) = xglWsiX11GetMSC;
+
+static XGL_RESULT ( XGLAPI  * real_xglWsiX11CreatePresentableImage)(
+    XGL_DEVICE                                  device,
+    const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE*                                  pImage,
+    XGL_GPU_MEMORY*                             pMem) = xglWsiX11CreatePresentableImage;
+
+static XGL_RESULT ( XGLAPI * real_xglWsiX11QueuePresent)(
+    XGL_QUEUE                                   queue,
+    const XGL_WSI_X11_PRESENT_INFO*             pPresentInfo,
+    XGL_FENCE                                   fence) = xglWsiX11QueuePresent;
+
+void AttachHooks_xglwsix11ext()
+{
+    BOOL hookSuccess = TRUE;
+#if defined(WIN32)
+    Mhook_BeginMultiOperation(FALSE);
+    if (real_xglWsiX11AssociateConnection != NULL)
+    {
+        hookSuccess = Mhook_SetHook((PVOID*)&real_xglWsiX11AssociateConnection, hooked_xglWsiX11AssociateConnection);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglWsiX11GetMSC, hooked_xglWsiX11GetMSC);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglWsiX11CreatePresentableImage, hooked_xglWsiX11CreatePresentableImage);
+        hookSuccess &= Mhook_SetHook((PVOID*)&real_xglWsiX11QueuePresent, hooked_xglWsiX11QueuePresent);
+    }
+
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook XGLWsiX11Ext.");
+    }
+
+    Mhook_EndMultiOperation();
+#elif defined(__linux__)
+    hookSuccess = glv_platform_get_next_lib_sym((PVOID*)&real_xglWsiX11AssociateConnection, "xglWsiX11AssociateConnection");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglWsiX11GetMSC, "xglWsiX11GetMSC");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglWsiX11CreatePresentableImage, "xglWsiX11CreatePresentableImage");
+    hookSuccess &= glv_platform_get_next_lib_sym((PVOID*)&real_xglWsiX11QueuePresent, "xglWsiX11QueuePresent");
+    if (!hookSuccess)
+    {
+        glv_LogError("Failed to hook XGLWsiX11Ext.");
+    }
+#endif
+}
+
+void DetachHooks_xglwsix11ext()
+{
+
+#ifdef WIN32
+    BOOL unhookSuccess = TRUE;
+
+    if (real_xglWsiX11AssociateConnection != NULL)
+    {
+        unhookSuccess = Mhook_Unhook((PVOID*)&real_real_xglWsiX11AssociateConnection);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglWsiX11GetMSC);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglWsiX11CreatePresentableImage);
+        unhookSuccess &= Mhook_Unhook((PVOID*)&real_xglWsiX11QueuePresent);
+    }
+    if (!unhookSuccess)
+    {
+        glv_LogError("Failed to unhook XGLWsiX11Ext.");
+    }
+#elif defined(__linux__)
+    return;
+#endif
+}
+
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI __HOOKED_xglWsiX11AssociateConnection(
+    XGL_PHYSICAL_GPU                            gpu,
+    const XGL_WSI_X11_CONNECTION_INFO*          pConnectionInfo)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglWsiX11AssociateConnection* pPacket;
+    SEND_ENTRYPOINT_ID(xglWsiX11AssociateConnection);
+    CREATE_TRACE_PACKET(xglWsiX11AssociateConnection, sizeof(XGL_WSI_X11_CONNECTION_INFO) +
+                       ((pConnectionInfo->pConnection != NULL) ? sizeof(void *) : 0));
+    // TODO xcb_connection_t is opaque struct  hope it is a pointer so sizeof(void *) = sizeof(xcb_connection_t)
+    result = real_xglWsiX11AssociateConnection(gpu, pConnectionInfo);
+    pPacket = interpret_body_as_xglWsiX11AssociateConnection(pHeader);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pConnectionInfo), sizeof(XGL_WSI_X11_CONNECTION_INFO), pConnectionInfo);
+    if (pConnectionInfo->pConnection != NULL) {
+        glv_add_buffer_to_trace_packet(pHeader, (void**) &(pPacket->pConnectionInfo->pConnection), sizeof(void *), pConnectionInfo->pConnection);
+        glv_finalize_buffer_address(pHeader, (void**) &(pPacket->pConnectionInfo->pConnection));
+    }
+    pPacket->gpu = gpu;
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pConnectionInfo));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI  __HOOKED_xglWsiX11GetMSC(
+    XGL_DEVICE                                  device,
+    xcb_randr_crtc_t                            crtc,
+    XGL_UINT64*                                 pMsc)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglWsiX11GetMSC* pPacket;
+    SEND_ENTRYPOINT_ID(xglWsiX11GetMSC);
+    CREATE_TRACE_PACKET(xglWsiX11GetMSC, sizeof(XGL_UINT64));
+    result = real_xglWsiX11GetMSC(device, crtc, pMsc);
+    pPacket = interpret_body_as_xglWsiX11GetMSC(pHeader);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMsc), sizeof(XGL_UINT64), pMsc);
+    pPacket->device = device;
+    pPacket->crtc = crtc;
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMsc));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI  __HOOKED_xglWsiX11CreatePresentableImage(
+    XGL_DEVICE                                  device,
+    const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE*                                  pImage,
+    XGL_GPU_MEMORY*                             pMem)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglWsiX11CreatePresentableImage* pPacket;
+    SEND_ENTRYPOINT_ID(xglWsiX11CreatePresentableImage);
+    CREATE_TRACE_PACKET(xglWsiX11CreatePresentableImage, sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO) +
+                        sizeof(XGL_IMAGE) + sizeof(XGL_GPU_MEMORY));
+    result = real_xglWsiX11CreatePresentableImage(device, pCreateInfo, pImage, pMem);
+    pPacket = interpret_body_as_xglWsiX11CreatePresentableImage(pHeader);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pCreateInfo), sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO), pCreateInfo);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pImage), sizeof(XGL_IMAGE), pImage);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pMem), sizeof(XGL_GPU_MEMORY), pMem);
+    pPacket->device = device;
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pCreateInfo));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pImage));
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pMem));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
+GLVTRACER_EXPORT XGL_RESULT XGLAPI  __HOOKED_xglWsiX11QueuePresent(
+    XGL_QUEUE                                   queue,
+    const XGL_WSI_X11_PRESENT_INFO*             pPresentInfo,
+    XGL_FENCE                                   fence)
+{
+    glv_trace_packet_header* pHeader;
+    XGL_RESULT result;
+    struct_xglWsiX11QueuePresent* pPacket;
+    SEND_ENTRYPOINT_ID(xglWsiX11QueuePresent);
+    CREATE_TRACE_PACKET(xglWsiX11QueuePresent, sizeof(XGL_WSI_X11_PRESENT_INFO));
+    result = real_xglWsiX11QueuePresent(queue, pPresentInfo, fence);
+    pPacket = interpret_body_as_xglWsiX11QueuePresent(pHeader);
+    glv_add_buffer_to_trace_packet(pHeader, (void**)&(pPacket->pPresentInfo), sizeof(XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO), pPresentInfo);
+    pPacket->queue = queue;
+    pPacket->fence = fence;
+    pPacket->result = result;
+    glv_finalize_buffer_address(pHeader, (void**)&(pPacket->pPresentInfo));
+    FINISH_TRACE_PACKET();
+    return result;
+}
+
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext.h
new file mode 100644
index 0000000..79344a3
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, Lunarg, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+#pragma once
+
+#include "xgl/inc/xgl.h"
+#include "xgl/inc/xglWsiX11Ext.h"
+void AttachHooks_xglwsix11ext();
+void DetachHooks_xglwsix11ext();
+
+#ifdef WIN32
+#define __HOOKED_xglWsiX11AssociateConnection hooked_xglWsiX11AssociateConnection
+#define __HOOKED_xglWsiX11GetMSC hooked_xglWsiX11GetMSC
+#define __HOOKED_xglWsiX11CreatePresentableImage hooked_xglWsiX11CreatePresentableImage
+#define __HOOKED_xglWsiX11QueuePresent hooked_xglWsiX11QueuePresent
+#elif defined(__linux__)
+#define __HOOKED_xglWsiX11AssociateConnection xglWsiX11AssociateConnection
+#define __HOOKED_xglWsiX11GetMSC xglWsiX11GetMSC
+#define __HOOKED_xglWsiX11CreatePresentableImage xglWsiX11CreatePresentableImage
+#define __HOOKED_xglWsiX11QueuePresent xglWsiX11QueuePresent
+#endif
+
+//================== hooked function declarations =============================
+XGL_RESULT XGLAPI  __HOOKED_xglWsiX11AssociateConnection(
+    XGL_PHYSICAL_GPU                            gpu,
+    const XGL_WSI_X11_CONNECTION_INFO*          pConnectionInfo);
+
+XGL_RESULT XGLAPI  __HOOKED_xglWsiX11GetMSC(
+    XGL_DEVICE                                  device,
+    xcb_randr_crtc_t                            crtc,
+    XGL_UINT64*                                 pMsc);
+
+XGL_RESULT XGLAPI  __HOOKED_xglWsiX11CreatePresentableImage(
+    XGL_DEVICE                                  device,
+    const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo,
+    XGL_IMAGE*                                  pImage,
+    XGL_GPU_MEMORY*                             pMem);
+
+XGL_RESULT XGLAPI  __HOOKED_xglWsiX11QueuePresent(
+    XGL_QUEUE                                   queue,
+    const XGL_WSI_X11_PRESENT_INFO*             pPresentInfo,
+    XGL_FENCE                                   fence);
+
diff --git a/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext_structs.h b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext_structs.h
new file mode 100644
index 0000000..ddb98ce
--- /dev/null
+++ b/tools/glave/src/glv_extensions/glvtrace_xgl/glvtrace_xgl_xglwsix11ext_structs.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, Lunarg, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+#pragma once
+
+#include "xgl/inc/xglWsiX11Ext.h"
+#include "glv_trace_packet_utils.h"
+
+//=============================================================================
+// entrypoints
+
+typedef struct struct_xglWsiX11AssociateConnection {
+    glv_trace_packet_header* pHeader;
+    XGL_PHYSICAL_GPU gpu;
+    const XGL_WSI_X11_CONNECTION_INFO* pConnectionInfo;
+    XGL_RESULT result;
+} struct_xglWsiX11AssociateConnection;
+
+static struct_xglWsiX11AssociateConnection* interpret_body_as_xglWsiX11AssociateConnection(glv_trace_packet_header* pHeader)
+{
+    struct_xglWsiX11AssociateConnection* pPacket = (struct_xglWsiX11AssociateConnection*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pConnectionInfo = (const XGL_WSI_X11_CONNECTION_INFO*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pConnectionInfo);
+    return pPacket;
+}
+
+typedef struct struct_xglWsiX11CreatePresentableImage{
+    glv_trace_packet_header* pHeader;
+    XGL_DEVICE device;
+    const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO* pCreateInfo;
+    XGL_IMAGE* pImage;
+    XGL_GPU_MEMORY* pMem;
+    XGL_RESULT result;
+} struct_xglWsiX11CreatePresentableImage;
+
+static struct_xglWsiX11CreatePresentableImage* interpret_body_as_xglWsiX11CreatePresentableImage(glv_trace_packet_header* pHeader)
+{
+    struct_xglWsiX11CreatePresentableImage* pPacket = (struct_xglWsiX11CreatePresentableImage*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pCreateInfo = (const XGL_WSI_X11_PRESENTABLE_IMAGE_CREATE_INFO*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pCreateInfo);
+    pPacket->pImage = (XGL_IMAGE*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pImage);
+    pPacket->pMem = (XGL_GPU_MEMORY*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMem);
+    return pPacket;
+}
+
+typedef struct struct_xglWsiX11GetMSC{
+    glv_trace_packet_header* pHeader;
+    XGL_DEVICE device;
+    xcb_randr_crtc_t crtc;
+    XGL_UINT64* pMsc;
+    XGL_RESULT result;
+} struct_xglWsiX11GetMSC;
+
+static struct_xglWsiX11GetMSC* interpret_body_as_xglWsiX11GetMSC(glv_trace_packet_header* pHeader)
+{
+    struct_xglWsiX11GetMSC* pPacket = (struct_xglWsiX11GetMSC*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pMsc = (XGL_UINT64*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pMsc);
+    return pPacket;
+}
+
+typedef struct struct_xglWsiX11QueuePresent{
+    glv_trace_packet_header* pHeader;
+    XGL_QUEUE queue;
+    const XGL_WSI_X11_PRESENT_INFO* pPresentInfo;
+    XGL_FENCE fence;
+    XGL_RESULT result;
+} struct_xglWsiX11QueuePresent;
+
+static struct_xglWsiX11QueuePresent* interpret_body_as_xglWsiX11QueuePresent(glv_trace_packet_header* pHeader)
+{
+    struct_xglWsiX11QueuePresent* pPacket = (struct_xglWsiX11QueuePresent*)pHeader->pBody;
+    pPacket->pHeader = pHeader;
+    pPacket->pPresentInfo = (const XGL_WSI_X11_PRESENT_INFO*) glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->pPresentInfo);
+    return pPacket;
+}
diff --git a/tools/glave/src/glvcommon/CMakeLists.txt b/tools/glave/src/glvcommon/CMakeLists.txt
new file mode 100644
index 0000000..5b3c706
--- /dev/null
+++ b/tools/glave/src/glvcommon/CMakeLists.txt
@@ -0,0 +1,50 @@
+project(glvcommon)
+cmake_minimum_required(VERSION 2.8)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/thirdparty
+)
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+    require_pthreads()
+endif()
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glv_filelike.c
+    glv_interconnect.c
+    glv_platform.c
+    glv_process.c
+    glv_settings.c
+    glv_tracelog.c
+    glv_trace_packet_utils.c
+)
+
+set_source_files_properties( ${SRC_LIST} PROPERTIES LANGUAGE C)
+
+file( GLOB_RECURSE HDRS *.[h|inl] )
+
+if (NOT MSVC)
+    add_compiler_flag("-fPIC")
+endif()
+
+add_library(${PROJECT_NAME} ${SRC_LIST} ${HDRS})
+
+
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+target_link_libraries(${PROJECT_NAME}
+    Rpcrt4.lib
+)
+elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+target_link_Libraries(${PROJECT_NAME}
+    dl
+    pthread
+)
+endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+
+build_options_finalize()
+
+set_target_properties(glvcommon PROPERTIES LINKER_LANGUAGE C)
diff --git a/tools/glave/src/glvcommon/glv_common.h b/tools/glave/src/glvcommon/glv_common.h
new file mode 100644
index 0000000..24b1b70
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_common.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+
+#pragma once
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "glv_platform.h"
+
+#include "glv_memory.h"
+#include "glv_tracelog.h"
+
+#if defined(WIN32)
+
+#define GLVTRACER_EXPORT __declspec(dllexport)
+#define GLVTRACER_STDCALL __stdcall
+#define GLVTRACER_EXIT void __cdecl
+#define GLVTRACER_ENTRY void
+#define GLVTRACER_LEAVE void
+
+#elif defined(PLATFORM_LINUX)
+
+#define GLVTRACER_EXPORT __attribute__ ((visibility ("default")))
+#define GLVTRACER_STDCALL
+#define GLVTRACER_EXIT void
+#define GLVTRACER_ENTRY void __attribute__ ((constructor))
+#define GLVTRACER_LEAVE void __attribute__ ((destructor))
+
+#endif
diff --git a/tools/glave/src/glvcommon/glv_filelike.c b/tools/glave/src/glvcommon/glv_filelike.c
new file mode 100644
index 0000000..28a7964
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_filelike.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#include "glv_filelike.h"
+#include "glv_common.h"
+#include "glv_interconnect.h"
+#include <assert.h>
+#include <stdlib.h>
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+Checkpoint* glv_Checkpoint_create(const char* _str)
+{
+    Checkpoint* pCheckpoint = GLV_NEW(Checkpoint);
+    pCheckpoint->mToken = _str;
+    pCheckpoint->mTokenLength = strlen(_str) + 1;
+    return pCheckpoint;
+}
+
+// ------------------------------------------------------------------------------------------------
+void glv_Checkpoint_write(Checkpoint* pCheckpoint, FileLike* _out)
+{
+    glv_FileLike_Write(_out, pCheckpoint->mToken, pCheckpoint->mTokenLength);
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_Checkpoint_read(Checkpoint* pCheckpoint, FileLike* _in)
+{
+    if (pCheckpoint->mTokenLength < 64) {
+        char buffer[64];
+        glv_FileLike_Read(_in, buffer, pCheckpoint->mTokenLength);
+        if (strcmp(buffer, pCheckpoint->mToken) != 0) {
+            return FALSE;
+        }
+    } else {
+        char* buffer = GLV_NEW_ARRAY(char, pCheckpoint->mTokenLength);
+        glv_FileLike_Read(_in, buffer, pCheckpoint->mTokenLength);
+        if (strcmp(buffer, pCheckpoint->mToken) != 0) {
+            GLV_DELETE(buffer);
+            return FALSE;
+        }
+        GLV_DELETE(buffer);
+    }
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+FileLike* glv_FileLike_create_file(FILE* fp)
+{
+    FileLike* pFile = NULL;
+    if (fp != NULL)
+    {
+        pFile = GLV_NEW(FileLike);
+        pFile->mMode = File;
+        pFile->mFile = fp;
+        pFile->mMessageStream = NULL;
+    }
+    return pFile;
+}
+
+// ------------------------------------------------------------------------------------------------
+FileLike* glv_FileLike_create_msg(MessageStream* _msgStream)
+{
+    FileLike* pFile = NULL;
+    if (_msgStream != NULL)
+    {
+        pFile = GLV_NEW(FileLike);
+        pFile->mMode = Socket;
+        pFile->mFile = NULL;
+        pFile->mMessageStream = _msgStream;
+    }
+    return pFile;
+}
+
+// ------------------------------------------------------------------------------------------------
+size_t glv_FileLike_Read(FileLike* pFileLike, void* _bytes, size_t _len)
+{
+    size_t bytesInStream = 0;
+    if (glv_FileLike_ReadRaw(pFileLike, &bytesInStream, sizeof(bytesInStream)) == FALSE)
+        return 0;
+    
+    if (bytesInStream > 0) {
+        assert(_len >= bytesInStream);
+        if (glv_FileLike_ReadRaw(pFileLike, _bytes, min(_len, bytesInStream)) == FALSE)
+            return 0;
+    }
+
+    return min(_len, bytesInStream);
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_FileLike_ReadRaw(FileLike* pFileLike, void* _bytes, size_t _len)
+{
+    BOOL result = TRUE;
+    assert((pFileLike->mFile != 0) ^ (pFileLike->mMessageStream != 0));
+
+    switch(pFileLike->mMode) {
+    case File:
+        {
+            if (1 != fread(_bytes, _len, 1, pFileLike->mFile))
+            {
+                if (ferror(pFileLike->mFile) != 0)
+                {
+                    perror("fread error");
+                }
+                else if (feof(pFileLike->mFile) != 0)
+                {
+                    glv_LogWarn("Reached end of file\n");
+                }
+                result = FALSE;
+            } 
+            break;
+        }
+    case Socket:
+        {
+            result = glv_MessageStream_BlockingRecv(pFileLike->mMessageStream, _bytes, _len);
+            break;
+        }
+
+        default: 
+            assert(!"Invalid mode in FileLike_ReadRaw");
+            result = FALSE;
+    }
+    return result;
+}
+
+void glv_FileLike_Write(FileLike* pFileLike, const void* _bytes, size_t _len)
+{
+    glv_FileLike_WriteRaw(pFileLike, &_len, sizeof(_len));
+    if (_len) {
+        glv_FileLike_WriteRaw(pFileLike, _bytes, _len);
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_FileLike_WriteRaw(FileLike* pFile, const void* _bytes, size_t _len)
+{
+    BOOL result = TRUE;
+    assert((pFile->mFile != 0) ^ (pFile->mMessageStream != 0));
+    switch (pFile->mMode)
+    {
+        case File:
+            if (1 != fwrite(_bytes, _len, 1, pFile->mFile))
+            {
+                result = FALSE;
+            }
+            break;
+        case Socket:
+            result = glv_MessageStream_Send(pFile->mMessageStream, _bytes, _len);
+            break;
+        default:
+            assert(!"Invalid mode in FileLike_WriteRaw");
+            result = FALSE;
+            break;
+    }
+    return result;
+}
diff --git a/tools/glave/src/glvcommon/glv_filelike.h b/tools/glave/src/glvcommon/glv_filelike.h
new file mode 100644
index 0000000..bec2f8d
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_filelike.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#pragma once
+
+#ifdef WIN32
+#include <WinSock2.h>
+#include <WS2tcpip.h>
+#pragma comment (lib, "Ws2_32.lib")
+#endif
+
+#include "glv_common.h"
+#include "glv_interconnect.h"
+
+typedef struct MessageStream MessageStream;
+
+struct FileLike;
+typedef struct FileLike FileLike;
+typedef struct FileLike
+{
+    enum { File, Socket } mMode;
+    FILE* mFile;
+    MessageStream* mMessageStream;
+} FileLike;
+
+// For creating checkpoints (consistency checks) in the various streams we're interacting with.
+typedef struct Checkpoint
+{
+    const char* mToken;
+    size_t mTokenLength;
+} Checkpoint;
+
+Checkpoint* glv_Checkpoint_create(const char* _str);
+void glv_Checkpoint_write(Checkpoint* pCheckpoint, FileLike* _out);
+BOOL glv_Checkpoint_read(Checkpoint* pCheckpoint, FileLike* _in);
+
+// An interface for interacting with sockets, files, and memory streams with a file-like interface.
+// This is a simple file-like interface--it doesn't support rewinding or anything fancy, just fifo 
+// reads and writes.
+
+// create a filelike interface for file streaming
+FileLike* glv_FileLike_create_file(FILE* fp);
+
+// create a filelike interface for network streaming
+FileLike* glv_FileLike_create_msg(MessageStream* _msgStream);
+
+// read a size and then a buffer of that size
+size_t glv_FileLike_Read(FileLike* pFileLike, void* _bytes, size_t _len);
+
+// Normally, Read expects the size to live in the stream prefixing the data to be read.
+// With ReadRaw, no size is expected first, and the bytes are directly read.
+BOOL glv_FileLike_ReadRaw(FileLike* pFileLike, void* _bytes, size_t _len);
+
+// write _len and then the buffer of size _len
+void glv_FileLike_Write(FileLike* pFileLike, const void* _bytes, size_t _len);
+
+// Normally, Write outputs the _len to the stream first--with WriteRaw the bytes are simply written, 
+// no size parameter first.
+BOOL glv_FileLike_WriteRaw(FileLike* pFile, const void* _bytes, size_t _len);
diff --git a/tools/glave/src/glvcommon/glv_interconnect.c b/tools/glave/src/glvcommon/glv_interconnect.c
new file mode 100644
index 0000000..5db7c1d
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_interconnect.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#include "glv_interconnect.h"
+#include "glv_common.h"
+
+#include "glv_filelike.h"
+
+const size_t kSendBufferSize = 1024 * 1024;
+
+MessageStream* gMessageStream = NULL;
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// private functions
+BOOL glv_MessageStream_SetupSocket(MessageStream* pStream);
+BOOL glv_MessageStream_SetupHostSocket(MessageStream* pStream);
+BOOL glv_MessageStream_SetupClientSocket(MessageStream* pStream);
+BOOL glv_MessageStream_Handshake(MessageStream* pStream);
+BOOL glv_MessageStream_ReallySend(MessageStream* pStream, const void* _bytes, size_t _size, BOOL _optional);
+void glv_MessageStream_FlushSendBuffer(MessageStream* pStream, BOOL _optional);
+
+// public functions
+MessageStream* glv_MessageStream_create_port_string(BOOL _isHost, const char* _address, const char* _port)
+{
+    MessageStream* pStream;
+    // make sure the strings are shorter than the destination buffer we have to store them!
+    assert(strlen(_address) + 1 <= 64);
+    assert(strlen(_port) + 1 <= 8);
+
+    pStream = GLV_NEW(MessageStream);
+    memcpy(pStream->mAddress, _address, strlen(_address) + 1);
+    memcpy(pStream->mPort, _port, strlen(_port) + 1);
+
+    pStream->mErrorNum = 0;
+    memset(pStream->mSmallBuffer, 0, 64);
+    pStream->mHost = _isHost;
+    pStream->mHostAddressInfo = NULL;
+    pStream->mNextPacketId = 0;
+    pStream->mSocket = INVALID_SOCKET;
+    pStream->mSendBuffer = NULL;
+
+    if (glv_MessageStream_SetupSocket(pStream) == FALSE)
+    {
+        pStream->mErrorNum = GLV_WSAGetLastError();
+    }
+
+    return pStream;
+}
+
+MessageStream* glv_MessageStream_create(BOOL _isHost, const char* _address, unsigned int _port)
+{
+    char portBuf[32];
+    memset(portBuf, 0, 32 * sizeof(char));
+    sprintf(portBuf, "%u", _port);
+    return glv_MessageStream_create_port_string(_isHost, _address, portBuf);
+}
+
+void glv_MessageStream_destroy(MessageStream** ppStream)
+{
+    if ((*ppStream)->mSendBuffer != NULL) { 
+        // Try to get our data out.
+        glv_MessageStream_FlushSendBuffer(*ppStream, TRUE);
+        glv_SimpleBuffer_destroy(&(*ppStream)->mSendBuffer);
+    }
+
+    if ((*ppStream)->mHostAddressInfo != NULL)
+    {
+        freeaddrinfo((*ppStream)->mHostAddressInfo);
+        (*ppStream)->mHostAddressInfo = NULL;
+    }
+
+#if defined(WIN32)
+    WSACleanup();
+#endif
+    GLV_DELETE(*ppStream);
+    (*ppStream) = NULL;
+}
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// private function implementations
+BOOL glv_MessageStream_SetupSocket(MessageStream* pStream)
+{
+    BOOL result = TRUE;
+#if defined(WIN32)
+    WSADATA wsaData;
+
+    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR) {
+        result = FALSE;
+    }
+    else
+#endif
+    {
+        if (pStream->mHost) {
+            result = glv_MessageStream_SetupHostSocket(pStream);
+        } else {
+            result = glv_MessageStream_SetupClientSocket(pStream);
+        }
+    }
+    return result;
+}
+
+BOOL glv_MessageStream_SetupHostSocket(MessageStream* pStream)
+{
+    int hr = 0;
+#ifdef PLATFORM_LINUX
+    int yes = 1;
+#endif
+    struct addrinfo hostAddrInfo = { 0 };
+    SOCKET listenSocket;
+
+    hostAddrInfo.ai_family = AF_INET;
+    hostAddrInfo.ai_socktype = SOCK_STREAM;
+    hostAddrInfo.ai_protocol = IPPROTO_TCP;
+    hostAddrInfo.ai_flags = AI_PASSIVE;
+
+    hr = getaddrinfo(NULL, pStream->mPort, &hostAddrInfo, &pStream->mHostAddressInfo);
+    if (hr != 0) {
+        glv_LogError("Host: Failed getaddrinfo\n");
+        return FALSE;
+    }
+
+    listenSocket = socket(pStream->mHostAddressInfo->ai_family, pStream->mHostAddressInfo->ai_socktype, pStream->mHostAddressInfo->ai_protocol);
+    if (listenSocket == INVALID_SOCKET) {
+        // TODO: Figure out errors
+        glv_LogError("Host: Failed creating a listen socket\n");
+        freeaddrinfo(pStream->mHostAddressInfo);
+        pStream->mHostAddressInfo = NULL;
+        return FALSE;
+    }
+
+#ifdef PLATFORM_LINUX
+    setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
+#endif
+    hr = bind(listenSocket, pStream->mHostAddressInfo->ai_addr, (int)pStream->mHostAddressInfo->ai_addrlen);
+    if (hr == SOCKET_ERROR) {
+        glv_LogError("Host: Failed binding socket err=%d\n", GLV_WSAGetLastError());
+        freeaddrinfo(pStream->mHostAddressInfo);
+        pStream->mHostAddressInfo = NULL;
+        closesocket(listenSocket);
+        return FALSE;
+    }
+
+    // Done with this.
+    freeaddrinfo(pStream->mHostAddressInfo);
+    pStream->mHostAddressInfo = NULL;
+
+    hr = listen(listenSocket, 1);
+    if (hr == SOCKET_ERROR) {
+        glv_LogError("Host: Failed listening on socket err=%d\n");
+        closesocket(listenSocket);
+        return FALSE;
+    }
+
+    // Fo reals.
+    pStream->mSocket = accept(listenSocket, NULL, NULL);
+    closesocket(listenSocket);
+
+    if (pStream->mSocket == INVALID_SOCKET) {
+        glv_LogError("Host: Failed accepting socket connection\n");
+        return FALSE;
+    }
+
+    if (glv_MessageStream_Handshake(pStream))
+    {
+        // TODO: The SendBuffer can cause big delays in sending messages back to the client.
+        // We haven't verified if this improves performance in real applications,
+        // so disable it for now.
+        //pStream->mSendBuffer = glv_SimpleBuffer_create(kSendBufferSize);
+        pStream->mSendBuffer = NULL;
+    }
+    else
+    {
+        glv_LogError("glv_MessageStream_SetupHostSocket failed handshake\n");
+    }
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_SetupClientSocket(MessageStream* pStream)
+{
+    int hr = 0;
+    unsigned int attempt = 0;
+    BOOL bConnected = FALSE;
+    struct addrinfo hostAddrInfo = { 0 },
+        *currentAttempt = NULL;
+
+    hostAddrInfo.ai_family = AF_UNSPEC;
+    hostAddrInfo.ai_socktype = SOCK_STREAM;
+    hostAddrInfo.ai_protocol = IPPROTO_TCP;
+
+    hr = getaddrinfo(pStream->mAddress, pStream->mPort, &hostAddrInfo, &pStream->mHostAddressInfo);
+    if (hr != 0) {
+        glv_LogError("Client: Failed getaddrinfo\n");
+        return FALSE;
+    }
+
+    // make several attempts to connect before bailing out
+    for (attempt = 0; attempt < 10 && !bConnected; attempt++)
+    {
+        for (currentAttempt = pStream->mHostAddressInfo; currentAttempt != NULL; currentAttempt = currentAttempt->ai_next)
+        {
+            pStream->mSocket = socket(currentAttempt->ai_family, currentAttempt->ai_socktype, currentAttempt->ai_protocol);
+
+            hr = connect(pStream->mSocket, currentAttempt->ai_addr, (int)currentAttempt->ai_addrlen);
+            if (hr == SOCKET_ERROR)
+            {
+                glv_LogVerbose("Client: Failed connect. Possibly non-fatal.\n");
+                closesocket(pStream->mSocket);
+                pStream->mSocket = INVALID_SOCKET;
+                continue;
+            }
+
+            bConnected = TRUE;
+            break;
+        }
+
+        if (!bConnected)
+        {
+            Sleep(1);
+            glv_LogVerbose("Client: Connect attempt %u on port %s failed, trying again.\n", attempt, pStream->mPort);
+        }
+        else
+        {
+            glv_LogVerbose("Client: Connected to port %s successfully\n", pStream->mPort);
+        }
+    }
+
+    freeaddrinfo(pStream->mHostAddressInfo);
+    pStream->mHostAddressInfo = NULL;
+
+    if (pStream->mSocket == INVALID_SOCKET) {
+        glv_LogError("Client: Couldn't find any connections.\n");
+        return FALSE;
+    }
+
+    if (!glv_MessageStream_Handshake(pStream))
+    {
+        glv_LogError("Client: Failed handshake with host.\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_Handshake(MessageStream* pStream)
+{
+    BOOL result = TRUE;
+    FileLike* fileLike = glv_FileLike_create_msg(pStream);
+    Checkpoint* syn = glv_Checkpoint_create("It's a trap!");
+    Checkpoint* ack = glv_Checkpoint_create(" - Admiral Ackbar");
+
+    if (pStream->mHost) {
+        glv_Checkpoint_write(syn, fileLike);
+        result = glv_Checkpoint_read(ack, fileLike);
+    } else {
+        if (glv_Checkpoint_read(syn, fileLike))
+        {
+            glv_Checkpoint_write(ack, fileLike);
+        }
+        else
+        {
+            result = FALSE;
+        }
+    }
+
+    // Turn on non-blocking modes for sockets now.
+    if (result)
+    {
+#if defined(WIN32)
+        u_long asyncMode = 1;
+        ioctlsocket(pStream->mSocket, FIONBIO, &asyncMode);
+#else
+        fcntl(pStream->mSocket, F_SETFL, O_NONBLOCK);
+#endif
+    }
+
+    GLV_DELETE(syn);
+    GLV_DELETE(ack);
+    GLV_DELETE(fileLike);
+
+    return result;
+}
+
+// ------------------------------------------------------------------------------------------------
+void glv_MessageStream_FlushSendBuffer(MessageStream* pStream, BOOL _optional)
+{
+    size_t bufferedByteSize = 0;
+    const void* bufferBytes = glv_SimpleBuffer_GetBytes(pStream->mSendBuffer, &bufferedByteSize);
+    if (bufferedByteSize > 0) {
+        // TODO use return value from ReallySend
+        glv_MessageStream_ReallySend(pStream, bufferBytes, bufferedByteSize, _optional);
+        glv_SimpleBuffer_EmptyBuffer(pStream->mSendBuffer);
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_BufferedSend(MessageStream* pStream, const void* _bytes, size_t _size, BOOL _optional)
+{
+    BOOL result = TRUE;
+    if (pStream->mSendBuffer == NULL) {
+        result = glv_MessageStream_ReallySend(pStream, _bytes, _size, _optional);
+    }
+    else
+    {
+        if (!glv_SimpleBuffer_WouldOverflow(pStream->mSendBuffer, _size)) {
+            result = glv_SimpleBuffer_AddBytes(pStream->mSendBuffer, _bytes, _size);
+        } else {
+            // Time to flush the cache.
+            glv_MessageStream_FlushSendBuffer(pStream, FALSE);
+
+            // Check to see if the packet is larger than the send buffer 
+            if (glv_SimpleBuffer_WouldOverflow(pStream->mSendBuffer, _size)) { 
+                result = glv_MessageStream_ReallySend(pStream, _bytes, _size, _optional); 
+            } else { 
+                result = glv_SimpleBuffer_AddBytes(pStream->mSendBuffer, _bytes, _size);
+            }
+        }
+    }
+    return result;
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_Send(MessageStream* pStream, const void* _bytes, size_t _len)
+{
+    return glv_MessageStream_BufferedSend(pStream, _bytes, _len, FALSE);
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_ReallySend(MessageStream* pStream, const void* _bytes, size_t _size, BOOL _optional)
+{
+    size_t bytesSent = 0;
+    assert(_size > 0);
+
+    do {
+        int sentThisTime = send(pStream->mSocket, (const char*)_bytes + bytesSent, (int)_size - (int)bytesSent, 0);
+        if (sentThisTime == SOCKET_ERROR) {
+            int socketError = GLV_WSAGetLastError();
+            if (socketError == WSAEWOULDBLOCK) {
+                // Try again. Don't sleep, because that nukes performance from orbit.
+                continue;
+            }
+
+            if (!_optional) {
+                return FALSE;
+            } 
+        }
+        if (sentThisTime == 0) {
+            if (!_optional) {
+                return FALSE;
+            }
+            break;
+        }
+
+        bytesSent += sentThisTime;
+
+    } while (bytesSent < _size);
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_Recv(MessageStream* pStream, void* _out, size_t _len)
+{
+    unsigned int totalDataRead = 0;
+    do {
+        int dataRead = recv(pStream->mSocket, ((char*)_out) + totalDataRead, (int)_len - totalDataRead, 0);
+        if (dataRead == SOCKET_ERROR) {
+            pStream->mErrorNum = GLV_WSAGetLastError();
+            if (pStream->mErrorNum == WSAEWOULDBLOCK || pStream->mErrorNum == EAGAIN) {
+                if (totalDataRead == 0) {
+                    return FALSE;
+                } else {
+                    // I don't do partial reads--once I start receiving I wait for everything.
+                    glv_LogDebug("Sleep on partial socket recv (%u bytes / %u), error num %d\n", totalDataRead, _len, pStream->mErrorNum);
+                    Sleep(1);
+                }
+                // I've split these into two blocks because one of them is expected and the other isn't.
+            } else if (pStream->mErrorNum == WSAECONNRESET) {
+                // The remote client disconnected, probably not an issue.
+                return FALSE;
+            } else {
+                // Some other wonky network error--place a breakpoint here.
+                glv_LogError("Unexpected error (%d) while receiving message stream\n", pStream->mErrorNum);
+                return FALSE;
+            }
+        } else {
+            totalDataRead += dataRead;
+        }
+    } while (totalDataRead < _len);
+
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_MessageStream_BlockingRecv(MessageStream* pStream, void* _outBuffer, size_t _len)
+{
+    while (!glv_MessageStream_Recv(pStream, _outBuffer, _len)) {
+        Sleep(1);
+    }
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+SimpleBuffer* glv_SimpleBuffer_create(size_t _bufferSize)
+{
+    SimpleBuffer* pBuffer = GLV_NEW(SimpleBuffer);
+    pBuffer->mBuffer = (unsigned char*)glv_malloc(_bufferSize);
+    if (pBuffer->mBuffer == NULL)
+    {
+        GLV_DELETE(pBuffer);
+        return NULL;
+    }
+
+    pBuffer->mEnd = 0;
+    pBuffer->mSize = _bufferSize;
+
+    return pBuffer;
+}
+
+void glv_SimpleBuffer_destroy(SimpleBuffer** ppBuffer)
+{
+    glv_free((*ppBuffer)->mBuffer);
+    GLV_DELETE(*ppBuffer);
+}
+
+BOOL glv_SimpleBuffer_AddBytes(SimpleBuffer* pBuffer, const void* _bytes, size_t _size)
+{
+    if (glv_SimpleBuffer_WouldOverflow(pBuffer, _size))
+    { 
+        return FALSE;
+    }
+
+    memcpy((unsigned char*)pBuffer->mBuffer + pBuffer->mEnd, _bytes, _size);
+    pBuffer->mEnd += _size;
+
+    return TRUE;
+}
+
+void glv_SimpleBuffer_EmptyBuffer(SimpleBuffer* pBuffer)
+{
+    pBuffer->mEnd = 0;
+}
+
+BOOL glv_SimpleBuffer_WouldOverflow(SimpleBuffer* pBuffer, size_t _requestedSize)
+{
+    return pBuffer->mEnd + _requestedSize > pBuffer->mSize;
+}
+
+const void* glv_SimpleBuffer_GetBytes(SimpleBuffer* pBuffer, size_t* _outByteCount)
+{
+    (*_outByteCount) = pBuffer->mEnd; 
+    return pBuffer->mBuffer; 
+}
+
+//// ------------------------------------------------------------------------------------------------
+//void RemoteCommand::Read(FileLike* _fileLike)
+//{
+//    unsigned int myCommand = 0;
+//    _fileLike->Read(&myCommand);
+//    mRemoteCommandType = (EnumRemoteCommand)myCommand;
+//}
+//
+//// ------------------------------------------------------------------------------------------------
+//void RemoteCommand::Write(FileLike* _fileLike) const
+//{
+//    _fileLike->Write((unsigned int)mRemoteCommandType);
+//}
diff --git a/tools/glave/src/glvcommon/glv_interconnect.h b/tools/glave/src/glvcommon/glv_interconnect.h
new file mode 100644
index 0000000..d7677c4
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_interconnect.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#pragma once
+
+#include <errno.h>
+#include "glv_common.h"
+
+#if defined(PLATFORM_POSIX)
+    #include <arpa/inet.h>
+    #include <netdb.h>
+    #include <netinet/in.h>
+    #include <netinet/tcp.h>
+    #include <sys/socket.h>
+    #define SOCKET int
+    #define INVALID_SOCKET 0
+    #define SOCKET_ERROR -1
+    #define closesocket close
+    #define GLV_WSAGetLastError() errno
+    #define WSAEWOULDBLOCK EWOULDBLOCK
+    #define WSAEAGAIN EAGAIN
+    #define WSAECONNRESET ECONNRESET
+#elif defined(WIN32)
+    #include <WinSock2.h>
+    #include <WS2tcpip.h>
+    #pragma comment (lib, "Ws2_32.lib")
+    #define GLV_WSAGetLastError() WSAGetLastError()
+#endif
+
+static const unsigned int GLV_BASE_PORT = 34199;
+struct SSerializeDataPacket;
+
+struct SimpleBuffer;
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+typedef struct MessageStream
+{
+    SOCKET mSocket;
+    struct addrinfo* mHostAddressInfo;
+    size_t mNextPacketId;
+    struct SimpleBuffer* mSendBuffer;
+
+    // Used if someone asks for a receive of a small string.
+    char mSmallBuffer[64];
+
+    char mAddress[64];
+
+    char mPort[8];
+
+    BOOL mHost;
+    int mErrorNum;
+} MessageStream;
+
+MessageStream* glv_MessageStream_create_port_string(BOOL _isHost, const char* _address, const char* _port);
+MessageStream* glv_MessageStream_create(BOOL _isHost, const char* _address, unsigned int _port);
+void glv_MessageStream_destroy(MessageStream** ppStream);
+BOOL glv_MessageStream_BufferedSend(MessageStream* pStream, const void* _bytes, size_t _size, BOOL _optional);
+BOOL glv_MessageStream_Send(MessageStream* pStream, const void* _bytes, size_t _len);
+
+BOOL glv_MessageStream_Recv(MessageStream* pStream, void* _out, size_t _len);
+BOOL glv_MessageStream_BlockingRecv(MessageStream* pStream, void* _outBuffer, size_t _len);
+
+extern MessageStream* gMessageStream;
+
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------------------------
+typedef struct SimpleBuffer
+{
+    void* mBuffer;
+    size_t mEnd;
+    size_t mSize;
+} SimpleBuffer;
+
+SimpleBuffer* glv_SimpleBuffer_create(size_t _bufferSize);
+void glv_SimpleBuffer_destroy(SimpleBuffer** ppBuffer);
+BOOL glv_SimpleBuffer_AddBytes(SimpleBuffer* pBuffer, const void* _bytes, size_t _size);
+void glv_SimpleBuffer_EmptyBuffer(SimpleBuffer* pBuffer);
+BOOL glv_SimpleBuffer_WouldOverflow(SimpleBuffer* pBuffer, size_t _requestedSize);
+const void* glv_SimpleBuffer_GetBytes(SimpleBuffer* pBuffer, size_t* _outByteCount);
diff --git a/tools/glave/src/glvcommon/glv_memory.h b/tools/glave/src/glvcommon/glv_memory.h
new file mode 100644
index 0000000..6cba374
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_memory.h
@@ -0,0 +1,162 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#define GLV_NEW(type) (type*)glv_malloc(sizeof(type))
+#define GLV_NEW_ARRAY(type, count) (type*)glv_malloc(sizeof(type)*count)
+#define GLV_DELETE(ptr) glv_free(ptr);
+#define GLV_REALLOC(ptr, size) glv_realloc(ptr, size);
+
+static void* glv_malloc(size_t size)
+{
+    void* pMem;
+    if (size == 0)
+        return NULL;
+
+    pMem = malloc(size);
+    if (pMem != NULL)
+    {
+        memset(pMem, 0, size);
+    }
+
+    return pMem;
+}
+
+static void glv_free(void* ptr)
+{
+    free(ptr);
+    ptr = NULL;
+}
+
+static void * glv_realloc(void *ptr,size_t size)
+{
+    void *pMem;
+    if (size == 0)
+        return NULL;
+
+    pMem = realloc(ptr, size);
+    if (pMem != NULL)
+    {
+        memset(pMem, 0, size);
+    }
+    return pMem;
+}
+
+static char* glv_allocate_and_copy(const char* _src)
+{
+    if (_src == NULL)
+    {
+        return NULL;
+    }
+    else
+    {
+        size_t bufferSize = 1 + strlen(_src);
+
+        char* retVal = GLV_NEW_ARRAY(char, bufferSize);
+#ifdef WIN32
+        strcpy_s(retVal, bufferSize, _src);
+#else // linux
+        strncpy(retVal, _src, bufferSize);
+#endif
+
+        return retVal;
+    }
+}
+
+static char* glv_allocate_and_copy_n(const char* _src, int _count)
+{
+    size_t bufferSize = 1 + _count;
+
+    char* retVal = GLV_NEW_ARRAY(char, bufferSize);
+
+#ifdef WIN32
+    strncpy_s(retVal, bufferSize, _src, _count);
+#else // linux
+    strncpy(retVal, _src, bufferSize);
+#endif
+
+    return retVal;
+}
+
+static char* glv_copy_and_append(const char* pBaseString, const char* pSeparator, const char* pAppendString)
+{
+    size_t baseSize = (pBaseString != NULL) ? strlen(pBaseString) : 0;
+    size_t separatorSize = (pSeparator != NULL) ? strlen(pSeparator) : 0;
+    size_t appendSize = (pAppendString != NULL) ? strlen(pAppendString) : 0;
+    size_t bufferSize = baseSize + separatorSize + appendSize + 1;
+    char* retVal = GLV_NEW_ARRAY(char, bufferSize);
+    if (retVal != NULL)
+    {
+#ifdef WIN32
+        strncpy_s(retVal, bufferSize, pBaseString, baseSize);
+        strncpy_s(&retVal[baseSize], bufferSize-baseSize, pSeparator, separatorSize);
+        strncpy_s(&retVal[baseSize+separatorSize], bufferSize-baseSize-separatorSize, pAppendString, appendSize);
+#else // linux
+        strncpy(retVal, pBaseString, baseSize);
+        strncpy(&retVal[baseSize], pSeparator, separatorSize);
+        strncpy(&retVal[baseSize+separatorSize], pAppendString, appendSize);
+#endif
+    }
+    return retVal;
+}
+
+static char* glv_copy_and_append_args(const char* pBaseString, const char* pSeparator, const char* pAppendFormat, va_list args)
+{
+    size_t baseSize = (pBaseString != NULL) ? strlen(pBaseString) : 0;
+    size_t separatorSize = (pSeparator != NULL) ? strlen(pSeparator) : 0;
+    size_t appendSize = 0;
+    size_t bufferSize = 0;
+    char* retVal = NULL;
+
+#if defined(WIN32)
+    appendSize = _vscprintf(pAppendFormat, args);
+#elif defined(PLATFORM_LINUX)
+    va_list argcopy;
+    va_copy(argcopy, args);
+    appendSize = vsnprintf(NULL, 0, pAppendFormat, argcopy);
+    va_end(argcopy);
+#endif
+
+    bufferSize = baseSize + separatorSize + appendSize + 1;
+    retVal = GLV_NEW_ARRAY(char, bufferSize);
+    if (retVal != NULL)
+    {
+#ifdef WIN32
+        strncpy_s(retVal, bufferSize, pBaseString, baseSize);
+        strncpy_s(&retVal[baseSize], bufferSize-baseSize, pSeparator, separatorSize);
+        _vsnprintf_s(&retVal[baseSize+separatorSize], bufferSize-baseSize-separatorSize, appendSize, pAppendFormat, args);
+#else // linux
+        strncpy(retVal, pBaseString, baseSize);
+        strncpy(&retVal[baseSize], pSeparator, separatorSize);
+        vsnprintf(&retVal[baseSize+separatorSize], appendSize, pAppendFormat, args);
+#endif
+    }
+    return retVal;
+}
+
diff --git a/tools/glave/src/glvcommon/glv_mhook.h b/tools/glave/src/glvcommon/glv_mhook.h
new file mode 100644
index 0000000..e97f6b2
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_mhook.h
@@ -0,0 +1,35 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "mhook/mhook-lib/mhook.h"
+#include "glv_tracelog.h"
+#include <stdio.h>
+
+#define GLV_MHOOK_SETHOOK(entrypoint) Mhook_SetHook((PVOID*)&real_##entrypoint, hooked_##entrypoint); \
+    if (hookSuccess == FALSE) { glv_LogError("Failed to hook " #entrypoint "\n"); }
+
+#define GLV_MHOOK_UNHOOK(entrypoint) Mhook_Unhook((PVOID*)&real_##entrypoint); \
+    if (unhookSuccess == FALSE) { printf("Failed to unhook " #entrypoint "\n"); }
diff --git a/tools/glave/src/glvcommon/glv_platform.c b/tools/glave/src/glvcommon/glv_platform.c
new file mode 100644
index 0000000..ff01d86
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_platform.c
@@ -0,0 +1,368 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glv_platform.h"
+
+#if defined(PLATFORM_LINUX)
+#include "glv_common.h"
+#include <pthread.h>
+#endif
+
+glv_process_id glv_get_pid()
+{
+#if defined(PLATFORM_LINUX)
+    return getpid();
+#elif defined(WIN32)
+    return GetCurrentProcessId();
+#endif
+}
+
+char* glv_platform_get_current_executable_directory()
+{
+    char* exePath = (char*)glv_malloc(_MAX_PATH);
+#if defined(WIN32)
+    DWORD s = GetModuleFileName(NULL, exePath, MAX_PATH);
+#elif defined(PLATFORM_LINUX)
+    ssize_t s = readlink("/proc/self/exe", exePath, _MAX_PATH);
+    if (s >= 0)
+    {
+        exePath[s] = '\0';
+    }
+    else
+    {
+        exePath[0] = '\0';
+    }
+#endif
+
+    while (s > 0)
+    {
+        if (exePath[s] == '/' || exePath[s] == '\\')
+        {
+            // NULL this location and break so that the shortened string can be returned.
+            exePath[s] = '\0';
+            break;
+        }
+
+        --s;
+    }
+
+    if (s <= 0)
+    {
+        assert(!"Unexpected path returned in glv_platform_get_current_executable_directory");
+        glv_free(exePath);
+        exePath = NULL;
+    }
+
+    return exePath;
+}
+
+BOOL glv_is_loaded_into_glvtrace()
+{
+    char exePath[_MAX_PATH];
+
+#if defined(WIN32)
+    char* substr = ((sizeof(void*) == 4)? "glvtrace32.exe" : "glvtrace64.exe");
+    GetModuleFileName(NULL, exePath, MAX_PATH);
+#elif defined(PLATFORM_LINUX)
+    char* substr = ((sizeof(void*) == 4)? "glvtrace32" : "glvtrace64");
+    ssize_t s = readlink("/proc/self/exe", exePath, _MAX_PATH);
+    if (s >= 0)
+    {
+        exePath[s] = '\0';
+    }
+    else
+    {
+        exePath[0] = '\0';
+    }
+#endif
+    return (strstr(exePath, substr) != NULL);
+}
+
+BOOL glv_platform_get_next_lib_sym(void * *ppFunc, const char * name)
+{
+#if defined(PLATFORM_LINUX)
+    if ((*ppFunc = dlsym(RTLD_NEXT, name)) == NULL) {
+         glv_LogError("dlsym: failed to find symbol %s %s\n", name, dlerror());
+         return FALSE;
+    }
+#elif defined(WIN32)
+    glv_LogError("unimplemented");
+    assert(0);
+    return FALSE;
+#endif
+   return TRUE;
+}
+
+glv_thread_id glv_platform_get_thread_id()
+{
+#if defined(PLATFORM_LINUX)
+    //return (glv_thread_id)syscall(SYS_gettid);
+    return pthread_self();
+#elif defined(WIN32)
+    return GetCurrentThreadId();
+#endif
+}
+
+size_t glv_platform_rand_s(uint32_t* out_array, size_t out_array_length)
+{
+#if defined(PLATFORM_LINUX)
+    static __thread unsigned int s_seed = 0;
+    size_t i = 0;
+
+    if (s_seed == 0)
+    {
+        // Try to seed rand_r() with /dev/urandom.
+        size_t nbytes = 0;
+        int fd = open("/dev/urandom", O_RDONLY);
+        if (fd != -1)
+        {
+            nbytes = read(fd, &s_seed, sizeof(s_seed));
+            close(fd);
+        }
+
+        // If that didn't work, fallback to time and thread id.
+        if (nbytes != sizeof(s_seed))
+        {
+            struct timeval time;
+            gettimeofday(&time, NULL);
+            s_seed = glv_platform_get_thread_id() ^ ((time.tv_sec * 1000) + (time.tv_usec / 1000));
+        }
+    }
+
+    for (i = 0; i < out_array_length; ++i)
+    {
+        out_array[i] = rand_r(&s_seed);
+    }
+
+    return out_array_length;
+#elif defined(WIN32)
+    //GLV_ASSUME(sizeof(uint32_t) == sizeof(unsigned int));
+
+    size_t ret_values = 0;
+    for (ret_values = 0; ret_values < out_array_length; ++ret_values)
+    {
+        if (FAILED(rand_s(&out_array[ret_values])))
+            return ret_values;
+    }
+
+    return ret_values;
+#endif
+}
+
+void * glv_platform_open_library(const char* libPath)
+{
+#if defined(WIN32)
+    return LoadLibrary(libPath);
+#elif defined(PLATFORM_LINUX)
+    return dlopen(libPath, RTLD_LAZY);
+#endif
+}
+
+void * glv_platform_get_library_entrypoint(void * libHandle, const char *name)
+{
+
+#ifdef WIN32
+    FARPROC proc = GetProcAddress((HMODULE)libHandle, name);
+    if (!proc)
+        glv_LogError("Failed to find symbol %s in library handle %p\n", name, libHandle);
+#else
+    void * proc = dlsym(libHandle, name);
+    if (!proc)
+        glv_LogError("Failed to find symbol %s in library handle %p, err %s\n", name, libHandle, dlerror());
+#endif
+    assert(libHandle);
+    return proc;
+}
+
+void glv_platform_close_library(void* pLibrary)
+{
+#if defined(WIN32)
+    FreeLibrary((HMODULE)pLibrary);
+#elif defined(PLATFORM_LINUX)
+    dlclose(pLibrary);
+#endif
+}
+
+void glv_platform_full_path(const char* partPath, unsigned long bytes, char* buffer)
+{
+    assert(buffer != NULL);
+#if defined(WIN32)
+    GetFullPathName(partPath, bytes, buffer, NULL);
+#elif defined(PLATFORM_LINUX)
+    realpath(partPath, buffer);
+#endif
+}
+
+char* glv_platform_extract_path(char* _path)
+{
+    // These functions actually work on const strings, but the C decl version exposed by the macro 
+    // takes non-const TCHAR*.
+    char* pDir;
+    size_t newLen;
+    char* pathSepBack = strrchr(_path, '\\');
+    char* pathSepFor = strrchr(_path, '/');
+    char* lastPathSep = pathSepBack > pathSepFor ? pathSepBack : pathSepFor;
+
+    if (lastPathSep == NULL)
+    {
+        return ".\\";
+    }
+
+    pDir = GLV_NEW_ARRAY(char, strlen(_path) + 1);
+    newLen = strlen(_path) - strlen(lastPathSep);
+    strncpy(pDir, _path, newLen);
+    pDir[newLen + 1] = '\0';
+    return pDir;
+}
+
+glv_thread glv_platform_create_thread(GLV_THREAD_ROUTINE_RETURN_TYPE(*start_routine)(LPVOID), void* args)
+{
+#if defined(PLATFORM_LINUX)
+    glv_thread thread = 0;
+    if(pthread_create(&thread, NULL, (void *(*) (void*)) start_routine, args) != 0)
+    {
+        glv_LogError("Failed to create thread");
+    }
+    return thread;
+#elif defined(WIN32)
+    return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, args, 0, NULL);
+#endif
+}
+
+void glv_platform_resume_thread(glv_thread* pThread)
+{
+    assert(pThread != NULL);
+#if defined(PLATFORM_LINUX)
+    assert(!"Add code to resume threads on Linux");
+#elif defined(WIN32)
+    assert(*pThread != NULL);
+    ResumeThread(*pThread);
+#endif
+}
+
+void glv_platform_sync_wait_for_thread(glv_thread* pThread)
+{
+    assert(pThread != NULL);
+#if defined(PLATFORM_LINUX)
+    if (pthread_join(*pThread, NULL) != 0)
+#else
+    if (WaitForSingleObject(*pThread, INFINITE) != WAIT_OBJECT_0)
+#endif
+    {
+        glv_LogError("Error occurred while waiting for thread to end.\n");
+    }
+}
+
+void glv_platform_delete_thread(glv_thread* pThread)
+{
+    assert(pThread != NULL);
+#if defined(PLATFORM_LINUX)
+    // Don't have to do anything!
+#elif defined(WIN32)
+    CloseHandle(*pThread);
+    *pThread = NULL;
+#endif
+}
+
+void glv_create_critical_section(GLV_CRITICAL_SECTION* pCriticalSection)
+{
+#if defined(WIN32)
+    InitializeCriticalSection(pCriticalSection);
+#elif defined(PLATFORM_LINUX)
+    pthread_mutex_init(pCriticalSection, NULL);
+#endif
+}
+
+void glv_enter_critical_section(GLV_CRITICAL_SECTION* pCriticalSection)
+{
+#if defined(WIN32)
+    EnterCriticalSection(pCriticalSection);
+#elif defined(PLATFORM_LINUX)
+    pthread_mutex_lock(pCriticalSection);
+#endif
+}
+
+void glv_leave_critical_section(GLV_CRITICAL_SECTION* pCriticalSection)
+{
+#if defined(WIN32)
+    LeaveCriticalSection(pCriticalSection);
+#elif defined(PLATFORM_LINUX)
+    pthread_mutex_unlock(pCriticalSection);
+#endif
+}
+
+void glv_delete_critical_section(GLV_CRITICAL_SECTION* pCriticalSection)
+{
+#if defined(WIN32)
+    DeleteCriticalSection(pCriticalSection);
+#elif defined(PLATFORM_LINUX)
+    pthread_mutex_destroy(pCriticalSection);
+#endif
+}
+
+BOOL glv_platform_remote_load_library(glv_process_handle pProcessHandle, const char* dllPath, glv_thread* pTracingThread, char ** ldPreload)
+{
+#if defined(WIN32)
+    SIZE_T bytesWritten = 0;
+    void* targetProcessMem = NULL;
+    glv_thread thread = NULL;
+    size_t byteCount = sizeof(char) * (strlen(dllPath) + 1);
+    targetProcessMem = VirtualAllocEx(pProcessHandle, 0, byteCount, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+    if (!targetProcessMem)
+    {
+        glv_LogError("Failed to inject ourselves into target process--couldn't allocate process memory.\n");
+        return FALSE;
+    }
+
+    if (!WriteProcessMemory(pProcessHandle, targetProcessMem, dllPath, byteCount, &bytesWritten))
+    {
+        glv_LogError("Failed to inject ourselves into target process--couldn't write inception DLL name into process.\n");
+        return FALSE;
+    }
+
+    thread = CreateRemoteThread(pProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibrary, targetProcessMem, 0, NULL);
+    if (thread == NULL)
+    {
+        glv_LogError("Failed to inject ourselves into target process--couldn't spawn thread.\n");
+        return FALSE;
+    }
+    assert(pTracingThread != NULL);
+    *pTracingThread = thread;
+
+#elif defined(PLATFORM_LINUX)
+    char *tmp;
+    if (*ldPreload == NULL)
+    {
+        tmp = glv_copy_and_append("LD_PRELOAD", "=", dllPath);
+    }
+    else
+    {
+        tmp = glv_copy_and_append(*ldPreload, " ", dllPath);
+        GLV_DELETE((void*)*ldPreload);
+    }
+    *ldPreload = tmp;
+#endif
+
+    return TRUE;
+}
diff --git a/tools/glave/src/glvcommon/glv_platform.h b/tools/glave/src/glvcommon/glv_platform.h
new file mode 100644
index 0000000..ca03718
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_platform.h
@@ -0,0 +1,116 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+
+#if defined(PLATFORM_LINUX)
+#define _GNU_SOURCE 1
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <spawn.h>
+#include <sys/syscall.h>
+#include <sys/time.h>
+#include <sys/prctl.h>
+#include <dlfcn.h>
+#include "wintypes.h"
+#define APIENTRY
+#define Sleep(n) usleep(n * 1000)
+#define GLV_WINAPI
+typedef pthread_t glv_thread;
+typedef pid_t glv_process_handle;
+typedef pid_t glv_thread_id;
+typedef pid_t glv_process_id;
+typedef unsigned int GLV_THREAD_ROUTINE_RETURN_TYPE;
+typedef pthread_mutex_t GLV_CRITICAL_SECTION;
+#define GLV_NULL_THREAD 0
+#define _MAX_PATH PATH_MAX
+
+#elif defined(WIN32)
+#define _CRT_RAND_S
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+#include <tchar.h>
+#define GLV_WINAPI WINAPI
+typedef HANDLE glv_thread;
+typedef HANDLE glv_process_handle;
+typedef DWORD glv_thread_id;
+typedef DWORD glv_process_id;
+typedef DWORD GLV_THREAD_ROUTINE_RETURN_TYPE;
+typedef CRITICAL_SECTION GLV_CRITICAL_SECTION;
+#define GLV_NULL_THREAD NULL
+#endif
+
+#if defined(WIN32)
+#include "glv_common.h"
+#endif
+
+// return the process ID of current process
+glv_process_id glv_get_pid();
+
+// Get the path of the currently running executable.
+// The string returned must be freed by the caller.
+char* glv_platform_get_current_executable_directory();
+
+// Determine if the current process is glvtrace[32|64]
+BOOL glv_is_loaded_into_glvtrace();
+
+// Get the thread id for this thread.
+glv_thread_id glv_platform_get_thread_id();
+
+// Provides out_array_length uint32s of random data from a secure service
+size_t glv_platform_rand_s(uint32_t* out_array, size_t byteCount);
+
+// Alternatives to loading libraries, getting proc addresses, etc
+void * glv_platform_open_library(const char* libPath);
+void * glv_platform_get_library_entrypoint(void * libHandle, const char *name);
+void glv_platform_close_library(void* plibrary);
+BOOL glv_platform_get_next_lib_sym(void * *ppFunc, const char * name);
+
+// Returns the partial path appended to the current directory to provide a full path.
+// Note the resulting string may not point to an existing file.
+void glv_platform_full_path(const char* partPath, unsigned long bytes, char* buffer);
+
+// returns a newly allocated string which contains just the directory structure of the supplied file path.
+char* glv_platform_extract_path(char* _path);
+
+glv_thread glv_platform_create_thread(GLV_THREAD_ROUTINE_RETURN_TYPE(*start_routine)(LPVOID), void* args);
+void glv_platform_resume_thread(glv_thread* pThread);
+void glv_platform_sync_wait_for_thread(glv_thread* pThread);
+void glv_platform_delete_thread(glv_thread* pThread);
+
+void glv_create_critical_section(GLV_CRITICAL_SECTION* pCriticalSection);
+void glv_enter_critical_section(GLV_CRITICAL_SECTION* pCriticalSection);
+void glv_leave_critical_section(GLV_CRITICAL_SECTION* pCriticalSection);
+void glv_delete_critical_section(GLV_CRITICAL_SECTION* pCriticalSection);
+
+#if defined(PLATFORM_LINUX)
+#define GLV_LIBRARY_NAME(projname) (sizeof(void*) == 4)? "lib"#projname"32.so" : "lib"#projname"64.so"
+#endif
+#if defined(WIN32)
+#define GLV_LIBRARY_NAME(projname) (sizeof(void*) == 4)? #projname"32.dll" : #projname"64.dll"
+#endif
+
+BOOL glv_platform_remote_load_library(glv_process_handle pProcessHandle, const char* dllPath, glv_thread* pTracingThread, char **ldPreload);
diff --git a/tools/glave/src/glvcommon/glv_process.c b/tools/glave/src/glvcommon/glv_process.c
new file mode 100644
index 0000000..9d4e221
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_process.c
@@ -0,0 +1,175 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glv_process.h"
+
+
+BOOL glv_process_spawn(glv_process_info* pInfo)
+{
+    assert(pInfo != NULL);
+
+#if defined(WIN32)
+    {
+    unsigned long processCreateFlags = CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED;
+    char fullExePath[_MAX_PATH];
+    PROCESS_INFORMATION processInformation;
+    STARTUPINFO si = { 0 };
+    si.cb = sizeof(si);
+
+    memset(&processInformation, 0, sizeof(PROCESS_INFORMATION));
+    memset(fullExePath, 0, sizeof(char)*_MAX_PATH);
+    fullExePath[0] = 0;
+
+    SetLastError(0);
+    SearchPath(NULL, pInfo->exeName, ".exe", ARRAYSIZE(fullExePath), fullExePath, NULL);
+
+    if (!CreateProcess(fullExePath, pInfo->processArgs, NULL, NULL, TRUE,
+        processCreateFlags, NULL, pInfo->workingDirectory,
+        &si, &processInformation))
+    {
+        glv_LogError("Failed to inject ourselves into target process--couldn't spawn '%s'.\n", fullExePath);
+        return FALSE;
+    }
+
+    pInfo->hProcess = processInformation.hProcess;
+    pInfo->hThread = processInformation.hThread;
+    pInfo->processId = processInformation.dwProcessId;
+    pInfo->hThread = processInformation.hThread;
+    }
+#elif defined(PLATFORM_LINUX)
+    pInfo->processId = fork();
+    if (pInfo->processId == -1)
+    {
+        glv_LogError("Failed to spawn process.\n");
+        return FALSE;
+    }
+    else if (pInfo->processId == 0)
+    {
+        char *envp[5];
+        envp[0] = pInfo->processLDPreload;
+        envp[4] = (char *) (NULL);
+        static char default_disp[] = "DISPLAY=:0";
+        char * libxgl_drivers_path = (char *) (NULL);
+        char * env_display = (char *) NULL;
+        char * ld_library_path = (char *) NULL;
+
+        // inside new process
+        // change process name so the the tracer DLLs will behave as expected when loaded.
+        // NOTE: Must be 15 characters or less.
+        const char * tmpProcName = "glvChildProcess";
+        prctl(PR_SET_NAME, (unsigned long)tmpProcName, 0, 0, 0);
+
+        // change working directory
+        if (chdir(pInfo->workingDirectory) == -1)
+        {
+            glv_LogError("Failed to set working directory.\n");
+        }
+
+        env_display = getenv("DISPLAY");
+        if (env_display != NULL)
+        {
+            char *disp = malloc(strlen(env_display) + strlen("DISPLAY=") + 1);
+            if (disp == NULL)
+                glv_LogError("Failed to malloc for env_display in glv_process_spawn().\n");
+            snprintf(disp, strlen(env_display) + strlen("DISPLAY=") + 1, "DISPLAY=%s", env_display);
+
+            envp[1] = disp;
+        } else
+        {
+            envp[1] = default_disp;
+        }
+
+        // TODO this needs to be generalized for other drivers
+        libxgl_drivers_path = getenv("LIBXGL_DRIVERS_PATH");
+        if (libxgl_drivers_path == NULL)
+        {
+            glv_LogWarn("LIBXGL_DRIVERS_PATH env var was not set. We recommend that you set it.\n");
+            envp[2] = NULL;
+        }
+        else
+        {
+            char *dPath = malloc(strlen(libxgl_drivers_path) + strlen("LIBXGL_DRIVERS_PATH=") + 1);
+            if (dPath == NULL)
+                glv_LogError("Failed to malloc in glv_process_spawn().\n");
+            snprintf(dPath, strlen(libxgl_drivers_path) + strlen("LIBXGL_DRIVERS_PATH=") + 1, "LIBXGL_DRIVERS_PATH=%s", libxgl_drivers_path);
+            envp[2] = dPath;
+        }
+
+        ld_library_path = getenv("LD_LIBRARY_PATH");
+        if (ld_library_path != NULL)
+        {
+            char *ld_lib = malloc(strlen(ld_library_path) + strlen("LD_LIBRARY_PATH=") + 1);
+            if (ld_lib == NULL)
+                glv_LogError("Failed to malloc for LD_LIBRARY_PATH in glv_process_spawn().\n");
+            snprintf(ld_lib, strlen(ld_library_path) + strlen("LD_LIBRARY_PATH=") + 1, "LD_LIBRARY_PATH=%s", ld_library_path);
+
+            envp[3] = ld_lib;
+        } else
+        {
+            envp[3] = NULL;
+        }
+
+        glv_LogInfo("exec process=%s args=%s \n     env0:%s env2:%s env3:%s\n",
+                pInfo->exeName, pInfo->processArgs, (envp[0] == NULL) ? "" : envp[0],
+                (envp[2] == NULL) ? "" : envp[2],
+                (envp[3] == NULL) ? "" : envp[3]);
+        extern char **environ;
+        environ = envp;
+        if (execl(pInfo->exeName, pInfo->exeName, pInfo->processArgs, (char *) 0) < 0)
+        {
+            glv_LogError("Failed to spawn process.\n");
+            return FALSE;
+        }
+    }
+#endif
+
+    return TRUE;
+}
+
+void glv_process_info_delete(glv_process_info* pInfo)
+{
+    unsigned int i = 0;
+    if (pInfo->pCaptureThreads != NULL)
+    {
+        for (i = 0; i < pInfo->tracerCount; i++)
+        {
+            glv_platform_delete_thread(&(pInfo->pCaptureThreads[i].recordingThread));
+        }
+        GLV_DELETE(pInfo->pCaptureThreads);
+    }
+
+#ifdef WIN32
+    glv_platform_delete_thread(&(pInfo->watchdogThread));
+#endif
+
+    GLV_DELETE(pInfo->workingDirectory);
+    GLV_DELETE(pInfo->processArgs);
+    GLV_DELETE(pInfo->exeName);
+
+    if (pInfo->pTraceFile != NULL)
+    {
+        fclose(pInfo->pTraceFile);
+    }
+    glv_delete_critical_section(&(pInfo->traceFileCriticalSection));
+}
diff --git a/tools/glave/src/glvcommon/glv_process.h b/tools/glave/src/glvcommon/glv_process.h
new file mode 100644
index 0000000..ecf58f5
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_process.h
@@ -0,0 +1,76 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "glv_platform.h"
+#include "glv_trace_packet_identifiers.h"
+
+typedef struct glv_process_capture_trace_thread_info glv_process_capture_trace_thread_info;
+
+typedef struct glv_process_info
+{
+    char* exeName;
+    char* processArgs;
+    char* workingDirectory;
+    char* traceFilename;
+    FILE* pTraceFile;
+
+    // glvtrace's thread id
+    glv_thread_id parentThreadId;
+
+    GLV_CRITICAL_SECTION traceFileCriticalSection;
+
+    volatile BOOL serverRequestsTermination;
+
+    unsigned int tracerCount;
+    glv_process_capture_trace_thread_info* pCaptureThreads;
+
+    // process id, handle, and main thread
+    glv_process_id processId;
+    glv_process_handle hProcess;
+    glv_thread hThread;
+    glv_thread watchdogThread;
+    char* processLDPreload;
+} glv_process_info;
+
+
+typedef struct glv_process_tracer_dll
+{
+    char * dllPath;
+    BOOL bLoaded;
+    GLV_TRACER_ID tid;
+} glv_process_tracer_dll;
+
+struct glv_process_capture_trace_thread_info
+{
+    glv_thread tracingThread;
+    glv_thread recordingThread;
+    glv_process_info* pProcessInfo;
+    GLV_TRACER_ID tracerId;
+    char* tracerPath;
+};
+
+BOOL glv_process_spawn(glv_process_info* pInfo);
+void glv_process_info_delete(glv_process_info* pInfo);
diff --git a/tools/glave/src/glvcommon/glv_settings.c b/tools/glave/src/glvcommon/glv_settings.c
new file mode 100644
index 0000000..bb530ba
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_settings.c
@@ -0,0 +1,391 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glv_settings.h"
+
+// local functions
+void glv_SettingInfo_print(const glv_SettingInfo* pSetting);
+
+// ------------------------------------------------------------------------------------------------
+void glv_SettingInfo_print(const glv_SettingInfo* pSetting)
+{
+    if (pSetting->bPrintInHelp)
+    {
+        char * pStrParams;
+        if (pSetting->type == GLV_SETTING_STRING)
+        {
+            pStrParams = "<string>";
+        } else if (pSetting->type == GLV_SETTING_BOOL) {
+            pStrParams = "<BOOL>  ";
+        } else if (pSetting->type == GLV_SETTING_UINT) {
+            pStrParams = "<uint>  ";
+        } else if (pSetting->type == GLV_SETTING_INT) {
+            pStrParams = "<int>   ";
+        } else {
+            pStrParams = "< ??? > ";
+        }
+        printf("    -%s,--%s %s\t: %s\n", pSetting->pShortName, pSetting->pLongName, pStrParams, pSetting->pDesc);
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+void glv_SettingInfo_print_all(const glv_SettingInfo* pSettings, unsigned int num_settings)
+{
+    unsigned int i;
+
+    printf("Available options:\n");
+
+    for (i = 0; i < num_settings; i++)
+    {
+        glv_SettingInfo_print(&(pSettings[i]));
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+BOOL glv_SettingInfo_parse_value(glv_SettingInfo* pSetting, const char* arg)
+{
+    switch(pSetting->type)
+    {
+    case GLV_SETTING_STRING:
+        {
+            glv_free(*((char**)pSetting->pType_data));
+            *((char**)pSetting->pType_data) = glv_allocate_and_copy(arg);
+        }
+        break;
+    case GLV_SETTING_BOOL:
+        {
+            BOOL bTrue = FALSE;
+            bTrue = strncmp(arg, "true", 4) == 0 || strncmp(arg, "TRUE", 4) == 0 || strncmp(arg, "True", 4) == 0;
+            *(BOOL*)pSetting->pType_data = bTrue;
+        }
+        break;
+    case GLV_SETTING_UINT:
+        {
+            if (sscanf(arg, "%u", (unsigned int*)pSetting->pType_data) != 1)
+            {
+                printf("Invalid unsigned int setting: '%s'\n", arg);
+                return FALSE;
+            }
+        }
+        break;
+    case GLV_SETTING_INT:
+        {
+            if (sscanf(arg, "%d", (int*)pSetting->pType_data) != 1)
+            {
+                printf("Invalid int setting: '%s'\n", arg);
+                return FALSE;
+            }
+        }
+        break;
+    default:
+        assert(!"Unhandled setting type");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+// ------------------------------------------------------------------------------------------------
+void glv_SettingInfo_reset_default(glv_SettingInfo* pSetting)
+{
+    assert(pSetting != NULL);
+    switch(pSetting->type)
+    {
+    case GLV_SETTING_STRING:
+        if (pSetting->pType_data != NULL)
+        {
+            glv_free(*((char**)pSetting->pType_data));
+        }
+
+        if (pSetting->pType_default == NULL)
+        {
+            *((char**)pSetting->pType_data) = NULL;
+        }
+        else
+        {
+            *((char**)pSetting->pType_data) = glv_allocate_and_copy(*((const char**)pSetting->pType_default));
+        }
+        break;
+    case GLV_SETTING_BOOL:
+        *(BOOL*)pSetting->pType_data = *(BOOL*)pSetting->pType_default;
+        break;
+    case GLV_SETTING_UINT:
+        *(unsigned int*)pSetting->pType_data = *(unsigned int*)pSetting->pType_default;
+        break;
+    case GLV_SETTING_INT:
+        *(int*)pSetting->pType_data = *(int*)pSetting->pType_default;
+        break;
+    default:
+        assert(!"Unhandled GLV_SETTING_TYPE");
+        break;
+    }
+}
+
+// ------------------------------------------------------------------------------------------------
+int glv_SettingInfo_init_from_file(glv_SettingInfo* pSettings, unsigned int num_settings, const char* filename, char** ppOut_remaining_args)
+{
+    FILE* pFile = NULL;
+    int retVal = 0;
+
+    if (filename != NULL)
+    {
+        pFile = fopen(filename, "r");
+    }
+
+    if (pFile == NULL)
+    {
+        glv_LogWarn("Settings file not found: '%s'.\n", filename);
+    }
+    else
+    {
+        char* line = GLV_NEW_ARRAY(char, 1024);
+        if (line == NULL)
+        {
+            printf("Out of memory while reading settings file\n");
+        }
+        else
+        {
+            char name[MAX_PATH];
+            char value[MAX_PATH];
+            while (feof(pFile) == 0 && ferror(pFile) == 0)
+            {
+                line = fgets(line, 1024, pFile);
+                if (line == NULL)
+                {
+                    break;
+                }
+
+                // if line ends with a newline, then replace it with a NULL
+                if (line[strlen(line)-1] == '\n')
+                {
+                    line[strlen(line)-1] = '\0';
+                }
+
+                // if the line starts with "#" or "//", then consider it a comment and ignore it.
+                // if the first 'word' is only "-- " then the remainder of the line is for application arguments
+                // else first 'word' in line should be a long setting name and the rest of line is value for setting
+                if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
+                {
+                    // its a comment, continue to next loop iteration
+                    continue;
+                }
+                else if (strncmp(line, "-- ", 3) == 0 && ppOut_remaining_args != NULL)
+                {
+                    // remainder of line is for the application arguments
+                    const char* strValue = &line[3];
+                    if (*ppOut_remaining_args == NULL || strlen(*ppOut_remaining_args) == 0)
+                    {
+                        *ppOut_remaining_args = glv_allocate_and_copy(strValue);
+                    }
+                    else
+                    {
+                        char* tmp = glv_copy_and_append(*ppOut_remaining_args, " ", &line[3]);
+                        glv_free(*ppOut_remaining_args);
+                        *ppOut_remaining_args = tmp;
+                    }
+                }
+                else if (sscanf(line, "%s = %c", name, value) != 2)
+                {
+                    printf("Could not parse settings file due to line: '%s'\n", line);
+                    retVal = -1;
+                }
+                else
+                {
+                    const char* strValue = &line[strlen(name) + strlen(" = ")];
+
+                    // figure out which setting it was
+                    unsigned int settingIndex;
+                    glv_SettingInfo* pSetting = NULL;
+                    for (settingIndex = 0; settingIndex < num_settings; settingIndex++)
+                    {
+                        pSetting = &pSettings[settingIndex];
+
+                        if (strcmp(name, pSetting->pLongName) == 0)
+                        {
+                            if (glv_SettingInfo_parse_value(&pSettings[settingIndex], strValue) == FALSE)
+                            {
+                                retVal = -1;
+                            }
+                            break;
+                        }
+                        pSetting = NULL;
+                    }
+
+                    if (pSetting == NULL)
+                    {
+                        printf("No matching setting found for '%s' in line '%s'\n", name, line);
+                        retVal = -1;
+                    }
+                }
+
+                if (retVal == -1)
+                {
+                    break;
+                }
+            }
+        }
+
+        fclose(pFile);
+    }
+
+    return retVal;
+}
+
+int glv_SettingInfo_init_from_cmdline(glv_SettingInfo* pSettings, unsigned int num_settings, int argc, char* argv[], char** ppOut_remaining_args)
+{
+    int i = 0;
+
+    // update settings based on command line options
+    for (i = 1; i < argc; )
+    {
+        unsigned int settingIndex;
+        int consumed = 0;
+        char* curArg = argv[i];
+
+        // if the arg is only "--" then all following args are for the application;
+        // if the arg starts with "-" then it is referring to a short name;
+        // if the arg starts with "--" then it is referring to a long name.
+        if (strcmp("--", curArg) == 0 && ppOut_remaining_args != NULL)
+        {
+            // all remaining args are for the application
+
+            // increment past the current arg
+            i += 1;
+            consumed++;
+            for (; i < argc; i++)
+            {
+                if (*ppOut_remaining_args == NULL || strlen(*ppOut_remaining_args) == 0)
+                {
+                    *ppOut_remaining_args = glv_allocate_and_copy(argv[i]);
+                }
+                else
+                {
+                    *ppOut_remaining_args = glv_copy_and_append(*ppOut_remaining_args, " ", argv[i]);
+                }
+                consumed++;
+            }
+        }
+        else
+        {
+            for (settingIndex = 0; settingIndex < num_settings; settingIndex++)
+            {
+                const char* pSettingName = NULL;
+                curArg = argv[i];
+                if (strncmp("--", curArg, 2) == 0)
+                {
+                    // long option name
+                    pSettingName = pSettings[settingIndex].pLongName;
+                    curArg += 2;
+                }
+                else if (strncmp("-", curArg, 1) == 0)
+                {
+                    // short option name
+                    pSettingName = pSettings[settingIndex].pShortName;
+                    curArg += 1;
+                }
+
+                if (pSettingName != NULL && strcmp(curArg, pSettingName) == 0)
+                {
+                    if (glv_SettingInfo_parse_value(&pSettings[settingIndex], argv[i+1]))
+                    {
+                        consumed += 2;
+                    }
+                    break;
+                }
+            }
+        }
+
+        if (consumed == 0)
+        {
+            printf("Error: Invalid argument found '%s'\n", curArg);
+            glv_SettingInfo_print_all(pSettings, num_settings);
+            glv_SettingInfo_delete(pSettings, num_settings);
+            return -1;
+        }
+
+        i += consumed;
+    }
+
+    return 0;
+}
+
+// ------------------------------------------------------------------------------------------------
+int glv_SettingInfo_init(glv_SettingInfo* pSettings, unsigned int num_settings, const char* settingsfile, int argc, char* argv[], char** ppOut_remaining_args)
+{
+    unsigned int u;
+
+    if (pSettings == NULL || num_settings == 0)
+    {
+        assert(!"No need to call glv_SettingInfo_init if the application has no settings");
+        return 0;
+    }
+
+    if (argc == 2 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0))
+    {
+        glv_SettingInfo_print_all(pSettings, num_settings);
+        return -1;
+    }
+
+    // Initially, set all options to their defaults
+    for (u = 0; u < num_settings; u++)
+    {
+        glv_SettingInfo_reset_default(&pSettings[u]);
+    }
+
+    // Secondly set options based on settings file
+    if (glv_SettingInfo_init_from_file(pSettings, num_settings, settingsfile, ppOut_remaining_args) == -1)
+    {
+        glv_SettingInfo_print_all(pSettings, num_settings);
+        return -1;
+    }
+
+    // Thirdly set options based on cmd line args
+    if (glv_SettingInfo_init_from_cmdline(pSettings, num_settings, argc, argv, ppOut_remaining_args) == -1)
+    {
+        glv_SettingInfo_print_all(pSettings, num_settings);
+        return -1;
+    }
+
+    return 0;
+}
+
+// ------------------------------------------------------------------------------------------------
+void glv_SettingInfo_delete(glv_SettingInfo* pSettings, unsigned int num_settings)
+{
+    unsigned int i;
+
+    // need to delete all strings
+    for (i = 0; i < num_settings; i++)
+    {
+        if (pSettings[i].type == GLV_SETTING_STRING)
+        {
+            if (pSettings[i].pType_data != NULL)
+            {
+                glv_free(*((char**)pSettings[i].pType_data));
+                pSettings[i].pType_data = NULL;
+            }
+        }
+    }
+}
diff --git a/tools/glave/src/glvcommon/glv_settings.h b/tools/glave/src/glvcommon/glv_settings.h
new file mode 100644
index 0000000..864a93d
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_settings.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "glv_common.h"
+
+typedef enum GLV_SETTING_TYPE
+{
+    GLV_SETTING_STRING,
+    GLV_SETTING_BOOL,
+    GLV_SETTING_UINT,
+    GLV_SETTING_INT
+} GLV_SETTING_TYPE;
+
+// ------------------------------------------------------------------------------------------------
+typedef struct glv_SettingInfo
+{
+    const char* const pShortName;
+    const char* const pLongName;
+    GLV_SETTING_TYPE type;
+    void* pType_data;
+    const void * const pType_default;
+    BOOL bPrintInHelp;
+    const char* pDesc;
+} glv_SettingInfo;
+
+int glv_SettingInfo_init(glv_SettingInfo* pSettings, unsigned int num_settings, const char* settingsfile, int argc, char* argv[], char** ppOut_remaining_args);
+void glv_SettingInfo_delete(glv_SettingInfo* pSettings, unsigned int num_settings);
+
+void glv_SettingInfo_print_all(const glv_SettingInfo* pSettings, unsigned int num_settings);
+void glv_SettingInfo_reset_default(glv_SettingInfo* pSetting);
diff --git a/tools/glave/src/glvcommon/glv_trace_packet_identifiers.h b/tools/glave/src/glvcommon/glv_trace_packet_identifiers.h
new file mode 100644
index 0000000..5a9f40e
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_trace_packet_identifiers.h
@@ -0,0 +1,125 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "glv_common.h"
+#include "glv_tracelog.h"
+
+#define GLV_TRACE_FILE_VERSION_1 0x0001
+#define GLV_TRACE_FILE_VERSION GLV_TRACE_FILE_VERSION_1
+#define GLV_TRACE_FILE_VERSION_MINIMUM_COMPATIBLE GLV_TRACE_FILE_VERSION_1
+
+#define GLV_MAX_TRACER_ID_ARRAY_SIZE 16
+
+typedef enum GLV_TRACER_ID
+{
+    GLV_TID_RESERVED = 0,
+    GLV_TID_GL_FPS,
+    GLV_TID_MANTLE,
+    GLV_TID_XGL,
+    GLV_TID_MANTLE_PERF
+    // Max enum must be less than GLV_MAX_TRACER_ID_ARRAY_SIZE
+} GLV_TRACER_ID;
+
+typedef struct GLV_TRACER_REPLAYER_INFO
+{
+    GLV_TRACER_ID tracerId;
+    BOOL needsReplayer;
+    const char* const replayerLibraryName;
+} GLV_TRACER_REPLAYER_INFO;
+
+// The index here should match the value of the GLV_TRACER_ID
+static const GLV_TRACER_REPLAYER_INFO gs_tracerReplayerInfo[GLV_MAX_TRACER_ID_ARRAY_SIZE] = {
+    {GLV_TID_RESERVED, FALSE, ""},
+    {GLV_TID_GL_FPS, FALSE, ""},
+    {GLV_TID_MANTLE, TRUE, GLV_LIBRARY_NAME(glvreplay_mantle)},
+    {GLV_TID_XGL, TRUE, GLV_LIBRARY_NAME(glvreplay_xgl)},
+    {GLV_TID_MANTLE_PERF, FALSE, ""},
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+    {GLV_TID_RESERVED, FALSE, ""}, // this can be updated as new tracers are added
+};
+
+typedef enum _GLV_TRACE_PACKET_ID
+{
+    GLV_TPI_MESSAGE,
+    GLV_TPI_MARKER_CHECKPOINT,
+    GLV_TPI_MARKER_API_BOUNDARY,
+    GLV_TPI_MARKER_API_GROUP_BEGIN,
+    GLV_TPI_MARKER_API_GROUP_END,
+    GLV_TPI_MARKER_TERMINATE_PROCESS,
+    GLV_TPI_BEGIN_API_HERE // this enum should always be the last in the list. Feel free to insert new ID above this one.
+} GLV_TRACE_PACKET_ID;
+
+typedef struct {
+    uint16_t trace_file_version;
+    uint32_t uuid[4];
+    uint64_t first_packet_offset;   // will be size of header including size of tracer_id_array and state_snapshot_path/binary
+    uint8_t tracer_count;           // number of tracers referenced in this trace file
+    uint8_t tracer_id_array[GLV_MAX_TRACER_ID_ARRAY_SIZE]; // array of tracer_ids which are referenced in the trace file
+    uint8_t contains_state_snapshot; // bool (0 = false, 1 = true)
+    uint32_t state_snapshot_size;   // either length of state_snapshot_path or bytecount of state_snapshot_binary
+    intptr_t state_snapshot_path;   // char* array text path to snapshot file
+    intptr_t state_snapshot_binary; // byte array binary blob
+    // unsigned int pointer_sizes; // indicates whether app is 32-bit or 64-bit
+} glv_trace_file_header;
+
+typedef struct {
+    uint64_t size; // total size, including extra data, needed to get to the next packet_header
+    uint64_t global_packet_index;
+    uint8_t tracer_id; // TODO: need to uniquely identify tracers in a way that is known by the replayer
+    uint16_t packet_id; // GLV_TRACE_PACKET_ID (or one of the api-specific IDs)
+    uint64_t entrypoint_begin_time;
+    uint64_t entrypoint_end_time;
+    uint64_t next_buffers_offset; // used for tracking the addition of buffers to the trace packet
+    uintptr_t pBody; // points to the body of the packet
+} glv_trace_packet_header;
+
+typedef struct {
+    glv_trace_packet_header* pHeader;
+    TraceLogLevel type;
+    uint32_t length;
+    char* message;
+} glv_trace_packet_message;
+
+typedef struct {
+    glv_trace_packet_header* pHeader;
+    unsigned int length;
+    char* label;
+} glv_trace_packet_marker_checkpoint;
+
+typedef glv_trace_packet_marker_checkpoint glv_trace_packet_marker_api_boundary;
+typedef glv_trace_packet_marker_checkpoint glv_trace_packet_marker_api_group_begin;
+typedef glv_trace_packet_marker_checkpoint glv_trace_packet_marker_api_group_end;
+
+typedef GLV_TRACER_ID (APIENTRY *funcptr_GLV_GetTracerId)();
diff --git a/tools/glave/src/glvcommon/glv_trace_packet_utils.c b/tools/glave/src/glvcommon/glv_trace_packet_utils.c
new file mode 100644
index 0000000..d715c65
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_trace_packet_utils.c
@@ -0,0 +1,264 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glv_trace_packet_utils.h"
+#include "glv_interconnect.h"
+#include "glv_filelike.h"
+#ifdef WIN32
+#include <rpc.h>
+#pragma comment (lib, "Rpcrt4.lib")
+#endif
+
+#if defined(PLATFORM_LINUX)
+#include <fcntl.h>
+#include <time.h>
+#endif
+
+static uint64_t g_packet_index = 0;
+static int g_reliable_rdtsc = -1;
+
+void glv_gen_uuid(uint32_t* pUuid)
+{
+    uint32_t buf[] = { 0xABCDEF, 0x12345678, 0xFFFECABC, 0xABCDDEF0 };
+    glv_platform_rand_s(buf, sizeof(buf)/sizeof(uint32_t));
+    
+    pUuid[0] = buf[0];
+    pUuid[1] = buf[1];
+    pUuid[2] = buf[2];
+    pUuid[3] = buf[3];
+}
+
+BOOL glv_init_time()
+{
+#if defined(PLATFORM_LINUX)
+    if (g_reliable_rdtsc == -1)
+    {
+        g_reliable_rdtsc = 0;
+
+        FILE *file = fopen("/sys/devices/system/clocksource/clocksource0/current_clocksource", "r");
+        if (file)
+        {
+            char buf[64];
+
+            if (fgets(buf, sizeof(buf), file))
+            {
+                if (buf[0] == 't' && buf[1] == 's' && buf[2] == 'c')
+                    g_reliable_rdtsc = 1;
+            }
+
+            fclose(file);
+        }
+    }
+
+    // return true for reliable rdtsc.
+    return !!g_reliable_rdtsc;
+#else
+    return TRUE;
+#endif
+}
+
+uint64_t glv_get_time()
+{
+#if defined(VOGL_USE_LINUX_API)
+    extern int g_reliable_rdtsc;
+    if (g_reliable_rdtsc == -1)
+        init_rdtsc();
+    if (g_reliable_rdtsc == 0)
+    {
+        //$ TODO: Should just use SDL_GetPerformanceCounter?
+        struct timespec time;
+        clock_gettime(CLOCK_MONOTONIC, &time);
+        return ((uint64_t)time.tv_sec * 1000000000) + time.tv_nsec;
+    }
+#elif defined(COMPILER_GCCLIKE)
+    unsigned int hi, lo;
+    __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
+    return ((uint64_t)hi << 32) | lo;
+#else
+    return __rdtsc();
+#endif
+}
+
+//=============================================================================
+// trace file header
+
+glv_trace_file_header* glv_create_trace_file_header()
+{
+    glv_trace_file_header* pHeader = GLV_NEW(glv_trace_file_header);
+    memset(pHeader, 0, sizeof(glv_trace_file_header));
+    pHeader->trace_file_version = GLV_TRACE_FILE_VERSION;
+    glv_gen_uuid(pHeader->uuid);
+    pHeader->contains_state_snapshot = FALSE;
+    pHeader->state_snapshot_path = (intptr_t)NULL;
+    pHeader->state_snapshot_binary = (intptr_t)NULL;
+
+    return pHeader;
+}
+
+void glv_delete_trace_file_header(glv_trace_file_header** ppHeader)
+{
+    glv_free(*ppHeader);
+    *ppHeader = NULL;
+}
+
+//=============================================================================
+// Methods for creating, populating, and writing trace packets
+
+glv_trace_packet_header* glv_create_trace_packet(uint8_t tracer_id, uint16_t packet_id, uint64_t packet_size, uint64_t additional_buffers_size)
+{
+    // Always allocate at least enough space for the packet header
+    uint64_t total_packet_size = sizeof(glv_trace_packet_header) + packet_size + additional_buffers_size;
+    void* pMem = glv_malloc((size_t)total_packet_size);
+
+    glv_trace_packet_header* pHeader = (glv_trace_packet_header*)pMem;
+    pHeader->size = total_packet_size;
+    pHeader->global_packet_index = g_packet_index++;
+    pHeader->tracer_id = tracer_id;
+    pHeader->packet_id = packet_id;
+    pHeader->entrypoint_begin_time = glv_get_time();
+    pHeader->entrypoint_end_time = 0;
+    pHeader->next_buffers_offset = sizeof(glv_trace_packet_header) + packet_size; // initial offset is from start of header to after the packet body
+    if (total_packet_size > sizeof(glv_trace_packet_header))
+    {
+        pHeader->pBody = (uintptr_t)(((char*)pMem) + sizeof(glv_trace_packet_header));
+    }
+    return pHeader;
+}
+
+void glv_delete_trace_packet(glv_trace_packet_header** ppHeader)
+{
+    if (ppHeader == NULL)
+        return;
+    if (*ppHeader == NULL)
+        return;
+
+    GLV_DELETE(*ppHeader);
+    *ppHeader = NULL;
+}
+
+void* glv_trace_packet_get_new_buffer_address(glv_trace_packet_header* pHeader, uint64_t byteCount)
+{
+    void* pBufferStart;
+    assert(byteCount > 0);
+    assert(pHeader->size >= pHeader->next_buffers_offset + byteCount);
+    if (pHeader->size < pHeader->next_buffers_offset + byteCount || byteCount == 0)
+    {
+        // not enough memory left in packet to hold buffer
+        // or request is for 0 bytes
+        return NULL;
+    }
+
+    pBufferStart = (void*)((char*)pHeader + pHeader->next_buffers_offset);
+    pHeader->next_buffers_offset += byteCount;
+    return pBufferStart;
+}
+
+void glv_add_buffer_to_trace_packet(glv_trace_packet_header* pHeader, void** ptr_address, uint64_t size, const void* pBuffer)
+{
+    assert(ptr_address != NULL);
+    if (pBuffer == NULL || size == 0)
+    {
+        *ptr_address = NULL;
+    }
+    else
+    {
+        // set ptr to the location of the added buffer
+        *ptr_address = glv_trace_packet_get_new_buffer_address(pHeader, size);
+
+        // copy buffer to the location
+        memcpy(*ptr_address, pBuffer, (size_t)size);
+    }
+}
+
+void glv_finalize_buffer_address(glv_trace_packet_header* pHeader, void** ptr_address)
+{
+    assert(ptr_address != NULL);
+
+    if (*ptr_address != NULL)
+    {
+        // turn ptr into an offset from the packet body
+        uint64_t offset = (uint64_t)*ptr_address - (uint64_t) (pHeader->pBody);
+        *ptr_address = (void*)offset;
+    }
+}
+
+void glv_finalize_trace_packet(glv_trace_packet_header* pHeader)
+{
+    pHeader->entrypoint_end_time = glv_get_time();
+}
+
+void glv_write_trace_packet(const glv_trace_packet_header* pHeader, FileLike* pFile)
+{
+    glv_FileLike_WriteRaw(pFile, pHeader, (size_t)pHeader->size);
+}
+
+//=============================================================================
+// Methods for Reading and interpretting trace packets
+
+glv_trace_packet_header* glv_read_trace_packet(FileLike* pFile)
+{
+    // read size
+    // allocate space
+    // offset to after size
+    // read the rest of the packet
+    uint64_t total_packet_size = 0;
+    void* pMem;
+    glv_trace_packet_header* pHeader;
+
+    if (glv_FileLike_ReadRaw(pFile, &total_packet_size, sizeof(uint64_t)) == FALSE)
+    {
+        return NULL;
+    }
+
+    // allocate space
+    pMem = glv_malloc((size_t)total_packet_size);
+    pHeader = (glv_trace_packet_header*)pMem;
+
+    if (pHeader != NULL)
+    {
+        pHeader->size = total_packet_size;
+        if (glv_FileLike_ReadRaw(pFile, (char*)pHeader + sizeof(uint64_t), (size_t)total_packet_size - sizeof(uint64_t)) == FALSE)
+        {
+            return NULL;
+        }
+
+        pHeader->pBody = (uintptr_t)pHeader + sizeof(glv_trace_packet_header);
+    }
+
+    return pHeader;
+}
+
+void* glv_trace_packet_interpret_buffer_pointer(glv_trace_packet_header* pHeader, intptr_t ptr_variable)
+{
+    // the pointer variable actually contains a byte offset from the packet body to the start of the buffer.
+    uint64_t offset = ptr_variable;
+    void* buffer_location;
+
+    // if the offset is 0, then we know the pointer to the buffer was NULL, so no buffer exists and we return NULL.
+    if (offset == 0)
+        return NULL;
+
+    buffer_location = (char*)(pHeader->pBody) + offset;
+    return buffer_location;
+}
diff --git a/tools/glave/src/glvcommon/glv_trace_packet_utils.h b/tools/glave/src/glvcommon/glv_trace_packet_utils.h
new file mode 100644
index 0000000..f77b87b
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_trace_packet_utils.h
@@ -0,0 +1,149 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#include "glv_trace_packet_identifiers.h"
+#include "glv_filelike.h"
+#include "glv_memory.h"
+#include "glv_process.h"
+
+// pUuid is expected to be an array of 4 unsigned ints
+void glv_gen_uuid(uint32_t* pUuid);
+
+BOOL glv_init_time();
+uint64_t glv_get_time();
+
+//=============================================================================
+// trace file header
+
+// there is a file header at the start of every trace file
+glv_trace_file_header* glv_create_trace_file_header();
+
+// deletes the trace file header and sets pointer to NULL
+void glv_delete_trace_file_header(glv_trace_file_header** ppHeader);
+
+static FILE* glv_write_trace_file_header(glv_process_info* pProcInfo)
+{
+    FILE* tracefp = NULL;
+    unsigned int index = 0;
+    glv_trace_file_header* pHeader = NULL;
+    size_t items_written = 0;
+    assert(pProcInfo != NULL);
+
+    // open trace file
+    tracefp = fopen(pProcInfo->traceFilename, "wb");
+    if (tracefp == NULL)
+    {
+        glv_LogError("Cannot open trace file for writing %s\n", pProcInfo->traceFilename);
+        return tracefp;
+    }
+
+    // populate header information
+    pHeader = glv_create_trace_file_header();
+    pHeader->first_packet_offset = sizeof(glv_trace_file_header);
+    pHeader->tracer_count = pProcInfo->tracerCount;
+
+    for (index = 0; index < pProcInfo->tracerCount; index++)
+    {
+        pHeader->tracer_id_array[index] = pProcInfo->pCaptureThreads[index].tracerId;
+    }
+
+    pHeader->contains_state_snapshot = FALSE;
+    pHeader->state_snapshot_size = 0;
+    pHeader->state_snapshot_binary = (intptr_t) NULL;
+    pHeader->state_snapshot_path = (intptr_t) NULL;
+
+    // create critical section
+    glv_create_critical_section(&pProcInfo->traceFileCriticalSection);
+
+    // write header into file
+    glv_enter_critical_section(&pProcInfo->traceFileCriticalSection);
+    items_written = fwrite(pHeader, sizeof(glv_trace_file_header), 1, tracefp);
+    glv_leave_critical_section(&pProcInfo->traceFileCriticalSection);
+    if (items_written != 1)
+    {
+        glv_LogError("Failed to write trace file header\n");
+    }
+    glv_delete_trace_file_header(&pHeader);
+    return tracefp;
+};
+
+
+//=============================================================================
+// trace packets
+// There is a trace_packet_header before every trace_packet_body.
+// Additional buffers will come after the trace_packet_body.
+
+//=============================================================================
+// Methods for creating, populating, and writing trace packets
+
+// \param packet_size should include the total bytes for the specific type of packet, and any additional buffers needed by the packet.
+//        The size of the header will be added automatically within the function.
+glv_trace_packet_header* glv_create_trace_packet(uint8_t tracer_id, uint16_t packet_id, uint64_t packet_size, uint64_t additional_buffers_size);
+
+// deletes a trace packet and sets pointer to NULL
+void glv_delete_trace_packet(glv_trace_packet_header** ppHeader);
+
+// gets the next address available to write a buffer into the packet
+void* glv_trace_packet_get_new_buffer_address(glv_trace_packet_header* pHeader, uint64_t byteCount);
+
+// copies buffer data into a trace packet at the specified offset (from the end of the header).
+// it is up to the caller to ensure that buffers do not overlap.
+void glv_add_buffer_to_trace_packet(glv_trace_packet_header* pHeader, void** ptr_address, uint64_t size, const void* pBuffer);
+
+// converts buffer pointers into byte offset so that pointer can be interpretted after being read into memory
+void glv_finalize_buffer_address(glv_trace_packet_header* pHeader, void** ptr_address);
+
+//void initialize_trace_packet_header(glv_trace_packet_header* pHeader, uint8_t tracer_id, uint16_t packet_id, uint64_t total_packet_size);
+void glv_finalize_trace_packet(glv_trace_packet_header* pHeader);
+
+// Write the trace packet to the filelike thing.
+// This has no knowledge of the details of the packet other than its size.
+void glv_write_trace_packet(const glv_trace_packet_header* pHeader, FileLike* pFile);
+
+//=============================================================================
+// Methods for Reading and interpretting trace packets
+
+// Reads in the trace packet header, the body of the packet, and additional buffers
+glv_trace_packet_header* glv_read_trace_packet(FileLike* pFile);
+
+// converts a pointer variable that is currently byte offset into a pointer to the actual offset location
+void* glv_trace_packet_interpret_buffer_pointer(glv_trace_packet_header* pHeader, intptr_t ptr_variable);
+
+//=============================================================================
+// trace packet message
+// Interpretting a trace_packet_message should be done only when:
+// 1) a trace_packet is first created and most of the contents are empty.
+// 2) immediately after the packet was read from memory
+// All other conversions of the trace packet body from the header should 
+// be performed using a C-style cast.
+static glv_trace_packet_message* glv_interpret_body_as_trace_packet_message(glv_trace_packet_header* pHeader)
+{
+    glv_trace_packet_message* pPacket = (glv_trace_packet_message*)pHeader->pBody;
+    // update pointers
+    pPacket->pHeader = pHeader;
+    pPacket->message = (char*)glv_trace_packet_interpret_buffer_pointer(pHeader, (intptr_t)pPacket->message);
+    return pPacket;
+}
diff --git a/tools/glave/src/glvcommon/glv_tracelog.c b/tools/glave/src/glvcommon/glv_tracelog.c
new file mode 100644
index 0000000..e3b2fc3
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_tracelog.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#ifdef _DEBUG
+#include "glv_common.h" // for OutputDebugString
+#endif
+
+#include "glv_tracelog.h"
+#include "glv_trace_packet_utils.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+// filelike thing that is used for outputting trace messages
+static FileLike* g_pFileOut = NULL;
+
+// filelike thing that is used for outputting log messages
+static FileLike* g_pLogFile = NULL;
+
+GLV_TRACER_ID g_tracelog_tracer_id = GLV_TID_RESERVED;
+
+void glv_tracelog_set_log_file(FileLike* pFileLike)
+{
+    g_pLogFile = pFileLike;
+}
+
+void glv_tracelog_delete_log_file()
+{
+    if (g_pLogFile != NULL)
+    {
+        fflush(g_pLogFile->mFile);
+        GLV_DELETE(g_pLogFile);
+        g_pLogFile = NULL;
+    }
+}
+
+void glv_trace_set_trace_file(FileLike* pFileLike)
+{
+    g_pFileOut = pFileLike;
+}
+
+FileLike* glv_trace_get_trace_file()
+{
+    return g_pFileOut;
+}
+
+void glv_tracelog_set_tracer_id(uint8_t tracerId)
+{
+    g_tracelog_tracer_id = (GLV_TRACER_ID)tracerId;
+}
+
+void TraceGuts(TraceLogLevel _level, BOOL _log, const char* _fmt, va_list _args)
+{
+#if defined(WIN32)
+    int requiredLength = _vscprintf(_fmt, _args) + 1;
+#elif defined(PLATFORM_LINUX)
+    int requiredLength;
+    va_list argcopy;
+    va_copy(argcopy, _args);
+    requiredLength = vsnprintf(NULL, 0, _fmt, argcopy) + 1;
+    va_end(argcopy);
+#endif
+
+    if (_log)
+    {
+        char* message = (char*)glv_malloc(requiredLength);
+#if defined(WIN32)
+        _vsnprintf_s(message, requiredLength, requiredLength - 1, _fmt, _args);
+#elif defined(PLATFORM_LINUX)
+        vsnprintf(message, requiredLength, _fmt, _args);
+#endif
+        glv_PrintTraceMessage(_level, message);
+        glv_free(message);
+    }
+    else if (g_pFileOut != NULL)
+    {
+        glv_trace_packet_header* pHeader = glv_create_trace_packet(g_tracelog_tracer_id, GLV_TPI_MESSAGE, sizeof(glv_trace_packet_message), requiredLength);
+        glv_trace_packet_message* pPacket = glv_interpret_body_as_trace_packet_message(pHeader);
+        pPacket->type = _level;
+        pPacket->length = requiredLength;
+        pPacket->message = (char*)glv_trace_packet_get_new_buffer_address(pHeader, requiredLength);
+#if defined(WIN32)
+        _vsnprintf_s(pPacket->message, requiredLength, requiredLength - 1, _fmt, _args);
+#elif defined(PLATFORM_LINUX)
+        vsnprintf(pPacket->message, requiredLength, _fmt, _args);
+#endif
+
+        glv_finalize_buffer_address(pHeader, (void**)&pPacket->message);
+        glv_finalize_trace_packet(pHeader);
+
+        glv_write_trace_packet(pHeader, g_pFileOut);
+        glv_delete_trace_packet(&pHeader);
+    }
+}
+
+void glv_TraceVerbose(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLVerbose, FALSE, fmt, args);
+    va_end(args);
+}
+
+void glv_TraceInfo(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLInfo, FALSE, fmt, args);
+    va_end(args);
+}
+
+void glv_TraceWarn(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLWarn, FALSE, fmt, args);
+    va_end(args);
+}
+
+void glv_TraceError(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLError, FALSE, fmt, args);
+    va_end(args);
+}
+
+void glv_LogDebug(const char* fmt, ...)
+{
+#ifdef _DEBUG
+    // same as LogInfo
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLInfo, TRUE, fmt, args);
+    va_end(args);
+#endif
+}
+
+void glv_LogVerbose(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLVerbose, TRUE, fmt, args);
+    va_end(args);
+}
+
+void glv_LogInfo(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLInfo, TRUE, fmt, args);
+    va_end(args);
+}
+
+void glv_LogWarn(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLWarn, TRUE, fmt, args);
+    va_end(args);
+}
+
+void glv_LogError(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+    TraceGuts(TLLError, TRUE, fmt, args);
+    va_end(args);
+}
+
+// To display the trace messages to stdout.
+void glv_PrintTraceMessage(int _level, const char* _body)
+{
+    const char* levelHeader = "Unknown";
+    switch (_level) 
+    {
+        case TLLVerbose: levelHeader = "Verbose"; break;
+        case TLLInfo: levelHeader = "Info"; break;
+        case TLLWarn: levelHeader = "Warning"; break;
+        case TLLError: levelHeader = "ERROR"; break;
+        default:
+            assert(0);
+            break;
+    };
+
+    if (g_pLogFile != NULL)
+    {
+        glv_FileLike_WriteRaw(g_pLogFile, _body, strlen(_body));
+    }
+    else
+    {
+        printf("%s: %s", levelHeader, _body);
+    }
+
+#if defined(_DEBUG) && defined(WIN32)
+    OutputDebugString(_body);
+#endif
+
+}
diff --git a/tools/glave/src/glvcommon/glv_tracelog.h b/tools/glave/src/glvcommon/glv_tracelog.h
new file mode 100644
index 0000000..d8d250b
--- /dev/null
+++ b/tools/glave/src/glvcommon/glv_tracelog.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+typedef struct FileLike FileLike;
+
+typedef enum {
+	TLLVerbose = 0,
+	TLLInfo,
+	TLLWarn,
+	TLLError
+} TraceLogLevel;
+
+void glv_tracelog_set_log_file(FileLike* pFileLike);
+void glv_tracelog_delete_log_file();
+
+void glv_trace_set_trace_file(FileLike* pFileLike);
+FileLike* glv_trace_get_trace_file();
+void glv_tracelog_set_tracer_id(uint8_t tracerId);
+
+// Inserts log of the appropriate level into the trace so it can be displayed later.
+void glv_TraceVerbose(const char* fmt, ...);
+void glv_TraceInfo(const char* fmt, ...);
+void glv_TraceWarn(const char* fmt, ...);
+void glv_TraceError(const char* fmt, ...);
+
+// These are only output in debug builds
+void glv_LogDebug(const char* fmt, ...);
+
+// These messages are displayed to stdout. During capture, Log messages should only be 
+// emitted by glvtrace--any logging from the tracee should come in the form of Trace*, above.
+void glv_LogVerbose(const char* fmt, ...);
+void glv_LogInfo(const char* fmt, ...);
+void glv_LogWarn(const char* fmt, ...);
+void glv_LogError(const char* fmt, ...);
+
+// To display the trace messages to stdout.
+void glv_PrintTraceMessage(int _level, const char* _body);
+
+/*
+#define Once(_call) \
+    do { \
+        static bool once = true; \
+        if (once) { \
+            _call; \
+            once = false; \
+        } \
+    } while (0)
+*/
diff --git a/tools/glave/src/glvcommon/wintypes.h b/tools/glave/src/glvcommon/wintypes.h
new file mode 100644
index 0000000..b708923
--- /dev/null
+++ b/tools/glave/src/glvcommon/wintypes.h
@@ -0,0 +1,77 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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.
+ *
+ **************************************************************************/
+#pragma once
+
+#if  defined __linux__
+#include <stdint.h>
+#include <stddef.h>
+typedef void * LPVOID;
+typedef void * PVOID;
+typedef void VOID;
+typedef char CHAR;
+typedef char TCHAR;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef int BOOL;
+typedef size_t SIZE_T;
+typedef unsigned long DWORD;
+typedef unsigned char BYTE;
+typedef unsigned char *PBYTE;
+typedef unsigned short USHORT;
+typedef unsigned char UCHAR;
+typedef unsigned short WORD;
+typedef DWORD * DWORD_PTR;
+typedef DWORD *PDWORD;
+typedef DWORD_PTR *PDWORD_PTR;
+typedef int32_t INT32;
+typedef int64_t LONG64;
+typedef uint64_t ULONG64;
+typedef const char * PCSTR;
+typedef const wchar_t * PCWSTR;
+#ifndef MAX_PATH
+#include <limits.h>
+#ifndef PATH_MAX
+#define MAX_PATH 4096
+#else
+#define MAX_PATH PATH_MAX
+#endif
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef min
+#define min(a,b)            (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b)            (((a) < (b)) ? (b) : (a))
+#endif
+#elif WIN32
+#include <windows.h>
+#endif
+
diff --git a/tools/glave/src/glvinception/CMakeLists.txt b/tools/glave/src/glvinception/CMakeLists.txt
new file mode 100644
index 0000000..865119a
--- /dev/null
+++ b/tools/glave/src/glvinception/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 2.8)
+project(glvinception)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glvinception.c
+)
+
+set_source_files_properties( ${SRC_LIST} PROPERTIES LANGUAGE C)
+
+include_directories(
+    ${SRC_DIR}
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/glvtrace
+    ${SRC_DIR}/thirdparty
+)
+
+add_library(${PROJECT_NAME} SHARED ${SRC_LIST})
+
+target_link_libraries(${PROJECT_NAME} 
+    glvcommon
+)
+
+build_options_finalize()
+
+set_target_properties(glvinception PROPERTIES LINKER_LANGUAGE C)
diff --git a/tools/glave/src/glvinception/glvinception.c b/tools/glave/src/glvinception/glvinception.c
new file mode 100644
index 0000000..d79d12c
--- /dev/null
+++ b/tools/glave/src/glvinception/glvinception.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#include "glv_common.h"
+#include <stdio.h>
+
+GLVTRACER_EXIT TrapExit(void)
+{
+    glv_LogInfo("atExit occurred.\n");
+}
+
+GLVTRACER_ENTRY _Load(void)
+{
+    if (glv_is_loaded_into_glvtrace() == FALSE)
+    {
+        // If you need to debug startup, build with this set to true, then attach and change it to false.
+    #ifdef _DEBUG
+        BOOL debugStartup = FALSE;
+        while (debugStartup);
+    #endif
+
+        // register exit handler
+        atexit(TrapExit);
+
+        glv_LogInfo("Hooks attached!\n");
+    }
+}
+
+GLVTRACER_LEAVE _Unload(void)
+{
+    if (glv_is_loaded_into_glvtrace() == FALSE)
+    {
+        // detach and unload
+        glv_LogInfo("Hooks detached!\n");
+    }
+}
+
+#if defined(WIN32)
+BOOL APIENTRY DllMain( HMODULE hModule,
+                       DWORD  ul_reason_for_call,
+                       LPVOID lpReserved
+					 )
+
+{
+	hModule;
+	lpReserved;
+
+	switch (ul_reason_for_call)
+	{
+	case DLL_PROCESS_ATTACH:
+    {
+        _Load();
+		break;
+	}
+	case DLL_PROCESS_DETACH:
+	{
+        _Unload();
+		break;
+	}
+	default:
+		break;
+	}
+	return TRUE;
+}
+#endif
diff --git a/tools/glave/src/glvreplay/CMakeLists.txt b/tools/glave/src/glvreplay/CMakeLists.txt
new file mode 100644
index 0000000..3fffb97
--- /dev/null
+++ b/tools/glave/src/glvreplay/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 2.8)
+project(glvreplay)
+
+include("${SRC_DIR}/build_options.cmake")
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glvreplay_factory.h
+    glvreplay_seq.h
+    glvreplay_window.h
+    glvreplay_main.cpp
+    glvreplay_seq.cpp
+    glvreplay_factory.cpp
+)
+
+include_directories(
+    ${SRC_DIR}/glvreplay
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/thirdparty
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+
+target_link_libraries(${PROJECT_NAME} 
+    getopt_bundled
+    glvcommon
+)
+
+build_options_finalize()
diff --git a/tools/glave/src/glvreplay/glvreplay_factory.cpp b/tools/glave/src/glvreplay/glvreplay_factory.cpp
new file mode 100644
index 0000000..d695075
--- /dev/null
+++ b/tools/glave/src/glvreplay/glvreplay_factory.cpp
@@ -0,0 +1,85 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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 "glvreplay_factory.h"
+#include "glv_trace_packet_identifiers.h"
+
+namespace glv_replay {
+
+glv_trace_packet_replay_library* ReplayFactory::Create(uint8_t tracerId)
+{
+    glv_trace_packet_replay_library* pReplayer = NULL;
+    void* pLibrary = NULL;
+    char* exeDir = glv_platform_get_current_executable_directory();
+
+    const GLV_TRACER_REPLAYER_INFO* pReplayerInfo = &(gs_tracerReplayerInfo[tracerId]);
+
+    if (pReplayerInfo->tracerId != tracerId)
+    {
+        glv_LogError("Replayer info for TracerId (%d) failed consistency check.\n", tracerId);
+        assert(!"TracerId in GLV_TRACER_REPLAYER_INFO does not match the requested tracerId. The array needs to be corrected.");
+    }
+    else if (pReplayerInfo->needsReplayer == TRUE)
+    {
+        char* replayerPath = glv_copy_and_append(exeDir,"/", pReplayerInfo->replayerLibraryName);
+        pLibrary = glv_platform_open_library(replayerPath);
+        if (pLibrary == NULL) glv_LogError("Failed to load replayer '%s.'\n", replayerPath);
+        glv_free(replayerPath);
+    }
+    else
+    {
+        glv_LogError("A replayer was requested for TracerId (%d), but it does not require a replayer.\n", tracerId);
+        assert(!"Invalid TracerId supplied to ReplayFactory");
+    }
+
+    glv_free(exeDir);
+
+    if (pLibrary != NULL)
+    {
+        pReplayer = GLV_NEW(glv_trace_packet_replay_library);
+        assert(pReplayer != NULL);
+        pReplayer->pLibrary = pLibrary;
+        pReplayer->Initialize = (funcptr_glvreplayer_initialize)glv_platform_get_library_entrypoint(pLibrary, "Initialize");
+        pReplayer->Deinitialize = (funcptr_glvreplayer_deinitialize)glv_platform_get_library_entrypoint(pLibrary, "Deinitialize");
+        pReplayer->Replay = (funcptr_glvreplayer_replay)glv_platform_get_library_entrypoint(pLibrary, "Replay");
+        assert(pReplayer->Initialize != NULL);
+        assert(pReplayer->Deinitialize != NULL);
+        assert(pReplayer->Replay != NULL);
+    }
+
+    return pReplayer;
+}
+
+void ReplayFactory::Destroy(glv_trace_packet_replay_library** ppReplayer)
+{
+    assert (ppReplayer != NULL);
+    assert (*ppReplayer != NULL);
+    glv_platform_close_library((*ppReplayer)->pLibrary);
+    GLV_DELETE(*ppReplayer);
+    *ppReplayer = NULL;
+}
+
+
+} // namespace glv_replay
diff --git a/tools/glave/src/glvreplay/glvreplay_factory.h b/tools/glave/src/glvreplay/glvreplay_factory.h
new file mode 100644
index 0000000..15fc3fb
--- /dev/null
+++ b/tools/glave/src/glvreplay/glvreplay_factory.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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.
+ *
+ **************************************************************************/
+#pragma once
+
+extern "C" {
+#include "glv_common.h"
+#include "glv_trace_packet_identifiers.h"
+}
+#include "glvreplay_window.h"
+
+namespace glv_replay {
+
+enum GLV_REPLAY_RESULT
+{
+    GLV_REPLAY_SUCCESS = 0,
+    GLV_REPLAY_ERROR,          // internal error unrelated to the specific packet
+    GLV_REPLAY_INVALID_ID,     // packet_id invalid
+    GLV_REPLAY_BAD_RETURN,     // replay return value != trace return value
+    GLV_REPLAY_CALL_ERROR,     // replaying call caused an error
+    GLV_REPLAY_INVALID_PARAMS, // trace file parameters are invalid
+};
+
+// entrypoints that must be exposed by each replayer library
+typedef int (*funcptr_glvreplayer_initialize)(glv_replay::Display* pDisplay, unsigned int debugLevel);
+typedef void (*funcptr_glvreplayer_deinitialize)();
+typedef glv_replay::GLV_REPLAY_RESULT (*funcptr_glvreplayer_replay)(glv_trace_packet_header* pPacket);
+
+struct glv_trace_packet_replay_library
+{
+    void* pLibrary;
+    funcptr_glvreplayer_initialize Initialize;
+    funcptr_glvreplayer_deinitialize Deinitialize;
+    funcptr_glvreplayer_replay Replay;
+};
+
+class ReplayFactory {
+public:
+    glv_trace_packet_replay_library *Create(uint8_t tracerId);
+    void Destroy(glv_trace_packet_replay_library** ppReplayer);
+};
+} // namespace glv_replay
diff --git a/tools/glave/src/glvreplay/glvreplay_main.cpp b/tools/glave/src/glvreplay/glvreplay_main.cpp
new file mode 100644
index 0000000..19972f4
--- /dev/null
+++ b/tools/glave/src/glvreplay/glvreplay_main.cpp
@@ -0,0 +1,243 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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>
+extern "C" {
+#include "glv_common.h"
+#include "glv_tracelog.h"
+#include "glv_filelike.h"
+#include "glv_trace_packet_utils.h"
+}
+#include "glvreplay_factory.h"
+#include "glvreplay_seq.h"
+#include "glvreplay_window.h"
+#include "getopt/getopt.h"
+
+const static char *shortOptions = "hb";
+
+enum {
+    DEBUG_OPT = 1
+};
+const static struct option longOptions[] = {
+        {"help", no_argument, 0, 'h'},
+        {"benchmark", no_argument, 0, 'b'},
+        {"debug", required_argument, 0, DEBUG_OPT},
+        //TODO add more options
+        {0, 0, 0, 0}};
+
+static void usage(const char *argv0)
+{
+   glv_LogInfo("%s [options] [trace file]\n",argv0);
+   glv_LogInfo("-h | --help print usage\n");
+   glv_LogInfo("-d debug_level 0-N higher is more debug features\n");
+   //TODO add details
+}
+
+namespace glv_replay {
+int main_loop(Sequencer &seq, glv_trace_packet_replay_library *replayerArray[])
+{
+    int err = 0;
+    glv_trace_packet_header *packet;
+    unsigned int res;
+    glv_trace_packet_replay_library *replayer;
+    glv_trace_packet_message* msgPacket;
+
+    while ((packet = seq.get_next_packet()) != NULL)
+    {
+        switch (packet->packet_id) {
+            case GLV_TPI_MESSAGE:
+                msgPacket = glv_interpret_body_as_trace_packet_message(packet);
+                glv_PrintTraceMessage(msgPacket->type, msgPacket->message);
+                break;
+            case GLV_TPI_MARKER_CHECKPOINT:
+                break;
+            case GLV_TPI_MARKER_API_BOUNDARY:
+                break;
+            case GLV_TPI_MARKER_API_GROUP_BEGIN:
+                break;
+            case GLV_TPI_MARKER_API_GROUP_END:
+                break;
+            case GLV_TPI_MARKER_TERMINATE_PROCESS:
+                break;
+            //TODO processing code for all the above cases
+            default:
+            {
+                if (packet->tracer_id >= GLV_MAX_TRACER_ID_ARRAY_SIZE  || packet->tracer_id == GLV_TID_RESERVED) {
+                    glv_LogError("Tracer_id from packet num packet %d invalid.\n", packet->packet_id);
+                    continue;
+                }
+                replayer = replayerArray[packet->tracer_id];
+                if (replayer == NULL) {
+                    glv_LogWarn("Tracer_id %d has no valid replayer.\n", packet->tracer_id);
+                    continue;
+                }
+                if (packet->packet_id >= GLV_TPI_BEGIN_API_HERE)
+                {
+                    // replay the API packet
+                    res = replayer->Replay(packet);
+                    if (res != GLV_REPLAY_SUCCESS)
+                    {
+                        glv_LogError("Failed to replay packet_id %d.\n",packet->packet_id);
+                    }
+                } else {
+                    glv_LogError("Bad packet type id=%d, index=%d.\n", packet->packet_id, packet->global_packet_index);
+                    return -1;
+                }
+            }
+        }
+    }
+
+    return err;
+}
+} // namespace glv_replay
+
+using namespace glv_replay;
+
+extern "C"
+int main(int argc, char **argv)
+{
+    //bool hasSnapshot = false;
+    //bool fastReplay = false;
+    unsigned int debugLevel = 1;
+    int err;
+
+    // parse command line options
+    int opt;
+    while ((opt = getopt_long_only(argc, argv, shortOptions, longOptions, NULL)) != -1) {
+        switch (opt) {
+        case 'h':
+            usage(argv[0]);
+            return 0;
+        case 'b':
+            //fastReplay = true;
+            break;
+        case DEBUG_OPT:
+            debugLevel = atoi(optarg);
+            break;
+        default:
+            glv_LogError("unknown option %d\n", opt);
+            usage(argv[0]);
+            return 1;
+        }
+    }
+
+    // open trace file and read in header
+    glv_trace_file_header fileHeader;
+    FILE *tracefp;
+
+    if (optind < argc  && strlen(argv[optind]) > 0) {
+        tracefp = fopen(argv[optind], "rb");
+        if (tracefp == NULL) {
+            glv_LogError("Cannot open trace file: '%s'\n", argv[optind]);
+            return 1;
+        }
+    }
+    else {
+        glv_LogError("No trace file specified\n");
+        usage(argv[0]);
+        return 1;
+    }
+
+    FileLike* traceFile = glv_FileLike_create_file(tracefp);
+    if (glv_FileLike_ReadRaw(traceFile, &fileHeader, sizeof(fileHeader)) == false)
+    {
+        glv_LogError("Unable to read header from file.\n");
+        GLV_DELETE(traceFile);
+        return 1;
+    }
+    
+    // Make sure trace file version is supported
+    if (fileHeader.trace_file_version < GLV_TRACE_FILE_VERSION_MINIMUM_COMPATIBLE)
+    {
+        glv_LogError("Trace file version %su is older than minimum compatible version (%su).\nYou'll need to make a new trace file, or use an older replayer.\n", fileHeader.trace_file_version, GLV_TRACE_FILE_VERSION_MINIMUM_COMPATIBLE);
+    }
+
+    // load any API specific driver libraries and init replayer objects
+    uint8_t tidApi = GLV_TID_RESERVED;
+    glv_trace_packet_replay_library* replayer[GLV_MAX_TRACER_ID_ARRAY_SIZE];
+    ReplayFactory makeReplayer;
+    Display disp(1024, 768, 0, false);
+    
+    for (int i = 0; i < GLV_MAX_TRACER_ID_ARRAY_SIZE; i++)
+    {
+        replayer[i] = NULL;
+    }
+
+    for (int i = 0; i < fileHeader.tracer_count; i++)
+    {
+        uint8_t tracerId = fileHeader.tracer_id_array[i];
+        tidApi = tracerId;
+
+        const GLV_TRACER_REPLAYER_INFO* pReplayerInfo = &(gs_tracerReplayerInfo[tracerId]);
+
+        if (pReplayerInfo->tracerId != tracerId)
+        {
+            glv_LogError("Replayer info for TracerId (%d) failed consistency check.\n", tracerId);
+            assert(!"TracerId in GLV_TRACER_REPLAYER_INFO does not match the requested tracerId. The array needs to be corrected.");
+        }
+        else if (pReplayerInfo->needsReplayer == TRUE)
+        {
+            // Have our factory create the necessary replayer
+            replayer[tracerId] = makeReplayer.Create(tracerId);
+
+            if (replayer[tracerId] == NULL)
+            {
+                // replayer failed to be created
+                return err;
+            }
+
+            // Initalize the replayer
+            err = replayer[tracerId]->Initialize(&disp, debugLevel);
+            if (err) {
+                glv_LogError("Couldn't Initialize replayer for TracerId %d.\n", tracerId);
+                return err;
+            }
+        }
+    }
+
+    if (tidApi == GLV_TID_RESERVED) {
+        glv_LogError("No API specified in tracefile for replaying.\n");
+        return -1;
+    }
+ 
+    // process snapshot if present
+    if (fileHeader.contains_state_snapshot) {
+        //TODO
+    }
+
+    // main loop
+    Sequencer sequencer(traceFile);
+    err = glv_replay::main_loop(sequencer, replayer);
+
+    for (int i = 0; i < GLV_MAX_TRACER_ID_ARRAY_SIZE; i++)
+    {
+        if (replayer[i] != NULL)
+        {
+            replayer[i]->Deinitialize();
+            makeReplayer.Destroy(&replayer[i]);
+        }
+    }
+    return err;
+}
diff --git a/tools/glave/src/glvreplay/glvreplay_seq.cpp b/tools/glave/src/glvreplay/glvreplay_seq.cpp
new file mode 100644
index 0000000..8a943f0
--- /dev/null
+++ b/tools/glave/src/glvreplay/glvreplay_seq.cpp
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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 "glvreplay_seq.h"
+
+extern "C" {
+#include "glv_trace_packet_utils.h"
+}
+
+namespace glv_replay {
+
+glv_trace_packet_header * Sequencer::get_next_packet()
+{    
+    glv_free(m_lastPacket);
+    if (!m_pFile)
+        return (NULL);
+    m_lastPacket = glv_read_trace_packet(m_pFile);
+    return(m_lastPacket);
+}
+
+void Sequencer::get_bookmark(seqBookmark &bookmark) {
+    bookmark.file_offset = m_bookmark.file_offset;
+    bookmark.next_index = m_bookmark.next_index;
+}
+
+
+void Sequencer::set_bookmark(const seqBookmark &bookmark) {
+    m_bookmark.file_offset = bookmark.file_offset;
+    m_bookmark.next_index = bookmark.next_index;
+    
+}
+
+} /* namespace glv_replay */
diff --git a/tools/glave/src/glvreplay/glvreplay_seq.h b/tools/glave/src/glvreplay/glvreplay_seq.h
new file mode 100644
index 0000000..2e39379
--- /dev/null
+++ b/tools/glave/src/glvreplay/glvreplay_seq.h
@@ -0,0 +1,75 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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.
+ *
+ **************************************************************************/
+#pragma once
+
+extern "C" {
+#include "glv_filelike.h"
+#include "glv_trace_packet_identifiers.h"
+}
+
+/* Class to handle fetching and sequencing packets from a tracefile.
+ * Contains no knowledge of type of tracer needed to process packet.
+ * Requires low level file/stream reading/seeking support. */
+namespace glv_replay {
+
+
+struct seqBookmark
+{
+    unsigned int file_offset;
+    uint64_t next_index;
+};
+
+
+// replay Sequencer interface
+ class AbstractSequencer
+ {
+ public:
+    virtual ~AbstractSequencer() {}
+    virtual glv_trace_packet_header *get_next_packet() = 0;
+    virtual void get_bookmark(seqBookmark &bookmark) = 0;
+    virtual void set_bookmark(const seqBookmark &bookmark) = 0;
+ };
+
+class Sequencer: public AbstractSequencer
+{
+
+public:
+    Sequencer(FileLike* pFile) : m_lastPacket(NULL), m_pFile(pFile) {}
+    ~Sequencer() { delete m_lastPacket;}
+    
+    glv_trace_packet_header *get_next_packet();
+    void get_bookmark(seqBookmark &bookmark);
+    void set_bookmark(const seqBookmark &bookmark);
+    
+private:
+    glv_trace_packet_header *m_lastPacket;
+    seqBookmark m_bookmark;
+    FileLike *m_pFile;
+    
+};
+
+} /* namespace glv_replay */
+
+
diff --git a/tools/glave/src/glvreplay/glvreplay_window.h b/tools/glave/src/glvreplay/glvreplay_window.h
new file mode 100644
index 0000000..a8e7049
--- /dev/null
+++ b/tools/glave/src/glvreplay/glvreplay_window.h
@@ -0,0 +1,136 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Lunarg, 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.
+ *
+ **************************************************************************/
+#pragma once
+
+extern "C"{
+#include "glv_platform.h"
+}
+
+#if defined(WIN32)
+typedef HWND glv_window_handle;
+#else
+typedef void* glv_window_handle;
+#endif
+
+/* classes to abstract the display and initialization of rendering API for presenting
+ * framebuffers for display into a window on the screen or else fullscreen.
+ * Uses Bridge design pattern.
+ */
+namespace glv_replay {
+
+class DisplayImp {
+public:
+    virtual ~DisplayImp() {}
+    virtual int init(const unsigned int gpu_idx) = 0;
+    virtual int set_window(glv_window_handle hWindow, unsigned int width, unsigned int height) = 0;
+    virtual int create_window(const unsigned int width, const unsigned int height) = 0;
+    virtual void process_event() = 0;
+};
+
+class Display {
+public:
+    Display()
+        : m_imp(NULL),
+        m_width(0),
+        m_height(0),
+        m_gpu(0),
+        m_fullscreen(false),
+        m_hWindow(0)
+    {
+
+    }
+
+    Display(const unsigned int width, const unsigned int height, const unsigned int gpu, const bool fullscreen) :
+        m_imp(NULL),
+        m_width(width),
+        m_height(height),
+        m_gpu(gpu),
+        m_fullscreen(fullscreen),
+        m_hWindow(0)
+    {
+    }
+
+    Display(glv_window_handle hWindow, unsigned int width, unsigned int height) :
+        m_imp(NULL),
+        m_width(width),
+        m_height(height),
+        m_gpu(0),
+        m_fullscreen(false),
+        m_hWindow(hWindow)
+    {
+    }
+
+    virtual ~Display()
+    {
+    }
+
+    void set_implementation(DisplayImp & disp)
+    {
+        m_imp = & disp;
+    }
+    void set_implementation(DisplayImp * disp)
+    {
+        m_imp = disp;
+    }
+    int init()
+    {
+        if (m_imp)
+            return m_imp->init(m_gpu);
+        else
+            return -1;
+    }
+    void process_event()
+    {
+        if(m_imp)
+            m_imp->process_event();
+    }
+    unsigned int get_gpu()
+    {
+        return m_gpu;
+    }
+    unsigned int get_width()
+    {
+        return m_width;
+    }
+    unsigned int get_height()
+    {
+        return m_height;
+    }
+
+    glv_window_handle get_window_handle()
+    {
+        return m_hWindow;
+    }
+
+private:
+    DisplayImp *m_imp;
+    unsigned int m_width;
+    unsigned int m_height;
+    unsigned int m_gpu;
+    bool m_fullscreen;
+    glv_window_handle m_hWindow;
+};
+
+}   // namespace glv_replay
diff --git a/tools/glave/src/glvtrace/CMakeLists.txt b/tools/glave/src/glvtrace/CMakeLists.txt
new file mode 100644
index 0000000..5cba273
--- /dev/null
+++ b/tools/glave/src/glvtrace/CMakeLists.txt
@@ -0,0 +1,28 @@
+cmake_minimum_required(VERSION 2.8)
+project(glvtrace)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+set(SRC_LIST
+    ${SRC_LIST}
+    glvtrace.cpp
+    glvtrace_process.h
+    glvtrace_process.cpp
+)
+
+include_directories(
+    ${SRC_DIR}
+    ${SRC_DIR}/glvcommon
+    ${SRC_DIR}/glvtrace
+)
+
+add_executable(${PROJECT_NAME} ${SRC_LIST})
+
+
+target_link_libraries(${PROJECT_NAME}
+    glvcommon
+)
+
+build_options_finalize()
diff --git a/tools/glave/src/glvtrace/glvtrace.cpp b/tools/glave/src/glvtrace/glvtrace.cpp
new file mode 100644
index 0000000..827a729
--- /dev/null
+++ b/tools/glave/src/glvtrace/glvtrace.cpp
@@ -0,0 +1,317 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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 "glvtrace.h"
+
+#include "glvtrace_process.h"
+
+extern "C" {
+#include "glv_common.h"
+#include "glv_filelike.h"
+#include "glv_interconnect.h"
+#include "glv_trace_packet_identifiers.h"
+#include "glv_trace_packet_utils.h"
+}
+
+glvtrace_settings g_settings;
+glvtrace_settings g_default_settings;
+
+glv_SettingInfo g_settings_info[] =
+{
+    // common command options
+    { "p", "program", GLV_SETTING_STRING, &g_settings.program, &g_default_settings.program, TRUE, "The program to trace."},
+    { "a", "arguments", GLV_SETTING_STRING, &g_settings.arguments, &g_default_settings.arguments, TRUE, "Cmd-line arguments to pass to trace program."},
+    { "w", "working_dir", GLV_SETTING_STRING, &g_settings.working_dir, &g_default_settings.working_dir, TRUE, "The program's working directory."},
+    { "o", "output_trace", GLV_SETTING_STRING, &g_settings.output_trace, &g_default_settings.output_trace, TRUE, "Path to the generated output trace file."},
+    { "l0", "trace_library0", GLV_SETTING_STRING, &g_settings.trace_library[0], NULL, TRUE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l1", "trace_library1", GLV_SETTING_STRING, &g_settings.trace_library[1], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l2", "trace_library2", GLV_SETTING_STRING, &g_settings.trace_library[2], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l3", "trace_library3", GLV_SETTING_STRING, &g_settings.trace_library[3], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l4", "trace_library4", GLV_SETTING_STRING, &g_settings.trace_library[4], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l5", "trace_library5", GLV_SETTING_STRING, &g_settings.trace_library[5], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l6", "trace_library6", GLV_SETTING_STRING, &g_settings.trace_library[6], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l7", "trace_library7", GLV_SETTING_STRING, &g_settings.trace_library[7], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l8", "trace_library8", GLV_SETTING_STRING, &g_settings.trace_library[8], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l9", "trace_library9", GLV_SETTING_STRING, &g_settings.trace_library[9], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l10", "trace_library10", GLV_SETTING_STRING, &g_settings.trace_library[10], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l11", "trace_library11", GLV_SETTING_STRING, &g_settings.trace_library[11], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l12", "trace_library12", GLV_SETTING_STRING, &g_settings.trace_library[12], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l13", "trace_library13", GLV_SETTING_STRING, &g_settings.trace_library[13], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l14", "trace_library14", GLV_SETTING_STRING, &g_settings.trace_library[14], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "l15", "trace_library15", GLV_SETTING_STRING, &g_settings.trace_library[15], NULL, FALSE, "Path to the dynamic tracer library to be injected, may use [0-15]."},
+    { "tlf", "trace_log_file", GLV_SETTING_STRING, &g_settings.tracelogfile, &g_default_settings.tracelogfile, TRUE, "Log file to write into from trace application."},
+    { "ptm", "print_trace_messages", GLV_SETTING_BOOL, &g_settings.print_trace_messages, &g_default_settings.print_trace_messages, TRUE, "Print trace messages to glvtrace console."},
+
+    //{ "s", "pause", GLV_SETTING_BOOL, &g_settings.pause, &g_default_settings.pause, TRUE, "Wait for a key at startup (so a debugger can be attached)" },
+    //{ "q", "quiet", GLV_SETTING_BOOL, &g_settings.quiet, &g_default_settings.quiet, TRUE, "Disable warning, verbose, and debug output" },
+    //{ "v", "verbose", GLV_SETTING_BOOL, &g_settings.verbose, &g_default_settings.verbose, TRUE, "Enable verbose output" },
+    //{ "d", "debug", GLV_SETTING_BOOL, &g_settings.debug, &g_default_settings.debug, TRUE, "Enable verbose debug information" },
+};
+
+// ------------------------------------------------------------------------------------------------
+#if defined(WIN32)
+void MessageLoop()
+{
+    MSG msg = { 0 };
+    bool quit = false;
+    while (!quit)
+    {
+        if (GetMessage(&msg, NULL, 0, 0) == FALSE)
+        {
+            quit = true;
+        }
+        else
+        {
+            quit = (msg.message == GLV_WM_COMPLETE);
+        }
+    }
+}
+#endif
+
+// returns the number of tracers that need to be injected
+int PrepareTracers(glvtrace_settings* pSettings, glv_process_capture_trace_thread_info** ppTracerInfo)
+{
+    // determine number of tracers to load and inject
+    unsigned int num_tracers = 0;
+    for (unsigned int i = 0; i < GLV_MAX_TRACER_ID_ARRAY_SIZE; i++)
+    {
+        if (g_settings.trace_library[i] != NULL)
+        {
+            ++num_tracers;
+        }
+    }
+
+    assert(ppTracerInfo != NULL && *ppTracerInfo == NULL);
+    *ppTracerInfo = GLV_NEW_ARRAY(glv_process_capture_trace_thread_info, num_tracers);
+    memset(*ppTracerInfo, 0, sizeof(glv_process_capture_trace_thread_info) * num_tracers);
+
+    // consolidate the list, but also reverse the order so that the entrypoints should be hooked in the expected order
+    unsigned int tmpTracerIndex = num_tracers;
+    for (unsigned int i = 0; i < GLV_MAX_TRACER_ID_ARRAY_SIZE; i++)
+    {
+        if (g_settings.trace_library[i] != NULL)
+        {
+            void* hLibrary = glv_platform_open_library(g_settings.trace_library[i]);
+            if (hLibrary == NULL)
+            {
+                glv_LogError("Failed to load tracer: %s\n", g_settings.trace_library[i]);
+            }
+            else
+            {
+                funcptr_GLV_GetTracerId GLV_GetTracerId = NULL;
+                GLV_GetTracerId = (funcptr_GLV_GetTracerId)glv_platform_get_library_entrypoint(hLibrary, "GLV_GetTracerId");
+
+                if (GLV_GetTracerId != NULL)
+                {
+                    --tmpTracerIndex;
+                    (*ppTracerInfo)[tmpTracerIndex].tracerPath = g_settings.trace_library[i];
+                    (*ppTracerInfo)[tmpTracerIndex].tracerId = GLV_GetTracerId();
+                }
+                else
+                {
+                    glv_LogError("Missing entrypoint GLV_GetTracerId() from %s\n", g_settings.trace_library[i]);
+                }
+                glv_platform_close_library(hLibrary);
+            }
+        }
+    }
+
+    if (tmpTracerIndex > 0)
+    {
+        glv_LogError("One or more tracers could not be loaded. Please correct the issue and try again.\n");
+    }
+
+    return num_tracers;
+}
+
+bool InjectTracersIntoProcess(glv_process_info* pInfo)
+{
+    bool bRecordingThreadsCreated = true;
+    for (unsigned int i = 0; i < pInfo->tracerCount; i++)
+    {
+        // inject tracers
+        if (glv_platform_remote_load_library(pInfo->hProcess, pInfo->pCaptureThreads[i].tracerPath, &pInfo->pCaptureThreads[i].tracingThread, &pInfo->processLDPreload))
+        {
+            // prepare data for capture threads
+            pInfo->pCaptureThreads[i].pProcessInfo = pInfo;
+            pInfo->pCaptureThreads[i].recordingThread = GLV_NULL_THREAD;
+
+            // create thread to record trace packets from the tracer
+            pInfo->pCaptureThreads[i].recordingThread = glv_platform_create_thread(Process_RunRecordTraceThread, &(pInfo->pCaptureThreads[i]));
+            if (pInfo->pCaptureThreads[i].recordingThread == GLV_NULL_THREAD)
+            {
+                glv_LogError("Failed to create trace recording thread.\n");
+                bRecordingThreadsCreated = false;
+            }
+
+#if defined(WIN32)
+            // wait for the hooking / tracing thread to complete now that its recording thread is listening
+            if (WaitForSingleObject(pInfo->pCaptureThreads[i].tracingThread, INFINITE) != WAIT_OBJECT_0)
+            {
+                glv_LogError("Injected tracer's thread did not return successfully.\n");
+                bRecordingThreadsCreated = false;
+            }
+#endif
+        }
+        else
+        {
+            // failed to inject a DLL
+            bRecordingThreadsCreated = false;
+            break;
+        }
+    }
+    return bRecordingThreadsCreated;
+}
+
+// ------------------------------------------------------------------------------------------------
+int main(int argc, char* argv[])
+{
+    unsigned int num_settings = sizeof(g_settings_info) / sizeof(g_settings_info[0]);
+
+    memset(&g_settings, 0, sizeof(glvtrace_settings));
+
+    // setup defaults
+    memset(&g_default_settings, 0, sizeof(glvtrace_settings));
+    g_default_settings.output_trace = glv_allocate_and_copy("glvtrace_out.trace");
+    g_default_settings.tracelogfile = glv_allocate_and_copy("glv_log.txt");
+    g_default_settings.print_trace_messages = FALSE;
+
+    if (glv_SettingInfo_init(g_settings_info, num_settings, "glvtrace_settings.txt", argc, argv, &g_settings.arguments) != 0)
+    {
+        // invalid cmd-line parameters
+        glv_SettingInfo_delete(g_settings_info, num_settings);
+        glv_free(g_default_settings.output_trace);
+        glv_free(g_default_settings.tracelogfile);
+        return -1;
+    }
+    else
+    {
+        BOOL validArgs = TRUE;
+        if (g_settings.program == NULL || strlen(g_settings.program) == 0)
+        {
+            glv_LogError("Missing parameter: Don't know the program to trace.\n");
+            validArgs = FALSE;
+        }
+        else
+        {
+            if (g_settings.working_dir == NULL || strlen(g_settings.working_dir) == 0)
+            {
+                CHAR buf[4096];
+                glv_LogWarn("Missing parameter: No working directory specified, assuming executable's path.\n");
+                glv_platform_full_path(g_settings.program, 4096, buf);
+                g_settings.working_dir = glv_platform_extract_path(buf);
+            }
+        }
+
+        if (g_settings.arguments != NULL && strlen(g_settings.arguments) > 0)
+        {
+            glv_LogInfo("Args to be passed to child process: '%s'\n", g_settings.arguments);
+        }
+    
+        if (validArgs == FALSE)
+        {
+            glv_SettingInfo_print_all(g_settings_info, num_settings);
+            return -1;
+        }
+    }
+
+    if (g_settings.tracelogfile != NULL && strlen(g_settings.tracelogfile) > 0)
+    {
+        glv_tracelog_set_log_file(glv_FileLike_create_file(fopen(g_settings.tracelogfile, "w+")));
+    }
+
+    {
+        // Create and start the process.
+
+        BOOL procStarted = TRUE;
+        glv_process_info procInfo;
+        memset(&procInfo, 0, sizeof(glv_process_info));
+        procInfo.exeName = glv_allocate_and_copy(g_settings.program);
+        procInfo.processArgs = glv_allocate_and_copy(g_settings.arguments);
+        procInfo.workingDirectory = glv_allocate_and_copy(g_settings.working_dir);
+        procInfo.traceFilename = glv_allocate_and_copy(g_settings.output_trace);
+        procInfo.parentThreadId = glv_platform_get_thread_id();
+
+        // setup tracers
+        procInfo.tracerCount = PrepareTracers(&g_settings, &procInfo.pCaptureThreads);
+
+#if defined(WIN32)
+        // call CreateProcess to launch the application
+        procStarted = glv_process_spawn(&procInfo);
+#endif
+
+        if (procStarted == TRUE && procInfo.tracerCount > 0)
+        {
+            if (InjectTracersIntoProcess(&procInfo) == FALSE)
+            {
+                glv_LogError("Failed to setup tracer communication threads.\n");
+            }
+            else
+            {
+                // create trace file before injecting tracers
+                procInfo.pTraceFile = glv_write_trace_file_header(&procInfo);
+            }
+        }
+
+#if defined(PLATFORM_LINUX)
+        // in linux we want to spawn the process AFTER setting up LD_PRELOAD (which happens in the loop above)
+        procStarted = glv_process_spawn(&procInfo);
+#endif
+
+        if (procStarted == FALSE)
+        {
+            glv_LogError("Failed to setup remote process.\n");
+        }
+        else
+        {
+            // create watchdog thread to monitor existence of remote process
+            procInfo.watchdogThread = glv_platform_create_thread(Process_RunWatchdogThread, &procInfo);
+
+#if defined(PLATFORM_LINUX)
+            // Sync wait for local threads and remote process to complete.
+            for (unsigned int i = 0; i < procInfo.tracerCount; i++)
+            {
+                glv_platform_sync_wait_for_thread(&(procInfo.pCaptureThreads[i].recordingThread));
+            }
+
+            glv_platform_sync_wait_for_thread(&procInfo.watchdogThread);
+#else
+            glv_platform_resume_thread(&procInfo.hThread);
+
+            // Now into the main message loop, listen for hotkeys to send over.
+            MessageLoop();
+#endif
+        }
+
+        glv_process_info_delete(&procInfo);
+    }
+
+    glv_SettingInfo_delete(g_settings_info, num_settings);
+    glv_free(g_default_settings.output_trace);
+    glv_free(g_default_settings.tracelogfile);
+    glv_tracelog_delete_log_file();
+
+    return 0;
+}
+
diff --git a/tools/glave/src/glvtrace/glvtrace.h b/tools/glave/src/glvtrace/glvtrace.h
new file mode 100644
index 0000000..3fbaf98
--- /dev/null
+++ b/tools/glave/src/glvtrace/glvtrace.h
@@ -0,0 +1,50 @@
+/**************************************************************************
+ *
+ * Copyright 2014 Valve Software
+ * 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.
+ *
+ **************************************************************************/
+#pragma once
+
+extern "C" {
+#include "glv_settings.h"
+}
+
+
+#if defined(WIN32)
+#define GLV_WM_COMPLETE (WM_USER + 0)
+#endif
+
+//----------------------------------------------------------------------------------------------------------------------
+// globals
+//----------------------------------------------------------------------------------------------------------------------
+typedef struct glvtrace_settings
+{
+    char* program;
+    char* arguments;
+    char* working_dir;
+    char* output_trace;
+    char* trace_library[16];
+    char* tracelogfile;
+    BOOL print_trace_messages;
+} glvtrace_settings;
+
+extern glvtrace_settings g_settings;
diff --git a/tools/glave/src/glvtrace/glvtrace_process.cpp b/tools/glave/src/glvtrace/glvtrace_process.cpp
new file mode 100644
index 0000000..604a90f
--- /dev/null
+++ b/tools/glave/src/glvtrace/glvtrace_process.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#include <string>
+#include "glvtrace_process.h"
+#include "glvtrace.h"
+
+#if defined(PLATFORM_LINUX)
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#endif
+
+extern "C" {
+#include "glv_filelike.h"
+#include "glv_interconnect.h"
+#include "glv_trace_packet_utils.h"
+}
+
+const unsigned long kWatchDogPollTime = 250;
+
+#if defined(WIN32)
+void SafeCloseHandle(HANDLE& _handle)
+{
+    if (_handle) {
+        CloseHandle(_handle);
+        _handle = NULL;
+    }
+}
+#endif
+
+// ------------------------------------------------------------------------------------------------
+GLV_THREAD_ROUTINE_RETURN_TYPE Process_RunWatchdogThread(LPVOID _procInfoPtr)
+{
+    glv_process_info* pProcInfo = (glv_process_info*)_procInfoPtr;
+
+#if defined(WIN32)
+
+    while (WaitForSingleObject(pProcInfo->hProcess, kWatchDogPollTime) == WAIT_TIMEOUT)
+    {
+        if (pProcInfo->serverRequestsTermination)
+        {
+            glv_LogInfo("GLVTrace has requested exit.\n");
+            return 0;
+        }
+    }
+
+    glv_LogInfo("Child Process has terminated.\n");
+
+    PostThreadMessage(pProcInfo->parentThreadId, GLV_WM_COMPLETE, 0, 0);
+    pProcInfo->serverRequestsTermination = TRUE;
+    
+#elif defined(PLATFORM_LINUX)
+    int status = 0;
+    int options = 0;
+    while (waitpid(pProcInfo->processId, &status, options) != -1)
+    {
+        if (WIFEXITED(status))
+        {
+            glv_LogInfo("Child process exited\n");
+            break;
+        }
+        else if (WCOREDUMP(status))
+        {
+            glv_LogInfo("Child process crashed\n");
+            break;
+        }
+        else if (WIFSIGNALED(status))
+            glv_LogInfo("Child process was signaled\n");
+        else if (WIFSTOPPED(status))
+            glv_LogInfo("Child process was stopped\n");
+        else if (WIFCONTINUED(status))
+            glv_LogInfo("Child process was continued\n");
+    }
+#endif
+    return 0;
+}
+
+// ------------------------------------------------------------------------------------------------
+GLV_THREAD_ROUTINE_RETURN_TYPE Process_RunRecordTraceThread(LPVOID _threadInfo)
+{
+    glv_process_capture_trace_thread_info* pInfo = (glv_process_capture_trace_thread_info*)_threadInfo;
+
+    MessageStream* pMessageStream = glv_MessageStream_create(FALSE, "127.0.0.1", GLV_BASE_PORT + pInfo->tracerId);
+
+    if (pMessageStream == NULL)
+    {
+        glv_LogError("Thread_CaptureTrace() cannot create message stream\n");
+        return 1;
+    }
+
+    FileLike* fileLikeSocket = glv_FileLike_create_msg(pMessageStream);
+    unsigned int total_packet_count = 0;
+    glv_trace_packet_header* pHeader = NULL;
+    size_t bytes_written;
+
+    while (pInfo->pProcessInfo->serverRequestsTermination == FALSE)
+    {
+        // get a packet
+        //glv_LogDebug("Waiting for a packet...");
+
+        // read entire packet in
+        pHeader = glv_read_trace_packet(fileLikeSocket);
+        ++total_packet_count;
+        if (pHeader == NULL)
+        {
+            if (pMessageStream->mErrorNum == WSAECONNRESET)
+            {
+                glv_LogError("Network Connection Reset\n");
+            }
+            else
+            {
+                glv_LogError("Network Connection Failed\n");
+            }
+            break;
+        }
+
+        //glv_LogDebug("Received packet id: %hu\n", pHeader->packet_id);
+        
+        if (pHeader->pBody == (uintptr_t) NULL)
+        {
+            glv_LogWarn("Received empty packet body for id: %hu\n", pHeader->packet_id);
+        }
+        else
+        {
+            // handle special case packets
+            if (pHeader->packet_id == GLV_TPI_MESSAGE)
+            {
+                if (g_settings.print_trace_messages == TRUE)
+                {
+                    glv_trace_packet_message* pPacket = glv_interpret_body_as_trace_packet_message(pHeader);
+                    glv_PrintTraceMessage(pPacket->type, pPacket->message);
+                    printf("packet index: %lu\n", pHeader->global_packet_index);
+                    glv_finalize_buffer_address(pHeader, (void **) &(pPacket->message));
+                }
+            }
+
+            if (pHeader->packet_id == GLV_TPI_MARKER_TERMINATE_PROCESS)
+            {
+                pInfo->pProcessInfo->serverRequestsTermination = true;
+                glv_delete_trace_packet(&pHeader);
+                printf("Thread_CaptureTrace is exiting\n");
+                break;
+            }
+
+            if (pInfo->pProcessInfo->pTraceFile != NULL)
+            {
+                glv_enter_critical_section(&pInfo->pProcessInfo->traceFileCriticalSection);
+                bytes_written = fwrite(pHeader, 1, (size_t)pHeader->size, pInfo->pProcessInfo->pTraceFile);
+                fflush(pInfo->pProcessInfo->pTraceFile);
+                glv_leave_critical_section(&pInfo->pProcessInfo->traceFileCriticalSection);
+                if (bytes_written != pHeader->size)
+                {
+                    glv_LogError("Failed to write the packet for packet_id = %hu\n", pHeader->packet_id);
+                }
+            }
+        }
+
+        // clean up
+        glv_delete_trace_packet(&pHeader);
+    }
+
+    GLV_DELETE(fileLikeSocket);
+    glv_MessageStream_destroy(&pMessageStream);
+
+    return 0;
+}
diff --git a/tools/glave/src/glvtrace/glvtrace_process.h b/tools/glave/src/glvtrace/glvtrace_process.h
new file mode 100644
index 0000000..2446dec
--- /dev/null
+++ b/tools/glave/src/glvtrace/glvtrace_process.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2014, Valve Software. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * 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.
+ *  * Neither the name of NVIDIA CORPORATION nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
+ */
+
+#pragma once
+
+extern "C" {
+#include "glv_common.h"
+#include "glv_process.h"
+#include "glv_interconnect.h"
+}
+
+GLV_THREAD_ROUTINE_RETURN_TYPE Process_RunRecordTraceThread(LPVOID);
+
+GLV_THREAD_ROUTINE_RETURN_TYPE Process_RunWatchdogThread(LPVOID);
diff --git a/tools/glave/src/thirdparty/getopt/CMakeLists.txt b/tools/glave/src/thirdparty/getopt/CMakeLists.txt
new file mode 100644
index 0000000..5e66aca
--- /dev/null
+++ b/tools/glave/src/thirdparty/getopt/CMakeLists.txt
@@ -0,0 +1,12 @@
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+include("${SRC_DIR}/build_options.cmake")
+
+set(SRC_LIST
+    getopt_long.c
+    getopt.h
+)
+add_library (getopt_bundled STATIC EXCLUDE_FROM_ALL ${SRC_LIST})
+
+
+build_options_finalize()
diff --git a/tools/glave/src/thirdparty/getopt/LICENSE b/tools/glave/src/thirdparty/getopt/LICENSE
new file mode 100644
index 0000000..1a9141b
--- /dev/null
+++ b/tools/glave/src/thirdparty/getopt/LICENSE
@@ -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.
diff --git a/tools/glave/src/thirdparty/getopt/getopt.h b/tools/glave/src/thirdparty/getopt/getopt.h
new file mode 100644
index 0000000..117608f
--- /dev/null
+++ b/tools/glave/src/thirdparty/getopt/getopt.h
@@ -0,0 +1,82 @@
+/*	$OpenBSD: getopt.h,v 1.2 2008/06/26 05:42:04 ray Exp $	*/
+/*	$NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $	*/
+
+/*-
+ * 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.
+ */
+
+#ifndef _GETOPT_H_
+#define _GETOPT_H_
+
+/*
+ * GNU-like getopt_long() and 4.4BSD getsubopt()/optreset extensions
+ */
+#define no_argument        0
+#define required_argument  1
+#define optional_argument  2
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct option {
+	/* name of long option */
+	const char *name;
+	/*
+	 * one of no_argument, required_argument, and optional_argument:
+	 * whether option takes an argument
+	 */
+	int has_arg;
+	/* if not NULL, set *flag to val when option found */
+	int *flag;
+	/* if flag not NULL, value to set *flag to; else return value */
+	int val;
+};
+
+int	 getopt_long(int, char * const *, const char *,
+	    const struct option *, int *);
+int	 getopt_long_only(int, char * const *, const char *,
+	    const struct option *, int *);
+#ifndef _GETOPT_DEFINED_
+#define _GETOPT_DEFINED_
+int	 getopt(int, char * const *, const char *);
+int	 getsubopt(char **, char * const *, char **);
+
+extern   char *optarg;                  /* getopt(3) external variables */
+extern   int opterr;
+extern   int optind;
+extern   int optopt;
+extern   int optreset;
+extern   char *suboptarg;               /* getsubopt(3) external variable */
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+ 
+#endif /* !_GETOPT_H_ */
diff --git a/tools/glave/src/thirdparty/getopt/getopt_long.c b/tools/glave/src/thirdparty/getopt/getopt_long.c
new file mode 100644
index 0000000..81268b8
--- /dev/null
+++ b/tools/glave/src/thirdparty/getopt/getopt_long.c
@@ -0,0 +1,511 @@
+/*	$OpenBSD: getopt_long.c,v 1.24 2010/07/22 19:31:53 blambert Exp $	*/
+/*	$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $	*/
+
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int	opterr = 1;		/* if error message should be printed */
+int	optind = 1;		/* index into parent argv vector */
+int	optopt = '?';		/* character checked for validity */
+int	optreset;		/* reset getopt */
+char    *optarg;		/* argument associated with option */
+
+#define PRINT_ERROR	((opterr) && (*options != ':'))
+
+#define FLAG_PERMUTE	0x01	/* permute non-options to the end of argv */
+#define FLAG_ALLARGS	0x02	/* treat non-options as args to option "-1" */
+#define FLAG_LONGONLY	0x04	/* operate as getopt_long_only */
+
+/* return values */
+#define	BADCH		(int)'?'
+#define	BADARG		((*options == ':') ? (int)':' : (int)'?')
+#define	INORDER 	(int)1
+
+#define	EMSG		""
+
+static int getopt_internal(int, char * const *, const char *,
+			   const struct option *, int *, int);
+static int parse_long_options(char * const *, const char *,
+			      const struct option *, int *, int);
+static int gcd(int, int);
+static void permute_args(int, int, int, char * const *);
+
+static char *place = EMSG; /* option letter processing */
+
+/* XXX: set optreset to 1 rather than these two */
+static int nonopt_start = -1; /* first non option argument (for permute) */
+static int nonopt_end = -1;   /* first option after non options (for permute) */
+
+/* Error messages */
+static const char recargchar[] = "option requires an argument -- %c";
+static const char recargstring[] = "option requires an argument -- %s";
+static const char ambig[] = "ambiguous option -- %.*s";
+static const char noarg[] = "option doesn't take an argument -- %.*s";
+static const char illoptchar[] = "unknown option -- %c";
+static const char illoptstring[] = "unknown option -- %s";
+
+/*
+ * Compute the greatest common divisor of a and b.
+ */
+static int
+gcd(int a, int b)
+{
+	int c;
+
+	c = a % b;
+	while (c != 0) {
+		a = b;
+		b = c;
+		c = a % b;
+	}
+
+	return (b);
+}
+
+/*
+ * Exchange the block from nonopt_start to nonopt_end with the block
+ * from nonopt_end to opt_end (keeping the same order of arguments
+ * in each block).
+ */
+static void
+permute_args(int panonopt_start, int panonopt_end, int opt_end,
+	char * const *nargv)
+{
+	int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
+	char *swap;
+
+	/*
+	 * compute lengths of blocks and number and size of cycles
+	 */
+	nnonopts = panonopt_end - panonopt_start;
+	nopts = opt_end - panonopt_end;
+	ncycle = gcd(nnonopts, nopts);
+	cyclelen = (opt_end - panonopt_start) / ncycle;
+
+	for (i = 0; i < ncycle; i++) {
+		cstart = panonopt_end+i;
+		pos = cstart;
+		for (j = 0; j < cyclelen; j++) {
+			if (pos >= panonopt_end)
+				pos -= nnonopts;
+			else
+				pos += nopts;
+			swap = nargv[pos];
+			/* LINTED const cast */
+			((char **) nargv)[pos] = nargv[cstart];
+			/* LINTED const cast */
+			((char **)nargv)[cstart] = swap;
+		}
+	}
+}
+
+/*
+ * parse_long_options --
+ *	Parse long options in argc/argv argument vector.
+ * Returns -1 if short_too is set and the option does not match long_options.
+ */
+static int
+parse_long_options(char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int short_too)
+{
+	char *current_argv, *has_equal;
+	size_t current_argv_len;
+	int i, match;
+
+	current_argv = place;
+	match = -1;
+
+	optind++;
+
+	if ((has_equal = strchr(current_argv, '=')) != NULL) {
+		/* argument found (--option=arg) */
+		current_argv_len = has_equal - current_argv;
+		has_equal++;
+	} else
+		current_argv_len = strlen(current_argv);
+
+	for (i = 0; long_options[i].name; i++) {
+		/* find matching long option */
+		if (strncmp(current_argv, long_options[i].name,
+		    current_argv_len))
+			continue;
+
+		if (strlen(long_options[i].name) == current_argv_len) {
+			/* exact match */
+			match = i;
+			break;
+		}
+		/*
+		 * If this is a known short option, don't allow
+		 * a partial match of a single character.
+		 */
+		if (short_too && current_argv_len == 1)
+			continue;
+
+		if (match == -1)	/* partial match */
+			match = i;
+		else {
+			/* ambiguous abbreviation */
+			if (PRINT_ERROR)
+				fprintf(stderr, ambig, (int)current_argv_len,
+				     current_argv);
+			optopt = 0;
+			return (BADCH);
+		}
+	}
+	if (match != -1) {		/* option found */
+		if (long_options[match].has_arg == no_argument
+		    && has_equal) {
+			if (PRINT_ERROR)
+				fprintf(stderr, noarg, (int)current_argv_len,
+				     current_argv);
+			/*
+			 * XXX: GNU sets optopt to val regardless of flag
+			 */
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			return (BADARG);
+		}
+		if (long_options[match].has_arg == required_argument ||
+		    long_options[match].has_arg == optional_argument) {
+			if (has_equal)
+				optarg = has_equal;
+			else if (long_options[match].has_arg ==
+			    required_argument) {
+				/*
+				 * optional argument doesn't use next nargv
+				 */
+				optarg = nargv[optind++];
+			}
+		}
+		if ((long_options[match].has_arg == required_argument)
+		    && (optarg == NULL)) {
+			/*
+			 * Missing argument; leading ':' indicates no error
+			 * should be generated.
+			 */
+			if (PRINT_ERROR)
+				fprintf(stderr, recargstring,
+				    current_argv);
+			/*
+			 * XXX: GNU sets optopt to val regardless of flag
+			 */
+			if (long_options[match].flag == NULL)
+				optopt = long_options[match].val;
+			else
+				optopt = 0;
+			--optind;
+			return (BADARG);
+		}
+	} else {			/* unknown option */
+		if (short_too) {
+			--optind;
+			return (-1);
+		}
+		if (PRINT_ERROR)
+			fprintf(stderr, illoptstring, current_argv);
+		optopt = 0;
+		return (BADCH);
+	}
+	if (idx)
+		*idx = match;
+	if (long_options[match].flag) {
+		*long_options[match].flag = long_options[match].val;
+		return (0);
+	} else
+		return (long_options[match].val);
+}
+
+/*
+ * getopt_internal --
+ *	Parse argc/argv argument vector.  Called by user level routines.
+ */
+static int
+getopt_internal(int nargc, char * const *nargv, const char *options,
+	const struct option *long_options, int *idx, int flags)
+{
+	char *oli;				/* option letter list index */
+	int optchar, short_too;
+	static int posixly_correct = -1;
+
+	if (options == NULL)
+		return (-1);
+
+	/*
+	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
+	 * string begins with a '+'.
+	 */
+	if (posixly_correct == -1)
+		posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
+	if (posixly_correct || *options == '+')
+		flags &= ~FLAG_PERMUTE;
+	else if (*options == '-')
+		flags |= FLAG_ALLARGS;
+	if (*options == '+' || *options == '-')
+		options++;
+
+	/*
+	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
+	 * XXX using optreset.  Work around this braindamage.
+	 */
+	if (optind == 0)
+		optind = optreset = 1;
+
+	optarg = NULL;
+	if (optreset)
+		nonopt_start = nonopt_end = -1;
+start:
+	if (optreset || !*place) {		/* update scanning pointer */
+		optreset = 0;
+		if (optind >= nargc) {          /* end of argument vector */
+			place = EMSG;
+			if (nonopt_end != -1) {
+				/* do permutation, if we have to */
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			else if (nonopt_start != -1) {
+				/*
+				 * If we skipped non-options, set optind
+				 * to the first of them.
+				 */
+				optind = nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
+		if (*(place = nargv[optind]) != '-' ||
+		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
+			place = EMSG;		/* found non-option */
+			if (flags & FLAG_ALLARGS) {
+				/*
+				 * GNU extension:
+				 * return non-option as argument to option 1
+				 */
+				optarg = nargv[optind++];
+				return (INORDER);
+			}
+			if (!(flags & FLAG_PERMUTE)) {
+				/*
+				 * If no permutation wanted, stop parsing
+				 * at first non-option.
+				 */
+				return (-1);
+			}
+			/* do permutation */
+			if (nonopt_start == -1)
+				nonopt_start = optind;
+			else if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				nonopt_start = optind -
+				    (nonopt_end - nonopt_start);
+				nonopt_end = -1;
+			}
+			optind++;
+			/* process next argument */
+			goto start;
+		}
+		if (nonopt_start != -1 && nonopt_end == -1)
+			nonopt_end = optind;
+
+		/*
+		 * If we have "-" do nothing, if "--" we are done.
+		 */
+		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+			optind++;
+			place = EMSG;
+			/*
+			 * We found an option (--), so if we skipped
+			 * non-options, we have to permute.
+			 */
+			if (nonopt_end != -1) {
+				permute_args(nonopt_start, nonopt_end,
+				    optind, nargv);
+				optind -= nonopt_end - nonopt_start;
+			}
+			nonopt_start = nonopt_end = -1;
+			return (-1);
+		}
+	}
+
+	/*
+	 * Check long options if:
+	 *  1) we were passed some
+	 *  2) the arg is not just "-"
+	 *  3) either the arg starts with -- we are getopt_long_only()
+	 */
+	if (long_options != NULL && place != nargv[optind] &&
+	    (*place == '-' || (flags & FLAG_LONGONLY))) {
+		short_too = 0;
+		if (*place == '-')
+			place++;		/* --foo long option */
+		else if (*place != ':' && strchr(options, *place) != NULL)
+			short_too = 1;		/* could be short option too */
+
+		optchar = parse_long_options(nargv, options, long_options,
+		    idx, short_too);
+		if (optchar != -1) {
+			place = EMSG;
+			return (optchar);
+		}
+	}
+
+	if ((optchar = (int)*place++) == (int)':' ||
+	    (optchar == (int)'-' && *place != '\0') ||
+	    (oli = strchr(options, optchar)) == NULL) {
+		/*
+		 * If the user specified "-" and  '-' isn't listed in
+		 * options, return -1 (non-option) as per POSIX.
+		 * Otherwise, it is an unknown option character (or ':').
+		 */
+		if (optchar == (int)'-' && *place == '\0')
+			return (-1);
+		if (!*place)
+			++optind;
+		if (PRINT_ERROR)
+			fprintf(stderr, illoptchar, optchar);
+		optopt = optchar;
+		return (BADCH);
+	}
+	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
+		/* -W long-option */
+		if (*place)			/* no space */
+			/* NOTHING */;
+		else if (++optind >= nargc) {	/* no arg */
+			place = EMSG;
+			if (PRINT_ERROR)
+				fprintf(stderr, recargchar, optchar);
+			optopt = optchar;
+			return (BADARG);
+		} else				/* white space */
+			place = nargv[optind];
+		optchar = parse_long_options(nargv, options, long_options,
+		    idx, 0);
+		place = EMSG;
+		return (optchar);
+	}
+	if (*++oli != ':') {			/* doesn't take argument */
+		if (!*place)
+			++optind;
+	} else {				/* takes (optional) argument */
+		optarg = NULL;
+		if (*place)			/* no white space */
+			optarg = place;
+		else if (oli[1] != ':') {	/* arg not optional */
+			if (++optind >= nargc) {	/* no arg */
+				place = EMSG;
+				if (PRINT_ERROR)
+					fprintf(stderr, recargchar, optchar);
+				optopt = optchar;
+				return (BADARG);
+			} else
+				optarg = nargv[optind];
+		}
+		place = EMSG;
+		++optind;
+	}
+	/* dump back option letter */
+	return (optchar);
+}
+
+/*
+ * getopt --
+ *	Parse argc/argv argument vector.
+ *
+ * [eventually this will replace the BSD getopt]
+ */
+int
+getopt(int nargc, char * const *nargv, const char *options)
+{
+
+	/*
+	 * We don't pass FLAG_PERMUTE to getopt_internal() since
+	 * the BSD getopt(3) (unlike GNU) has never done this.
+	 *
+	 * Furthermore, since many privileged programs call getopt()
+	 * before dropping privileges it makes sense to keep things
+	 * as simple (and bug-free) as possible.
+	 */
+	return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
+}
+
+/*
+ * getopt_long --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+	    FLAG_PERMUTE));
+}
+
+/*
+ * getopt_long_only --
+ *	Parse argc/argv argument vector.
+ */
+int
+getopt_long_only(int nargc, char * const *nargv, const char *options,
+    const struct option *long_options, int *idx)
+{
+
+	return (getopt_internal(nargc, nargv, options, long_options, idx,
+	    FLAG_PERMUTE|FLAG_LONGONLY));
+}
diff --git a/tools/glave/src/thirdparty/mhook/COPYING b/tools/glave/src/thirdparty/mhook/COPYING
new file mode 100644
index 0000000..1ca1bcf
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/COPYING
@@ -0,0 +1,20 @@
+Copyright (c) 2007-2008, Marton Anka
+Portions Copyright (c) 2007, Matt Conover
+
+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.
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/CMakeLists.txt b/tools/glave/src/thirdparty/mhook/disasm-lib/CMakeLists.txt
new file mode 100644
index 0000000..ac675a3
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/CMakeLists.txt
@@ -0,0 +1,30 @@
+project(disasm)
+cmake_minimum_required(VERSION 2.8)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(
+    ${SRC_DIR}/thirdparty/mhook/disasm-lib
+    ${SRC_DIR}/glvcommon
+)
+
+set(SRC_LIST
+    cpu.c
+    cpu.h
+    disasm.c
+    disasm.h
+    disasm_x86.c
+    disasm_x86.h
+    disasm_x86_tables.h
+    misc.c
+    misc.h
+)
+
+if (NOT MSVC)
+    add_compiler_flag("-fPIC")
+endif()
+
+add_library(${PROJECT_NAME} STATIC ${SRC_LIST})
+
+build_options_finalize()
+
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/cpu.c b/tools/glave/src/thirdparty/mhook/disasm-lib/cpu.c
new file mode 100644
index 0000000..6fc57b0
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/cpu.c
@@ -0,0 +1,94 @@
+// Copyright (C) 2003, Matt Conover (mconover@gmail.com)
+#include "cpu.h"
+#include <assert.h>
+
+// NOTE: this assumes default scenarios (i.e., we assume CS/DS/ES/SS and flat
+// and all have a base of 0 and limit of 0xffffffff, we don't try to verify
+// that in the GDT)
+//
+// TODO: use inline assembly to get selector for segment
+// Segment = x86 segment register (SEG_ES = 0, SEG_CS = 1, ...)
+BYTE *GetAbsoluteAddressFromSegment(BYTE Segment, DWORD Offset)
+{
+	switch (Segment)
+	{
+		// Windows uses a flat address space (except FS for x86 and GS for x64)
+		case 0: // SEG_ES
+		case 1: // SEG_CS
+		case 2: // SEG_SS
+		case 3: // SEG_DS
+			return (BYTE *)(DWORD_PTR)Offset;
+		case 4: // SEG_FS
+		case 5: // SEG_GS
+			return (BYTE *)(DWORD_PTR)Offset;
+			// Note: we're really supposed to do this, but get_teb is not implemented
+			// in this bastardized version of the disassembler.
+			// return (BYTE *)get_teb() + Offset;
+		default:
+			assert(0);
+			return (BYTE *)(DWORD_PTR)Offset;
+	}
+}
+
+#if 0
+// This is an GDT/LDT selector (pGDT+Selector)
+BYTE *GetAbsoluteAddressFromSelector(WORD Selector, DWORD Offset)
+{
+	DESCRIPTOR_ENTRY Entry;
+	GATE_ENTRY *Gate;
+	ULONG_PTR Base;
+	
+	assert(Selector < 0x10000);
+	if (!GetThreadSelectorEntry(GetCurrentThread(), Selector, (LDT_ENTRY *)&Entry)) return NULL;
+	if (!Entry.Present) return NULL;
+	if (Entry.System)
+	{
+		Base = 0;
+#ifdef _WIN64
+		Base |= (ULONG_PTR)Entry.HighOffset64 << 32;
+#endif
+		Base |= Entry.BaseHi << 24;
+		Base |= Entry.BaseMid << 16;
+		Base |= Entry.BaseLow;
+	}
+	else
+	{
+		switch (Entry.Type)
+		{
+			case 1: // 16-bit TSS (available)
+			case 2: // LDT
+			case 3: // 16-bit TSS (busy)
+			case 9: // 32-bit TSS (available)
+			case 11: // 32-bit TSS (busy)
+				Base = 0;
+#ifdef _WIN64
+				Base |= (ULONG_PTR)Entry.HighOffset64 << 32;
+#endif
+				Base |= Entry.BaseHi << 24;
+				Base |= Entry.BaseMid << 16;
+				Base |= Entry.BaseLow;
+				break;
+
+			case 4: // 16-bit call gate
+			case 5: // task gate
+			case 6: // 16-bit interrupt gate
+			case 7: // 16-bit task gate
+			case 12: // 32-bit call gate
+			case 14: // 32-bit interrupt gate
+			case 15: // 32-bit trap gate
+				Gate = (GATE_ENTRY *)&Entry;
+#ifdef _WIN64
+				Base = ((ULONG_PTR)Gate->HighOffset64 << 32) | (Gate->HighOffset << 16) | Gate->LowOffset;
+#else
+				Base = (Gate->HighOffset << 16) | Gate->LowOffset;
+#endif
+				assert(!Offset); Offset = 0;
+				break;
+			default:
+				assert(0);
+				return NULL;
+		}
+	}
+	return (BYTE *)Base + Offset;
+}
+#endif
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/cpu.h b/tools/glave/src/thirdparty/mhook/disasm-lib/cpu.h
new file mode 100644
index 0000000..677d91e
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/cpu.h
@@ -0,0 +1,277 @@
+// Copyright (C) 2003, Matt Conover (mconover@gmail.com)
+#ifndef CPU_H
+#define CPU_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+#pragma pack(push,1)
+
+#include "wintypes.h"
+#include "misc.h"
+
+////////////////////////////////////////////////////////
+// System descriptors
+////////////////////////////////////////////////////////
+
+#define GDT_NULL 0
+#define GDT_R0_CODE 0x08
+#define GDT_R0_DATA 0x10
+#define GDT_R3_CODE 0x18
+#define GDT_R3_DATA 0x20
+#define GDT_TSS 0x28
+#define GDT_PCR 0x30
+#define GDT_R3_TEB 0x38
+#define GDT_VDM 0x40
+#define GDT_LDT 0x48
+#define GDT_DOUBLEFAULT_TSS 0x50
+#define GDT_NMI_TSS 0x58
+
+// 16-bit GDT entries:
+// TODO: #define GDT_ABIOS_UNKNOWN   0x60  (22F30-32F2F)
+#define GDT_ABIOS_VIDEO 0x68
+#define GDT_ABIOS_GDT   0x70 // descriptor describing ABIOS GDT itself
+#define GDT_ABIOS_NTOS  0x78 // first 64K of NTOSKRNL
+#define GDT_ABIOS_CDA   0xE8 // common data area
+#define GDT_ABIOS_CODE  0xF0 // KiI386AbiosCall
+#define GDT_ABIOS_STACK 0xF8
+
+#define SELECTOR_RPL_MASK 0x03 // bits 0-1
+#define SELECTOR_LDT      0x04 // bit 2
+
+// for data selectors
+#define DATA_ACCESS_MASK       (1<<0)
+#define DATA_WRITE_ENABLE_MASK (1<<1)
+#define DATA_EXPAND_DOWN_MASK  (1<<2)
+
+// for code selectors
+#define CODE_ACCESS_MASK       (1<<0)
+#define CODE_READ_MASK         (1<<1)
+#define CODE_CONFORMING_MASK   (1<<2)
+#define CODE_FLAG              (1<<3)
+
+#define TASK_GATE      5
+#define INTERRUPT_GATE 6
+#define TRAP_GATE      7
+
+typedef struct _IDT_ENTRY
+{
+   USHORT LowOffset;
+   USHORT Selector;
+   UCHAR Ignored : 5;
+   UCHAR Zero : 3;
+   UCHAR Type : 3;
+   UCHAR Is32Bit : 1;
+   UCHAR Ignored2 : 1;
+   UCHAR DPL : 2;
+   UCHAR Present : 1;
+   USHORT HighOffset;
+#ifdef _WIN64
+   ULONG HighOffset64;
+   ULONG Reserved;
+#endif
+} IDT_ENTRY, TRAP_GATE_ENTRY;
+
+typedef struct _CALL_GATE_ENTRY
+{
+   USHORT LowOffset;
+   USHORT Selector;
+   UCHAR ParameterCount: 4;
+   UCHAR Ignored : 3;
+   UCHAR Type : 5;
+   UCHAR DPL : 2;
+   UCHAR Present : 1;
+   USHORT HighOffset;
+#ifdef _WIN64
+   ULONG HighOffset64;
+   ULONG Reserved;
+#endif
+} CALL_GATE_ENTRY;
+
+typedef struct _TASK_GATE_ENTRY
+{
+   USHORT Ignored;
+   USHORT Selector;
+   UCHAR Ignored2 : 5;
+   UCHAR Zero : 3;
+   UCHAR Type : 5;
+   UCHAR DPL : 2;
+   UCHAR Present : 1;
+   USHORT Ignored3;
+} TASK_GATE_ENTRY;
+
+typedef struct _DESCRIPTOR_ENTRY
+{
+    USHORT  LimitLow;
+    USHORT  BaseLow;
+    UCHAR   BaseMid;
+    UCHAR   Type : 4;        // 10EWA (code), E=ExpandDown, W=Writable, A=Accessed
+                             // 11CRA (data), C=Conforming, R=Readable, A=Accessed
+    UCHAR   System : 1;      // if 1 then it is a gate or LDT
+    UCHAR   DPL : 2;         // descriptor privilege level; 
+                             // for data selectors, MAX(CPL, RPL) must be <= DPL to access (or else GP# fault)
+                             // for non-conforming code selectors (without callgate), MAX(CPL, RPL) must be <= DPL to access (or else GP# fault)
+                             // for conforming code selectors, MAX(CPL, RPL) must be >= DPL (i.e., CPL 0-2 cannot access if DPL is 3)
+                             // for non-conforming code selectors (with call gate), DPL indicates lowest privilege allowed to access gate
+    UCHAR   Present : 1;
+    UCHAR   LimitHigh : 4;
+    UCHAR   Available: 1;    // aka AVL
+    UCHAR   Reserved : 1;
+    UCHAR   Is32Bit : 1;     // aka B flag
+    UCHAR   Granularity : 1; // aka G flag
+    UCHAR   BaseHi : 8;
+#ifdef _WIN64
+   ULONG HighOffset64;
+   ULONG Reserved2;
+#endif
+} DESCRIPTOR_ENTRY;
+
+typedef struct _GATE_ENTRY
+{
+   USHORT LowOffset;
+   UCHAR Skip;
+   UCHAR Type : 5;
+   UCHAR DPL : 2;
+   UCHAR Present : 1;
+   USHORT HighOffset;
+#ifdef _WIN64
+   ULONG HighOffset64;
+   ULONG Reserved;
+#endif
+} GATE_ENTRY;
+
+// TODO: update for X64
+typedef struct _PTE_ENTRY
+{
+    ULONG Present : 1;
+    ULONG Write : 1;
+    ULONG Owner : 1; // E.g., user mode or supervisor mode
+    ULONG WriteThrough : 1;
+    ULONG CacheDisable : 1;
+    ULONG Accessed : 1;
+    ULONG Dirty : 1;
+    ULONG PAT : 1;
+    ULONG Global : 1;
+    ULONG CopyOnWrite : 1;
+    ULONG Prototype : 1;
+    ULONG Transition : 1;
+    ULONG Address : 20;
+} PTE_ENTRY;
+
+// TODO: update for X64
+typedef struct _PDE_ENTRY
+{
+	ULONG Present : 1;
+	ULONG Write : 1;
+	ULONG Owner : 1;
+	ULONG WriteThrough : 1;
+	ULONG CacheDisable : 1;
+	ULONG Accessed : 1;
+	ULONG Reserved1 : 1;
+	ULONG PageSize : 1;
+	ULONG Global : 1;
+	ULONG Reserved : 3;
+	ULONG Address : 20;
+} PDE_ENTRY;
+
+// TODO: update for X64
+typedef struct _IO_ACCESS_MAP
+{
+    UCHAR DirectionMap[32];
+    UCHAR IoMap[8196];
+} IO_ACCESS_MAP;
+
+#define MIN_TSS_SIZE FIELD_OFFSET(TSS_ENTRY, IoMaps)
+// TODO: update for X64
+typedef struct _TSS_ENTRY
+{
+    USHORT  Backlink;
+    USHORT  Reserved0;
+    ULONG   Esp0;
+    USHORT  Ss0;
+    USHORT  Reserved1;
+    ULONG   NotUsed1[4];
+    ULONG   CR3;
+    ULONG   Eip;
+    ULONG   NotUsed2[9];
+    USHORT  Es;
+    USHORT  Reserved2;
+    USHORT  Cs;
+    USHORT  Reserved3;
+    USHORT  Ss;
+    USHORT  Reserved4;
+    USHORT  Ds;
+    USHORT  Reserved5;
+    USHORT  Fs;
+    USHORT  Reserved6;
+    USHORT  Gs;
+    USHORT  Reserved7;
+    USHORT  LDT;
+    USHORT  Reserved8;
+    USHORT  Flags;
+    USHORT  IoMapBase;
+    IO_ACCESS_MAP IoMaps[1];
+    UCHAR IntDirectionMap[32];
+} TSS_ENTRY;
+
+// TODO: update for X64
+typedef struct _TSS16_ENTRY
+{
+    USHORT  Backlink;
+    USHORT  Sp0;
+    USHORT  Ss0;
+    USHORT  Sp1;
+    USHORT  Ss1;
+    USHORT  Sp2;
+    USHORT  Ss3;
+    USHORT  Ip;
+    USHORT  Flags;
+    USHORT  Ax;
+    USHORT  Cx;
+    USHORT  Dx;
+    USHORT  Bx;
+    USHORT  Sp;
+    USHORT  Bp;
+    USHORT  Si;
+    USHORT  Di;
+    USHORT  Es;
+    USHORT  Cs;
+    USHORT  Ss;
+    USHORT  Ds;
+    USHORT  LDT;
+} TSS16_ENTRY;
+
+// TODO: update for X64
+typedef struct _GDT_ENTRY
+{
+    USHORT  LimitLow;
+    USHORT  BaseLow;
+    union {
+        struct {
+            UCHAR   BaseMid;
+            UCHAR   Flags1;
+            UCHAR   Flags2;
+            UCHAR   BaseHi;
+        } Bytes;
+        struct {
+            ULONG   BaseMid : 8;
+            ULONG   Type : 5;
+            ULONG   Dpl : 2;
+            ULONG   Pres : 1;
+            ULONG   LimitHi : 4;
+            ULONG   Sys : 1;
+            ULONG   Reserved_0 : 1;
+            ULONG   Default_Big : 1;
+            ULONG   Granularity : 1;
+            ULONG   BaseHi : 8;
+        } Bits;
+    } HighWord;
+} GDT_ENTRY;
+
+BYTE *GetAbsoluteAddressFromSegment(BYTE Segment, DWORD Offset);
+BYTE *GetAbsoluteAddressFromSelector(WORD Selector, DWORD Offset);
+
+#pragma pack(pop)
+#ifdef __cplusplus
+}
+#endif
+#endif // CPU_H
\ No newline at end of file
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/disasm.c b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm.c
new file mode 100644
index 0000000..9e7994d
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm.c
@@ -0,0 +1,123 @@
+// Copyright (C) 2004, Matt Conover (mconover@gmail.com)
+#undef NDEBUG
+#include <assert.h>
+#include "disasm.h"
+#ifdef __linux__
+#include <string.h>
+#endif
+#ifdef NO_SANITY_CHECKS
+#define NDEBUG
+#undef assert
+#define assert(x)
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Global variables
+//////////////////////////////////////////////////////////////////////
+
+ARCHITECTURE_FORMAT SupportedArchitectures[] =
+{
+	{ ARCH_X86,	&X86 },
+	{ ARCH_X86_16, &X86 },
+	{ ARCH_X64,	&X86 },
+	{ ARCH_UNKNOWN, NULL }
+};
+
+typedef struct _DISASM_ARG_INFO
+{
+	INSTRUCTION *MatchedInstruction;
+	BOOL MatchPrefix;
+	U8 *Opcode;
+	U32 OpcodeLength;
+	INSTRUCTION_TYPE InstructionType;
+	U32 Count;
+} DISASM_ARG_INFO;
+
+//////////////////////////////////////////////////////////////////////
+// Function prototypes
+//////////////////////////////////////////////////////////////////////
+
+BOOL InitInstruction(INSTRUCTION *Instruction, DISASSEMBLER *Disassembler);
+static struct _ARCHITECTURE_FORMAT *GetArchitectureFormat(ARCHITECTURE_TYPE Type);
+
+//////////////////////////////////////////////////////////////////////
+// Disassembler setup
+//////////////////////////////////////////////////////////////////////
+
+BOOL InitDisassembler(DISASSEMBLER *Disassembler, ARCHITECTURE_TYPE Architecture)
+{
+	ARCHITECTURE_FORMAT *ArchFormat;
+
+	memset(Disassembler, 0, sizeof(DISASSEMBLER));
+	Disassembler->Initialized = DISASSEMBLER_INITIALIZED;
+	
+	ArchFormat = GetArchitectureFormat(Architecture);
+	if (!ArchFormat) { assert(0); return FALSE; }
+	Disassembler->ArchType = ArchFormat->Type;
+	Disassembler->Functions = ArchFormat->Functions;
+	return TRUE;
+}
+
+void CloseDisassembler(DISASSEMBLER *Disassembler)
+{
+	memset(Disassembler, 0, sizeof(DISASSEMBLER));
+}
+
+//////////////////////////////////////////////////////////////////////
+// Instruction setup
+//////////////////////////////////////////////////////////////////////
+
+BOOL InitInstruction(INSTRUCTION *Instruction, DISASSEMBLER *Disassembler)
+{
+	memset(Instruction, 0, sizeof(INSTRUCTION));
+	Instruction->Initialized = INSTRUCTION_INITIALIZED;
+	Instruction->Disassembler = Disassembler;
+	memset(Instruction->String, ' ', MAX_OPCODE_DESCRIPTION-1);
+	Instruction->String[MAX_OPCODE_DESCRIPTION-1] = '\0';
+	return TRUE;
+}
+
+// If Decode = FALSE, only the following fields are valid:
+// Instruction->Length, Instruction->Address, Instruction->Prefixes, Instruction->PrefixCount,
+// Instruction->OpcodeBytes, Instruction->Instruction->OpcodeLength, Instruction->Groups,
+// Instruction->Type, Instruction->OperandCount
+//
+// If Disassemble = TRUE, then Instruction->String is valid (also requires Decode = TRUE)
+//
+// WARNING: This will overwrite the previously obtained instruction
+INSTRUCTION *GetInstruction(DISASSEMBLER *Disassembler, U64 VirtualAddress, U8 *Address, U32 Flags)
+{
+	if (Disassembler->Initialized != DISASSEMBLER_INITIALIZED) { assert(0); return NULL; }
+	assert(Address);
+	InitInstruction(&Disassembler->Instruction, Disassembler);
+	Disassembler->Instruction.Address = Address;	
+	Disassembler->Instruction.VirtualAddressDelta = VirtualAddress - (U64)Address;
+	if (!Disassembler->Functions->GetInstruction(&Disassembler->Instruction, Address, Flags))
+	{
+		assert(Disassembler->Instruction.Address == Address);
+		assert(Disassembler->Instruction.Length < MAX_INSTRUCTION_LENGTH);
+
+		// Save the address that failed, in case the lower-level disassembler didn't
+		Disassembler->Instruction.Address = Address;
+		Disassembler->Instruction.ErrorOccurred = TRUE;
+		return NULL;
+	}
+	return &Disassembler->Instruction;
+}
+
+///////////////////////////////////////////////////////////////////////////
+// Miscellaneous
+///////////////////////////////////////////////////////////////////////////
+
+static ARCHITECTURE_FORMAT *GetArchitectureFormat(ARCHITECTURE_TYPE Type)
+{
+	ARCHITECTURE_FORMAT *Format;
+	for (Format = SupportedArchitectures; Format->Type != ARCH_UNKNOWN; Format++)
+	{
+		if (Format->Type == Type) return Format;
+	}
+
+	assert(0);
+	return NULL;
+}
+
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/disasm.h b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm.h
new file mode 100644
index 0000000..b7047c8
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm.h
@@ -0,0 +1,583 @@
+// Copyright (C) 2004, Matt Conover (mconover@gmail.com)
+//
+// WARNING:
+// I wouldn't recommend changing any flags like OP_*, ITYPE_*, or *_MASK
+// aside from those marked as UNUSED. This is because the flags parts of
+// the flags are architecture independent and other are left to specific
+// architectures to define, so unless you understand the relationships
+// between them, I would leave them as is.
+
+#ifndef DISASM_H
+#define DISASM_H
+
+#include "wintypes.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __linux__
+#include <string.h>
+#endif
+#include <stdio.h>
+#include "misc.h"
+
+typedef signed char S8;
+typedef unsigned char U8;
+typedef signed short S16;
+typedef unsigned short U16;
+typedef signed int S32;
+typedef unsigned int U32;
+typedef LONG64 S64;
+typedef ULONG64 U64;
+
+#ifdef SPEEDY
+// On Visual Studio 6, making the internal functions inline makes compiling take forever
+#define INTERNAL static _inline 
+#define INLINE _inline
+#else
+#define INTERNAL static
+#define INLINE
+#endif
+
+#define VALID_INSTRUCTION(i) ((i) && !((i)->ErrorOccurred))
+#define NEXT_INSTRUCTION(i) ((i)->Address + (i)->Length)
+#define DISASM_ARCH_TYPE(dis) ((dis)->ArchType)
+#define INS_ARCH_TYPE(ins) DISASM_ARCH_TYPE((ins)->Disassembler)
+
+// NOTE: these should be as big set to the maximum of the supported architectures
+#define MAX_PREFIX_LENGTH 15
+#define MAX_OPERAND_COUNT 3
+#define MAX_INSTRUCTION_LENGTH 25
+#define MAX_OPCODE_LENGTH 3
+#define MAX_OPCODE_DESCRIPTION 256
+
+/////////////////////////////////////////////////////////////////////
+// Code branch
+/////////////////////////////////////////////////////////////////////
+
+#define MAX_CODE_REFERENCE_COUNT 3
+
+typedef struct _CODE_BRANCH
+{
+	U64 Addresses[MAX_CODE_REFERENCE_COUNT]; // NULL if multiple to addresses
+	U32 Count;
+	U8 IsLoop : 1;
+	U8 IsCall : 1; // branch if false
+	U8 IsIndirect : 1; // call/jmp [Address]
+	U8 AddressOffset: 5;
+	struct _INSTRUCTION_OPERAND *Operand; // the operand containg the address
+} CODE_BRANCH;
+
+/////////////////////////////////////////////////////////////////////
+// Data references
+/////////////////////////////////////////////////////////////////////
+
+#define MAX_DATA_REFERENCE_COUNT 3
+
+typedef struct _DATA_REFERENCE
+{
+	U64 Addresses[MAX_DATA_REFERENCE_COUNT]; // NULL if multiple to addresses
+	U32 Count;
+	ULONG_PTR DataSize;
+	struct _INSTRUCTION_OPERAND *Operand; // the operand containg the address
+} DATA_REFERENCE;
+
+////////////////////////////////////////////////////////////////////
+// Instruction
+/////////////////////////////////////////////////////////////////////
+
+//
+// Instruction types (bits 0-7)
+// Instruction groups (bits 8-26)
+//
+#define ITYPE_EXEC_OFFSET     (1<<8)
+#define ITYPE_ARITH_OFFSET    (1<<9)
+#define ITYPE_LOGIC_OFFSET    (1<<10)
+#define ITYPE_STACK_OFFSET    (1<<11)
+#define ITYPE_TESTCOND_OFFSET (1<<12)
+#define ITYPE_LOAD_OFFSET     (1<<13)
+#define ITYPE_ARRAY_OFFSET    (1<<14)
+#define ITYPE_BIT_OFFSET      (1<<15)
+#define ITYPE_FLAG_OFFSET     (1<<16)
+#define ITYPE_FPU_OFFSET      (1<<17)
+#define ITYPE_TRAPS_OFFSET    (1<<18)
+#define ITYPE_SYSTEM_OFFSET   (1<<19)
+#define ITYPE_OTHER_OFFSET    (1<<20)
+#define ITYPE_UNUSED1_OFFSET  (1<<21)
+#define ITYPE_UNUSED2_OFFSET  (1<<22)
+#define ITYPE_UNUSED3_OFFSET  (1<<23)
+#define ITYPE_UNUSED4_OFFSET  (1<<24)
+#define ITYPE_UNUSED5_OFFSET  (1<<25)
+#define ITYPE_UNUSED6_OFFSET  (1<<26)
+#define ITYPE_EXT_UNUSED1     (1<<27)
+#define ITYPE_EXT_UNUSED2     (1<<28)
+#define ITYPE_EXT_UNUSED3     (1<<29)
+#define ITYPE_EXT_UNUSED4     (1<<30)
+#define ITYPE_EXT_UNUSED5     (1<<31)
+
+//
+// X86-specific flags (bits 27-31)
+//
+
+#define ITYPE_EXT_64     ITYPE_EXT_UNUSED1 // Use index 1 if in 64-bit mode and 0 otherwise
+#define ITYPE_EXT_MODRM  ITYPE_EXT_UNUSED2 // ModRM byte may extend the opcode
+#define ITYPE_EXT_SUFFIX ITYPE_EXT_UNUSED3 // byte after ModRM/SIB/displacement is the third opcode
+#define ITYPE_EXT_PREFIX ITYPE_EXT_UNUSED4 // prefix
+#define ITYPE_EXT_FPU    ITYPE_EXT_UNUSED5 // FPU instructions require special handling
+
+#define ITYPE_3DNOW_OFFSET ITYPE_UNUSED1_OFFSET
+#define ITYPE_MMX_OFFSET   ITYPE_UNUSED2_OFFSET
+#define ITYPE_SSE_OFFSET   ITYPE_UNUSED3_OFFSET
+#define ITYPE_SSE2_OFFSET  ITYPE_UNUSED4_OFFSET
+#define ITYPE_SSE3_OFFSET  ITYPE_UNUSED5_OFFSET
+
+//
+// Instruction types
+//
+
+#define ITYPE_TYPE_MASK  0x7FFFFFFF
+#define ITYPE_GROUP_MASK 0x7FFFFF00
+
+typedef enum _INSTRUCTION_TYPE
+{
+	// ITYPE_EXEC group
+	ITYPE_EXEC = ITYPE_EXEC_OFFSET,
+	ITYPE_BRANCH,
+	ITYPE_BRANCHCC, // conditional (not necessarily just flags)
+	ITYPE_CALL,
+	ITYPE_CALLCC, // conditional (not necessarily just flags)
+	ITYPE_RET,
+	ITYPE_LOOPCC,
+
+	// ITYPE_ARITH group
+	ITYPE_ARITH = ITYPE_ARITH_OFFSET,
+	ITYPE_XCHGADD,
+	ITYPE_ADD,
+	ITYPE_SUB,
+	ITYPE_MUL,
+	ITYPE_DIV,
+	ITYPE_INC,
+	ITYPE_DEC,
+	ITYPE_SHL,
+	ITYPE_SHR,
+	ITYPE_ROL,
+	ITYPE_ROR,
+
+	// ITYPE_LOGIC group
+	ITYPE_LOGIC=ITYPE_LOGIC_OFFSET,
+	ITYPE_AND,
+	ITYPE_OR,
+	ITYPE_XOR,
+	ITYPE_NOT,
+	ITYPE_NEG,
+
+	// ITYPE_STACK group
+	ITYPE_STACK=ITYPE_STACK_OFFSET,
+	ITYPE_PUSH,
+	ITYPE_POP,
+	ITYPE_PUSHA,
+	ITYPE_POPA,
+	ITYPE_PUSHF,
+	ITYPE_POPF,
+	ITYPE_ENTER,
+	ITYPE_LEAVE,
+
+	// ITYPE_TESTCOND group
+	ITYPE_TESTCOND=ITYPE_TESTCOND_OFFSET,
+		ITYPE_TEST,
+		ITYPE_CMP,
+
+	// ITYPE_LOAD group
+	ITYPE_LOAD=ITYPE_LOAD_OFFSET,
+		ITYPE_MOV,
+		ITYPE_MOVCC, // conditional
+		ITYPE_LEA,
+		ITYPE_XCHG,
+		ITYPE_XCHGCC, // conditional
+
+	// ITYPE_ARRAY group
+	ITYPE_ARRAY=ITYPE_ARRAY_OFFSET,
+		ITYPE_STRCMP,
+		ITYPE_STRLOAD,
+		ITYPE_STRMOV,
+		ITYPE_STRSTOR,
+		ITYPE_XLAT,
+
+	// ITYPE_BIT group
+	ITYPE_BIT=ITYPE_BIT_OFFSET,
+		ITYPE_BITTEST,
+		ITYPE_BITSET,
+		ITYPE_BITCLR,
+
+	// ITYPE_FLAG group
+	// PF = parify flag
+	// ZF = zero flag
+	// OF = overflow flag
+	// DF = direction flag
+	// SF = sign flag
+	ITYPE_FLAG=ITYPE_FLAG_OFFSET,
+		// clear
+		ITYPE_CLEARCF, 
+		ITYPE_CLEARZF,
+		ITYPE_CLEAROF,
+		ITYPE_CLEARDF,
+		ITYPE_CLEARSF,
+		ITYPE_CLEARPF,
+		// set
+		ITYPE_SETCF, 
+		ITYPE_SETZF,
+		ITYPE_SETOF,
+		ITYPE_SETDF,
+		ITYPE_SETSF,
+		ITYPE_SETPF,
+		// toggle
+		ITYPE_TOGCF, 
+		ITYPE_TOGZF,
+		ITYPE_TOGOF,
+		ITYPE_TOGDF,
+		ITYPE_TOGSF,
+		ITYPE_TOGPF,
+
+	// ITYPE_FPU group
+	ITYPE_FPU=ITYPE_FPU_OFFSET,
+		ITYPE_FADD,
+		ITYPE_FSUB,
+		ITYPE_FMUL,
+		ITYPE_FDIV,
+		ITYPE_FCOMP,
+		ITYPE_FEXCH,
+		ITYPE_FLOAD,
+		ITYPE_FLOADENV,
+		ITYPE_FSTORE,
+		ITYPE_FSTOREENV,
+		ITYPE_FSAVE,
+		ITYPE_FRESTORE,
+		ITYPE_FMOVCC,
+
+	ITYPE_UNUSED1=ITYPE_UNUSED1_OFFSET,
+	ITYPE_UNUSED2=ITYPE_UNUSED2_OFFSET,
+	ITYPE_UNUSED3=ITYPE_UNUSED3_OFFSET,
+
+	// ITYPE_MMX group
+	ITYPE_MMX=ITYPE_MMX_OFFSET,
+		ITYPE_MMX_MOV,
+		ITYPE_MMX_ADD,
+		ITYPE_MMX_SUB,
+		ITYPE_MMX_MUL,
+		ITYPE_MMX_DIV,
+		ITYPE_MMX_AND,
+		ITYPE_MMX_OR,
+		ITYPE_MMX_XOR,
+		ITYPE_MMX_CMP,
+
+	// ITYPE_SSE group
+	ITYPE_SSE=ITYPE_SSE_OFFSET,
+		ITYPE_SSE_MOV,
+		ITYPE_SSE_ADD,
+		ITYPE_SSE_SUB,
+		ITYPE_SSE_MUL,
+		ITYPE_SSE_DIV,
+		ITYPE_SSE_AND,
+		ITYPE_SSE_OR,
+		ITYPE_SSE_XOR,
+		ITYPE_SSE_CMP,
+		
+		// ITYPE_SSE2 group
+	ITYPE_SSE2=ITYPE_SSE2_OFFSET,
+		ITYPE_SSE2_MOV,
+		ITYPE_SSE2_ADD,
+		ITYPE_SSE2_SUB,
+		ITYPE_SSE2_MUL,
+		ITYPE_SSE2_DIV,
+		ITYPE_SSE2_AND,
+		ITYPE_SSE2_OR,
+		ITYPE_SSE2_XOR,
+		ITYPE_SSE2_CMP,
+
+	// ITYPE_SSE3 group
+	ITYPE_SSE3=ITYPE_SSE3_OFFSET,
+		ITYPE_SSE3_MOV,
+		ITYPE_SSE3_ADD,
+		ITYPE_SSE3_SUB,
+		ITYPE_SSE3_MUL,
+		ITYPE_SSE3_DIV,
+		ITYPE_SSE3_AND,
+		ITYPE_SSE3_OR,
+		ITYPE_SSE3_XOR,
+		ITYPE_SSE3_CMP,
+
+	// ITYPE_3DNOW group
+	ITYPE_3DNOW=ITYPE_3DNOW_OFFSET,
+		ITYPE_3DNOW_ADD,
+		ITYPE_3DNOW_SUB,
+		ITYPE_3DNOW_MUL,
+		ITYPE_3DNOW_DIV,
+		ITYPE_3DNOW_CMP,
+		ITYPE_3DNOW_XCHG,
+
+	// ITYPE_TRAP
+	ITYPE_TRAPS=ITYPE_TRAPS_OFFSET, 
+		ITYPE_TRAP, // generate trap
+		ITYPE_TRAPCC,  // conditional trap gen
+		ITYPE_TRAPRET,    // return from trap
+		ITYPE_BOUNDS,  // gen bounds trap
+		ITYPE_DEBUG,   // gen breakpoint trap
+		ITYPE_TRACE,   // gen single step trap
+		ITYPE_INVALID, // gen invalid instruction
+		ITYPE_OFLOW,   // gen overflow trap
+
+	// ITYPE_SYSTEM group
+	ITYPE_SYSTEM=ITYPE_SYSTEM_OFFSET,
+		ITYPE_HALT,    // halt machine
+		ITYPE_IN,      // input form port
+		ITYPE_OUT,     // output to port
+		ITYPE_CPUID,   // identify cpu
+		ITYPE_SETIF,   // allow interrupts
+		ITYPE_CLEARIF, // block interrupts
+		ITYPE_SYSCALL,
+		ITYPE_SYSCALLRET,
+
+	// ITYPE_OTHER group
+	ITYPE_OTHER = ITYPE_OTHER_OFFSET,
+		ITYPE_NOP,
+		ITYPE_BCDCONV, // convert to/from BCD
+		ITYPE_SZCONV   // convert size of operand
+} INSTRUCTION_TYPE;
+
+//
+// Operand flags
+//
+
+// Type = bits 0-6 (these are mutually exclusive -- bits 0-6 will always be a power of 2))
+#define OPTYPE_NONE    0x00
+#define OPTYPE_IMM    0x01 // immediate value
+#define OPTYPE_OFFSET 0x02 // relative offset
+#define OPTYPE_FLOAT  0x03 // floating point
+#define OPTYPE_BCD    0x04
+#define OPTYPE_STRING 0x05
+#define OPTYPE_SPECIAL 0x06
+#define OPTYPE_MASK   0x7F
+
+// Flags = bits 7-23 (these can be combinations)
+// These are used in the X86 opcode table
+#define OP_REG      (1<<7) // 0x80
+#define OP_SIGNED   (1<<8)
+#define OP_SYS      (1<<9) // parameter is an index into some system structure
+#define OP_CONDR    (1<<10)
+#define OP_CONDW    (1<<11)
+#define OP_UNUSED   (1<<12)
+#define OP_SRC      (1<<13) // operand is source operand
+#define OP_DST      (1<<14) // operand is destination operand
+#define OP_EXEC     (1<<15) // operand is executed
+
+#define OP_CONDE     OP_CONDR
+#define OP_COND_EXEC (OP_CONDE|OP_EXEC) // executed only if the pre-conditions are met
+#define OP_COND_SRC  (OP_CONDR|OP_SRC) // set only if pre-conditions are met
+#define OP_COND_DST  (OP_CONDW|OP_DST) // set only if pre-conditions are met
+#define OP_COND      (OP_CONDR|OP_CONDW)
+
+// Bits 16-31 are available for use outside of the opcode table, but they can only
+// be used in INSTRUCTION_OPERAND.Flags, they may conflit with the architecture specific
+// operands. For example, bits 16-31 are used in X86 for AMODE_* and OPTYPE_*
+#define OP_ADDRESS    (1<<16)
+#define OP_LOCAL      (1<<17)
+#define OP_PARAM      (1<<18)
+#define OP_GLOBAL     (1<<19)
+#define OP_FAR        (1<<20)
+#define OP_IPREL      (1<<21)
+
+//
+// X86-specific flags (bits 27-31)
+//
+#define OP_MSR      (OP_SYS|OP_UNUSED)
+
+//
+// Other architecture flags
+//
+#define OP_DELAY  OP_UNUSED // delayed instruction (e.g., delayed branch that executes after the next instruction)
+
+/////////////////////////////////////////////////////////////////////
+// Architectures
+/////////////////////////////////////////////////////////////////////
+
+typedef enum _ARCHITECTURE_TYPE
+{
+	ARCH_UNKNOWN=0,
+	
+	// x86-based
+	ARCH_X86,    // 32-bit x86
+	ARCH_X86_16, // 16-bit x86
+	ARCH_X64,    // AMD64 and Intel EMD64
+	
+	// everything else
+	ARCH_ALPHA,
+	ARCH_ARM,
+	ARCH_DOTNET,
+	ARCH_EFI,
+	ARCH_IA64,
+	ARCH_M68K,
+	ARCH_MIPS,
+	ARCH_PPC,
+	ARCH_SH3,
+	ARCH_SH4,
+	ARCH_SPARC,
+	ARCH_THUMB
+
+} ARCHITECTURE_TYPE;
+struct _INSTRUCTION;
+typedef BOOL (*INIT_INSTRUCTION)(struct _INSTRUCTION *Instruction);
+typedef void (*DUMP_INSTRUCTION)(struct _INSTRUCTION *Instruction, BOOL ShowBytes, BOOL Verbose);
+typedef BOOL (*GET_INSTRUCTION)(struct _INSTRUCTION *Instruction, U8 *Address, U32 Flags);
+typedef U8 *(*FIND_FUNCTION_BY_PROLOGUE)(struct _INSTRUCTION *Instruction, U8 *StartAddress, U8 *EndAddress, U32 Flags);
+
+typedef struct _ARCHITECTURE_FORMAT_FUNCTIONS
+{
+	INIT_INSTRUCTION InitInstruction;
+	DUMP_INSTRUCTION DumpInstruction;
+	GET_INSTRUCTION GetInstruction;
+	FIND_FUNCTION_BY_PROLOGUE FindFunctionByPrologue;
+} ARCHITECTURE_FORMAT_FUNCTIONS;
+
+typedef struct _ARCHITECTURE_FORMAT
+{
+	ARCHITECTURE_TYPE Type;
+	ARCHITECTURE_FORMAT_FUNCTIONS *Functions;
+} ARCHITECTURE_FORMAT;
+
+#define DISASSEMBLER_INITIALIZED 0x1234566F
+#define INSTRUCTION_INITIALIZED 0x1234567F
+
+#include "disasm_x86.h"
+
+typedef struct DECLSPEC_ALIGN(16) _S128
+{
+    U64 Low;
+    S64 High;
+} S128;
+typedef struct DECLSPEC_ALIGN(16) _U128
+{
+    U64 Low;
+    U64 High;
+} U128;
+
+typedef struct _INSTRUCTION_OPERAND
+{
+	U32 Flags;
+	U8 Type : 6;
+	U8 Unused : 2;
+	U16 Length;
+	
+
+	// If non-NULL, this indicates the target address of the instruction (e.g., a branch or
+	// a displacement with no base register). However, this address is only reliable if the
+	// image is mapped correctly (e.g., the executable is mapped as an image and fixups have
+	// been applied if it is not at its preferred image base).
+	//
+	// If disassembling a 16-bit DOS application, TargetAddress is in the context of 
+	// X86Instruction->Segment. For example, if TargetAddress is the address of a code branch, 
+	// it is in the CS segment (unless X86Instruction->HasSegmentOverridePrefix is set). If 
+	// TargetAddress is a data pointer, it is in the DS segment (unless 
+	// X86Instruction->HasSegmentOverridePrefix is set)
+	U64 TargetAddress;
+	U32 Register;
+
+	union
+	{
+		// All 8/16/32-bit operands are extended to 64-bits automatically
+		// If you want to downcast, check whether Flags & OP_SIGNED is set
+		// Like this:
+		// U32 GetOperand32(OPERAND *Operand)
+		// {
+		//	if (Operand->Flags & OP_SIGNED) return (S32)Operand->Value_S64;
+		//	else return (U32)Operand->Value_U64;
+		//}
+		U64 Value_U64;
+		S64 Value_S64;
+		U128 Value_U128;
+		U128 Float128;
+		U8 Float80[80];
+		U8 BCD[10];
+	};
+} INSTRUCTION_OPERAND;
+
+typedef struct _INSTRUCTION
+{
+	U32 Initialized;
+	struct _DISASSEMBLER *Disassembler;
+
+	char String[MAX_OPCODE_DESCRIPTION];
+	U8 StringIndex;
+	U64 VirtualAddressDelta;
+
+	U32 Groups; // ITYPE_EXEC, ITYPE_ARITH, etc. -- NOTE groups can be OR'd together
+	INSTRUCTION_TYPE Type; // ITYPE_ADD, ITYPE_RET, etc. -- NOTE there is only one possible type
+
+	U8 *Address;
+	U8 *OpcodeAddress;
+	U32 Length;
+
+	U8 Prefixes[MAX_PREFIX_LENGTH];
+	U32 PrefixCount;
+
+	U8 LastOpcode; // last byte of opcode
+	U8 OpcodeBytes[MAX_OPCODE_LENGTH];
+	U32 OpcodeLength; // excludes any operands and prefixes
+
+	INSTRUCTION_OPERAND Operands[MAX_OPERAND_COUNT];
+	U32 OperandCount;
+
+	X86_INSTRUCTION X86;
+
+	DATA_REFERENCE DataSrc;
+	DATA_REFERENCE DataDst;
+	CODE_BRANCH CodeBranch;
+
+	// Direction depends on which direction the stack grows
+	// For example, on x86 a push results in StackChange < 0 since the stack grows down
+	// This is only relevant if (Group & ITYPE_STACK) is true
+	//
+	// If Groups & ITYPE_STACK is set but StackChange = 0, it means that the change
+	// couldn't be determined (non-constant)
+	LONG StackChange;
+
+	// Used to assist in debugging
+	// If set, the current instruction is doing something that requires special handling
+	// For example, popf can cause tracing to be disabled
+
+	U8 StringAligned : 1; // internal only
+	U8 NeedsEmulation : 1; // instruction does something that re
+	U8 Repeat : 1; // instruction repeats until some condition is met (e.g., REP prefix on X86)
+	U8 ErrorOccurred : 1; // set if instruction is invalid
+	U8 AnomalyOccurred : 1; // set if instruction is anomalous
+	U8 LastInstruction : 1; // tells the iterator callback it is the last instruction
+	U8 CodeBlockFirst: 1;
+	U8 CodeBlockLast : 1;
+} INSTRUCTION;
+
+typedef struct _DISASSEMBLER
+{
+	U32 Initialized;
+	ARCHITECTURE_TYPE ArchType;
+	ARCHITECTURE_FORMAT_FUNCTIONS *Functions;
+	INSTRUCTION Instruction;
+	U32 Stage1Count; // GetInstruction called
+	U32 Stage2Count; // Opcode fully decoded
+	U32 Stage3CountNoDecode;   // made it through all checks when DISASM_DECODE is not set
+	U32 Stage3CountWithDecode; // made it through all checks when DISASM_DECODE is set
+} DISASSEMBLER;
+
+#define DISASM_DISASSEMBLE         (1<<1)
+#define DISASM_DECODE              (1<<2)
+#define DISASM_SUPPRESSERRORS      (1<<3)
+#define DISASM_SHOWFLAGS           (1<<4)
+#define DISASM_ALIGNOUTPUT         (1<<5)
+#define DISASM_DISASSEMBLE_MASK (DISASM_ALIGNOUTPUT|DISASM_SHOWBYTES|DISASM_DISASSEMBLE)
+
+BOOL InitDisassembler(DISASSEMBLER *Disassembler, ARCHITECTURE_TYPE Architecture);
+void CloseDisassembler(DISASSEMBLER *Disassembler);
+INSTRUCTION *GetInstruction(DISASSEMBLER *Disassembler, U64 VirtualAddress, U8 *Address, U32 Flags);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // DISASM_H
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86.c b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86.c
new file mode 100644
index 0000000..2db04f3
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86.c
@@ -0,0 +1,4667 @@
+// Copyright (C) 2004, Matt Conover (mconover@gmail.com)
+#undef NDEBUG
+#include <assert.h>
+#include "disasm.h"
+#include "cpu.h"
+
+// Since addresses are internally represented as 64-bit, we need to specially handle
+// cases where IP + Displacement wraps around for 16-bit/32-bit operand size
+// Otherwise, ignorethe possibility of wraparounds
+#define SUPPORT_WRAPAROUND
+
+#ifdef NO_SANITY_CHECKS
+#undef NDEBUG
+#undef DEBUG_DISASM
+#undef assert
+#define assert(x)
+#endif
+
+#ifdef DEBUG_DISASM
+#define DISASM_OUTPUT(x) printf x
+#else
+#define DISASM_OUTPUT(x)
+#endif
+
+#include "disasm_x86_tables.h"
+
+#ifdef _WIN64
+#pragma warning(disable:4311 4312)
+#endif
+
+////////////////////////////////////////////////////////////////////////
+// Internal macros
+////////////////////////////////////////////////////////////////////////
+
+#define VIRTUAL_ADDRESS ((U64)Instruction->Address + Instruction->VirtualAddressDelta)
+
+#define AMD64_DIFF (AMD64_8BIT_OFFSET-X86_8BIT_OFFSET)
+#define IS_AMD64() (INS_ARCH_TYPE(Instruction) == ARCH_X64)
+#define IS_X86_32() (INS_ARCH_TYPE(Instruction) == ARCH_X86)
+#define IS_X86_16() (INS_ARCH_TYPE(Instruction) == ARCH_X86_16)
+
+#define X86_BOUND 0x62
+#define X86_PUSH_REG 0x50
+#define X86_PUSH_CS 0x0e
+#define X86_PUSH_DS 0x1e
+#define X86_PUSH_SS 0x16
+#define X86_PUSH_ES 0x06
+#define X86_PUSH_FS 0xa0
+#define X86_PUSH_GS 0xa8
+#define X86_PUSH_U8 0x6a
+#define X86_PUSH_U32 0x68
+#define X86_POP_DS 0x1f
+#define X86_POP_ES 0x07
+#define X86_POP_SS 0x17
+#define X86_POP_FS 0xa1
+#define X86_POP_GS 0xa9
+#define X86_POP_REG 0x58
+
+#define OPCSTR Instruction->String+Instruction->StringIndex
+#if defined(WIN32)
+#define APPEND Instruction->StringIndex += (U8)_snprintf
+#else
+#define APPEND Instruction->StringIndex += (U8)snprintf
+#endif
+
+#define APPENDPAD(x) \
+{ \
+	if (Instruction->StringAligned) \
+	{  \
+			if (Instruction->StringIndex > x) assert(0); \
+			while (x != Instruction->StringIndex) APPENDB(' ');  \
+	}  \
+	else if (Instruction->StringIndex) \
+	{  \
+		APPENDB(' '); \
+	} \
+}
+
+#define APPENDB(a) Instruction->String[Instruction->StringIndex++] = a
+#define APPENDS(a) APPEND(OPCSTR, SIZE_LEFT, a);
+
+#define SIZE_LEFT (MAX_OPCODE_DESCRIPTION-1 > Instruction->StringIndex ? MAX_OPCODE_DESCRIPTION-Instruction->StringIndex : 0)
+
+// If an address size prefix is used for an instruction that doesn't make sense, restore it
+// to the default
+
+#define SANITY_CHECK_OPERAND_SIZE() \
+{ \
+	if (!Instruction->AnomalyOccurred && X86Instruction->HasOperandSizePrefix) \
+	{ \
+		if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Unexpected operand size prefix\n", VIRTUAL_ADDRESS); \
+		Instruction->AnomalyOccurred = TRUE; \
+		X86Instruction->HasOperandSizePrefix = FALSE; \
+		switch (X86Instruction->OperandSize) \
+		{ \
+			case 4: X86Instruction->OperandSize = 2; break; \
+			case 2: X86Instruction->OperandSize = 4; break; \
+			default: assert(0); \
+		} \
+	} \
+}
+
+#define SANITY_CHECK_ADDRESS_SIZE() \
+{ \
+	if (!Instruction->AnomalyOccurred && X86Instruction->HasAddressSizePrefix) \
+	{ \
+		if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Unexpected address size prefix\n", VIRTUAL_ADDRESS); \
+		Instruction->AnomalyOccurred = TRUE; \
+	} \
+	X86Instruction->HasAddressSizePrefix = FALSE; \
+	switch (INS_ARCH_TYPE(Instruction)) \
+	{ \
+		case ARCH_X64: X86Instruction->AddressSize = 8; break; \
+		case ARCH_X86: X86Instruction->AddressSize = 4; break; \
+		case ARCH_X86_16: X86Instruction->AddressSize = 2; break; \
+	} \
+}
+
+#define SANITY_CHECK_SEGMENT_OVERRIDE() \
+	if (!Instruction->AnomalyOccurred && X86Instruction->HasSegmentOverridePrefix) \
+	{ \
+		if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Unexpected segment override\n", VIRTUAL_ADDRESS); \
+		Instruction->AnomalyOccurred = TRUE; \
+	}
+
+#define INSTR_INC(size) \
+{ \
+	Instruction->Length += size; \
+	Address += size; \
+}
+
+#define X86_SET_TARGET() \
+{ \
+	if (X86Instruction->HasSelector) \
+	{ \
+		if (!Instruction->AnomalyOccurred) \
+		{ \
+			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: unexpected segment 0x%02X\n", VIRTUAL_ADDRESS, X86Instruction->Selector); \
+			Instruction->AnomalyOccurred = TRUE; \
+		} \
+	} \
+	else \
+	{ \
+		switch (X86Instruction->Segment) \
+		{ \
+			case SEG_CS: \
+			case SEG_DS: \
+			case SEG_SS: \
+			case SEG_ES: \
+				assert(!X86Instruction->HasSelector); \
+				Operand->TargetAddress = (U64)X86Instruction->Displacement; \
+				/* assert(!GetAbsoluteAddressFromSegment((BYTE)X86Instruction->Segment, (DWORD)X86Instruction->Displacement) || GetAbsoluteAddressFromSegment(X86Instruction->Segment, (DWORD)X86Instruction->Displacement) == Operand->TargetAddress); */ \
+				break; \
+			case SEG_FS: \
+			case SEG_GS: \
+				assert(!X86Instruction->HasSelector); \
+				Operand->TargetAddress = (U64)GetAbsoluteAddressFromSegment((BYTE)X86Instruction->Segment, (DWORD)X86Instruction->Displacement); \
+				break; \
+			default: \
+				assert(0); /* shouldn't be possible */ \
+				break; \
+		} \
+	} \
+}
+
+#define X86_SET_SEG(reg) \
+{ \
+	if (!X86Instruction->HasSegmentOverridePrefix && (reg == REG_EBP || reg == REG_ESP)) \
+	{ \
+		assert(!X86Instruction->HasSelector); \
+		X86Instruction->Segment = SEG_SS; \
+	} \
+}
+
+#define X86_SET_ADDR() \
+{ \
+	if (Operand->Flags & OP_DST) \
+	{ \
+		assert(!X86Instruction->HasDstAddressing); \
+		X86Instruction->HasDstAddressing = TRUE; \
+		X86Instruction->DstOpIndex[X86Instruction->DstOpCount] = (U8)OperandIndex; \
+		X86Instruction->DstOpCount++; \
+		X86Instruction->DstAddressIndex = (U8)OperandIndex; \
+	} \
+	if (Operand->Flags & OP_SRC) \
+	{ \
+		if (Instruction->Type != ITYPE_STRCMP) assert(!X86Instruction->HasSrcAddressing); \
+		X86Instruction->HasSrcAddressing = TRUE; \
+		X86Instruction->SrcOpIndex[X86Instruction->SrcOpCount] = (U8)OperandIndex; \
+		X86Instruction->SrcOpCount++; \
+		X86Instruction->SrcAddressIndex = (U8)OperandIndex; \
+	} \
+}
+
+#define X86_SET_REG(reg) \
+{ \
+	if (Operand->Flags & OP_DST) \
+	{ \
+		X86Instruction->DstOpIndex[X86Instruction->DstOpCount] = (U8)OperandIndex; \
+		X86Instruction->DstOpCount++; \
+		assert(OperandIndex < 2); \
+		if (Operand->Length > 1 && reg == REG_ESP) Instruction->Groups |= ITYPE_STACK; \
+	} \
+	if (Operand->Flags & OP_SRC) \
+	{ \
+		X86Instruction->SrcOpIndex[X86Instruction->SrcOpCount] = (U8)OperandIndex; \
+		X86Instruction->SrcOpCount++; \
+	} \
+} 
+
+#define CHECK_AMD64_REG() { if (IS_AMD64()) Operand->Register += AMD64_DIFF; }
+
+////////////////////////////////////////////////////////////////////////
+// Internal structures/variables
+////////////////////////////////////////////////////////////////////////
+
+ARCHITECTURE_FORMAT_FUNCTIONS X86 = 
+{
+	X86_InitInstruction, 
+	NULL,
+	X86_GetInstruction,
+	X86_FindFunctionByPrologue 
+};
+
+char *X86_Registers[0xE0] = 
+{
+	// Segments
+	"es", // 0x00
+	"cs", // 0x01
+	"ss", // 0x02
+	"ds", // 0x03
+	"fs", // 0x04
+	"gs", // 0x05
+	"flags", // 0x06
+	"eflags", // 0x07
+	"rflags", // 0x08
+	"ip+ilen", // 0x09
+	"eip+ilen", // 0x0A
+	"rip+ilen", // 0x0B
+	NULL, // 0x0C
+	NULL, // 0x0D
+	NULL, // 0x0E
+	NULL, // 0x0F
+
+	// Test
+	"tr0", // 0x10
+	"tr1", // 0x11
+	"tr2", // 0x12
+	"tr3", // 0x13
+	"tr4", // 0x14
+	"tr5", // 0x15
+	"tr6", // 0x16
+	"tr7", // 0x17
+	"tr8", // 0x18
+	"tr9", // 0x19
+	"tr10", // 0x1A
+	"tr11", // 0x1B
+	"tr12", // 0x1C
+	"tr13", // 0x1D
+	"tr14", // 0x1E
+	"tr15", // 0x1F
+
+	// Control
+	"cr0", // 0x20
+	"cr1", // 0x21
+	"cr2", // 0x22
+	"cr3", // 0x23
+	"cr4", // 0x24
+	"cr5", // 0x25
+	"cr6", // 0x26
+	"cr7", // 0x27
+	"cr8", // 0x18
+	"cr9", // 0x19
+	"cr10", // 0x1A
+	"cr11", // 0x1B
+	"cr12", // 0x1C
+	"cr13", // 0x1D
+	"cr14", // 0x1E
+	"cr15", // 0x1F
+
+	// Debug
+	"dr0", // 0x30
+	"dr1", // 0x31
+	"dr2", // 0x32
+	"dr3", // 0x33
+	"dr4", // 0x34
+	"dr5", // 0x35
+	"dr6", // 0x36
+	"dr7", // 0x37
+	"dr8", // 0x38
+	"dr9", // 0x39
+	"dr10", // 0x3A
+	"dr11", // 0x3B
+	"dr12", // 0x3C
+	"dr13", // 0x3D
+	"dr14", // 0x3E
+	"dr15", // 0x3F
+
+	// FPU
+	"st(0)", // 0x40
+	"st(1)", // 0x41
+	"st(2)", // 0x42
+	"st(3)", // 0x43
+	"st(4)", // 0x44
+	"st(5)", // 0x45
+	"st(6)", // 0x46
+	"st(7)", // 0x47
+	NULL, // 0x48
+	NULL, // 0x49
+	NULL, // 0x4A
+	NULL, // 0x4B
+	NULL, // 0x4C
+	NULL, // 0x4D
+	NULL, // 0x4E
+	NULL, // 0x4F
+
+	// MMX
+	"mm0", // 0x50
+	"mm1", // 
+	"mm2",
+	"mm3",
+	"mm4",
+	"mm5",
+	"mm6",
+	"mm7",
+	NULL, // 0x58
+	NULL, // 0x59
+	NULL, // 0x5A
+	NULL, // 0x5B
+	NULL, // 0x5C
+	NULL, // 0x5D
+	NULL, // 0x5E
+	NULL, // 0x5F
+
+	// XMM
+	"xmm0", // 0x60
+	"xmm1", // 0x61
+	"xmm2", // 0x62
+	"xmm3", // 0x63
+	"xmm4", // 0x64
+	"xmm5", // 0x65
+	"xmm6", // 0x66
+	"xmm7", // 0x67
+	"xmm8", // 0x68
+	"xmm9", // 0x69
+	"xmm10", // 0x6a
+	"xmm11", // 0x6b
+	"xmm12", // 0x6c
+	"xmm13", // 0x6d
+	"xmm14", // 0x6e
+	"xmm15", // 0x6f
+
+	// 8-bit
+	"al", // 0x70
+	"cl", // 0x71
+	"dl", // 0x72
+	"bl", // 0x73
+	"ah", // 0x74
+	"ch", // 0x75
+	"dh", // 0x76
+	"bh", // 0x77
+ 	NULL, // 0x78
+	NULL, // 0x79
+	NULL, // 0x7A
+	NULL, // 0x7B
+	NULL, // 0x7C
+	NULL, // 0x7D
+	NULL, // 0x7E
+	NULL, // 0x7F
+
+	// 16-bit
+	"ax", // 0x80
+	"cx", // 0x81
+	"dx", // 0x82
+	"bx", // 0x83
+	"sp", // 0x84
+	"bp", // 0x85
+	"si", // 0x86
+	"di", // 0x87
+	NULL, // 0x88
+	NULL, // 0x89
+	NULL, // 0x8A
+	NULL, // 0x8B
+	NULL, // 0x8C
+	NULL, // 0x8D
+	NULL, // 0x8E
+	NULL, // 0x8F
+
+	// 32-bit
+	"eax", // 0x90
+	"ecx", // 0x91
+	"edx", // 0x92
+	"ebx", // 0x93
+	"esp", // 0x94
+	"ebp", // 0x95
+	"esi", // 0x96
+	"edi", // 0x97
+	NULL, // 0x98
+	NULL, // 0x99
+	NULL, // 0x9A
+	NULL, // 0x9B
+	NULL, // 0x9C
+	NULL, // 0x9D
+	NULL, // 0x9E
+	NULL, // 0x9F
+
+	// X86-64 8-bit register
+	"al", // 0xA0
+	"cl", // 0xA1
+	"dl", // 0xA2
+	"bl", // 0xA3
+	"spl", // 0xA4
+	"bpl", // 0xA5
+	"sil", // 0xA6
+	"dil", // 0xA7
+	"r8b", // 0xA8
+	"r9b", // 0xA9
+	"r10b", // 0xAA
+	"r11b", // 0xAB
+	"r12b", // 0xAC
+	"r13b", // 0xAD
+	"r14b", // 0xAE
+	"r15b", // 0xAF
+
+	// X86-64 16-bit register	
+	"ax", // 0xB0
+	"cx", // 0xB1
+	"dx", // 0xB2
+	"bx", // 0xB3
+	"sp", // 0xB4
+	"bp", // 0xB5
+	"si", // 0xB6
+	"di", // 0xB7
+	"r8w", // 0xB8
+	"r9w", // 0xB9
+	"r10w", // 0xBA
+	"r11w", // 0xBB
+	"r12w", // 0xBC
+	"r13w", // 0xBD
+	"r14w", // 0xBE
+	"r15w", // 0xBF
+
+	// X86-64 32-bit register
+	"eax", // 0xC0
+	"ecx", // 0xC1
+	"edx", // 0xC2
+	"ebx", // 0xC3
+	"esp", // 0xC4
+	"ebp", // 0xC5
+	"esi", // 0xC6
+	"edi", // 0xC7
+	"r8d", // 0xC8
+	"r9d", // 0xC9
+	"r10d", // 0xCA
+	"r11d", // 0xCB
+	"r12d", // 0xCC
+	"r13d", // 0xCD
+	"r14d", // 0xCE
+	"r15d", // 0xCF
+
+	// X86-64 64-bit register	
+	"rax", // 0xD0
+	"rcx", // 0xD1
+	"rdx", // 0xD2
+	"rbx", // 0xD3
+	"rsp", // 0xD4
+	"rbp", // 0xD5
+	"rsi", // 0xD6
+	"rdi", // 0xD7
+	"r8", // 0xD8
+	"r9", // 0xD9
+	"r10", // 0xDA
+	"r11", // 0xDB
+	"r12", // 0xDC
+	"r13", // 0xDD
+	"r14", // 0xDE
+	"r15" // 0xDF
+};
+
+void OutputBounds(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputDescriptor(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputSegOffset(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputPackedReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputPackedBCD(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputScalarReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputScalarGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputFPUEnvironment(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputFPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+void OutputCPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+
+typedef void (*OUTPUT_OPTYPE)(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex);
+#define OPTYPE_SHIFT 24
+#define MAX_OPTYPE_INDEX 26
+OUTPUT_OPTYPE OptypeHandlers[] =
+{
+	NULL,
+	OutputBounds,         // 01 OPTYPE_a
+	OutputGeneral,        // 02 OPTYPE_b
+	OutputGeneral,        // 03 OPTYPE_d
+	OutputSegOffset,      // 04 OPTYPE_p
+	OutputGeneral,        // 05 OPTYPE_q
+	OutputDescriptor,     // 06 OPTYPE_dt
+	OutputGeneral,        // 07 OPTYPE_v
+	OutputGeneral,        // 08 OPTYPE_w
+	OutputPackedReal,     // 09 OPTYPE_ps
+	OutputPackedReal,     // 0A OPTYPE_pd
+	OutputPackedBCD,      // 0B OPTYPE_pb
+	OutputScalarReal,     // 0C OPTYPE_ss
+	OutputScalarReal,     // 0D OPTYPE_sd
+	OutputScalarReal,     // 0E OPTYPE_se
+	OutputFPUEnvironment, // 0F OPTYPE_fev
+	OutputFPUState,       // 10 OPTYPE_fst1
+	OutputFPUState,       // 11 OPTYPE_fst2
+	OutputGeneral,        // 12 OPTYPE_z
+	OutputGeneral,        // 13 OPTYPE_o
+	OutputGeneral,        // 14 OPTYPE_dq
+	OutputGeneral,        // 15 OPTYPE_mw
+	OutputScalarGeneral,  // 16 OPTYPE_sso
+	OutputScalarGeneral,  // 17 OPTYPE_sdo
+	OutputCPUState,       // 18 OPTYPE_cpu
+	OutputGeneral,        // 19 OPTYPE_lea
+};
+
+#define OPTYPE_a    0x01000000
+#define OPTYPE_b    0x02000000
+#define OPTYPE_d    0x03000000
+#define OPTYPE_p    0x04000000
+#define OPTYPE_q    0x05000000
+#define OPTYPE_dt   0x06000000
+#define OPTYPE_v    0x07000000
+#define OPTYPE_w    0x08000000
+#define OPTYPE_ps   0x09000000 // packed 128-bit single real
+#define OPTYPE_pd   0x0A000000 // packed 128-bit double real
+#define OPTYPE_pb	  0x0B000000 // packed BCD (10 bytes, 18-bit precision)
+#define OPTYPE_ss   0x0C000000 // scalar single real
+#define OPTYPE_sd   0x0D000000 // scalar double real
+#define OPTYPE_se   0x0E000000 // scalar extended real
+#define OPTYPE_fev  0x0F000000 // FPU environment (28 bytes if 32-bit modes, 14 bytes in 16-bit mode)
+#define OPTYPE_fst1 0x10000000 // FPU state (108 bytes in 32-bit modes, 94 bytes in 16-bit real mode)
+#define OPTYPE_fst2 0x11000000 // FPU/MMX/XMM/MXCSR state (512 bytes)
+#define OPTYPE_z	  0x12000000
+#define OPTYPE_o	  0x13000000
+#define OPTYPE_dq   0x14000000 // OPTYPE_d or OPTYPE_o
+#define OPTYPE_mw   0x15000000 // word if memory, register size otherwise
+#define OPTYPE_sso  0x16000000 // OPTYPE_ss or OPTYPE_o
+#define OPTYPE_sdo  0x17000000 // OPTYPE_ss or OPTYPE_o
+#define OPTYPE_cpu  0x18000000 // pointer to CPU state structure
+#define OPTYPE_lea  0x19000000 // size set by other operand
+
+////////////////////////////////////////////////////////////////////////
+// Internal functions
+////////////////////////////////////////////////////////////////////////
+
+#ifdef TEST_DISASM // TODO: remove
+U32 X86_GetLength(INSTRUCTION *Instruction, U8 *Address);
+#endif
+
+INTERNAL BOOL IsValidLockPrefix(X86_INSTRUCTION *Instruction, U8 Opcode, U32 OpcodeLength, U8 Group, U8 OpcodeExtension);
+INTERNAL U8 *SetOperands(INSTRUCTION *Instruction, U8 *Address, U32 Flags);
+INTERNAL U8 *SetModRM32(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors);
+INTERNAL U8 *SetModRM16(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors);
+INTERNAL U8 *SetSIB(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors);
+INTERNAL U64 ApplyDisplacement(U64 Address, INSTRUCTION *Instruction);
+
+//////////////////////////////////////////////////////////
+// Instruction setup
+//////////////////////////////////////////////////////////
+
+#define APPLY_OFFSET(addr) \
+{ \
+	switch (X86Instruction->OperandSize) \
+	{ \
+		case 8: addr = ((U64)(addr + Instruction->VirtualAddressDelta)); break; \
+		case 4: addr = (U64)((U32)(addr + Instruction->VirtualAddressDelta)); break; \
+		case 2: addr = (U64)((U8)(addr + Instruction->VirtualAddressDelta)); break; \
+		default: assert(0); break; \
+	} \
+}
+
+BOOL X86_InitInstruction(INSTRUCTION *Instruction)
+{
+	X86_INSTRUCTION *X86Instruction;
+#ifdef NO_SANITY_CHECKS
+	assert(0); // be sure assertions are disabled
+#endif
+	X86Instruction = &Instruction->X86;
+	memset(X86Instruction, 0, sizeof(X86_INSTRUCTION));
+	
+	switch (INS_ARCH_TYPE(Instruction))
+	{
+		case ARCH_X64:
+			X86Instruction->AddressSize = 8;
+			X86Instruction->OperandSize = 4;
+			break;
+		case ARCH_X86:
+			X86Instruction->AddressSize = 4;
+			X86Instruction->OperandSize = 4;
+			break;
+		case ARCH_X86_16:
+			X86Instruction->AddressSize = 2;
+			X86Instruction->OperandSize = 2;
+			break;
+		default:
+			assert(0);
+			return FALSE;
+	}
+	X86Instruction->Instruction = Instruction;
+	X86Instruction->Segment = SEG_DS;
+	return TRUE;
+}
+
+////////////////////////////////////////////////////////////
+// Formatting
+// You can change these to whatever you prefer
+////////////////////////////////////////////////////////////
+
+#define X86_WRITE_OPFLAGS() \
+	if (Flags & DISASM_SHOWFLAGS) \
+	{ \
+		APPENDB('{'); \
+		assert(Operand->Flags & (OP_EXEC|OP_SRC|OP_DST)); \
+		if (Operand->Flags & OP_IPREL) APPENDB('r'); \
+		if (Operand->Flags & OP_FAR) APPENDB('f'); \
+		if (Operand->Flags & OP_CONDR) APPENDB('c'); \
+		if (Operand->Flags & OP_EXEC) APPENDB('X'); \
+		else if (Operand->Flags & OP_SRC) APPENDB('R'); \
+		if (Operand->Flags & OP_CONDW) APPENDB('c'); \
+		if (Operand->Flags & OP_DST) APPENDB('W'); \
+		if (Operand->Flags & OP_SYS) APPENDB('S'); \
+		if (Operand->Flags & OP_ADDRESS) APPENDB('A'); \
+		if (Operand->Flags & OP_PARAM) APPENDB('P'); \
+		if (Operand->Flags & OP_LOCAL) APPENDB('L'); \
+		if (Operand->Flags & OP_GLOBAL) APPENDB('G'); \
+		APPENDB('}'); \
+	}
+
+#define X86_WRITE_IMMEDIATE() \
+{ \
+	switch (Operand->Length) \
+	{ \
+		case 8: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%02I64X=", Operand->Value_U64); \
+			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%I64u", Operand->Value_U64); \
+			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02I64X=%I64d", -Operand->Value_S64, Operand->Value_S64);*/ \
+			else APPEND(OPCSTR, SIZE_LEFT, "%I64d", Operand->Value_S64); \
+			break; \
+		case 4: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%02lX=", (U32)Operand->Value_U64); \
+			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%lu", (U32)Operand->Value_U64); \
+			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02lX=%ld", (U32)-Operand->Value_S64, (S32)Operand->Value_S64);*/ \
+			else APPEND(OPCSTR, SIZE_LEFT, "%ld", (S32)Operand->Value_S64); \
+			break; \
+		case 2: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%02X=", (U16)Operand->Value_U64); \
+			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%u", (U16)Operand->Value_U64); \
+			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02X=%d", (U16)-Operand->Value_S64, (S16)Operand->Value_S64);*/ \
+			else APPEND(OPCSTR, SIZE_LEFT, "%d", (S16)Operand->Value_S64); \
+			break; \
+		case 1: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%02X=", (U8)Operand->Value_U64); \
+			if (Operand->Value_S64 >= 0 || !(Operand->Flags & OP_SIGNED)) APPEND(OPCSTR, SIZE_LEFT, "%u", (U8)Operand->Value_U64); \
+			/*else APPEND(OPCSTR, SIZE_LEFT, "-0x%02X=%d", (U8)-Operand->Value_S64, (S8)Operand->Value_S64);*/ \
+			else APPEND(OPCSTR, SIZE_LEFT, "%d", (S8)Operand->Value_S64); \
+			break; \
+		default: assert(0); break; \
+	} \
+}
+
+#define X86_WRITE_ABSOLUTE_DISPLACEMENT() \
+{  \
+	switch (X86Instruction->AddressSize) \
+	{ \
+		case 8: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%04I64X", X86Instruction->Displacement); \
+			break; \
+		case 4: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%04lX", (U32)X86Instruction->Displacement); \
+			break; \
+		case 2: \
+			APPEND(OPCSTR, SIZE_LEFT, "0x%04X", (U16)X86Instruction->Displacement); \
+			break; \
+		default: assert(0); break; \
+	} \
+}
+
+#define X86_WRITE_RELATIVE_DISPLACEMENT64() \
+	if (X86Instruction->Displacement >= 0) APPEND(OPCSTR, SIZE_LEFT, "+0x%02I64X", X86Instruction->Displacement); \
+	else APPEND(OPCSTR, SIZE_LEFT, "-0x%02I64X", -X86Instruction->Displacement);
+
+#define X86_WRITE_RELATIVE_DISPLACEMENT32() \
+	if (X86Instruction->Displacement >= 0) APPEND(OPCSTR, SIZE_LEFT, "+0x%02lX", (U32)X86Instruction->Displacement); \
+	else APPEND(OPCSTR, SIZE_LEFT, "-0x%02lX", (U32)-X86Instruction->Displacement);
+
+#define X86_WRITE_RELATIVE_DISPLACEMENT16() \
+	if (X86Instruction->Displacement >= 0) APPEND(OPCSTR, SIZE_LEFT, "+0x%02X", (U16)X86Instruction->Displacement); \
+	else APPEND(OPCSTR, SIZE_LEFT, "-0x%02X", (U16)-X86Instruction->Displacement);
+
+#define X86_WRITE_RELATIVE_DISPLACEMENT() \
+{  \
+	switch (X86Instruction->AddressSize) \
+	{ \
+		case 8: \
+			X86_WRITE_RELATIVE_DISPLACEMENT64() \
+			break; \
+		case 4: \
+			X86_WRITE_RELATIVE_DISPLACEMENT32() \
+			break; \
+		case 2: \
+			X86_WRITE_RELATIVE_DISPLACEMENT16() \
+			break; \
+		default: assert(0); break; \
+	} \
+}
+
+#define X86_WRITE_IP_OFFSET(op) \
+{ \
+	switch (X86Instruction->OperandSize) \
+	{ \
+		case 8: \
+			APPENDS("[rip+ilen"); \
+			assert((op)->TargetAddress); \
+			X86_WRITE_RELATIVE_DISPLACEMENT64() \
+			APPEND(OPCSTR, SIZE_LEFT, "]=0x%04I64X", (op)->TargetAddress+Instruction->VirtualAddressDelta); \
+			break; \
+		case 4: \
+			APPENDS("[eip+ilen"); \
+			assert((op)->TargetAddress); \
+			X86_WRITE_RELATIVE_DISPLACEMENT32() \
+			APPEND(OPCSTR, SIZE_LEFT, "]=0x%04lX", (U32)((op)->TargetAddress+Instruction->VirtualAddressDelta)); \
+			break; \
+		case 2: \
+			APPENDS("[ip+ilen"); \
+			X86_WRITE_RELATIVE_DISPLACEMENT16() \
+			APPEND(OPCSTR, SIZE_LEFT, "]=0x%04X", (U16)((op)->TargetAddress+Instruction->VirtualAddressDelta)); \
+			break; \
+		default: assert(0); break; \
+	} \
+}
+
+#define X86_WRITE_OFFSET(op) \
+{ \
+	assert((op)->Length <= 8); \
+	if (X86Instruction->HasSelector) \
+	{ \
+		assert((op)->Flags & OP_FAR); \
+		APPEND(OPCSTR, SIZE_LEFT, "%s 0x%02X:[", DataSizes[((op)->Length >> 1)], X86Instruction->Selector); \
+	} \
+	else \
+	{ \
+		assert(!((op)->Flags & OP_FAR)); \
+		assert(X86Instruction->Segment < SEG_MAX) ; \
+		APPEND(OPCSTR, SIZE_LEFT, "%s %s:[", DataSizes[((op)->Length >> 1)], Segments[X86Instruction->Segment]); \
+	} \
+	X86_WRITE_ABSOLUTE_DISPLACEMENT() \
+	APPENDB(']'); \
+}
+
+void OutputAddress(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	BOOL ShowDisplacement = FALSE;
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+
+	assert(!X86Instruction->HasSelector);
+	assert(X86Instruction->SrcAddressIndex == OperandIndex || X86Instruction->DstAddressIndex == OperandIndex);
+	if (Operand->Length > 16 || (Operand->Length > 1 && (Operand->Length & 1))) APPEND(OPCSTR, SIZE_LEFT, "%d_byte ptr ", Operand->Length);
+	else APPEND(OPCSTR, SIZE_LEFT, "%s ", DataSizes[Operand->Length >> 1]);
+
+	//
+	// This attempts to display the address intelligently
+	// If it has a positive 32-bit displacement, it is shown as seg:Displacement[base+index*scale]
+	// If it is a negative displacement or 8-bit, it is shown as seg:[base+index*scale+displacement]
+	//
+	APPEND(OPCSTR, SIZE_LEFT, "%s:", Segments[X86Instruction->Segment]);
+	if (X86Instruction->HasBaseRegister)
+	{
+		if (X86Instruction->Displacement)
+		{
+			if (X86Instruction->HasFullDisplacement) X86_WRITE_ABSOLUTE_DISPLACEMENT()
+			else ShowDisplacement = TRUE;
+		}
+		APPEND(OPCSTR, SIZE_LEFT, "[%s", X86_Registers[X86Instruction->BaseRegister]);
+		if (X86Instruction->HasIndexRegister)
+		{
+			APPEND(OPCSTR, SIZE_LEFT, "+%s", X86_Registers[X86Instruction->IndexRegister]);
+			if (X86Instruction->Scale > 1) APPEND(OPCSTR, SIZE_LEFT, "*%d", X86Instruction->Scale);
+		}
+		if (ShowDisplacement) X86_WRITE_RELATIVE_DISPLACEMENT()
+		APPENDB(']');
+		if (X86Instruction->Relative)
+		{
+			U64 Address = Operand->TargetAddress;
+			assert(Address);
+			APPLY_OFFSET(Address)
+			APPEND(OPCSTR, SIZE_LEFT, "=[0x%04I64X]", Address);
+		}
+	}
+	else if (X86Instruction->HasIndexRegister)
+	{
+		if (X86Instruction->Displacement)
+		{
+			if (X86Instruction->HasFullDisplacement) X86_WRITE_ABSOLUTE_DISPLACEMENT()
+			else ShowDisplacement = TRUE;
+		}
+		APPEND(OPCSTR, SIZE_LEFT, "[%s", X86_Registers[X86Instruction->IndexRegister]);
+		if (X86Instruction->Scale > 1) APPEND(OPCSTR, SIZE_LEFT, "*%d", X86Instruction->Scale);
+		if (ShowDisplacement) X86_WRITE_RELATIVE_DISPLACEMENT()
+		APPENDB(']');
+	}
+	else // just a displacement
+	{
+		APPENDB('[');
+		X86_WRITE_ABSOLUTE_DISPLACEMENT()
+		APPENDB(']');
+	}
+}
+
+void OutputBounds(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	assert(X86Instruction->HasSrcAddressing);
+	assert(!(Operand->Length & 1));
+	Operand->Length >>= 1;
+	APPENDB('(');
+	OutputAddress(Instruction, Operand, OperandIndex);
+	APPENDS(", ");
+	X86Instruction->Displacement += Operand->Length;
+	OutputAddress(Instruction, Operand, OperandIndex);
+	X86Instruction->Displacement -= Operand->Length;
+	APPENDB(')');
+	Operand->Length <<= 1;
+}
+
+void OutputGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
+		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
+	{
+		OutputAddress(Instruction, Operand, OperandIndex);
+	}
+	else
+	{
+		APPENDS(X86_Registers[Operand->Register]);
+	}
+}
+
+void OutputDescriptor(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	assert(X86Instruction->HasSrcAddressing || X86Instruction->HasDstAddressing);
+	OutputAddress(Instruction, Operand, OperandIndex);
+}
+
+void OutputPackedReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
+		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
+	{
+		OutputAddress(Instruction, Operand, OperandIndex);
+	}
+	else
+	{
+		APPENDS(X86_Registers[Operand->Register]);
+	}
+}
+
+void OutputPackedBCD(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
+		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
+	{
+		OutputAddress(Instruction, Operand, OperandIndex);
+	}
+	else
+	{
+		APPENDS(X86_Registers[Operand->Register]);
+	}
+}
+
+void OutputScalarReal(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	if ((X86Instruction->HasDstAddressing && X86Instruction->DstAddressIndex == OperandIndex) ||
+		(X86Instruction->HasSrcAddressing && X86Instruction->SrcAddressIndex == OperandIndex))
+	{
+		OutputAddress(Instruction, Operand, OperandIndex);
+	}
+	else
+	{
+		APPENDS(X86_Registers[Operand->Register]);
+	}
+}
+
+void OutputScalarGeneral(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	if (Operand->Type == OPTYPE_FLOAT)
+	{
+		OutputScalarReal(Instruction, Operand, OperandIndex);
+	}
+	else
+	{
+		OutputGeneral(Instruction, Operand, OperandIndex);
+	}
+}
+
+void OutputFPUEnvironment(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	assert(X86Instruction->HasSrcAddressing || X86Instruction->HasDstAddressing);
+	OutputAddress(Instruction, Operand, OperandIndex);
+}
+
+void OutputFPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	assert(X86Instruction->HasSrcAddressing || X86Instruction->HasDstAddressing);
+	OutputAddress(Instruction, Operand, OperandIndex);
+}
+
+void OutputCPUState(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	assert(X86Instruction->HasSrcAddressing);
+	OutputAddress(Instruction, Operand, OperandIndex);
+}
+
+void OutputSegOffset(INSTRUCTION *Instruction, INSTRUCTION_OPERAND *Operand, U32 OperandIndex)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	assert(X86Instruction->HasSrcAddressing);
+	OutputAddress(Instruction, Operand, OperandIndex);	
+}
+
+////////////////////////////////////////////////////////////
+// Prologue support
+////////////////////////////////////////////////////////////
+
+typedef struct _PROLOGUE
+{
+	char *Data;
+	U32 Length;
+} PROLOGUE;
+
+PROLOGUE StandardPrologues[] =
+{
+	{ "\x55\x8b\xec", 3 },
+	{ "\x55\x89\xe5", 3 },
+	{ "\x83\xec", 2 },
+	{ "\x81\xec", 2 },
+	// TODO: add AMD64 prologues
+	// TODO: add VS2003/VS2003 prologues
+	// TODO: add any unique prologues from other compilers
+	{ NULL, 0 }
+};
+
+// Find the first function between StartAddress and EndAddress
+// 
+// This will match a standard prologue and then analyze the following instructions to verify
+// it is a valid function
+U8 *X86_FindFunctionByPrologue(struct _INSTRUCTION *Instruction, U8 *StartAddress, U8 *EndAddress, U32 Flags)
+{
+	assert(0); // TODO
+	return NULL;
+}
+
+//////////////////////////////////////////////////////////
+// Instruction decoder
+//////////////////////////////////////////////////////////
+
+BOOL X86_GetInstruction(struct _INSTRUCTION *Instruction, U8 *Address, U32 Flags)
+{
+	BOOL SpecialExtension = FALSE;
+	U8 Opcode = 0, OpcodeExtension = 0, Group = 0, SSE_Prefix = 0, Suffix;
+	U32 i = 0, Result = 0, tmpScale;
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	X86_OPCODE *X86Opcode;
+#ifdef TEST_DISASM
+	U32 InstructionLength = 0;
+#endif
+	INSTRUCTION_OPERAND *Operand, *Operand1 = NULL;
+	DISASSEMBLER *Disassembler = Instruction->Disassembler;
+	BOOL Decode = Flags & DISASM_DECODE;
+	BOOL Disassemble = Flags & DISASM_DISASSEMBLE;
+	BOOL SuppressErrors = Flags & DISASM_SUPPRESSERRORS;
+
+	if (Disassemble && !Decode)
+	{
+		assert(0);
+		Decode = TRUE;
+	}
+
+	if (!Address || !X86_InitInstruction(Instruction))
+	{
+		assert(0);
+		goto abort;
+	}
+
+	assert(Instruction->Address == Address);
+	assert(!Instruction->StringIndex && !Instruction->Length);
+
+	Disassembler->Stage1Count++;
+	if (Flags & DISASM_ALIGNOUTPUT) Instruction->StringAligned = TRUE;
+
+	//
+	// Get prefixes or three byte opcode
+	//
+	while (TRUE)
+	{
+		Opcode = *Address;
+		INSTR_INC(1); // increment Instruction->Length and address
+		X86Opcode = &X86_Opcodes_1[Opcode];
+
+		// Handle a misplaced REX prefix -- AMD64 manual says it is just ignored
+		if (IS_AMD64() && (Opcode >= REX_PREFIX_START && Opcode <= REX_PREFIX_END) && X86_PREFIX((&X86_Opcodes_1[*Address])))
+		{
+			if (!Instruction->AnomalyOccurred)
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: REX prefix before legacy prefix 0x%02X\n", VIRTUAL_ADDRESS, Opcode);
+				Instruction->AnomalyOccurred = TRUE;
+			}
+			continue;
+		}
+		
+		if (X86_PREFIX(X86Opcode))
+		{
+			if (!Instruction->AnomalyOccurred)
+			{
+				for (i = 0; i < Instruction->PrefixCount; i++)
+				{
+					if (Instruction->Prefixes[i] == Opcode)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Duplicate prefix 0x%02X\n", VIRTUAL_ADDRESS, Opcode);
+						Instruction->AnomalyOccurred = TRUE;
+						break;
+					}
+				}
+			}
+
+			switch (Opcode)
+			{
+				case PREFIX_REPNE: // may be three byte opcode
+					SSE_Prefix = Opcode;
+					if (!Instruction->AnomalyOccurred && X86Instruction->HasRepeatWhileEqualPrefix)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					Instruction->Repeat = TRUE;
+					X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
+					X86Instruction->HasRepeatWhileNotEqualPrefix = TRUE;
+					break;
+				case PREFIX_REP: // may be three byte opcode
+					SSE_Prefix = Opcode;
+					if (!Instruction->AnomalyOccurred && X86Instruction->HasRepeatWhileNotEqualPrefix)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+
+					Instruction->Repeat = TRUE;
+					X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
+					X86Instruction->HasRepeatWhileEqualPrefix = TRUE;
+					break;
+
+				case PREFIX_OPERAND_SIZE: // may be three byte opcode
+					SSE_Prefix = Opcode;
+					if (!Instruction->AnomalyOccurred && X86Instruction->HasOperandSizePrefix)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					
+					if (X86Instruction->HasOperandSizePrefix) break;
+					else X86Instruction->HasOperandSizePrefix = TRUE;
+					switch (X86Instruction->OperandSize)
+					{
+						case 4: X86Instruction->OperandSize = 2; break;
+						case 2: X86Instruction->OperandSize = 4; break;
+						default: assert(0); goto abort;
+					}
+					break;
+
+				case PREFIX_ADDRESS_SIZE:
+					if (!Instruction->AnomalyOccurred && X86Instruction->HasAddressSizePrefix)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+
+					if (X86Instruction->HasAddressSizePrefix) break;
+					else X86Instruction->HasAddressSizePrefix = TRUE;
+					switch (X86Instruction->AddressSize)
+					{
+						case 8:
+							X86Instruction->AddressSize = 4;
+							break;
+						case 4:
+							assert(!IS_AMD64()); // this should not be possible
+							X86Instruction->AddressSize = 2;
+							break;
+						case 2:
+							X86Instruction->AddressSize = 4;
+							break;
+						default: 
+							assert(0); goto abort;
+					}
+					break;
+
+				case PREFIX_SEGMENT_OVERRIDE_ES:
+					SANITY_CHECK_SEGMENT_OVERRIDE();
+					if (!IS_AMD64())
+					{
+						X86Instruction->HasSegmentOverridePrefix = TRUE;
+						X86Instruction->Segment = SEG_ES;
+					}
+					else if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					break;
+				case PREFIX_SEGMENT_OVERRIDE_CS:
+					SANITY_CHECK_SEGMENT_OVERRIDE();
+					if (!IS_AMD64())
+					{
+						X86Instruction->HasSegmentOverridePrefix = TRUE;
+						X86Instruction->Segment = SEG_CS;  
+					}
+					else if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					break;
+				case PREFIX_SEGMENT_OVERRIDE_SS:
+					SANITY_CHECK_SEGMENT_OVERRIDE();
+					if (!IS_AMD64())
+					{
+						X86Instruction->HasSegmentOverridePrefix = TRUE;
+						X86Instruction->Segment = SEG_SS;
+					}
+					else if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					break;
+				case PREFIX_SEGMENT_OVERRIDE_DS:
+					SANITY_CHECK_SEGMENT_OVERRIDE();
+					if (!IS_AMD64())
+					{
+						X86Instruction->HasSegmentOverridePrefix = TRUE;
+						X86Instruction->Segment = SEG_DS;
+					}
+					else if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Meaningless segment override\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					break;
+				case PREFIX_SEGMENT_OVERRIDE_FS:
+					SANITY_CHECK_SEGMENT_OVERRIDE();
+					X86Instruction->HasSegmentOverridePrefix = TRUE;
+					X86Instruction->Segment = SEG_FS;
+					break;
+				case PREFIX_SEGMENT_OVERRIDE_GS:
+					SANITY_CHECK_SEGMENT_OVERRIDE();
+					X86Instruction->HasSegmentOverridePrefix = TRUE;
+					X86Instruction->Segment = SEG_GS;
+					break;
+
+				case PREFIX_LOCK:
+					if (!Instruction->AnomalyOccurred && X86Instruction->HasLockPrefix)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Conflicting prefix\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					X86Instruction->HasLockPrefix = TRUE;
+					break;
+
+				default:
+					assert(0);
+					goto abort;
+			}
+
+			if (Instruction->PrefixCount >= X86_MAX_INSTRUCTION_LEN)
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
+				goto abort;
+			}
+			else if (Instruction->PrefixCount == X86_MAX_PREFIX_LENGTH)
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
+				Instruction->AnomalyOccurred = TRUE;
+			}
+
+			assert(Instruction->AnomalyOccurred || Instruction->PrefixCount < X86_MAX_PREFIX_LENGTH);
+			Instruction->Prefixes[Instruction->PrefixCount] = Opcode;
+			Instruction->PrefixCount++;
+			//DISASM_OUTPUT(("[0x%08I64X] Prefix 0x%02X (prefix count %d)\n", VIRTUAL_ADDRESS, Opcode, Instruction->PrefixCount));
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	// Check for REX opcode
+	// This is checked here instead of the prefix loop above because it must be the
+	// last prefix
+	if (IS_AMD64() && (Opcode >= REX_PREFIX_START && Opcode <= REX_PREFIX_END))
+	{
+		if (Instruction->PrefixCount >= X86_MAX_INSTRUCTION_LEN)
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
+			goto abort;
+		}
+		else if (!Instruction->AnomalyOccurred && Instruction->PrefixCount == AMD64_MAX_PREFIX_LENGTH)
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Reached maximum prefix count %d\n", VIRTUAL_ADDRESS, X86_MAX_PREFIX_LENGTH);
+			Instruction->AnomalyOccurred = TRUE;
+		}
+
+		assert(Instruction->AnomalyOccurred || Instruction->PrefixCount < AMD64_MAX_PREFIX_LENGTH);
+
+		Instruction->Prefixes[Instruction->PrefixCount] = Opcode;
+		Instruction->PrefixCount++;
+		X86Instruction->rex_b = Opcode;
+		SET_REX(X86Instruction->rex, X86Instruction->rex_b);
+		DISASM_OUTPUT(("[0x%08I64X] REX prefix 0x%02X (prefix count %d, w=%d, r=%d, x=%d, b=%d)\n", VIRTUAL_ADDRESS, Opcode, Instruction->PrefixCount, X86Instruction->rex.w, X86Instruction->rex.r, X86Instruction->rex.x, X86Instruction->rex.b));
+
+		assert(X86Instruction->AddressSize >= 4);
+		if (X86Instruction->rex.w)
+		{
+			X86Instruction->OperandSize = 8;
+			X86Instruction->HasOperandSizePrefix = FALSE;
+		}
+		else if (X86Instruction->HasOperandSizePrefix)
+		{
+			assert(X86Instruction->OperandSize == 2);
+		}
+		else if (X86Instruction->rex_b == REX_PREFIX_START)
+		{
+			if (!Instruction->AnomalyOccurred)
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: meaningless REX prefix used\n", VIRTUAL_ADDRESS);
+				Instruction->AnomalyOccurred = TRUE;
+			}
+			X86Instruction->rex_b = 0;
+		}
+
+		Opcode = *Address;
+		INSTR_INC(1); // increment Instruction->Length and address
+
+		X86Opcode = &X86_Opcodes_1[Opcode];
+		assert(!X86_PREFIX(X86Opcode));
+	}
+	//DISASM_OUTPUT(("[0x%08I64X] OperandSize = %d, AddressSize = %d\n", VIRTUAL_ADDRESS, X86Instruction->OperandSize, X86Instruction->AddressSize));
+	Instruction->LastOpcode = Opcode;
+	Instruction->OpcodeAddress = Address-1;
+
+	if (X86_INVALID(X86Opcode))
+	{
+		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid opcode 0x%02X\n", VIRTUAL_ADDRESS, Opcode);
+		goto abort;
+	}
+
+	if (Opcode == X86_TWO_BYTE_OPCODE)
+	{
+		//
+		// Handle case that it is a group (with opcode extension), floating point, or two byte opcode
+		//
+		assert(!Instruction->OpcodeLength);
+		Instruction->LastOpcode = Opcode = *Address;
+		INSTR_INC(1); // increment Instruction->Length and address
+		assert(X86Opcode->Table == X86_Opcodes_2);
+		X86Opcode = &X86_Opcodes_2[Opcode];
+
+		//
+		// Check for errors
+		//
+		if (X86_INVALID(X86Opcode))
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid two byte opcode 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode);
+			goto abort;
+		}
+		
+		if (X86Instruction->AddressSize == 8)
+		{
+			if (X86_Invalid_Addr64_2[Opcode])
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X 0x%02X (\"%s\") illegal in 64-bit mode\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, X86Opcode->Mnemonic);
+				goto abort;
+			}
+#if 0
+			if (X86Instruction->rex_b &&
+					(GET_REX_B(X86Instruction->rex_b) && !GET_REX_B(X86_REX_2[Opcode]) ||
+					 GET_REX_X(X86Instruction->rex_b) && !GET_REX_X(X86_REX_2[Opcode]) ||
+					 GET_REX_R(X86Instruction->rex_b) && !GET_REX_R(X86_REX_2[Opcode]) ||
+					 GET_REX_W(X86Instruction->rex_b) && !GET_REX_W(X86_REX_2[Opcode])))
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal REX prefix 0x%02X for opcode 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86Instruction->rex_b, X86_TWO_BYTE_OPCODE, Opcode);
+				assert(0);
+				goto abort;
+			}
+#endif
+		}
+
+		if (X86Instruction->OperandSize == 2 && X86_Invalid_Op16_2[Opcode])
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X 0x%02X (\"%s\") illegal with 16-bit operand size\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, X86Opcode->Mnemonic);
+			goto abort;
+		}
+
+		X86Instruction->HasModRM = X86_ModRM_2[Opcode];
+		if (X86Instruction->HasModRM) X86Instruction->modrm_b = *Address;
+		Instruction->OpcodeBytes[0] = X86_TWO_BYTE_OPCODE;
+		Instruction->OpcodeBytes[1] = Opcode;
+		Instruction->OpcodeLength = 2;
+
+		if (X86_SPECIAL_EXTENSION(X86Opcode))
+		{
+			DISASM_OUTPUT(("[0x%08I64X] Special opcode extension 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode));
+			SpecialExtension = TRUE;
+			goto HasSpecialExtension;
+		}
+		else if (SSE_Prefix && !X86_INVALID(&X86_SSE[Opcode])) // SSEx instruction
+		{
+			Instruction->OpcodeLength = 3;
+			Instruction->OpcodeBytes[2] = SSE_Prefix;
+			assert(Instruction->OpcodeBytes[1] == Opcode);
+
+			// Since the prefix was really an opcode extension, remove it from
+			// the prefix list
+			for (i = 0; i < Instruction->PrefixCount; i++)
+			{
+				if (Instruction->Prefixes[i]) break;
+			}
+			assert(i != Instruction->PrefixCount);
+			Instruction->PrefixCount--;
+			Instruction->Prefixes[i] = 0;
+
+			// Slide any prefixes following the removed prefix down by 1
+			memmove(&Instruction->Prefixes[i], &Instruction->Prefixes[i+1], Instruction->PrefixCount-i);
+			Instruction->Prefixes[Instruction->PrefixCount] = 0;
+			Instruction->Repeat = FALSE;
+			X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
+			X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
+			X86Instruction->HasOperandSizePrefix = FALSE;
+			if (SSE_Prefix == PREFIX_OPERAND_SIZE)
+			{
+				if (IS_AMD64() && X86Instruction->rex.w) X86Instruction->OperandSize = 8;
+				else X86Instruction->OperandSize = 4;
+			}
+
+			if (IS_X86_16())
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: SSE invalid in 16-bit mode\n", VIRTUAL_ADDRESS);
+				goto abort;
+			}
+		
+			assert(X86Instruction->HasModRM);
+			switch (SSE_Prefix)
+			{
+				case PREFIX_OPERAND_SIZE: X86Opcode = &X86_SSE[0x000+Opcode]; break;
+				case PREFIX_REPNE: X86Opcode = &X86_SSE[0x100+Opcode]; break;
+				case PREFIX_REP: X86Opcode = &X86_SSE[0x200+Opcode]; break;
+			}
+
+			if (X86_INVALID(X86Opcode))
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal SSE instruction opcode 0x%02X 0x%02X + prefix 0x%02X\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], Instruction->OpcodeBytes[2]);
+				goto abort;
+			}
+			else if (X86_EXTENDED_OPCODE(X86Opcode))
+			{
+				// SSE in group (13, 14, or 15)
+				OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
+				Group = X86_Groups_2[Opcode];
+				X86Instruction->Group = (U8)Group;
+				assert(Group >= 13 && Group <= 15 && X86Opcode->Table);
+				switch (SSE_Prefix)
+				{
+					case PREFIX_OPERAND_SIZE: X86Opcode = &X86Opcode->Table[0x00+OpcodeExtension]; break;
+					case PREFIX_REPNE: X86Opcode = &X86Opcode->Table[0x08+OpcodeExtension]; break;
+					case PREFIX_REP: X86Opcode = &X86Opcode->Table[0x10+OpcodeExtension]; break;
+				}
+
+				if (X86_INVALID(X86Opcode))
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal SSE instruction opcode 0x%02X 0x%02X + prefix 0x%02X + extension %d\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], Instruction->OpcodeBytes[2], OpcodeExtension);
+					goto abort;
+				}
+			}
+
+			Instruction->Repeat = FALSE;
+			X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
+			X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
+			X86Instruction->HasOperandSizePrefix = FALSE;
+			switch (X86_GET_CATEGORY(X86Opcode))
+			{
+				case ITYPE_SSE: case ITYPE_SSE2: case ITYPE_SSE3: break;
+				default: assert(0); goto abort;
+			}
+		}
+		else if (X86_EXTENDED_OPCODE(X86Opcode)) // 2 byte group
+		{
+			assert(!X86Opcode->MnemonicFlags);
+			OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
+
+			assert(X86Opcode->Table);
+			X86Opcode = &X86Opcode->Table[OpcodeExtension];
+			if (X86_INVALID(X86Opcode))
+			{
+				Instruction->Length++;
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid group opcode 0x%02X 0x%02X extension 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension);
+				goto abort;
+			}
+
+			assert(!X86_SPECIAL_EXTENSION(X86Opcode));
+			Group = X86_Groups_2[Opcode];
+			X86Instruction->Group = (U8)Group;
+			assert(Group > 0 && Group <= 19);
+			assert(X86Opcode->Mnemonic);
+			DISASM_OUTPUT(("[0x%08I64X] Group %d (bytes 0x%02X 0x%02X) extension 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Group, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension, X86Opcode->Mnemonic));
+		}
+		else
+		{
+			assert(X86Opcode->Mnemonic);
+			DISASM_OUTPUT(("[0x%08I64X] Two byte opcode 0x%02X 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, X86Opcode->Mnemonic));
+			X86Instruction->HasModRM = X86_ModRM_2[Opcode];
+			if (X86Instruction->HasModRM) X86Instruction->modrm_b = *Address;
+		}
+	}
+	else // 1-byte opcode
+	{
+		if (X86Instruction->AddressSize == 8)
+		{
+			if (X86_Invalid_Addr64_1[Opcode])
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X (\"%s\") illegal in 64-bit mode\n", VIRTUAL_ADDRESS, Opcode, X86Opcode->Mnemonic);
+				goto abort;
+			}
+
+#if 0
+			if (X86Instruction->rex_b &&
+				(GET_REX_B(X86Instruction->rex_b) && !GET_REX_B(X86_REX_1[Opcode]) ||
+				 GET_REX_X(X86Instruction->rex_b) && !GET_REX_X(X86_REX_1[Opcode]) ||
+				 GET_REX_R(X86Instruction->rex_b) && !GET_REX_R(X86_REX_1[Opcode]) ||
+				 GET_REX_W(X86Instruction->rex_b) && !GET_REX_W(X86_REX_1[Opcode])))
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal REX prefix 0x%02X for opcode 0x%02X\n", VIRTUAL_ADDRESS, X86Instruction->rex_b, Opcode);
+				assert(0);
+				goto abort;
+			}
+#endif
+		}
+
+		if (X86Instruction->OperandSize == 2 && X86_Invalid_Op16_1[Opcode])
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ERROR: Opcode 0x%02X (\"%s\") illegal with 16-bit operand size\n", VIRTUAL_ADDRESS, Opcode, X86Opcode->Mnemonic);
+			goto abort;
+		}
+
+		Instruction->OpcodeBytes[0] = Opcode;
+		Instruction->OpcodeLength = 1;
+		X86Instruction->HasModRM = X86_ModRM_1[Opcode];
+		if (X86Instruction->HasModRM) X86Instruction->modrm_b = *Address;
+
+		if (X86_EXTENDED_OPCODE(X86Opcode)) // a group
+		{
+			assert(X86Instruction->HasModRM);
+			OpcodeExtension = GET_MODRM_EXT(*Address); // leave Address pointing at ModRM byte
+
+			if (X86_SPECIAL_EXTENSION(X86Opcode))
+			{
+				DISASM_OUTPUT(("[0x%08I64X] Special opcode extension 0x%02X 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode));
+				SpecialExtension = TRUE;
+				goto HasSpecialExtension;
+			}
+
+			assert(X86Opcode->Table);
+			X86Opcode = &X86Opcode->Table[OpcodeExtension];
+			if (X86_INVALID(X86Opcode))
+			{
+				Instruction->Length++;
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid group opcode 0x%02X extension 0x%02X\n", VIRTUAL_ADDRESS, Opcode, OpcodeExtension);
+				goto abort;
+			}
+
+			Group = X86_Groups_1[Opcode];
+			X86Instruction->Group = (U8)Group;
+			DISASM_OUTPUT(("[0x%08I64X] Group %d (byte 0x%02X) extension 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Group, Opcode, OpcodeExtension, X86Opcode->Mnemonic));
+			assert(Group > 0 && Group <= 17);
+			assert(X86Opcode->Mnemonic);
+		}
+		else
+		{
+			if (X86_SPECIAL_EXTENSION(X86Opcode))
+			{
+				DISASM_OUTPUT(("[0x%08I64X] Special opcode extension 0x%02X\n", VIRTUAL_ADDRESS, Opcode));
+				SpecialExtension = TRUE;
+				goto HasSpecialExtension;
+			}
+
+			DISASM_OUTPUT(("[0x%08I64X] One byte opcode 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Opcode, X86Opcode->Mnemonic));
+		}
+	}
+
+HasSpecialExtension:
+	if (SpecialExtension)
+	{
+		if (X86Opcode->MnemonicFlags & ITYPE_EXT_MODRM)
+		{
+			assert(X86Opcode->Table);
+			assert(Instruction->OpcodeLength == 2);
+			assert(X86Instruction->HasModRM);
+			X86Opcode = &X86Opcode->Table[*Address];
+			if (X86_INVALID(X86Opcode))
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal opcode 0x%02X 0x%02X + modrm 0x%02X\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], *Address);
+				goto abort;
+			}
+			else if (X86_EXTENDED_OPCODE(X86Opcode))
+			{
+				assert(!X86Opcode->MnemonicFlags);
+				OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
+
+				assert(X86Opcode->Table);
+				X86Opcode = &X86Opcode->Table[OpcodeExtension];
+				if (X86_INVALID(X86Opcode))
+				{
+					Instruction->Length++;
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid group opcode 0x%02X 0x%02X extension 0x%02X\n", VIRTUAL_ADDRESS, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension);
+					goto abort;
+				}
+
+				assert(!X86_SPECIAL_EXTENSION(X86Opcode));
+				Group = X86_Groups_2[Opcode];
+				X86Instruction->Group = (U8)Group;
+				assert(Group > 0 && Group <= 19);
+				assert(X86Opcode->Mnemonic);
+				DISASM_OUTPUT(("[0x%08I64X] Group %d (bytes 0x%02X 0x%02X) extension 0x%02X (\"%s\")\n", VIRTUAL_ADDRESS, Group, X86_TWO_BYTE_OPCODE, Opcode, OpcodeExtension, X86Opcode->Mnemonic));
+			}
+			else if (!X86_OPERAND_COUNT(X86Opcode))
+			{
+				INSTR_INC(1); // increment Instruction->Length and address
+			}
+		}
+		else if (X86Opcode->MnemonicFlags & ITYPE_EXT_FPU)
+		{
+			assert(X86Opcode->Table);		
+			if (X86Instruction->modrm_b < 0xC0)
+			{
+				// It is an opcode extension, use the X86Opcode->Table
+				OpcodeExtension = GET_MODRM_EXT(X86Instruction->modrm_b);
+				X86Opcode = &X86Opcode->Table[OpcodeExtension];
+			}
+			else
+			{
+				// The whole ModRM byte is used, these start at index 0x08 in X86Opcode->Table
+				OpcodeExtension = (X86Instruction->modrm_b & 0x3F);
+				X86Opcode = &X86Opcode->Table[0x08 + OpcodeExtension];
+			}
+
+			if (X86_INVALID(X86Opcode))
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Invalid FPU opcode 0x%02X + modrm extension 0x%02X (index 0x%02X)\n", VIRTUAL_ADDRESS, Opcode, X86Instruction->modrm_b, 0x08 + OpcodeExtension);
+				goto abort;
+			}
+
+			DISASM_OUTPUT(("[0x%08I64X] FPU instruction is (\"%s\"): 0x%02X + modrm 0x%02X (index 0x%02X)\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Opcode, X86Instruction->modrm_b, 0x08 + OpcodeExtension));
+			if (!X86_OPERAND_COUNT(X86Opcode)) INSTR_INC(1); // increment Instruction->Length and address
+		}
+		else if (X86Opcode->MnemonicFlags & ITYPE_EXT_SUFFIX)
+		{
+			if (X86Instruction->HasOperandSizePrefix)
+			{
+				if (!Instruction->AnomalyOccurred && X86Opcode->Table == X86_3DNOW_0F)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: operand size prefix used with 3DNOW instruction\n", VIRTUAL_ADDRESS);
+					Instruction->AnomalyOccurred = TRUE;
+				}
+				X86Instruction->HasOperandSizePrefix = FALSE;
+				X86Instruction->OperandSize = 4;
+			}
+			Instruction->OperandCount = X86_OPERAND_COUNT(X86Opcode);
+			assert(Instruction->OpcodeLength == 2 && X86Instruction->HasModRM && Instruction->OperandCount == 2);
+			memcpy(&X86Instruction->Opcode, X86Opcode, sizeof(X86_OPCODE));
+			Instruction->Operands[0].Flags = X86Opcode->OperandFlags[0] & X86_OPFLAGS_MASK;
+			Instruction->Operands[1].Flags = X86Opcode->OperandFlags[1] & X86_OPFLAGS_MASK;
+			Instruction->Operands[2].Flags = X86Opcode->OperandFlags[2] & X86_OPFLAGS_MASK;
+			assert(Address == Instruction->Address + Instruction->Length);
+			if (!SetOperands(Instruction, Address, Flags & DISASM_SUPPRESSERRORS)) goto abort;
+			Suffix = Instruction->Address[Instruction->Length++];
+			Instruction->OpcodeBytes[2] = Suffix;
+			Instruction->OpcodeLength = 3;
+			X86Opcode = &X86Opcode->Table[Suffix];
+			
+			if (X86_INVALID(X86Opcode))
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal opcode 0x%02X 0x%02X + suffix 0x%02X\n", VIRTUAL_ADDRESS, Instruction->OpcodeBytes[0], Instruction->OpcodeBytes[1], Suffix);
+				goto abort;
+			}
+			assert(Instruction->Length >= 4 + Instruction->PrefixCount);
+		}
+		else if (X86Opcode->MnemonicFlags & ITYPE_EXT_64)
+		{
+			assert(X86Opcode->Table);
+			if (IS_AMD64()) X86Opcode = &X86Opcode->Table[1];
+			else X86Opcode = &X86Opcode->Table[0];
+			assert(!X86_INVALID(X86Opcode));
+		}
+	}
+
+	// Detect incompatibilities	
+	if (IS_X86_16() && X86Opcode->CPU > CPU_I386)
+	{
+		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Instruction \"%s\" (opcode 0x%02X) can't be used in 16-bit X86\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Instruction->LastOpcode);
+		goto abort;
+	}
+	if (!IS_AMD64() && X86Opcode->CPU >= CPU_AMD64)
+	{
+		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Instruction \"%s\" (opcode 0x%02X) can only be used in X86-64\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Instruction->LastOpcode);
+		goto abort;
+	}
+
+	// Copy the opcode into the local structure and set the fields 
+	assert(Instruction->OpcodeLength && !X86_INVALID(X86Opcode));
+	memcpy(&X86Instruction->Opcode, X86Opcode, sizeof(X86_OPCODE));
+	Instruction->Groups |= X86_GET_CATEGORY(X86Opcode);
+	assert(Instruction->Groups);
+	Instruction->Type |= X86_GET_TYPE(X86Opcode);
+	assert((U32)Instruction->Type >= Instruction->Groups);
+	Instruction->OperandCount = X86_OPERAND_COUNT(X86Opcode);
+
+	//
+	// Sanity check prefixes now that opcode is known and prefixes are resolved
+	//
+
+	// Instructions that implicitly reference the CS/DS can't have segment override prefixes
+	switch (Instruction->Type)
+	{
+		case ITYPE_PUSHF: case ITYPE_POPF:
+		case ITYPE_ENTER: case ITYPE_LEAVE:
+			SANITY_CHECK_SEGMENT_OVERRIDE();
+			X86Instruction->HasSegmentOverridePrefix = FALSE;
+			X86Instruction->Segment = SEG_SS;
+			break;
+		case ITYPE_RET: case ITYPE_DEBUG: 
+		case ITYPE_OFLOW: case ITYPE_TRAP: 
+		case ITYPE_TRAPRET:
+			SANITY_CHECK_SEGMENT_OVERRIDE();
+			X86Instruction->HasSegmentOverridePrefix = FALSE;
+			X86Instruction->Segment = SEG_CS;
+			break;
+	}
+
+	// Check illegal prefixes used with FPU/MMX/SSEx
+	if (Instruction->Groups & (ITYPE_FPU|ITYPE_MMX|ITYPE_SSE|ITYPE_SSE2|ITYPE_SSE3))
+	{
+		// Check for prefixes that produce unpredictable results
+		for (i = 0; i < Instruction->PrefixCount; i++)
+		{
+			switch (Instruction->Prefixes[i])
+			{
+				case PREFIX_OPERAND_SIZE:
+					switch (Instruction->Type)
+					{
+						case ITYPE_FSTOREENV: case ITYPE_FLOADENV: case ITYPE_FSAVE: case ITYPE_FRESTORE: continue;
+						default: break;
+					}
+
+					if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: operand size prefix used with FPU/MMX/SSEx\n", VIRTUAL_ADDRESS);
+						goto abort;
+					}
+					X86Instruction->HasOperandSizePrefix = FALSE;
+					if (X86Instruction->OperandSize == 2) X86Instruction->OperandSize = 2;
+					break;
+
+				case PREFIX_REPNE:
+				case PREFIX_REP:
+					if (Instruction->Groups & ITYPE_FPU) { assert(Instruction->Repeat); continue; }
+					// The Intel manual says this results in unpredictable behavior -- it's not even
+					// clear which SSE prefix is used as the third opcode byte in this case
+					// (e.g., is it the first or last SSE prefix?)
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: rep/repne used with MMX/SSEx\n", VIRTUAL_ADDRESS);
+					goto abort;
+
+				default:
+					break;
+			}
+		}
+	}
+
+	// Check for conflicts involving operand size
+	if (IS_AMD64())
+	{
+		// Check for use of rex.w=1 with an operand size prefix
+		if (X86Instruction->rex.w)
+		{
+			assert(X86Instruction->OperandSize == 8);
+			for (i = 0; i < Instruction->PrefixCount; i++)
+			{
+				if (Instruction->Prefixes[i] == PREFIX_OPERAND_SIZE)
+				{
+					X86Instruction->HasOperandSizePrefix = FALSE;
+					if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of operand size prefix meaningless when REX.w=1\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}				
+				}
+			}
+		}
+
+		// Set default operand size to 64 instead of 32 for some instructions
+		switch (Instruction->Type)
+		{
+			case ITYPE_PUSH: case ITYPE_POP: 
+			case ITYPE_PUSHF: case ITYPE_POPF:
+			case ITYPE_ENTER: case ITYPE_LEAVE:
+			case ITYPE_CALL: case ITYPE_BRANCH:
+			case ITYPE_LOOPCC: case ITYPE_RET:
+				X86Instruction->HasDefault64Operand = TRUE;
+				break;
+
+			case ITYPE_SYSTEM:
+				if (Instruction->OpcodeLength != 2) break;
+
+				// lgdt/lidt/lldt/ltr
+				if ((Instruction->LastOpcode == 0x00 || Instruction->LastOpcode == 0x01) && 
+					(OpcodeExtension == 0x02 || OpcodeExtension == 0x03))
+				{
+					X86Instruction->HasDefault64Operand = TRUE;
+				}
+				break;
+
+			default:
+				break;
+		}
+
+		if (X86Instruction->HasDefault64Operand)
+		{
+			if (X86Instruction->rex.w)
+			{
+				if (!Instruction->AnomalyOccurred)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of REX.w is meaningless (default operand size is 64)\n", VIRTUAL_ADDRESS);
+					Instruction->AnomalyOccurred = TRUE;
+				}
+				X86Instruction->rex_b &= ~8;
+				X86Instruction->rex.w = 0;
+			}
+
+			if (X86Instruction->HasOperandSizePrefix)
+			{
+				assert(X86Instruction->OperandSize == 2);
+				X86Instruction->HasDefault64Operand = FALSE;
+			}
+			else
+			{
+				assert(X86Instruction->OperandSize >= 4);
+				X86Instruction->OperandSize = 8;
+			}
+		}
+	}
+
+	// Make sure rep/repe/repne is set correctly based on instruction
+	if (Instruction->Repeat)
+	{
+		switch (Instruction->Type)
+		{
+			case ITYPE_IN:
+			case ITYPE_OUT:
+			case ITYPE_STRMOV:
+			case ITYPE_STRSTOR:
+			case ITYPE_STRLOAD:
+				if (X86Instruction->HasRepeatWhileNotEqualPrefix)
+				{
+					if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: REPNE should only be used with cmps/scas\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					// Treat it as just a "rep"
+					X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
+					X86Instruction->HasRepeatWhileEqualPrefix = TRUE;
+				}
+				break;
+			case ITYPE_STRCMP:
+				break;
+			default:
+				if (!Instruction->AnomalyOccurred)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Repeat prefix used with non-string instruction\n", VIRTUAL_ADDRESS);
+					Instruction->AnomalyOccurred = TRUE;
+				}
+				Instruction->Repeat = FALSE;
+				X86Instruction->HasRepeatWhileEqualPrefix = FALSE;
+				X86Instruction->HasRepeatWhileNotEqualPrefix = FALSE;
+				break;
+		}
+	}
+
+	if (Disassemble)
+	{
+		assert(!Instruction->StringIndex);
+		if (X86Instruction->HasRepeatWhileEqualPrefix)
+		{
+			if (Instruction->Type == ITYPE_STRCMP) { APPENDS("repe "); }
+			else { APPENDS("rep "); }
+		}
+		if (X86Instruction->HasRepeatWhileNotEqualPrefix) APPENDS("repne "); 
+		if (X86Instruction->HasLockPrefix) APPENDS("lock "); 
+		if (X86Instruction->HasBranchTakenPrefix) APPENDS("hinttake ");
+		if (X86Instruction->HasBranchNotTakenPrefix) APPENDS("hintskip ");
+		APPENDPAD(12);
+		APPEND(OPCSTR, SIZE_LEFT, "%s", X86Opcode->Mnemonic);
+		APPENDPAD(24);
+	}
+
+	if (Instruction->OperandCount)
+	{
+		Instruction->Operands[0].Flags = X86Opcode->OperandFlags[0] & X86_OPFLAGS_MASK;
+		Instruction->Operands[1].Flags = X86Opcode->OperandFlags[1] & X86_OPFLAGS_MASK;
+		Instruction->Operands[2].Flags = X86Opcode->OperandFlags[2] & X86_OPFLAGS_MASK;
+		Address = SetOperands(Instruction, Address, Flags);
+		if (!Address) goto abort;
+		assert(!(Instruction->Operands[0].Flags & 0x7F));
+		assert(!(Instruction->Operands[1].Flags & 0x7F));
+		assert(!(Instruction->Operands[2].Flags & 0x7F));
+	}
+
+	Disassembler->Stage2Count++;
+
+#ifdef TEST_DISASM
+	//////////////////////////////////////////////////////////////////////
+	// Test against other disassemblers
+	//////////////////////////////////////////////////////////////////////
+
+	if (IS_X86_32())
+	{
+		InstructionLength = X86_GetLength(Instruction, Instruction->Address);
+		if (InstructionLength && Instruction->Length != InstructionLength)
+		{
+			printf("[0x%08I64X] WARNING: instruction lengths differ (%d vs %d)\n", VIRTUAL_ADDRESS, Instruction->Length, InstructionLength);
+			DumpInstruction(Instruction, TRUE, TRUE);
+			assert(0);
+		}
+	}
+	else if (IS_AMD64())
+	{
+		// TODO: need other amd64 (x86-64) disassembler to test against
+	}
+	else if (IS_X86_16())
+	{
+		// TODO: need other x86 16-bit disassembler to test against
+	}
+#endif
+
+	//////////////////////////////////////////////////////////////////////
+	// Post-operand sanity checks
+	//////////////////////////////////////////////////////////////////////
+
+	if (!X86Instruction->HasDstAddressing && !X86Instruction->HasSrcAddressing)
+	{
+		if (X86Instruction->HasAddressSizePrefix)
+		{
+			if (!Instruction->AnomalyOccurred)
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: address size prefix used with no addressing\n", VIRTUAL_ADDRESS);
+				Instruction->AnomalyOccurred = TRUE;
+			}
+			X86Instruction->HasAddressSizePrefix = FALSE;
+		}
+
+		if (X86Instruction->HasSegmentOverridePrefix)
+		{
+			if (!Instruction->AnomalyOccurred)
+			{
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: segment override used with no addressing\n", VIRTUAL_ADDRESS);
+				Instruction->AnomalyOccurred = TRUE;
+			}
+			X86Instruction->HasSegmentOverridePrefix = FALSE;
+		}	
+	}
+
+	// Detect use of unusual segments
+	if (!Instruction->AnomalyOccurred && !IS_X86_16())
+	{
+		switch (X86Instruction->Segment)
+		{
+			case SEG_CS: case SEG_DS: case SEG_SS:
+				break;
+			case SEG_ES:
+				switch (Instruction->Type)
+				{
+ 					case ITYPE_IN: case ITYPE_STRMOV: case ITYPE_STRCMP: case ITYPE_STRSTOR:
+						break;
+					default:
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of unexpected segment ES\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+						break;
+				}
+				break;
+			case SEG_FS:
+				if (IS_X86_32() && !(Instruction->Groups & ITYPE_EXEC)) break;
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of unexpected segment FS\n", VIRTUAL_ADDRESS);
+				Instruction->AnomalyOccurred = TRUE;
+				break;
+			case SEG_GS:
+				if (IS_AMD64() && !(Instruction->Groups & ITYPE_EXEC)) break;
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: use of unexpected segment GS\n", VIRTUAL_ADDRESS);
+				Instruction->AnomalyOccurred = TRUE;
+				break;
+			default:
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: unexpected segment 0x%02X\n", VIRTUAL_ADDRESS, X86Instruction->Selector);
+				Instruction->AnomalyOccurred = TRUE;
+				break;
+		}
+	}
+
+	if ((X86Opcode->OperandFlags[0] & OP_COND_EXEC) == OP_COND_EXEC)
+	{
+ 		assert(Instruction->Type == ITYPE_BRANCHCC || Instruction->Type == ITYPE_LOOPCC);
+		for (i = 0; i < Instruction->PrefixCount; i++)
+		{
+			switch (Instruction->Prefixes[i])
+			{
+				case PREFIX_BRANCH_NOT_TAKEN:
+					if (!Instruction->AnomalyOccurred && X86Instruction->Segment != SEG_CS)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Segment override used with conditional branch\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					X86Instruction->HasSegmentOverridePrefix = FALSE;
+					X86Instruction->Segment = SEG_CS;
+					X86Instruction->HasBranchNotTakenPrefix = TRUE;
+					break;
+				case PREFIX_BRANCH_TAKEN:
+					if (!Instruction->AnomalyOccurred && X86Instruction->Segment != SEG_DS)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Segment override used with conditional branch\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					X86Instruction->HasSegmentOverridePrefix = FALSE;
+					X86Instruction->Segment = SEG_CS;
+					X86Instruction->HasBranchTakenPrefix = TRUE;
+					break;
+			}
+		}
+	}
+
+	//
+	// If lock prefix is enabled, verify it is valid
+	//
+	if (X86Instruction->HasLockPrefix && 
+		!IsValidLockPrefix(X86Instruction, Opcode, Instruction->OpcodeLength, Group, OpcodeExtension))
+	{
+		if (!SuppressErrors) printf("[0x%08I64X] ERROR: Illegal use of lock prefix for instruction \"%s\"\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic);
+		goto abort;
+	}
+
+	//////////////////////////////////////////////////////////////////////
+	// Generate disassembly output
+	//////////////////////////////////////////////////////////////////////
+
+	if (Disassemble)
+	{
+		if ((Flags & DISASM_SHOWFLAGS) && 
+			(X86Instruction->Opcode.Preconditions || X86Instruction->Opcode.FlagsChanged || X86Instruction->Opcode.ResultsIfTrue))
+		{
+			APPENDPAD(124);
+			if (X86Instruction->Opcode.Preconditions)
+			{
+				Result = X86Instruction->Opcode.Preconditions;
+				APPENDS("COND:{ ");
+				if (Result & COND_L) APPENDS("L ");
+				if (Result & COND_NL) APPENDS("NL ");
+				if (Result & COND_LE) APPENDS("LE ");
+				if (Result & COND_NLE) APPENDS("NLE ");
+				if (Result & COND_G) APPENDS("G ");
+				if (Result & COND_NG) APPENDS("NG ");
+				if (Result & COND_GE) APPENDS("GE ");
+				if (Result & COND_NGE) APPENDS("NGE ");
+				if (Result & COND_A) APPENDS("A ");
+				if (Result & COND_NA) APPENDS("NA ");
+				if (Result & COND_AE) APPENDS("AE ");
+				if (Result & COND_NAE) APPENDS("NAE ");
+				if (Result & COND_B) APPENDS("B ");
+				if (Result & COND_NB) APPENDS("NB ");
+				if (Result & COND_BE) APPENDS("BE ");
+				if (Result & COND_NBE) APPENDS("NBE ");
+				if (Result & COND_E) APPENDS("E ");
+				if (Result & COND_NE) APPENDS("NE ");
+				if (Result & COND_C) APPENDS("C ");
+				if (Result & COND_NC) APPENDS("NC ");
+				if (Result & COND_Z) APPENDS("Z ");
+				if (Result & COND_NZ) APPENDS("NZ ");
+				if (Result & COND_P) APPENDS("P ");
+				if (Result & COND_NP) APPENDS("NP ");
+				if (Result & COND_PE) APPENDS("PE ");
+				if (Result & COND_PO) APPENDS("PO ");
+				if (Result & COND_O) APPENDS("O ");
+				if (Result & COND_NO) APPENDS("NO ");
+				if (Result & COND_U) APPENDS("U ");
+				if (Result & COND_NU) APPENDS("NU ");
+				if (Result & COND_S) APPENDS("S ");
+				if (Result & COND_NS) APPENDS("NS ");
+				if (Result & COND_D) APPENDS("D ");
+				APPENDB('}');
+			}
+
+			if (X86Instruction->Opcode.FlagsChanged)
+			{
+				Result = X86Instruction->Opcode.FlagsChanged;
+
+				if (Result & FLAG_SET_MASK)
+				{
+					APPENDS("SET:{ ");
+					if (Result & FLAG_CF_SET) APPENDS("C ");
+					if (Result & FLAG_DF_SET) APPENDS("D ");
+					if (Result & FLAG_IF_SET) APPENDS("I ");
+					APPENDB('}');
+				}
+
+				if (Result & FLAG_CLR_MASK)
+				{
+					APPENDS("CLR:{ ");
+					if (Result & FLAG_SF_CLR) APPENDS("S ");
+					if (Result & FLAG_ZF_CLR) APPENDS("Z ");
+					if (Result & FLAG_AF_CLR) APPENDS("A ");
+					if (Result & FLAG_CF_CLR) APPENDS("C ");
+					if (Result & FLAG_DF_CLR) APPENDS("D ");
+					if (Result & FLAG_IF_CLR) APPENDS("I ");
+					if (Result & FLAG_OF_CLR) APPENDS("O ");
+					if ((Result & FPU_ALL_CLR) == FPU_ALL_CLR)
+					{
+						APPENDS("FPU_ALL ");
+					}
+					else
+					{
+						if (Result & FPU_C0_CLR) APPENDS("FPU_C0 ");
+						if (Result & FPU_C1_CLR) APPENDS("FPU_C1 ");
+						if (Result & FPU_C2_CLR) APPENDS("FPU_C2 ");
+						if (Result & FPU_C3_CLR) APPENDS("FPU_C3 ");
+					}
+					APPENDB('}');
+				}
+
+				if ((Result & FLAG_MOD_MASK) == FLAG_MOD_MASK)
+				{
+					APPENDS("MOD:{ ");
+					if ((Result & FLAG_ALL_MOD) == FLAG_ALL_MOD)
+					{
+						APPENDS("FLAGS_ALL ");
+					}
+					else if ((Result & FLAG_COMMON_MOD) == FLAG_COMMON_MOD)
+					{
+						APPENDS("FLAGS_COMMON ");
+					}
+					else
+					{
+						if (Result & FLAG_OF_MOD) APPENDS("O ");
+						if (Result & FLAG_SF_MOD) APPENDS("S ");
+						if (Result & FLAG_ZF_MOD) APPENDS("Z ");
+						if (Result & FLAG_AF_MOD) APPENDS("A ");
+						if (Result & FLAG_PF_MOD) APPENDS("P ");
+						if (Result & FLAG_CF_MOD) APPENDS("C ");
+						if (Result & FLAG_DF_MOD) APPENDS("D ");
+						if (Result & FLAG_IF_MOD) APPENDS("I ");
+					}
+					if ((Result & FPU_ALL_MOD) == FPU_ALL_MOD)
+					{
+						APPENDS("FPU_ALL ");
+					}
+					else
+					{
+						if (Result & FPU_C0_MOD) APPENDS("FPU_C0 ");
+						if (Result & FPU_C1_MOD) APPENDS("FPU_C1 ");
+						if (Result & FPU_C2_MOD) APPENDS("FPU_C2 ");
+						if (Result & FPU_C3_MOD) APPENDS("FPU_C3 ");
+					}
+					APPENDB('}');
+				}
+
+				if (Result & FLAG_TOG_MASK)
+				{
+					APPENDS("TOG:{ ");
+					if (Result & FLAG_CF_TOG) APPENDS("C ");
+					APPENDB('}');
+				}
+			}
+		}
+
+		APPENDS("\n");
+	}
+	else
+	{
+		Instruction->String[0] = '\0';
+	}
+
+	if (!Instruction->Length || Instruction->Length > X86_MAX_INSTRUCTION_LEN)
+	{
+		if (!SuppressErrors) printf("[0x%08I64X] ERROR: maximum instruction length reached (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+		goto abort;
+	}
+
+	if (!Decode)
+	{
+		Disassembler->Stage3CountNoDecode++;
+		return TRUE; // all work is done
+	}
+
+	//////////////////////////////////////////////////////////////////////
+	// Detect particularly interesting intructions
+	//////////////////////////////////////////////////////////////////////
+
+	Operand1 = &Instruction->Operands[0];
+	if (Instruction->Groups & ITYPE_EXEC)
+	{
+		// If it is a negative offset with a 1-byte or 2-byte offset, assume it is a loop
+		if (Operand1->Type == OPTYPE_OFFSET && 
+			Operand1->Length <= 2 && X86Instruction->Displacement < 0)
+		{
+			Instruction->CodeBranch.IsLoop = TRUE;
+			Instruction->CodeBranch.Operand = Operand1;
+		}
+
+		if (!Instruction->AnomalyOccurred &&
+			Operand1->TargetAddress >= (U64)Instruction->Address &&
+			Operand1->TargetAddress < (U64)Instruction->Address + Instruction->Length)
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: branch into the middle of an instruction\n", VIRTUAL_ADDRESS);
+			Instruction->AnomalyOccurred = TRUE;
+		}
+
+		switch (Instruction->Type)
+		{
+			case ITYPE_BRANCH:
+				Operand1->Flags |= OP_ADDRESS;
+				assert(Instruction->OperandCount == 1);
+				if (!(Operand1->Flags & (OP_GLOBAL|OP_FAR)))
+				{
+					assert(!X86Instruction->HasSelector);
+					X86Instruction->Segment = SEG_CS;
+				}
+				
+				if (Operand1->TargetAddress)
+				{
+					assert(!Instruction->CodeBranch.AddressOffset);
+					Instruction->CodeBranch.Count = 1;
+					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
+					Instruction->CodeBranch.Operand = Operand1;
+				}
+				// If there is both a base and index register, the Result will probably be too wrong
+				// to even guess
+				else if (X86Instruction->HasFullDisplacement && 
+					 ((X86Instruction->HasBaseRegister && !X86Instruction->HasIndexRegister) ||
+					 (!X86Instruction->HasBaseRegister && X86Instruction->HasIndexRegister)))
+				{
+					assert(Operand1->Length <= 0xFF);
+					if (!X86Instruction->Scale)
+					{
+						if (Operand1->Length) X86Instruction->Scale = (U8)Operand1->Length;
+						else X86Instruction->Scale = X86Instruction->OperandSize;
+					}
+					assert(Operand1->Length <= 0xFF);
+					tmpScale = MAX(X86Instruction->Scale, Operand1->Length);
+
+					assert(tmpScale <= 16);
+					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
+					for (i = 0; i < MAX_CODE_REFERENCE_COUNT; i++) Instruction->CodeBranch.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
+					Instruction->CodeBranch.Count = i;
+					Instruction->CodeBranch.IsIndirect = TRUE;
+					Instruction->CodeBranch.Operand = Operand1;
+				}
+				break;
+
+			case ITYPE_CALL:
+				Instruction->Groups |= ITYPE_STACK;
+				Instruction->CodeBranch.IsCall = TRUE;
+				Operand1->Flags |= OP_ADDRESS;
+				assert(Instruction->OperandCount == 1);
+				if (!(Operand1->Flags & (OP_GLOBAL|OP_FAR)))
+				{
+					assert(!X86Instruction->HasSelector);
+					X86Instruction->Segment = SEG_CS;
+				}
+								
+				if (Operand1->TargetAddress)
+				{
+					assert(!Instruction->CodeBranch.AddressOffset);
+					Instruction->CodeBranch.Count = 1;
+					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
+					Instruction->CodeBranch.Operand = Operand1;
+				}
+				// If there is both a base and index register, the Result will probably be too wrong
+				// to even guess
+				else if (X86Instruction->HasFullDisplacement &&
+					((X86Instruction->HasBaseRegister && !X86Instruction->HasIndexRegister) ||
+					 (!X86Instruction->HasBaseRegister && X86Instruction->HasIndexRegister)))
+				{
+					//DISASM_OUTPUT(("[0x%08I64X] Scale %d, displacement 0x%08I64x\n", VIRTUAL_ADDRESS, X86Instruction->Scale, X86Instruction->Displacement));
+					if (!X86Instruction->Scale)
+					{
+						assert(Operand1->Length <= 0xFF);
+						if (Operand1->Length) X86Instruction->Scale = (U8)Operand1->Length;
+						else X86Instruction->Scale = X86Instruction->OperandSize;
+					}
+					tmpScale = MAX(X86Instruction->Scale, Operand1->Length);
+
+					assert(tmpScale <= 16);
+					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
+					assert(X86Instruction->Scale > 1);
+					for (i = 0; i < MAX_CODE_REFERENCE_COUNT; i++) Instruction->CodeBranch.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
+					Instruction->CodeBranch.Count = i;
+					Instruction->CodeBranch.IsIndirect = TRUE;
+					Instruction->CodeBranch.Operand = Operand1;
+				}
+				break;
+
+			case ITYPE_BRANCHCC:
+				assert(Instruction->OperandCount == 1);
+				assert(Operand1->Flags & OP_ADDRESS);
+				assert(Operand1->Type == OPTYPE_OFFSET);
+				if (!(Operand1->Flags & (OP_GLOBAL|OP_FAR)))
+				{
+					assert(!X86Instruction->HasSelector);
+					X86Instruction->Segment = SEG_CS;
+				}
+
+				if (Operand1->TargetAddress)
+				{
+					assert(!Instruction->CodeBranch.AddressOffset);
+					Instruction->CodeBranch.Count = 2;
+					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
+					Instruction->CodeBranch.Addresses[1] = (U64)Instruction->Address + Instruction->Length;
+					Instruction->CodeBranch.Operand = Operand1;
+				}
+				break;
+
+			case ITYPE_LOOPCC:
+				Instruction->CodeBranch.IsLoop = TRUE;
+				assert(Instruction->OperandCount == 1);
+				assert(Operand1->Flags & OP_ADDRESS);
+				assert(Operand1->Type == OPTYPE_OFFSET);
+				assert(!(Operand1->Flags & (OP_GLOBAL|OP_FAR)));
+				if (Operand1->TargetAddress)
+				{
+					assert(!Instruction->CodeBranch.AddressOffset);
+					Instruction->CodeBranch.Count = 2;
+					Instruction->CodeBranch.Addresses[0] = Operand1->TargetAddress;
+					Instruction->CodeBranch.Addresses[1] = (U64)Instruction->Address + Instruction->Length;
+					Instruction->CodeBranch.Operand = Operand1;
+				}
+				break;
+
+			case ITYPE_RET:
+				Instruction->Groups |= ITYPE_STACK;
+				break;
+
+			default:
+				break; // do nothing
+		}
+	}
+	else // possible data instruction
+	{
+		for (i = 0, Operand = Instruction->Operands; i < Instruction->OperandCount; i++, Operand++)
+		{
+			if (Operand->TargetAddress)
+			{
+				if (Operand->Flags & OP_DST)
+				{
+					assert(!Instruction->DataDst.Count);
+					Instruction->DataDst.Count = 1;
+					Instruction->DataDst.Addresses[0] = Operand->TargetAddress;
+					Instruction->DataDst.DataSize = Operand->Length;
+					Instruction->DataDst.Operand = Operand;
+					DISASM_OUTPUT(("[0x%08I64X] Write of size %d to 0x%04I64X\n", VIRTUAL_ADDRESS, Operand->Length, Operand->TargetAddress));
+				}
+				if (Operand->Flags & OP_SRC)
+				{
+					assert(!Instruction->DataSrc.Count);
+					Instruction->DataSrc.Count = 1;
+					Instruction->DataSrc.Addresses[0] = Operand->TargetAddress;
+					Instruction->DataSrc.DataSize = Operand->Length;
+					Instruction->DataSrc.Operand = Operand;
+					DISASM_OUTPUT(("[0x%08I64X] Read of size %d to 0x%04I64X\n", VIRTUAL_ADDRESS, Operand->Length, Operand->TargetAddress));
+				}
+			}
+
+			// If there is both a base and index register, the Result will probably be too wrong
+			// to even guess
+			else if (Operand->Flags & OP_GLOBAL && 
+				((X86Instruction->HasBaseRegister && !X86Instruction->HasIndexRegister) ||
+				 (!X86Instruction->HasBaseRegister && X86Instruction->HasIndexRegister)))
+			{
+				DISASM_OUTPUT(("[0x%08I64X] Data reference (scale %d, size %d, displacement 0x%08I64x)\n", VIRTUAL_ADDRESS, X86Instruction->Scale, Operand->Length, X86Instruction->Displacement));
+				if (!X86Instruction->Scale)
+				{
+					assert(Operand->Length <= 0xFF);
+					if (Operand->Length) X86Instruction->Scale = (U8)Operand->Length;
+					else X86Instruction->Scale = X86Instruction->OperandSize;
+				}
+				tmpScale = MAX(X86Instruction->Scale, Operand->Length);
+
+				assert(X86Instruction->HasFullDisplacement);
+				if (Operand->Flags & OP_DST)
+				{
+					assert(!Instruction->DataDst.Count);
+					assert(tmpScale <= 16);
+					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
+					for (i = 0; i < MAX_DATA_REFERENCE_COUNT; i++) Instruction->DataDst.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
+					Instruction->DataDst.Count = i;
+					Instruction->DataDst.DataSize = Operand->Length;
+					Instruction->DataDst.Operand = Operand;
+				}					
+				if (Operand->Flags & OP_SRC)
+				{
+					assert(!Instruction->DataSrc.Count);
+					assert(tmpScale <= 16);
+					Instruction->CodeBranch.AddressOffset = (U8)tmpScale;
+					for (i = 0; i < MAX_DATA_REFERENCE_COUNT; i++) Instruction->DataSrc.Addresses[i] = (U64)X86Instruction->Displacement + (i * tmpScale);
+					Instruction->DataSrc.Count = i;
+					Instruction->DataSrc.DataSize = Operand->Length;
+					Instruction->DataSrc.Operand = Operand;
+				}
+			}
+		}
+	}
+
+	if (Instruction->Groups & ITYPE_STACK)
+	{
+		switch (Instruction->Type)
+		{
+			case ITYPE_PUSH:
+				assert(Instruction->OperandCount == 1 && Operand1->Length);
+				Instruction->StackChange = -Operand1->Length;
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_POP:
+				assert(Instruction->OperandCount == 1 && Operand1->Length);
+				Instruction->StackChange = Operand1->Length;
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_PUSHA:
+				Instruction->StackChange = -(X86Instruction->OperandSize * 8); // xAX, xCX, xDX, xBX, xBP, xSP, xSI, xDI
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_POPA:
+				Instruction->StackChange = X86Instruction->OperandSize * 8; // xDI, xSI, xSP, xBP, xBX, xDX, xCX, xAX
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_PUSHF:			
+				Instruction->StackChange = -Operand1->Length;
+				Instruction->NeedsEmulation = TRUE;
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_POPF:
+				Instruction->StackChange = Operand1->Length;
+				Instruction->NeedsEmulation = TRUE;
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_ENTER:
+				if (!Instruction->AnomalyOccurred)
+				{
+					if (Instruction->Operands[1].Value_U64 & 3)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: ENTER has invalid operand 2\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					if (Instruction->Operands[2].Value_U64 & ~0x1F)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: ENTER has invalid operand 3\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+				}
+				SANITY_CHECK_ADDRESS_SIZE();
+				Instruction->Operands[2].Value_U64 &= 0x1F;
+
+				// frame pointer + stack space
+				i = Operand1->Length + (U32)Instruction->Operands[1].Value_U64;
+				Instruction->StackChange = -((LONG)i);
+				i = (U32)Instruction->Operands[2].Value_U64 * Operand1->Length;
+				Instruction->StackChange -= i;
+				break;
+
+			case ITYPE_LEAVE:
+				// This will do "mov esp, ebp; pop ebp" so the StackChange size is dynamic
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_CALL:
+				Instruction->StackChange = -X86Instruction->OperandSize;
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_RET:
+				Instruction->StackChange = X86Instruction->OperandSize;
+
+				switch (Opcode)
+				{
+					case 0xC3: // ret with no args
+						break;
+
+					case 0xC2: // ret with 1 arg
+						if (!Instruction->AnomalyOccurred && (Operand1->Value_U64 & 3))
+						{
+							if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: ret has invalid operand 1\n", VIRTUAL_ADDRESS);
+							Instruction->AnomalyOccurred = TRUE;
+						}
+						Instruction->StackChange += (LONG)Operand1->Value_U64;
+						break;
+
+					case 0xCB: // far ret with no args
+						Instruction->StackChange *= 2; // account for segment
+						Instruction->StackChange += (LONG)Operand1->Value_U64;
+						break;
+
+					case 0xCA: // far ret with 1 arg
+						if (!Instruction->AnomalyOccurred && (Operand1->Value_U64 & 3))
+						{
+							if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: retf has invalid operand 1\n", VIRTUAL_ADDRESS);
+							Instruction->AnomalyOccurred = TRUE;
+						}
+						Instruction->StackChange *= 2; // account for segment
+						Instruction->StackChange += (LONG)Operand1->Value_U64;
+						break;
+				}
+				SANITY_CHECK_ADDRESS_SIZE();
+				break;
+
+			case ITYPE_ADD:
+			case ITYPE_XCHGADD:
+				if (Instruction->Operands[1].Value_S64) Instruction->StackChange = (LONG)(Instruction->Operands[1].Value_S64);
+				break;
+			case ITYPE_SUB:
+				if (Instruction->Operands[1].Value_S64) Instruction->StackChange = (LONG)(-Instruction->Operands[1].Value_S64);
+				break;
+			case ITYPE_MOV:
+			case ITYPE_AND:
+				break;
+
+			default:
+				if (!Instruction->AnomalyOccurred)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Instruction \"%s\" is modifying the stack\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic);
+					Instruction->AnomalyOccurred = TRUE;
+				}
+				break;
+		}
+
+		if (!Instruction->AnomalyOccurred &&
+			((X86Instruction->OperandSize != 2 && (Instruction->StackChange & 3)) || (Instruction->StackChange & 1)))
+		{
+			if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: \"%s\" has invalid stack change 0x%02X\n", VIRTUAL_ADDRESS, X86Opcode->Mnemonic, Instruction->StackChange);
+			Instruction->AnomalyOccurred = TRUE;
+		}
+	}
+
+	if (Instruction->Groups & ITYPE_TRAPS)
+	{
+		switch (Instruction->Type)
+		{
+			case ITYPE_TRAP:
+			case ITYPE_TRAPCC:
+			case ITYPE_TRAPRET:
+			case ITYPE_BOUNDS:
+			case ITYPE_DEBUG:
+			case ITYPE_TRACE:
+			case ITYPE_INVALID:
+			case ITYPE_OFLOW:
+				Instruction->NeedsEmulation = TRUE;
+				break;
+			default:
+				assert(0);
+				break;
+		}
+	}
+
+	if (Instruction->Groups & ITYPE_SYSTEM)
+	{
+		switch (Instruction->Type)
+		{
+			case ITYPE_CPUID:
+			case ITYPE_SYSCALL:
+			case ITYPE_SYSCALLRET:
+				// This doesn't require privileges
+				break;
+
+			case ITYPE_HALT:
+			case ITYPE_IN:
+			case ITYPE_OUT:
+			default:
+				Instruction->NeedsEmulation = TRUE;
+				break;
+		}
+	}
+
+	Disassembler->Stage3CountWithDecode++;
+	return TRUE;
+
+abort:
+	if (!SuppressErrors)
+	{
+#ifdef TEST_DISASM
+		printf("Dump of 0x%04I64X:\n", VIRTUAL_ADDRESS);
+		__try { DumpAsBytes(stdout, Instruction->Address, (ULONG_PTR)VIRTUAL_ADDRESS, 16, TRUE); }
+		__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {}
+#endif
+		fflush(stdout);
+	}
+	return FALSE;
+}
+
+// Address = address to first byte after the opcode (e.g., first byte of ModR/M byte or
+// immediate value
+//
+// Returns the address immediately following the operand (e.g., the next operand or the
+// start of the next instruction
+INTERNAL U8 *SetOperands(INSTRUCTION *Instruction, U8 *Address, U32 Flags)
+{
+	INSTRUCTION_OPERAND *Operand;
+	U32 Index, OperandIndex;
+	S64 Displacement = 0;
+	U8 Register;
+	U32 OperandFlags, OperandType, AddressMode, Segment;
+	U8 Opcode;
+	MODRM modrm;
+	REX rex;
+	REX_MODRM rex_modrm;
+	X86_OPCODE *X86Opcode;
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+	BOOL Decode = Flags & DISASM_DECODE;
+	BOOL Disassemble = Flags & DISASM_DISASSEMBLE;
+	BOOL SuppressErrors = Flags & DISASM_SUPPRESSERRORS;
+
+	Opcode = Instruction->LastOpcode;
+	X86Opcode = &X86Instruction->Opcode;
+
+	// Setup Mod R/M byte
+	if (X86Instruction->HasModRM)
+	{
+		SET_MODRM(X86Instruction->modrm, X86Instruction->modrm_b);
+		modrm = X86Instruction->modrm;
+		rex = X86Instruction->rex;
+		SET_REX_MODRM(X86Instruction->rex_modrm, rex, modrm);
+		rex_modrm = X86Instruction->rex_modrm;
+		//DISASM_OUTPUT(("[0x%08I64X] ModRM = 0x%02X (mod=%d, reg=%d, rm=%d)\n", VIRTUAL_ADDRESS, X86Instruction->modrm_b, modrm.mod, rex_modrm.reg, rex_modrm.rm));
+		INSTR_INC(1); // increment Instruction->Length and address
+	}
+	else
+	{
+		// initialize them to 0
+		modrm = X86Instruction->modrm;
+		rex = X86Instruction->rex;
+		rex_modrm = X86Instruction->rex_modrm;
+	}
+
+	for (OperandIndex = 0; OperandIndex < Instruction->OperandCount; OperandIndex++)
+	{
+		Operand = &Instruction->Operands[OperandIndex];
+		assert(!(Operand->Flags & 0x7F));
+		
+		OperandFlags = X86Opcode->OperandFlags[OperandIndex] & X86_OPFLAGS_MASK;
+		OperandType = X86Opcode->OperandFlags[OperandIndex] & X86_OPTYPE_MASK;
+		AddressMode = X86Opcode->OperandFlags[OperandIndex] & X86_AMODE_MASK;
+		if (Decode && OperandIndex != 0) APPENDS(", ");
+
+		switch (OperandType)
+		{
+			////////////////////////////////////////////////////////////
+			// Special operand types with no associated addressing mode
+			////////////////////////////////////////////////////////////
+
+			case OPTYPE_0:
+				if (!Decode) continue;
+				Operand->Value_U64 = 0;
+				Operand->Type = OPTYPE_IMM;
+				//DISASM_OUTPUT(("[SetOperand] const 0\n"));
+				if (Disassemble)
+				{
+					APPENDS("<0>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_1:
+				if (!Decode) continue;
+				Operand->Value_U64 = 1;
+				Operand->Type = OPTYPE_IMM;
+				//DISASM_OUTPUT(("[SetOperand] const 1\n"));
+				if (Disassemble)
+				{
+					APPENDS("<1>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FF:
+				if (!Decode) continue;
+				Operand->Value_U64 = 0xFF;
+				Operand->Type = OPTYPE_IMM;
+				//DISASM_OUTPUT(("[SetOperand] const 0xff\n"));
+				if (Disassemble)
+				{
+					APPENDS("<0xFF>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_TSC:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] TSC\n"));
+				if (Disassemble)
+				{
+					APPENDS("<TSC_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_CS_MSR:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] CS MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<CS_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_EIP_MSR:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] EIP MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<EIP_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_ESP_MSR:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] ESP MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<ESP_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_KERNELBASE_MSR:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] KernelBase MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<KRNLBASE_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_STAR_MSR:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] KernelBase MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<STAR_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_CSTAR_MSR:
+				assert(!IS_AMD64());
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] CSTAR MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<CSTAR_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_LSTAR_MSR:
+				assert(IS_AMD64());
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] LSTAR MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<LSTAR_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FMASK_MSR:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_SPECIAL;
+				//DISASM_OUTPUT(("[SetOperand] FMASK MSR\n"));
+				if (Disassemble)
+				{
+					APPENDS("<FMASK_MSR>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OP_REG:
+				if (!Decode) continue;
+				// The reg field is included in the opcode
+				Operand->Length = X86Instruction->OperandSize;
+				Register = X86_GET_REG64(Opcode);
+				switch (X86Instruction->OperandSize)
+				{
+					case 8:
+						Operand->Register = AMD64_64BIT_OFFSET + Register;
+						break;
+					case 4:
+						Operand->Register = X86_32BIT_OFFSET + Register;
+						CHECK_AMD64_REG();
+						break;
+					case 2:
+						Operand->Register = X86_16BIT_OFFSET + Register;
+						CHECK_AMD64_REG();
+						break;
+					case 1:
+						Operand->Register = X86_8BIT_OFFSET + Register;
+						if (X86Instruction->rex_b) CHECK_AMD64_REG();
+						break;
+					default:
+						assert(0);
+						return NULL;
+				}
+				X86_SET_REG(Register);
+
+				//DISASM_OUTPUT(("[SetOperand] OP_REG %s\n", X86_Registers[Operand->Register]));
+				if (Disassemble)
+				{
+					APPENDB('<'); APPENDS(X86_Registers[Operand->Register]); APPENDB('>');
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_REG8:
+				if (!Decode) continue;
+				// The reg field is included in the opcode
+				Operand->Length = 1;
+				Register = X86_GET_REG64(Opcode);
+				Operand->Register = X86_8BIT_OFFSET + Register;
+				CHECK_AMD64_REG();
+				X86_SET_REG(Register);
+
+				//DISASM_OUTPUT(("[SetOperand] OP_REG %s\n", X86_Registers[Operand->Register]));
+				if (Disassemble)
+				{
+					APPENDB('<'); APPENDS(X86_Registers[Operand->Register]); APPENDB('>');
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_REG_AL:
+				if (!Decode) continue;
+				Operand->Length = 1;
+				Operand->Register = X86_REG_AL;
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] reg AL\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_REG_CL:
+				if (!Decode) continue;
+				Operand->Length = 1;
+				Operand->Register = X86_REG_CL;
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] reg CL\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_REG_AH:
+				if (!Decode) continue;
+				Operand->Length = 1;
+				Operand->Register = X86_REG_AH;
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] reg AH\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_REG_AX:
+				if (!Decode) continue;
+				Operand->Length = 2;
+				Operand->Register = X86_REG_AX;
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] reg AX\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_REG_DX:
+				if (!Decode) continue;
+				Operand->Length = 2;
+				Operand->Register = X86_REG_DX;
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] reg DX\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_REG_ECX:
+				if (!Decode) continue;
+				Operand->Length = 4;
+				Operand->Register = X86_REG_ECX;
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] reg ECX\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_REG_xBP:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize; 
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: Operand->Register = AMD64_REG_RBP; break;
+					case 4: Operand->Register = X86_REG_EBP; break;
+					case 2: Operand->Register = X86_REG_BP; break;
+					default: assert(0); return NULL;
+				}
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] xAX_BIG (size = %d)\n", Operand->Length));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_REG_xAX_BIG:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize; 
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: Operand->Register = AMD64_REG_RAX; break;
+					case 4: Operand->Register = X86_REG_EAX; break;
+					case 2: Operand->Register = X86_REG_AX; break;
+					default: assert(0); return NULL;
+				}
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] xAX_BIG (size = %d)\n", Operand->Length));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_REG_xAX_SMALL:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize >> 1; 
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: Operand->Register = X86_REG_EAX; break;
+					case 4: Operand->Register = X86_REG_AX; break;
+					case 2: Operand->Register = X86_REG_AL; break;
+					default: assert(0); return NULL;
+				}
+				X86_SET_REG(0);
+				//DISASM_OUTPUT(("[SetOperand] xAX_SMALL (size = %d)\n", Operand->Length));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_xCX_HI_xBX_LO:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize << 1; 
+				if (Disassemble)
+				{
+					switch (X86Instruction->OperandSize)
+					{
+						case 8: APPENDS("<RCX:RBX>"); break;
+						case 4: APPENDS("<ECX:EBX>"); break;
+						case 2: APPENDS("<CX:BX>"); break;
+						default: assert(0); return NULL;
+					}
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] xCX_BIG:xBX_BIG (size = %d)\n", Operand->Length));
+				continue;
+			case OPTYPE_xDX_HI_xAX_LO:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize << 1; 
+				if (Disassemble)
+				{
+					switch (X86Instruction->OperandSize)
+					{
+						case 8: APPENDS("<RDX:RAX>"); break;
+						case 4: APPENDS("<EDX:EAX>"); break;
+						case 2: APPENDS("<DX:AX>"); break;
+						default: assert(0); return NULL;
+					}
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] xDX_BIG:xAX_BIG (size = %d)\n", Operand->Length));
+				continue;
+
+			case OPTYPE_EDX_HI_EAX_LO:
+				if (!Decode) continue;
+				Operand->Length = 8;
+				//DISASM_OUTPUT(("[SetOperand] EDX:EAX\n"));
+				if (Disassemble)
+				{
+					APPENDS("<EDX:EAX>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_EDX_ECX_EBX_EAX:
+				Operand->Length = 32;
+				//DISASM_OUTPUT(("[SetOperand] EDX:ECX:EBX:EAX\n"));
+				if (Disassemble)
+				{
+					APPENDS("<EDX:ECX:EBX:EAX>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_FLAGS:
+				if (!Decode) continue;
+				Operand->Length = 2;
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_REG_FLAGS;
+				//DISASM_OUTPUT(("[SetOperand] reg FLAGS\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_xFLAGS:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize; 
+				Operand->Flags |= OP_REG;
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: Operand->Register = AMD64_REG_RFLAGS; break;
+					case 4: Operand->Register = X86_REG_EFLAGS; break;
+					case 2: Operand->Register = X86_REG_FLAGS; break;
+					default: assert(0); return NULL;
+				}
+				//DISASM_OUTPUT(("[SetOperand] reg xFLAGS (size = %d)\n", Operand->Length));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_CS:
+				if (!Decode) continue;
+				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
+				else Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_SEG_CS;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] seg CS\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_DS:
+				if (!Decode) continue;
+				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
+				else Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_SEG_DS;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] seg DS\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_ES:
+				if (!Decode) continue;
+				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
+				else Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_SEG_ES;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] seg ES\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FS:
+				if (!Decode) continue;
+				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
+				else Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_SEG_FS;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] seg FS\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_GS:
+				if (!Decode) continue;
+				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
+				else Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_SEG_GS;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] seg GS\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_SS:
+				if (!Decode) continue;
+				if (Instruction->Type != ITYPE_PUSH && Instruction->Type != ITYPE_POP) Operand->Length = 2;
+				else Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_SEG_SS;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] seg SS\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_CR0:
+				if (!Decode) continue;
+				Operand->Length = X86Instruction->OperandSize;
+				Operand->Register = X86_REG_CR0;
+				Operand->Flags |= OP_REG;
+				//DISASM_OUTPUT(("[SetOperand] reg CR0\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_STx:
+				if (!Decode) continue;
+				Operand->Length = 10;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Flags |= OP_REG;
+				Register = X86_GET_REG(X86Instruction->modrm_b);
+				Operand->Register = X86_FPU_OFFSET + Register;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_STx: reg st(%d)\n", Register));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_ST0:
+				if (!Decode) continue;
+				Operand->Length = 10;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_REG_ST0;
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_ST1:
+				if (!Decode) continue;
+				Operand->Length = 10;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_REG_ST1;
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "<%s>", X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_FPU_STATUS:
+				if (!Decode) continue;
+				Operand->Length = 2;
+				if (Disassemble)
+				{
+					APPENDS("<FPUSTAT>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_FPU_CONTROL:
+				if (!Decode) continue;
+				Operand->Length = 2;
+				if (Disassemble)
+				{
+					APPENDS("<FPUCTRL>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_FPU_TAG:
+				if (!Decode) continue;
+				Operand->Length = 2;
+				if (Disassemble)
+				{
+					APPENDS("<FPUTAG>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case OPTYPE_FLDZ:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<0.0>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FLD1:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<1.0>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FLDPI:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<pi>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FLDL2T:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<log_2 10>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FLDL2E:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<log_2 e>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FLDLG2:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<log_10 2>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			case OPTYPE_FLDLN2:
+				if (!Decode) continue;
+				Operand->Type = OPTYPE_FLOAT;
+				Operand->Length = 10;
+				if (Disassemble)
+				{
+					APPENDS("<ln 2>");
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			////////////////////////////////////////////////////////////
+			// Fixed sizes regardless of operand size
+			////////////////////////////////////////////////////////////
+
+			case OPTYPE_b: // byte regardless of operand size
+				Operand->Length = 1;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_b (size 1, signed %d)\n", ((OperandFlags & OP_SIGNED) != 0)));
+				break;
+
+			case OPTYPE_w: // word regardless of operand size
+				Operand->Length = 2;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_w (size 2)\n"));
+				break;
+
+			case OPTYPE_d: // dword regardless of operand size
+				Operand->Length = 4;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_d (size 4)\n"));
+				break;
+
+			case OPTYPE_q: // qword regardless of operand size
+				Operand->Length = 8;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_q (size 8)\n"));
+				break;
+
+			case OPTYPE_o: // oword regardless of operand size
+				Operand->Length = 16;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_o (size 16)\n"));
+				break;
+
+			case OPTYPE_dt: // 6-byte or 10-byte pseudo descriptor (sgdt, lgdt, sidt, lidt)
+				if (IS_AMD64()) Operand->Length = 10;
+				else Operand->Length = 6;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_dt (%d bytes)\n", Operand->Length));
+				break;
+
+			case OPTYPE_cpu:
+				if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Undocumented loadall instruction?\n", VIRTUAL_ADDRESS);
+				Instruction->AnomalyOccurred = TRUE;
+				Operand->Length = 204;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_cpu (size 204)\n"));
+				break;
+
+			////////////////////////////////////////////////////////////
+			// Sizes depending on the operand size
+			////////////////////////////////////////////////////////////
+
+			case OPTYPE_z: // word if operand size is 16 bits and dword otherwise
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: case 4: Operand->Length = 4; break;
+					case 2: Operand->Length = 2; break;
+					default: assert(0); return NULL;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_z (length %d)\n", Operand->Length));
+				break;
+
+			case OPTYPE_v: // word, dword, or qword
+				Operand->Length = X86Instruction->OperandSize;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_v (size %d, signed = %d)\n", Operand->Length, ((OperandFlags & OP_SIGNED) != 0)));
+				break;
+
+			case OPTYPE_a: // two word or dword operands in memory (used only by bound)
+				assert(Instruction->OpcodeBytes[0] == X86_BOUND);
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: case 4: Operand->Length = 8; break;
+					case 2: Operand->Length = 4; break;
+					default: assert(0); return NULL;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_a (size %d)\n", Operand->Length));
+				break;
+
+			case OPTYPE_p: // 32-bit or 48-bit pointer depending on operand size
+				if (!Instruction->AnomalyOccurred && X86Instruction->HasSegmentOverridePrefix)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Segment override used when segment is explicit\n", VIRTUAL_ADDRESS);
+					Instruction->AnomalyOccurred = TRUE;
+				}
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: case 4: Operand->Length = 6; break;
+					case 2: Operand->Length = 4; break;
+					default: assert(0); return NULL;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_p (length %d)\n", Operand->Length));
+				break;
+
+			case OPTYPE_dq: // dword or qword
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_dq (size 4 or 8)\n"));
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: Operand->Length = 8; break;
+					case 4: case 2: Operand->Length = 4; break;
+					default: assert(0); return NULL;
+				}
+				break;
+
+			case OPTYPE_mw: // a word if the destination operand is memory
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_mw (size 0)\n"));
+				assert(X86Instruction->HasModRM);		
+				if (modrm.mod == 3) Operand->Length = X86Instruction->OperandSize; // using register
+				else Operand->Length = 2; // using memory
+				break;
+
+			case OPTYPE_lea:
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_lea (size 0)\n"));
+				assert(OperandIndex == 1);
+				Operand->Length = Instruction->Operands[0].Length;
+				break;
+
+			////////////////////////////////////////////////////////////
+			// FPU types
+			////////////////////////////////////////////////////////////
+
+			case OPTYPE_ps: // packed single real
+				Operand->Length = 4;
+				Operand->Type = OPTYPE_FLOAT;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_ps (packed single real)\n"));
+				break;
+			case OPTYPE_pd: // packed double real
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_FLOAT;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_pd (packed double real)\n"));
+				break;
+			case OPTYPE_pb: // packed BCD
+				Operand->Length = 10;
+				Operand->Type = OPTYPE_BCD;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_pb (packed BCD)\n"));
+				break;
+			case OPTYPE_ss: // scalar single real
+				Operand->Length = 4;
+				Operand->Type = OPTYPE_FLOAT;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_ss (single real)\n"));
+				break;
+			case OPTYPE_sd: // scalar double real
+				Operand->Length = 8;
+				Operand->Type = OPTYPE_FLOAT;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_sd (double real)\n"));
+				break;
+			case OPTYPE_se: // extended real
+				Operand->Length = 10;
+				Operand->Type = OPTYPE_FLOAT;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_se (extended real)\n"));
+				break;
+
+			case OPTYPE_fev: // FPU environment (28 bytes in 32-bit modes, 14 bytes in 16-bit real mode)
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: case 4: Operand->Length = 28; break;
+					case 2: Operand->Length = 14; break;
+					default: assert(0); return NULL;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_fev (FPU environment, length %d)\n", Operand->Length));
+				break;
+
+			case OPTYPE_fst1: // FPU state (108 bytes in 32-bit modes, 94 bytes in 16-bit real mode)
+				switch (X86Instruction->OperandSize)
+				{
+					case 8: case 4: Operand->Length = 108; break;
+					case 2: Operand->Length = 94; break;
+					default: assert(0); return NULL;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_fst1 (FPU state, length %d)\n", Operand->Length));
+				break;
+
+			case OPTYPE_fst2: // 512 bytes for FPU state (FPU + MMX + XXM + MXCSR)
+				Operand->Length = 512;
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_fst2 (FPU + MMX + XXM + MXCSR state, length 512)\n"));
+				break;
+
+			case OPTYPE_sso:
+				if (modrm.mod == 3) // from register
+				{
+					Operand->Length = 16;
+				}
+				else // from memory
+				{
+					Operand->Length = 4;
+					Operand->Type = OPTYPE_FLOAT;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_sso (single real or oword)\n"));
+				break;
+
+			case OPTYPE_sdo:
+				if (modrm.mod == 3) // from register
+				{
+					Operand->Length = 16;
+				}
+				else // from memory
+				{
+					Operand->Length = 8;
+					Operand->Type = OPTYPE_FLOAT;
+				}
+				//DISASM_OUTPUT(("[SetOperand] OPTYPE_sso (double real or oword)\n"));
+				break;
+
+			default:
+				assert(0);
+				return NULL;
+		}
+
+		switch (AddressMode)
+		{
+			////////////////////////////////////////////////////////////
+			// Special types
+			////////////////////////////////////////////////////////////
+
+			case AMODE_xlat: // DS:[EBX+AL]
+				if (!Decode) continue;
+				assert(Operand->Length == 1);
+				Operand->Flags |= OP_ADDRESS | OP_REG;
+				Operand->Type = OPTYPE_STRING;
+				
+				switch (X86Instruction->AddressSize)
+				{
+					case 8: Operand->Register = AMD64_REG_RBX; break;
+					case 4: Operand->Register = X86_REG_EBX; break;
+					case 2: Operand->Register = X86_REG_BX; break;
+					default: assert(0); return NULL;
+				}
+				X86_SET_ADDR();
+				X86Instruction->Scale = 1;
+				X86Instruction->BaseRegister = Operand->Register;
+				X86Instruction->HasBaseRegister = TRUE;
+				X86Instruction->IndexRegister = X86_REG_AL;
+				X86Instruction->HasIndexRegister = TRUE;
+
+				//DISASM_OUTPUT(("[SetOperand] AMODE_xlat (DS:[EBX+AL])\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "%s:[%s]", 
+						Segments[X86Instruction->Segment], X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			////////////////////////////////////////////////////////////
+			// Without mod R/M byte
+			////////////////////////////////////////////////////////////
+
+			case AMODE_I: // immediate value
+				if (Decode)
+				{
+					Operand->Type = OPTYPE_IMM;
+					switch (Operand->Length)
+					{
+						case 8:
+							if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S64 *)Address);
+							else Operand->Value_U64 = (U64)*((U64 *)Address);
+							break;
+						case 4:
+							if (!(OperandFlags & OP_SIGNED) && OperandIndex == 1 && 
+								(Instruction->Operands[0].Flags & (OP_REG|OP_ADDRESS)) &&
+								Instruction->Operands[0].Length == 8)
+							{
+								// For some opcodes the second operand is a sign-extended imm32 value
+								assert(X86Instruction->OperandSize == 8);
+								switch (Instruction->Type)
+								{
+									case ITYPE_AND:
+									case ITYPE_ADD:
+									case ITYPE_XCHGADD:
+									case ITYPE_CMP:
+									case ITYPE_MOV:
+									case ITYPE_SUB:
+									case ITYPE_TEST:
+									case ITYPE_OR:
+									case ITYPE_XOR:
+										assert(OperandIndex == 1);
+										Operand->Value_S64 = (S64)*((S32 *)Address);
+										break;
+									default:
+										assert(0);
+										if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S32 *)Address);
+										else Operand->Value_U64 = (U64)*((U32 *)Address);
+										break;
+								}
+							}
+							else
+							{
+								if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S32 *)Address);
+								else Operand->Value_U64 = (U64)*((U32 *)Address);
+							}
+							break;
+						case 2:
+							if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S16 *)Address);
+							else Operand->Value_U64 = (U64)*((U16 *)Address);
+							break;
+						case 1:
+							if (OperandFlags & OP_SIGNED) Operand->Value_S64 = (S64)*((S8 *)Address);
+							else Operand->Value_U64 = (U64)*((U8 *)Address);
+							break;
+						default:
+							assert(0);
+							return NULL;
+					}
+				}
+				INSTR_INC(Operand->Length); // increment Instruction->Length and address
+				assert(X86Instruction->OperandSize >= Operand->Length);
+				if (Instruction->Type == ITYPE_PUSH) Operand->Length = X86Instruction->OperandSize;
+
+				//DISASM_OUTPUT(("[SetOperand] AMODE_I (immediate data)\n"));
+				if (Disassemble)
+				{
+					X86_WRITE_IMMEDIATE();
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case AMODE_J: // IP-relative jump offset
+				SANITY_CHECK_ADDRESS_SIZE();
+				if (Decode)
+				{
+					Operand->Flags |= OP_IPREL | OP_SIGNED | OP_REG | OP_ADDRESS;
+					Operand->Type = OPTYPE_OFFSET;
+					switch (X86Instruction->OperandSize)
+					{
+						case 8: Operand->Register = AMD64_REG_RIP; break;
+						case 4: Operand->Register = X86_REG_EIP; break;
+						case 2: Operand->Register = X86_REG_IP; break;
+						default: assert(0); return NULL;
+					}
+					switch (Operand->Length)
+					{
+						case 8: X86Instruction->Displacement = *((S64 *)Address); break;
+						case 4: X86Instruction->Displacement = (S64)*((S32 *)Address); break;
+						case 2: X86Instruction->Displacement = (S64)*((S16 *)Address); break;
+						case 1: X86Instruction->Displacement = (S64)*((S8 *)Address); break;
+						default: assert(0); return NULL;
+					}					
+
+					Operand->Value_S64 = X86Instruction->Displacement;
+					X86Instruction->Relative = TRUE;
+
+					if ((Operand->Flags & OP_COND) && !X86Instruction->Displacement)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: Both conditions of branch go to same address\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+				}
+
+				INSTR_INC(Operand->Length); // increment Instruction->Length and address
+				if (!Decode) continue;
+
+				assert((Operand->Flags & OP_EXEC) && (Instruction->Groups & ITYPE_EXEC));
+				Operand->TargetAddress = ApplyDisplacement((U64)Address, Instruction);
+				X86Instruction->Relative = TRUE; 
+				X86_SET_ADDR();
+				SANITY_CHECK_SEGMENT_OVERRIDE();
+				X86Instruction->HasSegmentOverridePrefix = FALSE;
+				X86Instruction->Segment = SEG_CS;
+				X86Instruction->BaseRegister = Operand->Register;
+				X86Instruction->HasBaseRegister = TRUE;
+				assert(Instruction->OperandCount == 1);
+				//DISASM_OUTPUT(("[SetOperand] AMODE_J (branch with relative offset)\n"));
+				if (Disassemble)
+				{
+					X86_WRITE_IP_OFFSET(Operand);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case AMODE_O: // word/dword offset
+				Operand->Type = OPTYPE_OFFSET;
+				Operand->Flags |= OP_ADDRESS;
+				SANITY_CHECK_OPERAND_SIZE();
+				switch (X86Instruction->AddressSize)
+				{
+					case 8:
+						if (Operand->Flags & OP_SIGNED) X86Instruction->Displacement = *((S64 *)Address);
+						else X86Instruction->Displacement = (S64)*((U64 *)Address);
+						break;
+					case 4:
+						if (Operand->Flags & OP_SIGNED) X86Instruction->Displacement = (S64)*((S32 *)Address);
+						else X86Instruction->Displacement = (S64)*((U32 *)Address);
+						break;
+					case 2:
+						if (Operand->Flags & OP_SIGNED) X86Instruction->Displacement = (S64)*((S16 *)Address);
+						else X86Instruction->Displacement = (S64)*((U16 *)Address);
+						break;
+					default:
+						assert(0);
+						return FALSE;
+				}
+
+				INSTR_INC(X86Instruction->AddressSize); // increment Instruction->Length and address
+				if (!Decode) continue;
+
+				X86Instruction->HasFullDisplacement = TRUE;
+				X86_SET_ADDR();
+				X86_SET_TARGET();
+				assert(X86Instruction->Segment == SEG_DS || X86Instruction->HasSegmentOverridePrefix);
+				//DISASM_OUTPUT(("[SetOperand] AMODE_O (offset)\n"));
+				if (Disassemble)
+				{
+					X86_WRITE_OFFSET(Operand);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case AMODE_A: // absolute address
+				Operand->Flags |= OP_ADDRESS | OP_FAR;
+				SANITY_CHECK_ADDRESS_SIZE();
+				SANITY_CHECK_SEGMENT_OVERRIDE();
+				X86Instruction->HasSelector = TRUE;
+				X86Instruction->HasSegmentOverridePrefix = FALSE;
+				switch (Operand->Length)
+				{
+					case 6:
+						X86Instruction->Segment = *((U16 *)Address); INSTR_INC(2);
+						X86Instruction->Displacement = (S64)*((S32 *)Address); INSTR_INC(4);
+						break;
+					case 4:
+						X86Instruction->Segment = *((U16 *)Address); INSTR_INC(2);
+						X86Instruction->Displacement = (S64)*((S16 *)Address); INSTR_INC(2);
+						break;
+					default:
+						assert(0);
+						return FALSE;
+				}
+				if (!Decode) continue;
+				X86Instruction->HasFullDisplacement = TRUE;
+				X86_SET_ADDR();
+				X86_SET_TARGET();
+				//DISASM_OUTPUT(("[SetOperand] AMODE_A (absolute address)\n"));
+				if (Disassemble)
+				{
+					X86_WRITE_OFFSET(Operand);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case AMODE_X: // DS:[ESI]
+				if (!Decode) continue;
+				Operand->Flags |= OP_ADDRESS | OP_REG;
+				Operand->Type = OPTYPE_STRING;
+				switch (X86Instruction->AddressSize)
+				{
+					case 8: Operand->Register = AMD64_REG_RSI; break;
+					case 4: Operand->Register = X86_REG_ESI; break;
+					case 2: Operand->Register = X86_REG_SI; break;
+					default: assert(0); return NULL;
+				}
+
+				X86Instruction->BaseRegister = Operand->Register;
+				X86Instruction->HasBaseRegister = TRUE;
+				X86_SET_ADDR();
+				if (!X86Instruction->HasSegmentOverridePrefix) X86Instruction->Segment = SEG_DS;
+
+				//DISASM_OUTPUT(("[SetOperand] AMODE_X (addressing via DS:[ESI])\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "%s:[%s]", 
+						Segments[X86Instruction->Segment], X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+
+			case AMODE_Y: // ES:[EDI]
+				if (!Decode) continue;
+				Operand->Flags |= OP_ADDRESS | OP_REG;
+				Operand->Type = OPTYPE_STRING;
+				switch (X86Instruction->AddressSize)
+				{
+					case 8: Operand->Register = AMD64_REG_RDI; break;
+					case 4: Operand->Register = X86_REG_EDI; break;
+					case 2: Operand->Register = X86_REG_DI; break;
+					default: assert(0); return NULL;
+				}
+
+				X86Instruction->BaseRegister = Operand->Register;
+				X86Instruction->HasBaseRegister = TRUE;
+				X86_SET_ADDR();
+				if (X86Instruction->HasSegmentOverridePrefix)
+				{
+					if (!Instruction->AnomalyOccurred)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ANOMALY: segment override used with AMODE_Y\n", VIRTUAL_ADDRESS);
+						Instruction->AnomalyOccurred = TRUE;
+					}
+					Segment = X86Instruction->DstSegment = SEG_ES;
+					X86Instruction->HasDstSegment = TRUE;
+				}
+				else
+				{
+					Segment = X86Instruction->Segment = SEG_ES;
+				}
+
+				//DISASM_OUTPUT(("[SetOperand] AMODE_Y (addressing via ES:[EDI])\n"));
+				if (Disassemble)
+				{
+					APPEND(OPCSTR, SIZE_LEFT, "%s:[%s]", 
+						Segments[Segment], X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				continue;
+			
+			////////////////////////////////////////////////////////////
+			// Mod R/M byte with only registers
+			// Handle that case here since it is straightforward
+			////////////////////////////////////////////////////////////
+
+			case AMODE_PR: // modrm.rm = mmx register and modrm.mod = 11
+				assert(X86Instruction->HasModRM);
+				if (modrm.mod != 3)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod != 3 for AMODE_PR (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				else if (rex_modrm.rm > 7)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: invalid mmx register %d for AMODE_PR (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.rm, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				else if (X86Instruction->OperandSize == 2)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_PR illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.rm, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				if (!Decode) continue;
+
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_MMX_OFFSET + rex_modrm.rm;
+				X86_SET_REG(0);
+
+				if (Disassemble)
+				{
+					assert(X86_Registers[Operand->Register]);
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_PR (MMX register)\n"));
+				continue;
+
+			case AMODE_VR: // modrm.rm = xmm register and modrm.mod = 11
+				assert(X86Instruction->HasModRM);
+				if (modrm.mod != 3)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod != 3 for AMODE_VR (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				else if (X86Instruction->OperandSize == 2)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_VR illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.rm, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				if (!Decode) continue;
+
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_XMM_OFFSET + rex_modrm.rm;
+				X86_SET_REG(0);
+
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_VR (XMM register)\n"));
+				continue;
+
+			case AMODE_P: // modrm.reg = mmx register
+				assert(X86Instruction->HasModRM);
+				if (rex_modrm.reg > 7)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: invalid mmx register %d for AMODE_P (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.reg, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				else if (X86Instruction->OperandSize == 2)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_P illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				if (!Decode) continue;
+
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_MMX_OFFSET + rex_modrm.reg;
+				X86_SET_REG(0);
+
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_P (MMX register)\n"));
+				continue;
+
+			case AMODE_V: // modrm.reg = xmm register
+				assert(X86Instruction->HasModRM);
+				if (X86Instruction->OperandSize == 2)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: AMODE_P illegal in 16-bit mode (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				if (!Decode) continue;
+
+				Operand->Flags |= OP_REG;
+				Operand->Register = X86_XMM_OFFSET + rex_modrm.reg; break;
+				X86_SET_REG(0);
+
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_V (XMM register)\n"));
+				continue;
+
+			case AMODE_R: // modrm.rm is general register and modrm.mod = 11
+				assert(X86Instruction->HasModRM);
+				if (modrm.mod != 3)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod != 3 for AMODE_R (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				if (!Decode) continue;
+				Operand->Flags |= OP_REG;
+				switch (Operand->Length)
+				{
+					case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.rm; break;
+					case 4: Operand->Register = X86_32BIT_OFFSET, rex_modrm.rm; CHECK_AMD64_REG(); break;
+					case 2: Operand->Register = X86_16BIT_OFFSET, rex_modrm.rm; CHECK_AMD64_REG(); break;
+					case 1: Operand->Register = X86_8BIT_OFFSET, rex_modrm.rm; if (X86Instruction->rex_b) CHECK_AMD64_REG(); break;
+					default: assert(0); return NULL;
+				}
+				X86_SET_REG(rex_modrm.rm);
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_R (general register)\n"));
+				continue;
+
+			case AMODE_G: // modrm.reg = general register
+				assert(X86Instruction->HasModRM);
+				if (!Decode) continue;
+				Operand->Flags |= OP_REG;
+				switch (Operand->Length)
+				{
+					case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.reg; break;
+					case 4: Operand->Register = X86_32BIT_OFFSET + rex_modrm.reg; CHECK_AMD64_REG(); break;
+					case 2: Operand->Register = X86_16BIT_OFFSET + rex_modrm.reg; CHECK_AMD64_REG(); break;
+					case 1: Operand->Register = X86_8BIT_OFFSET + rex_modrm.reg; if (X86Instruction->rex_b) CHECK_AMD64_REG(); break;
+					default: assert(0); return NULL;
+				}
+				X86_SET_REG(rex_modrm.reg);
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_G (general register)\n"));
+				continue;
+			
+			case AMODE_S: // modrm.reg = segment register
+				assert(X86Instruction->HasModRM);
+				if (!Decode) continue;
+				Operand->Flags |= OP_REG;
+				switch (X86Instruction->OperandSize)
+				{
+					case 8:
+					case 4:
+					case 2:
+						if (rex_modrm.reg <= 5) Operand->Register = X86_SEGMENT_OFFSET + rex_modrm.reg;
+						break;
+					default:
+						assert(0);
+						return NULL;
+				}
+
+				X86_SET_REG(0);
+				if (Disassemble)
+				{
+					if (rex_modrm.reg > 5) APPEND(OPCSTR, SIZE_LEFT, "seg_%02X", rex_modrm.reg);
+					else APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_S (segment register)\n"));
+				continue;
+
+			case AMODE_T: // modrm.reg = test register
+				assert(X86Instruction->HasModRM);
+				if (!Decode) continue;
+				Instruction->Groups |= ITYPE_SYSTEM;
+				Instruction->NeedsEmulation = TRUE;
+				Operand->Flags |= OP_REG;
+				switch (X86Instruction->OperandSize)
+				{
+					case 8:
+					case 4:
+					case 2:
+						Operand->Register = X86_TEST_OFFSET + rex_modrm.reg;
+						break;
+					default:
+						assert(0);
+						return NULL;
+				}
+
+				X86_SET_REG(0);
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_T (test register)\n"));
+				continue;
+
+			case AMODE_C: // modrm.reg = control register
+				assert(X86Instruction->HasModRM);
+				assert(Instruction->Type == ITYPE_MOV);
+				if (!Decode) continue;
+				Instruction->Groups |= ITYPE_SYSTEM;
+				Instruction->NeedsEmulation = TRUE;
+				Operand->Flags |= OP_REG;
+				if (IS_AMD64()) X86Instruction->OperandSize = 8;
+				switch (X86Instruction->OperandSize)
+				{
+					case 8:
+					case 4:
+					case 2:
+						Operand->Register = X86_CONTROL_OFFSET + rex_modrm.reg;
+						break;
+					default:
+						assert(0);
+						return NULL;
+				}
+
+				X86_SET_REG(0);
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_C (control register)\n"));
+				continue;
+
+			case AMODE_D: // modrm.reg = debug register
+				assert(X86Instruction->HasModRM);
+				assert(Instruction->Type == ITYPE_MOV);
+				if (!Decode) continue;
+				Instruction->NeedsEmulation = TRUE;
+				Operand->Flags |= OP_REG;
+				Instruction->Groups |= ITYPE_SYSTEM;
+				Instruction->NeedsEmulation = TRUE;
+				if (IS_AMD64()) X86Instruction->OperandSize = 8;
+				switch (X86Instruction->OperandSize)
+				{
+					case 8:
+					case 4:
+					case 2:
+						Operand->Register = X86_DEBUG_OFFSET + rex_modrm.reg;
+						break;
+					default:
+						assert(0);
+						return NULL;
+				}
+
+				X86_SET_REG(0);
+				if (Disassemble)
+				{
+					APPENDS(X86_Registers[Operand->Register]);
+					X86_WRITE_OPFLAGS();
+				}
+				//DISASM_OUTPUT(("[SetOperand] AMODE_D (debug register)\n"));
+				continue;
+
+			////////////////////////////////////////////////////////////
+			// Mod R/M byte with memory or register
+			////////////////////////////////////////////////////////////
+
+			case AMODE_M: // memory only
+				assert(X86Instruction->HasModRM);
+				if (modrm.mod == 3)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod = 3 for AMODE_M (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+				assert(X86Instruction->Segment == SEG_DS || X86Instruction->HasSegmentOverridePrefix);
+				//DISASM_OUTPUT(("[SetOperand] AMODE_M (memory only)\n"));
+				Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
+				if (!Address) return NULL;
+				break;
+
+			case AMODE_E: // general register or memory
+				assert(X86Instruction->HasModRM);
+				if (OperandType == OPTYPE_p && modrm.mod == 3)
+				{
+					if (!SuppressErrors) printf("[0x%08I64X] ERROR: mod = 3 for AMODE_E with OPTYPE_p (\"%s\")\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic);
+					goto abort;
+				}
+
+				//DISASM_OUTPUT(("[SetOperand] AMODE_E (general register or memory)\n"));
+				Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
+				if (!Address) return NULL;
+				if (Decode && (Instruction->Type == ITYPE_PUSH || Instruction->Type == ITYPE_POP))
+				{
+					assert(X86Instruction->OperandSize >= Operand->Length);
+					Operand->Length = X86Instruction->OperandSize;
+				}
+				break;
+
+			case AMODE_Q: // mmx register or memory address
+				assert(X86Instruction->HasModRM);
+				//DISASM_OUTPUT(("[SetOperand] AMODE_Q (MMX register or memory address)\n"));
+				if (modrm.mod == 3) // it is a register
+				{
+					if (rex_modrm.rm > 7)
+					{
+						if (!SuppressErrors) printf("[0x%08I64X] ERROR: invalid mmx register %d for AMODE_P (\"%s\")\n", VIRTUAL_ADDRESS, rex_modrm.rm, X86Instruction->Opcode.Mnemonic);
+						goto abort;
+					}
+					Operand->Register = X86_MMX_OFFSET + rex_modrm.rm;
+					Operand->Flags |= OP_REG;
+					X86_SET_REG(0);
+				}
+				else
+				{
+					Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
+					if (!Address) return NULL;
+				}
+				break;
+
+			case AMODE_W: // xmm register or memory address
+				assert(X86Instruction->HasModRM);
+				//DISASM_OUTPUT(("[SetOperand] AMODE_W (XMM register or memory address)\n"));
+				if (modrm.mod == 3) // it is a register
+				{
+					Operand->Register = X86_XMM_OFFSET + rex_modrm.rm;
+					Operand->Flags |= OP_REG;
+					X86_SET_REG(0);
+				}
+				else
+				{
+					Address = SetModRM32(Instruction, Address, Operand, OperandIndex, SuppressErrors);
+					if (!Address) return NULL;
+				}
+				break;
+
+			default:
+				assert(0);
+				return NULL;
+		}
+
+		if (!Decode) continue;
+
+		// If this is reached then SetModRM32 was called
+		if ((Operand->Flags & OP_ADDRESS))
+		{
+			assert(Operand->Length);
+			switch (Operand->Register)
+			{
+				case X86_REG_BP:
+				case X86_REG_EBP:
+				case AMD64_REG_RBP:
+					if (X86Instruction->Displacement > 0) Operand->Flags |= OP_PARAM;
+					else Operand->Flags |= OP_LOCAL;
+					break;
+				default:
+					break;
+			}
+		}
+
+		if (Disassemble)
+		{
+			Index = OperandType >> OPTYPE_SHIFT;
+			assert(Index > 0 && Index < MAX_OPTYPE_INDEX && OptypeHandlers[Index]);
+			OptypeHandlers[Index](Instruction, Operand, OperandIndex);
+			X86_WRITE_OPFLAGS();
+		}
+	}
+
+	return Address;
+
+abort:
+	if (!SuppressErrors)
+	{
+#ifdef TEST_DISASM
+		printf("Dump of 0x%04I64X:\n", VIRTUAL_ADDRESS);
+		__try { DumpAsBytes(stdout, Instruction->Address, (ULONG_PTR)VIRTUAL_ADDRESS, 16, TRUE); }
+		__except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {}
+#endif
+		fflush(stdout);
+	}
+	return NULL;
+}
+
+// NOTE: Address points one byte after ModRM
+INTERNAL U8 *SetModRM16(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors)
+{
+	MODRM modrm;
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+
+	DISASM_OUTPUT(("[SetModRM16] Current instruction length = %d\n", Instruction->Length));
+	modrm = X86Instruction->modrm;
+	assert(!X86Instruction->rex_b);
+
+	//
+	// Both operands are registers
+	// Condition: mod = 3
+	//
+	if (modrm.mod == 3)
+	{
+		//DISASM_OUTPUT(("[SetModRM16] Both regs (rm_reg %d)\n", modrm.rm));
+		switch (Operand->Length)
+		{
+			case 4: Operand->Register = X86_32BIT_OFFSET + modrm.rm; break;
+			case 2: Operand->Register = X86_16BIT_OFFSET + modrm.rm; break;
+			case 1: Operand->Register = X86_8BIT_OFFSET + modrm.rm; break;
+			default: assert(0); return NULL;
+		}
+		Operand->Flags |= OP_REG;
+	}
+
+	// 
+	// Address is an absolute address (technically a 16-bit offset from DS:0)
+	// Condition: mod = 0 and rm = 6
+	//
+	else if (modrm.mod == 0 && modrm.rm == 6)
+	{
+		//DISASM_OUTPUT(("[SetModRM16] Absolute addressing (displacement 0x%04X)\n", *(S16 *)Address));
+		X86Instruction->Displacement = (S64)(*((S16 *)Address));
+		if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+		{
+			X86Instruction->HasFullDisplacement = TRUE;
+			X86_SET_TARGET();
+			Operand->Flags |= OP_GLOBAL;
+		}
+		X86_SET_ADDR();
+		Operand->Flags |= OP_ADDRESS;
+		INSTR_INC(2);
+	}
+
+	// Conditions:
+	// (1) mod = 0 and rm != 6
+	// (2) mod = 1-2 and rm = 0-7
+	else
+	{
+		switch (modrm.mod)
+		{
+			case 0: // no displacement
+				//DISASM_OUTPUT(("[SetModRM16] Indirect addressing (no displacement)\n"));
+				break; 
+			case 1: // 8-bit signed displacement
+				//DISASM_OUTPUT(("[SetModRM16] Indirect addressing (displacement = 0x%02X, reg_rm = %d)\n", *(S8 *)Address, modrm.rm));
+				X86Instruction->Displacement = (S64)(*((S8 *)Address));
+				INSTR_INC(1); // increment Instruction->Length and address
+				break;
+			case 2: // 16-bit displacement
+				//DISASM_OUTPUT(("[SetModRM16] Indirect addressing (displacement = 0x%04X, reg_rm = %d)\n", *(S16 *)Address, modrm.rm));
+				X86Instruction->Displacement = (S64)(*((S16 *)Address));
+				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+				{
+					Operand->Flags |= OP_GLOBAL;
+					X86Instruction->HasFullDisplacement = TRUE;
+				}
+				INSTR_INC(2);
+				break;
+		}
+
+		switch (modrm.rm)
+		{
+			case 0:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BX+SI]\n"));
+				X86Instruction->BaseRegister = X86_REG_BX;
+				X86Instruction->IndexRegister = X86_REG_SI;
+				X86Instruction->HasIndexRegister = TRUE;
+				break;
+			case 1:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BX+DI]\n"));
+				X86Instruction->BaseRegister = X86_REG_BX;
+				X86Instruction->IndexRegister = X86_REG_DI;
+				X86Instruction->HasIndexRegister = TRUE;
+				break;
+			case 2:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BP+SI]\n"));
+				X86Instruction->BaseRegister = X86_REG_BP;
+				X86Instruction->IndexRegister = X86_REG_SI;
+				X86Instruction->HasIndexRegister = TRUE;
+				X86_SET_SEG(REG_BP);
+				break;
+			case 3:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BP+DI]\n"));
+				X86Instruction->BaseRegister = X86_REG_BP;
+				X86Instruction->IndexRegister = X86_REG_DI;
+				X86Instruction->HasIndexRegister = TRUE;
+				X86_SET_SEG(REG_BP);
+				break;
+			case 4:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [SI]\n"));
+				X86Instruction->BaseRegister = X86_REG_SI;
+				break;
+			case 5:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [DI]\n"));
+				X86Instruction->BaseRegister = X86_REG_DI;
+				break;
+			case 6:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BP]\n"));
+				X86Instruction->BaseRegister = X86_REG_BP;
+				break;
+			case 7:
+				//DISASM_OUTPUT(("[SetModRM16] Addressing mode [BX]\n"));
+				X86Instruction->BaseRegister = X86_REG_BX;
+				break;
+		}
+
+		X86Instruction->HasBaseRegister = TRUE;
+		Operand->Flags |= OP_ADDRESS | OP_REG;
+		X86_SET_ADDR();
+	}
+
+	return Address;
+}
+
+// NOTE: Address points one byte after ModRM
+INTERNAL U8 *SetModRM32(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors)
+{
+	MODRM modrm;
+	REX_MODRM rex_modrm;
+	U32 i, ImmediateSize = 0;
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+
+	if (X86Instruction->AddressSize == 2)
+	{
+		return SetModRM16(Instruction, Address, Operand, OperandIndex, SuppressErrors);
+	}
+
+	//DISASM_OUTPUT(("[SetModRM32] Length %d, modrm = 0x%02X\n", Instruction->Length, X86Instruction->modrm_b));
+	modrm = X86Instruction->modrm;
+	rex_modrm = X86Instruction->rex_modrm;
+
+	//
+	// Both operands are registers
+	// Condition: mod = 3
+	//
+	if (modrm.mod == 3)
+	{
+		switch (Operand->Length)
+		{
+			case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.rm; break;
+			case 4: Operand->Register = X86_32BIT_OFFSET + rex_modrm.rm; CHECK_AMD64_REG(); break;
+			case 2: Operand->Register = X86_16BIT_OFFSET + rex_modrm.rm; CHECK_AMD64_REG(); break;
+			case 1: Operand->Register = X86_8BIT_OFFSET + rex_modrm.rm; if (X86Instruction->rex_b) CHECK_AMD64_REG(); break;
+			default: assert(0); return NULL;
+		}
+		X86_SET_REG(rex_modrm.rm);
+		Operand->Flags |= OP_REG;
+	}
+
+	// 
+	// Address is an absolute address (technically a 32-bit offset from DS:0)
+	// mod = 0 and rm = 5
+	//
+	else if (modrm.mod == 0 && modrm.rm == 5)
+	{
+		//DISASM_OUTPUT(("[SetModRM32] Absolute addressing (displacement 0x%08lX)\n", *(S32 *)Address));
+		Operand->Flags |= OP_ADDRESS;
+		X86Instruction->Displacement = (S64)*((S32 *)Address);
+		INSTR_INC(4); // increment Instruction->Length and address
+
+		if (IS_AMD64())
+		{
+			// RIP-relative addressing always replaced Disp32, even when using a 32-bit address space
+			// (via address size override prefix)
+			switch (X86Instruction->OperandSize)
+			{
+				case 8: Operand->Register = AMD64_REG_RIP; break;
+				case 4: Operand->Register = X86_REG_EIP; break;
+				case 2: Operand->Register = X86_REG_IP; break;
+				default: assert(0); return NULL;
+			}
+			X86Instruction->BaseRegister = Operand->Register;
+			X86Instruction->HasBaseRegister = TRUE;
+			X86Instruction->Relative = TRUE;
+			Operand->Flags |= OP_IPREL | OP_SIGNED | OP_REG;
+			SANITY_CHECK_SEGMENT_OVERRIDE();
+			if (!X86Instruction->HasSegmentOverridePrefix) X86Instruction->Segment = SEG_CS;
+			X86Instruction->HasFullDisplacement = TRUE;
+
+			// Since there may be an immediate value to follow, it is necessary
+			// to determine the length in order get the proper offset
+			//
+			// Maybe there is a better way to do this, since this is wasteful
+			// (the size of the immediate value will have to be decoded again later
+			// in SetOperands)
+
+			for (ImmediateSize = 0, i = OperandIndex+1; i < Instruction->OperandCount; i++)
+			{
+				if ((X86Instruction->Opcode.OperandFlags[i] & X86_AMODE_MASK) != AMODE_I) continue;
+				else assert(!ImmediateSize);
+				switch (X86Instruction->Opcode.OperandFlags[i] & X86_OPTYPE_MASK)
+				{
+					case OPTYPE_v:
+						ImmediateSize = X86Instruction->OperandSize;
+						break;
+					case OPTYPE_z:
+						switch (X86Instruction->OperandSize)
+						{
+							case 8: case 4: ImmediateSize = 4; break;
+							case 2: ImmediateSize = 2; break;
+							default: assert(0); return NULL;
+						}
+						break;
+					case OPTYPE_b:
+						ImmediateSize = 1;
+						break;
+					case OPTYPE_w:
+						ImmediateSize = 2;
+						break;
+					case OPTYPE_1:
+						break;
+					default:
+						assert(0);
+						break;
+				}
+			}
+
+			Operand->TargetAddress = ApplyDisplacement((U64)Address + ImmediateSize, Instruction);
+		}
+		else if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+		{
+			X86_SET_TARGET();
+			Operand->Flags |= OP_GLOBAL;
+			X86Instruction->HasFullDisplacement = TRUE;
+		}
+
+		X86_SET_ADDR();
+	}
+
+	//
+	// Addressing mode indicated by SIB byte
+	// Condition: mod = 0-2 and rm = 4
+	//
+	else if (modrm.rm == 4)
+	{
+		// The X86_SET_*() is called from within SetSIB()
+		Address = SetSIB(Instruction, Address, Operand, OperandIndex, SuppressErrors);
+		if (!Address)
+		{
+			assert(0);
+			return NULL;
+		}
+
+		if (X86Instruction->sib.base != 5) // if base == 5, the displacement is handled in SetSIB
+		{
+			switch (modrm.mod)
+			{
+				case 1: // 8-bit displacement
+					//DISASM_OUTPUT(("[SetModRM32] After SIB: displacement 0x%02X\n", *((S8 *)Address)));
+					X86Instruction->Displacement = (S64)(*((S8 *)Address));
+					INSTR_INC(1); // increment Instruction->Length and address
+					break;
+				case 2: // 32-bit displacement
+					//DISASM_OUTPUT(("[SetModRM32] After SIB: displacement 0x%08lX\n", *((S32 *)Address)));
+					X86Instruction->Displacement = (S64)*((S32 *)Address);
+					if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+					{
+						Operand->Flags |= OP_GLOBAL;
+						X86Instruction->HasFullDisplacement = TRUE;
+					}
+					INSTR_INC(4); // increment Instruction->Length and address
+					break;
+			}	
+		}
+	}
+
+	// Indirect addressing
+	// Conditions:
+	// (1) mod = 0 and (rm = 0-3 or 6-7)
+	// (2) mod = 1-2 and rm != 4
+	else
+	{
+		switch (X86Instruction->AddressSize)
+		{
+			case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_modrm.rm; break;
+			case 4: Operand->Register = X86_32BIT_OFFSET + rex_modrm.rm; CHECK_AMD64_REG(); break;
+			default: assert(0); return NULL;
+		}
+		X86Instruction->BaseRegister = Operand->Register;
+		X86Instruction->HasBaseRegister = TRUE;
+		Operand->Flags |= OP_ADDRESS | OP_REG;
+		X86_SET_SEG(rex_modrm.rm);
+		X86_SET_ADDR();
+
+		switch (modrm.mod)
+		{
+			case 0: // no displacement
+				//DISASM_OUTPUT(("[SetModRM32] Indirect addressing (no displacement, reg_rm = %d)\n", rex_modrm.rm));
+				break; 
+			case 1: // 8-bit signed displacement
+				//DISASM_OUTPUT(("[SetModRM32] Indirect addressing (displacement = 0x%02X, reg_rm = %d)\n", *(S8 *)Address, rex_modrm.rm));
+				X86Instruction->Displacement = (S64)(*((S8 *)Address));
+				INSTR_INC(1); // increment Instruction->Length and address
+				break;
+			case 2: // 32-bit displacement
+				//DISASM_OUTPUT(("[SetModRM32] Indirect addressing (displacement = 0x%08lX, reg_rm = %d)\n", *(S32 *)Address, rex_modrm.rm));
+				X86Instruction->Displacement = (S64)*((S32 *)Address);
+				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+				{
+					Operand->Flags |= OP_GLOBAL;
+					X86Instruction->HasFullDisplacement = TRUE;
+				}
+				INSTR_INC(4); // increment Instruction->Length and address
+				break;
+		}
+	}
+
+	return Address;
+}
+
+// NOTE: Address points at SIB
+INTERNAL U8 *SetSIB(INSTRUCTION *Instruction, U8 *Address, INSTRUCTION_OPERAND *Operand, U32 OperandIndex, BOOL SuppressErrors)
+{
+	REX rex;
+	SIB sib;
+	REX_SIB rex_sib;
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+
+	X86Instruction->sib_b = *Address;
+	SET_SIB(X86Instruction->sib, *Address);
+	sib = X86Instruction->sib;
+	rex = X86Instruction->rex;
+	SET_REX_SIB(X86Instruction->rex_sib, rex, sib);
+	rex_sib = X86Instruction->rex_sib;
+
+	//if (!X86Instruction->rex_b) DISASM_OUTPUT(("[0x%08I64X] SIB = 0x%02X (scale=%d, index=%d, base=%d)\n", VIRTUAL_ADDRESS, *Address, sib.scale, sib.index, sib.base)); \
+	//else DISASM_OUTPUT(("[0x%08I64X] SIB = 0x%02X (scale=%d, index=%d, base=%d)\n", VIRTUAL_ADDRESS, *Address, sib.scale, rex_sib.index, rex_sib.base)); \
+	//DISASM_OUTPUT(("[SetSIB] Current instruction length = %d\n", Instruction->Length));
+
+	Operand->Flags |= OP_ADDRESS;
+	X86_SET_ADDR();
+	INSTR_INC(1); // increment Instruction->Length and address
+
+	if (sib.base == 5)
+	{
+		switch (X86Instruction->modrm.mod)
+		{
+			case 0:
+				X86Instruction->Displacement = (S64)*((S32 *)Address);
+				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+				{
+					X86Instruction->HasFullDisplacement = TRUE;
+					X86_SET_TARGET();
+					Operand->Flags |= OP_GLOBAL;
+				}
+				INSTR_INC(4);
+				break;
+			case 1:
+				X86Instruction->Displacement = (S64)(*((S8 *)Address));
+				if (rex_sib.base == 5)
+				{
+					switch (X86Instruction->AddressSize)
+					{
+						case 8: Operand->Register = AMD64_REG_RBP; break;
+						case 4: Operand->Register = X86_REG_EBP; break;
+						default: assert(0); return NULL;
+					}
+					X86_SET_SEG(REG_EBP);
+				}
+				else
+				{
+					Operand->Register = AMD64_REG_R13;
+				}
+
+				X86Instruction->BaseRegister = Operand->Register;
+				X86Instruction->HasBaseRegister = TRUE;
+				Operand->Flags |= OP_REG;
+				INSTR_INC(1);
+				break;
+			case 2:
+				X86Instruction->Displacement = (S64)*((S32 *)Address);
+				if (rex_sib.base == 5)
+				{
+					switch (X86Instruction->AddressSize)
+					{
+						case 8: Operand->Register = AMD64_REG_RBP; break;
+						case 4: Operand->Register = X86_REG_EBP; break;
+						default: assert(0); return NULL;
+					}
+					X86_SET_SEG(REG_EBP);
+				}
+				else
+				{
+					Operand->Register = AMD64_REG_R13;
+				}
+
+				if (IS_VALID_ADDRESS(X86Instruction->Displacement))
+				{
+					Operand->Flags |= OP_GLOBAL;
+					X86Instruction->HasFullDisplacement = TRUE;
+				}
+				X86Instruction->BaseRegister = Operand->Register;
+				X86Instruction->HasBaseRegister = TRUE;
+				Operand->Flags |= OP_REG;
+				INSTR_INC(4);
+				break;
+		}
+	}
+	else
+	{
+		switch (X86Instruction->AddressSize)
+		{
+			case 8: Operand->Register = AMD64_64BIT_OFFSET + rex_sib.base; break;
+			case 4: Operand->Register = X86_32BIT_OFFSET + rex_sib.base; CHECK_AMD64_REG(); break;
+			default: assert(0); return NULL;
+		}
+		X86Instruction->BaseRegister = Operand->Register;
+		X86Instruction->HasBaseRegister = TRUE;
+		X86_SET_SEG(rex_sib.base);
+		Operand->Flags |= OP_REG;
+	}
+
+	if (rex_sib.index != 4)
+	{
+		switch (X86Instruction->AddressSize)
+		{
+			case 8:
+				X86Instruction->IndexRegister = AMD64_64BIT_OFFSET + rex_sib.index;
+				break;
+			case 4:
+				X86Instruction->IndexRegister = X86_32BIT_OFFSET + rex_sib.index;
+				break;
+			default:
+				fflush(stdout);
+				assert(0);
+				return NULL;
+		}
+
+		Operand->TargetAddress = 0;
+		X86Instruction->HasIndexRegister = TRUE;
+		//DISASM_OUTPUT(("[SetSIB] Index register = %s\n", X86_Registers[X86_32BIT_OFFSET + rex_sib.index]));
+
+		switch (sib.scale)
+		{
+			case 0: X86Instruction->Scale = 1; break;
+			case 1: X86Instruction->Scale = 2; break;
+			case 2: X86Instruction->Scale = 4; break;
+			case 3: X86Instruction->Scale = 8; break;
+		}
+		//DISASM_OUTPUT(("[SetSIB] Scale = %d\n", X86Instruction->Scale));
+	}
+
+	return Address;
+}
+
+INTERNAL U64 ApplyDisplacement(U64 Address, INSTRUCTION *Instruction)
+{
+	X86_INSTRUCTION *X86Instruction = &Instruction->X86;
+
+#ifdef SUPPORT_WRAPAROUND
+	U64 VirtualAddress = Address + Instruction->VirtualAddressDelta;
+	switch (X86Instruction->OperandSize)
+	{
+		case 8:
+		{
+			U64 PreAddr = VirtualAddress;
+			U64 PostAddr = PreAddr + X86Instruction->Displacement;
+			return Address + (PostAddr - PreAddr);
+		}
+		case 4:
+		{
+			// We have to do this carefully...
+			// If EIP = FFFFF000 and Displacement=2000 then the final IP should be 1000
+			// due to wraparound
+			U32 PreAddr = (U32)VirtualAddress;
+			U32 PostAddr = PreAddr + (S32)X86Instruction->Displacement;
+			return Address + (PostAddr - PreAddr);
+		}
+		case 2:
+		{
+			// We have to do this carefully...
+			// If IP = F000 and Displacement=2000 then the final IP should be 1000
+			// due to wraparound
+			U16 PreAddr = (U16)VirtualAddress;
+			U16 PostAddr = PreAddr + (S16)X86Instruction->Displacement;
+			return Address + (PostAddr - PreAddr);
+		}
+		default:
+			assert(0);
+			return 0;
+	}
+#else
+	return (Address + X86Instruction->Displacement);
+#endif
+}
+
+
+
+INTERNAL BOOL IsValidLockPrefix(X86_INSTRUCTION *X86Instruction, U8 Opcode, U32 OpcodeLength, U8 Group, U8 OpcodeExtension)
+{
+	switch (OpcodeLength)
+	{
+		case 1:
+			switch (X86_LockPrefix_1[Opcode])
+			{
+				case 0: // instruction can't be locked
+					return FALSE;
+				case 1: // instruction can be locked
+					break;
+				case GR:
+					assert(Group);
+					if (!X86_LockPrefix_Groups[Group-1][OpcodeExtension]) return FALSE;
+					break;
+				default:
+					assert(0);
+					return FALSE;
+			}
+			break;
+
+		case 2:
+		case 3:
+			switch (X86_LockPrefix_2[Opcode])
+			{
+				case 0: // lock prefix is not acceptable
+					return FALSE;
+				case 1: // lock prefix allowed
+					break;
+				case GR:
+					assert(Group);
+					if (!X86_LockPrefix_Groups[Group-1][OpcodeExtension]) return FALSE;
+					break;
+				default:
+					assert(0);
+					return FALSE;
+			}
+			break;
+
+		default:
+			assert(0);
+			return FALSE;
+	}
+
+	if (!X86Instruction->HasModRM || X86Instruction->modrm.mod == 3 || !X86Instruction->HasDstAddressing)
+	{
+		DISASM_OUTPUT(("[0x%08I64X] ERROR: Instruction \"%s\" with LOCK prefix has invalid ModRM addressing\n", VIRTUAL_ADDRESS, X86Instruction->Opcode.Mnemonic, X86Instruction->Instruction->Address));
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86.h b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86.h
new file mode 100644
index 0000000..aa9a90e
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86.h
@@ -0,0 +1,836 @@
+// Copyright (C) 2004, Matt Conover (mconover@gmail.com)
+#ifndef X86_DISASM_H
+#define X86_DISASM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// NOTE: the processor may actually accept less than this amount (officially 15)
+// #define AMD64_MAX_INSTRUCTION_LEN 15 // theoretical max 25=5+2+1+1+8+8
+#define AMD64_MAX_PREFIX_LENGTH 5 // 4 legacy + 1 rex
+#define AMD64_MAX_ADDRESS_LENGTH 18 // modrm + sib + 8 byte displacement + 8 byte immediate value
+
+// NOTE: the processor may actually accept less than this amount (officially 15)
+#define X86_MAX_INSTRUCTION_LEN 15 // theoretical 16=4+2+1+1+4+4
+#define X86_MAX_PREFIX_LENGTH 4
+#define X86_MAX_OPCODE_LENGTH 3 // third byte is either a suffix or prefix
+#define X86_MAX_ADDRESS_LENGTH 10 // modrm + sib + 4 byte displacement + 4 byte immediate value
+#define X86_MAX_OPERANDS 3
+
+#define X86_PREFIX(a) ((a)->MnemonicFlags == ITYPE_EXT_PREFIX)
+#define X86_SPECIAL_EXTENSION(a) ((a)->MnemonicFlags & (ITYPE_EXT_MODRM|ITYPE_EXT_FPU|ITYPE_EXT_SUFFIX|ITYPE_EXT_64))
+#define X86_EXTENDED_OPCODE(a) ((a)->Table)
+#define X86_INVALID(a) (!(a)->MnemonicFlags && !(a)->Table)
+#define X86_OPERAND_COUNT(a) ((a)->OperandFlags[0] ? ((a)->OperandFlags[1] ? ((a)->OperandFlags[2] ? 3 : 2) : 1) : 0)
+#define X86_GET_CATEGORY(p) ((p)->MnemonicFlags & ITYPE_GROUP_MASK)
+#define X86_GET_TYPE(p) ((p)->MnemonicFlags & ITYPE_TYPE_MASK)
+
+// Various instructions being specially decoded
+#define X86_TWO_BYTE_OPCODE 0x0f
+#define PREFIX_SEGMENT_OVERRIDE_ES 0x26
+#define PREFIX_SEGMENT_OVERRIDE_CS 0x2e
+#define PREFIX_BRANCH_NOT_TAKEN 0x2e // used only with conditional jumps
+#define PREFIX_SEGMENT_OVERRIDE_SS 0x36
+#define PREFIX_SEGMENT_OVERRIDE_DS 0x3e
+#define PREFIX_BRANCH_TAKEN 0x3e // used only with conditional jumps
+#define PREFIX_SEGMENT_OVERRIDE_FS 0x64
+#define PREFIX_SEGMENT_OVERRIDE_GS 0x65
+#define PREFIX_OPERAND_SIZE 0x66
+#define PREFIX_ADDRESS_SIZE 0x67
+#define PREFIX_LOCK 0xf0
+#define PREFIX_REPNE 0xf2
+#define PREFIX_REP 0xf3
+
+//////////////////////////////////////////////////////////////////
+// Implicit operand handling
+//////////////////////////////////////////////////////////////////
+
+#define X86_AMODE_MASK   0x00FF0000 // bits 16-23 (AMODE_*)
+#define X86_OPFLAGS_MASK 0x0000FF80 // bits 7-15 (OPTYPE_*)
+#define X86_OPTYPE_MASK  0xFF0000FF // bits 0-7 (OPTYPE_* below + OP_REG) and 24-31 (OPTYPE_* above)
+
+#define OPTYPE_0   0x01
+#define OPTYPE_1   0x02
+#define OPTYPE_FF  0x03
+//...
+#define OPTYPE_CS  0x10
+#define OPTYPE_DS  0x11
+#define OPTYPE_ES  0x12
+#define OPTYPE_FS  0x13
+#define OPTYPE_GS  0x14
+#define OPTYPE_SS  0x15
+#define OPTYPE_CR0 0x16
+#define OPTYPE_TSC 0x17 // time stamp counter
+//...
+#define OPTYPE_FLAGS  0x20
+#define OPTYPE_xFLAGS 0x21 // RFLAGS/EFLAGS (depending on operand size)
+#define OPTYPE_xCX_HI_xBX_LO 0x22 // represented by 2 registers CX:BX or ECX:EBX (depending on operand size)
+#define OPTYPE_xDX_HI_xAX_LO 0x23 // DX:AX or EDX:EAX (depending on operand size)
+#define OPTYPE_EDX_HI_EAX_LO 0x24 // DX:AX or EDX:EAX (depending on operand size)
+#define OPTYPE_EDX_ECX_EBX_EAX 0x25 // all registers are set
+//...
+#define OPTYPE_STx 0x30
+#define OPTYPE_ST0 0x31
+#define OPTYPE_ST1 0x32
+#define OPTYPE_FPU_STATUS  0x33
+#define OPTYPE_FPU_CONTROL 0x34
+#define OPTYPE_FPU_TAG 0x35
+#define OPTYPE_FLDZ   0x36 // 0
+#define OPTYPE_FLD1   0x37 // 1
+#define OPTYPE_FLDPI  0x38 // pi
+#define OPTYPE_FLDL2T 0x39 // lg 10
+#define OPTYPE_FLDL2E 0x3A // lg e
+#define OPTYPE_FLDLG2 0x3B // log_10 2
+#define OPTYPE_FLDLN2 0x3C // log_e 2
+//...
+#define OPTYPE_CS_MSR 0x40
+#define OPTYPE_EIP_MSR 0x41
+#define OPTYPE_ESP_MSR 0x42
+#define OPTYPE_KERNELBASE_MSR 0x43
+#define OPTYPE_FMASK_MSR 0x44
+#define OPTYPE_STAR_MSR 0x45
+#define OPTYPE_CSTAR_MSR 0x46 // 32-bit mode
+#define OPTYPE_LSTAR_MSR 0x47 // 64-bit mode
+
+
+// NOTE: OPTYPES >= 0x80 reserved for registers (OP_REG+XX)
+#define OPTYPE_REG_AL (OP_REG+0x01)
+#define OPTYPE_REG_CL (OP_REG+0x02)
+#define OPTYPE_REG_AH (OP_REG+0x03)
+#define OPTYPE_REG_AX (OP_REG+0x04)
+#define OPTYPE_REG_DX (OP_REG+0x05)
+#define OPTYPE_REG_ECX (OP_REG+0x06)
+#define OPTYPE_REG8 (OP_REG+0x07)
+
+// If address size is 2, use BP
+// If address size is 4, use EBP
+// If address size is 8, use RBP
+#define OPTYPE_REG_xBP (OP_REG+0x08)
+
+// If address size is 2, use BP
+// If address size is 4, use EBP
+// If address size is 8, use RBP
+#define OPTYPE_REG_xSP (OP_REG+0x09)
+
+// If operand size is 2, take 8-bit register
+// If operand size is 4, take 16-bit register
+// If operand size is 8, take 32-bit register
+#define OPTYPE_REG_xAX_SMALL (OP_REG+0x0a)
+// If operand size is 2, take 16-bit register
+// If operand size is 4, take 32-bit register
+// If operand size is 8, take 64-bit register
+#define OPTYPE_REG_xAX_BIG (OP_REG+0x0b)
+
+typedef enum _CPU_TYPE
+{
+	CPU_UNKNOWN=0,
+
+	///////////////////////////////////////
+	// 1st generation
+	///////////////////////////////////////
+	// 1978
+	//CPU_8086 = 1MB address limit, 16-bit registers
+	// 1982
+	//CPU_i186
+
+	///////////////////////////////////////
+	// 2nd generation
+	///////////////////////////////////////
+	// 1982
+	//CPU_I286 // 16MB limit, 16-bit registers, added protected mode
+	CPU_I287, // CPU_I286 + math coprocessor
+
+	///////////////////////////////////////
+	// 3rd generation
+	///////////////////////////////////////
+	// 1985
+	CPU_I386, // 32-bit registers, 4GB memory limit
+	// 1988
+	CPU_I387, // CPU_I386 + math coprocessor
+
+	///////////////////////////////////////
+	// 4th generation (1989)
+	///////////////////////////////////////
+	CPU_I486,
+
+	///////////////////////////////////////
+	// 5th generation
+	///////////////////////////////////////
+	// 1993
+	CPU_PENTIUM, // superscalar architecture
+	// 1997
+	//CPU_PENTIUM_MMX
+	
+	///////////////////////////////////////
+	// 6th generation (1995)
+	///////////////////////////////////////
+	CPU_PENTIUM_PRO, // P6 architecture, no MMX, out-of-order execution, speculative execution
+	//CPU_CYRIX_6X86,
+	//CPU_AMD_K5 // RISC processor
+	// 1997
+	CPU_PENTIUM2, // Pentium Pro architecture + MMX
+	//CPU_AMD_K6,
+	//CPU_CYRIX_6X86MX, // Cyrix 6x86 + MMX
+	// 1998
+	CPU_AMD_K6_2, // added 3DNow! (MMX)
+	// 1999
+	// CPU_AMD_K6_3 // added SSE
+
+	///////////////////////////////////////
+	// 7th generation
+	///////////////////////////////////////
+	// 1999
+	CPU_PENTIUM3, // introduced SSE
+	// CPU_AMD_K7 // aka Athlon
+	// 2000
+	CPU_PENTIUM4, // introduced SSE2 and hyperthreading
+
+	// 2004? 2005?
+	CPU_PRESCOTT, // introduced SSE3
+
+	///////////////////////////////////////
+	// 8th generation (X86-64)
+	// IA32 instruction set with 64-bit extensions, >4GB RAM
+	///////////////////////////////////////
+
+	// 2003
+	CPU_AMD64, // includes Athlon 64 and Opteron aka X86-64
+
+	// 2004?
+	//CPU_EMD64 // Intel's version of AMD64
+	CPU_IA64 // aka Itanium: new instruction set -- adds JMPE to IA32 mode to return to IA64 native code
+
+} CPU_TYPE;
+
+//////////////////////////////////////////////////////////////////
+// Conditions (these can be OR'd)
+//////////////////////////////////////////////////////////////////
+
+// Used for Flags.Preconditions
+#define COND_O   (1<<0)  // overflow (signed)
+#define COND_C   (1<<1)  // below (unsigned)
+#define COND_Z   (1<<2)  // equal (unsigned)
+#define COND_S   (1<<3)  // sign set (signed)
+#define COND_P   (1<<4)  // parity even
+#define COND_BE  (1<<5)  // CF or ZF is set (unsigned)
+#define COND_L   (1<<6)  // (SF && !OF) || (OF && !SF)
+#define COND_LE  (1<<7)  // ZF || (SF && !OF) || (OF && !SF) (signed)
+#define COND_NO  (1<<8)  // !O
+#define COND_NC  (1<<9)  // !C (not below, above or equal to)
+#define COND_NZ  (1<<10) // !Z (not equal)
+#define COND_NS  (1<<11) // !S
+#define COND_NP  (1<<12) // !P (parity odd)
+#define COND_NL  (1<<13) // (!SF && !OF) || (SF && OF)
+#define COND_G   (1<<14) // !ZF && ((!SF && !OF) || (SF && OF))
+#define COND_D   (1<<15) // DF
+#define COND_REG_xCX_BIG_Z  (1<<16) // CX/ECX/RCX (depending on address size) == 0
+#define COND_REG_xCX_BIG_NZ (1<<17) // CX/ECX/RCX (depending on address size) != 0
+#define COND_OP1_EQ_OP2 (1<<18)
+#define COND_OP1_EQ_OP3 (1<<19)
+#define COND_B   COND_C
+#define COND_NAE COND_C
+#define COND_E   COND_Z
+#define COND_NA  COND_BE
+#define COND_PE  COND_P
+#define COND_U   COND_P
+#define COND_NGE COND_L
+#define COND_NG  COND_LE
+#define COND_PO  COND_NP
+#define COND_NU  COND_NP
+#define COND_NE  COND_NZ
+#define COND_NB  COND_NC
+#define COND_AE  COND_NC
+#define COND_NE  COND_NZ
+#define COND_A   (COND_NC|COND_NZ)
+#define COND_NBE COND_A
+#define COND_GE COND_NL
+#define COND_NLE COND_G
+
+// Used for Opcode.FlagsChanged
+#define FLAG_CF_SET (1<<0)
+#define FLAG_DF_SET (1<<1)
+#define FLAG_IF_SET (1<<2)
+#define FLAG_SET_MASK (FLAG_CF_SET|FLAG_DF_SET|FLAG_IF_SET)
+
+#define FLAG_SF_CLR (1<<3)
+#define FLAG_ZF_CLR (1<<4)
+#define FLAG_AF_CLR (1<<5)
+#define FLAG_CF_CLR (1<<6)
+#define FLAG_DF_CLR (1<<7)
+#define FLAG_IF_CLR (1<<8)
+#define FLAG_OF_CLR (1<<9)
+#define FPU_C0_CLR (1<<19)
+#define FPU_C1_CLR (1<<20)
+#define FPU_C2_CLR (1<<21)
+#define FPU_C3_CLR (1<<22)
+#define FPU_ALL_CLR (FPU_C0_CLR|FPU_C1_CLR|FPU_C2_CLR|FPU_C3_CLR)
+#define FLAG_CLR_MASK (FLAG_SF_CLR|FLAG_ZF_CLR|FLAG_AF_CLR|FLAG_CF_CLR|FLAG_DF_CLR|FLAG_IF_CLR|FLAG_OF_CLR|FPU_ALL_CLR)
+
+#define FLAG_OF_MOD (1<<10)
+#define FLAG_SF_MOD (1<<11)
+#define FLAG_ZF_MOD (1<<12)
+#define FLAG_AF_MOD (1<<13)
+#define FLAG_PF_MOD (1<<14)
+#define FLAG_CF_MOD (1<<15)
+#define FLAG_DF_MOD (1<<16)
+#define FLAG_IF_MOD (1<<17)
+#define FLAG_ALL_MOD (FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD|FLAG_CF_MOD|FLAG_DF_MOD|FLAG_IF_MOD)
+#define FLAG_COMMON_MOD (FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD|FLAG_CF_MOD)
+#define FPU_C0_MOD (1<<23)
+#define FPU_C1_MOD (1<<24)
+#define FPU_C2_MOD (1<<25)
+#define FPU_C3_MOD (1<<26)
+#define FPU_ALL_MOD (FPU_C0_MOD|FPU_C1_MOD|FPU_C2_MOD|FPU_C3_MOD)
+#define FLAG_MOD_MASK (FLAG_ALL_MOD|FPU_ALL_MOD)
+
+#define FLAG_CF_TOG (1<<18)
+#define FLAG_TOG_MASK FLAG_CF_TOG
+
+// Used for Opcode.ResultsIfTrue and Opcode.ResultsIfFalse
+#define OP1_DST         (1<<0)
+#define OP2_DST         (1<<1)
+#define OP3_DST         (1<<2)
+#define OP1_SRC         (1<<3)
+#define OP2_SRC         (1<<4)
+#define OP3_SRC         (1<<5)
+#define FPU_STACK_INC   (1<<6)
+#define FPU_STACK_INC2  (1<<7)
+#define FPU_STACK_DEC   (1<<8)
+#define SERIALIZE_WRITE (1<<9)
+#define SERIALIZE_READ  (1<<10)
+#define xCX_DEC         (1<<11)
+#define xCX_REP_DEC     (1<<12)
+#define xDI_DEC         (1<<13)
+#define xDI_INC         (1<<14)
+#define xSI_DEC         (1<<15)
+#define xSI_INC         (1<<16)
+#define xDI_DECx        (1<<17)
+#define xDI_INCx        (1<<18)
+#define xSI_DECx        (1<<19)
+#define xSI_INCx        (1<<20)
+#define FPU_STACK_PUSH FPU_STACK_DEC
+#define FPU_STACK_POP  FPU_STACK_INC
+#define FPU_STACK_POP2 FPU_STACK_INC2
+#define SERIALIZE_ALL (SERIALIZE_WRITE|SERIALIZE_READ)
+
+#define X86_SEGMENT_OFFSET 0x00
+#define X86_TEST_OFFSET    0x10
+#define X86_CONTROL_OFFSET 0x20
+#define X86_DEBUG_OFFSET   0x30
+#define X86_FPU_OFFSET     0x40
+#define X86_MMX_OFFSET     0x50
+#define X86_XMM_OFFSET     0x60
+#define X86_8BIT_OFFSET    0x70
+#define X86_16BIT_OFFSET   0x80
+#define X86_32BIT_OFFSET   0x90
+#define AMD64_8BIT_OFFSET  0xA0
+#define AMD64_16BIT_OFFSET 0xB0
+#define AMD64_32BIT_OFFSET 0xC0
+#define AMD64_64BIT_OFFSET 0xD0
+
+typedef enum _X86_REGISTER
+{
+	// Segments
+	X86_SEG_ES = X86_SEGMENT_OFFSET,
+	X86_SEG_CS,
+	X86_SEG_SS,
+	X86_SEG_DS,
+	X86_SEG_FS,
+	X86_SEG_GS,
+
+	// Miscellaneous
+	X86_REG_FLAGS,
+	X86_REG_EFLAGS,
+	AMD64_REG_RFLAGS,
+	X86_REG_IP,
+	X86_REG_EIP,
+	AMD64_REG_RIP,
+
+	// Test registers
+	X86_REG_TR0 = X86_TEST_OFFSET,
+	X86_REG_TR1,
+	X86_REG_TR2,
+	X86_REG_TR3,
+	X86_REG_TR4,
+	X86_REG_TR5,
+	X86_REG_TR6,
+	X86_REG_TR7,
+	X86_REG_TR8,
+	X86_REG_TR9,
+	X86_REG_TR10,
+	X86_REG_TR11,
+	X86_REG_TR12,
+	X86_REG_TR13,
+	X86_REG_TR14,
+	X86_REG_TR15,
+
+	// Control registers
+	X86_REG_CR0=X86_CONTROL_OFFSET,
+	X86_REG_CR1,
+	X86_REG_CR2,
+	X86_REG_CR3,
+	X86_REG_CR4,
+	X86_REG_CR5,
+	X86_REG_CR6,
+	X86_REG_CR7,
+	X86_REG_CR8,
+	X86_REG_CR9,
+	X86_REG_CR10,
+	X86_REG_CR11,
+	X86_REG_CR12,
+	X86_REG_CR13,
+	X86_REG_CR14,
+	X86_REG_CR15,
+
+	// Debug registers
+	X86_REG_DR0=X86_DEBUG_OFFSET,
+	X86_REG_DR1,
+	X86_REG_DR2,
+	X86_REG_DR3,
+	X86_REG_DR4,
+	X86_REG_DR5,
+	X86_REG_DR6,
+	X86_REG_DR7,
+	X86_REG_DR8,
+	X86_REG_DR9,
+	X86_REG_DR10,
+	X86_REG_DR11,
+	X86_REG_DR12,
+	X86_REG_DR13,
+	X86_REG_DR14,
+	X86_REG_DR15,
+
+	// FPU registers
+	X86_REG_ST0=X86_FPU_OFFSET,
+	X86_REG_ST1,
+	X86_REG_ST2,
+	X86_REG_ST3,
+	X86_REG_ST4,
+	X86_REG_ST5,
+	X86_REG_ST6,
+	X86_REG_ST7,
+
+	// MMX registers
+	X86_REG_MM0=X86_MMX_OFFSET,
+	X86_REG_MM1,
+	X86_REG_MM2,
+	X86_REG_MM3,
+	X86_REG_MM4,
+	X86_REG_MM5,
+	X86_REG_MM6,
+	X86_REG_MM7,
+
+	// XMM registers
+	X86_REG_XMM0=X86_XMM_OFFSET,
+	X86_REG_XMM1,
+	X86_REG_XMM2,
+	X86_REG_XMM3,
+	X86_REG_XMM4,
+	X86_REG_XMM5,
+	X86_REG_XMM6,
+	X86_REG_XMM7,
+
+	// 8-bit registers
+	X86_REG_AL=X86_8BIT_OFFSET,
+	X86_REG_CL,
+	X86_REG_DL,
+	X86_REG_BL,
+	X86_REG_AH,
+	X86_REG_CH,
+	X86_REG_DH,
+	X86_REG_BH,
+
+	// 16-bit registers
+	X86_REG_AX=X86_16BIT_OFFSET,
+	X86_REG_CX,
+	X86_REG_DX,
+	X86_REG_BX,
+	X86_REG_SP,
+	X86_REG_BP,
+	X86_REG_SI,
+	X86_REG_DI,
+
+	// 32-bit registers
+	X86_REG_EAX=X86_32BIT_OFFSET,
+	X86_REG_ECX,
+	X86_REG_EDX,
+	X86_REG_EBX,
+	X86_REG_ESP,
+	X86_REG_EBP,
+	X86_REG_ESI,
+	X86_REG_EDI,
+
+	// AMD64 8-bit registers
+	AMD64_REG_AL=AMD64_8BIT_OFFSET,
+	AMD64_REG_CL,
+	AMD64_REG_DL,
+	AMD64_REG_BL,
+	AMD64_REG_SPL,
+	AMD64_REG_BPL,
+	AMD64_REG_SIL,
+	AMD64_REG_DIL,
+	AMD64_REG_R8B,
+	AMD64_REG_R9B,
+	AMD64_REG_R10B,
+	AMD64_REG_R11B,
+	AMD64_REG_R12B,
+	AMD64_REG_R13B,
+	AMD64_REG_R14B,
+	AMD64_REG_R15B,
+
+	// AMD64 16-bit registers
+	AMD64_REG_AX=AMD64_16BIT_OFFSET,
+	AMD64_REG_CX,
+	AMD64_REG_DX,
+	AMD64_REG_BX,
+	AMD64_REG_SP,
+	AMD64_REG_BP,
+	AMD64_REG_SI,
+	AMD64_REG_DI,
+	AMD64_REG_R8W,
+	AMD64_REG_R9W,
+	AMD64_REG_R10W,
+	AMD64_REG_R11W,
+	AMD64_REG_R12W,
+	AMD64_REG_R13W,
+	AMD64_REG_R14W,
+	AMD64_REG_R15W,
+
+	// AMD64 32-bit registers
+	AMD64_REG_EAX=AMD64_32BIT_OFFSET,
+	AMD64_REG_ECX,
+	AMD64_REG_EDX,
+	AMD64_REG_EBX,
+	AMD64_REG_ESP,
+	AMD64_REG_EBP,
+	AMD64_REG_ESI,
+	AMD64_REG_EDI,
+	AMD64_REG_R8D,
+	AMD64_REG_R9D,
+	AMD64_REG_R10D,
+	AMD64_REG_R11D,
+	AMD64_REG_R12D,
+	AMD64_REG_R13D,
+	AMD64_REG_R14D,
+	AMD64_REG_R15D,
+
+	// AMD64 64-bit registers
+	AMD64_REG_RAX=AMD64_64BIT_OFFSET,
+	AMD64_REG_RCX,
+	AMD64_REG_RDX,
+	AMD64_REG_RBX,
+	AMD64_REG_RSP,
+	AMD64_REG_RBP,
+	AMD64_REG_RSI,
+	AMD64_REG_RDI,
+	AMD64_REG_R8,
+	AMD64_REG_R9,
+	AMD64_REG_R10,
+	AMD64_REG_R11,
+	AMD64_REG_R12,
+	AMD64_REG_R13,
+	AMD64_REG_R14,
+	AMD64_REG_R15
+} X86_REGISTER;
+
+typedef enum _X86_TEST_REGISTER
+{
+	REG_TR0=0,
+	REG_TR1,
+	REG_TR2,
+	REG_TR3,
+	REG_TR4,
+	REG_TR5,
+	REG_TR6,
+	REG_TR7,
+	REG_TR8,
+	REG_TR9,
+	REG_TR10,
+	REG_TR11,
+	REG_TR12,
+	REG_TR13,
+	REG_TR14,
+	REG_TR15
+} X86_TEST_REGISTER;
+
+typedef enum _X86_CONTROL_REGISTER
+{
+	REG_CR0,
+	REG_CR1,
+	REG_CR2,
+	REG_CR3,
+	REG_CR4,
+	REG_CR5,
+	REG_CR6,
+	REG_CR7,
+	REG_CR8,
+	REG_CR9,
+	REG_CR10,
+	REG_CR11,
+	REG_CR12,
+	REG_CR13,
+	REG_CR14,
+	REG_CR15
+} X86_CONTROL_REGISTER;
+
+typedef enum _X86_DEBUG_REGISTER
+{
+	REG_DR0,
+	REG_DR1,
+	REG_DR2,
+	REG_DR3,
+	REG_DR4,
+	REG_DR5,
+	REG_DR6,
+	REG_DR7,
+	REG_DR8,
+	REG_DR9,
+	REG_DR10,
+	REG_DR11,
+	REG_DR12,
+	REG_DR13,
+	REG_DR14,
+	REG_DR15
+} X86_DEBUG_REGISTER;
+
+typedef enum _X86_MMX_REGISTER
+{
+	REG_MM0=0,
+	REG_MM1=1,
+	REG_MM2=2,
+	REG_MM3=3,
+	REG_MM4=4,
+	REG_MM5=5,
+	REG_MM6=6,
+	REG_MM7=7
+} X86_MMX_REGISTER;
+
+typedef enum _X86_SSE_REGISTER
+{
+	REG_XMM0=0,
+	REG_XMM1=1,
+	REG_XMM2=2,
+	REG_XMM3=3,
+	REG_XMM4=4,
+	REG_XMM5=5,
+	REG_XMM6=6,
+	REG_XMM7=7
+} X86_SSE_REGISTER;
+
+typedef enum _X86_FPU_REGISTER
+{
+	REG_ST0=0,
+	REG_ST1=1,
+	REG_ST2=2,
+	REG_ST3=3,
+	REG_ST4=4,
+	REG_ST5=5,
+	REG_ST6=6,
+	REG_ST7=7
+} X86_FPU_REGISTER;
+
+typedef enum _X86_8BIT_REGISTER
+{
+	REG_AL = 0,
+	REG_CL = 1,
+	REG_DL = 2,
+	REG_BL = 3,
+	REG_AH = 4,
+	REG_CH = 5,
+	REG_DH = 6,
+	REG_BH = 7
+} X86_8BIT_REGISTER;
+
+typedef enum _X86_16BIT_REGISTER
+{
+	REG_AX = 0,
+	REG_CX = 1,
+	REG_DX = 2,
+	REG_BX = 3,
+	REG_SP = 4,
+	REG_BP = 5,
+	REG_SI = 6,
+	REG_DI = 7
+} X86_16BIT_REGISTER;
+
+typedef enum _X86_32BIT_REGISTER
+{
+	REG_EAX = 0,
+	REG_ECX = 1,
+	REG_EDX = 2,
+	REG_EBX = 3,
+	REG_ESP = 4,
+	REG_EBP = 5,
+	REG_ESI = 6,
+	REG_EDI = 7
+} X86_32BIT_REGISTER;
+
+typedef enum _X86_SEGMENT
+{
+	SEG_ES = 0,
+	SEG_CS = 1,
+	SEG_SS = 2,
+	SEG_DS = 3,
+	SEG_FS = 4,
+	SEG_GS = 5,
+	SEG_MAX = 6
+} X86_SEGMENT;
+
+extern char *X86_Registers[];
+
+#pragma pack(push,1)
+typedef struct _MODRM
+{
+	U8 mod : 2;
+	U8 reg : 3;
+	U8 rm : 3;
+} MODRM;
+typedef struct _SIB
+{
+	U8 scale : 2;
+	U8 index : 3;
+	U8 base : 3;
+} SIB;
+typedef struct _REX
+{
+	U8 unused : 4; // bits 4,5,6,7
+	U8 w : 1; // bit 3
+	U8 r : 1; // bit 2
+	U8 x : 1; // bit 1
+	U8 b : 1; // bit 0
+} REX;
+typedef struct _REX_MODRM
+{
+	U8 reg : 4;
+	U8 rm : 4;
+} REX_MODRM;
+typedef struct _REX_SIB
+{
+	U8 index : 4;
+	U8 base : 4;
+} REX_SIB;
+#pragma pack(pop)
+
+//
+// Properties:
+// If an operand is OP_COND_EXEC, it means that it is executed only if the pre-conditions are met.
+//
+// If if an instruction has one or more OP_COND_DST operands, then the actions are determined by
+// whether the Opcode.Preconditions are met or not. If all the COND_* flags in Opcode.Preconditions 
+// are true, then the results are determined by ResultsIfTrue. If the preconditions are not met, then
+// the results are determined by ResultsIfFalse.
+//
+// If Preconditions == NOCOND, then results in ResultsIfTrue are unconditional and ResultsIfFalse
+// is ignored
+//
+typedef struct _X86_OPCODE
+{
+	struct _X86_OPCODE *Table;
+	CPU_TYPE CPU; // minimum CPU (starting with i386)
+	U32 MnemonicFlags;
+	char Mnemonic[X86_MAX_INSTRUCTION_LEN+1];
+	U32 OperandFlags[X86_MAX_OPERANDS];
+	U32 Preconditions;
+	U32 FlagsChanged; // changes in flags
+	U32 ResultsIfTrue; // results if Preconditions are met
+	U32 ResultsIfFalse; // results if Preconditions are not met
+} X86_OPCODE;
+
+typedef struct _X86_INSTRUCTION
+{
+	struct _INSTRUCTION *Instruction; // the generic instruction format representing this instruction
+
+	X86_OPCODE Opcode;
+
+	U8 sib_b;
+	U8 modrm_b;
+	MODRM modrm;
+	SIB sib;
+	U8 rex_b;
+	REX rex;
+	REX_MODRM rex_modrm;
+	REX_SIB rex_sib;
+
+	X86_SEGMENT DstSegment;
+	union
+	{
+		X86_SEGMENT Segment;
+		DWORD Selector;
+	};
+
+	// NOTE: these are for internal use, use Instruction->Operands[]
+	//
+	// If DstRegAddressing or SrcRegAddressing = TRUE then BaseRegister is the base register
+	// It is the operand represented by SIBOperand
+	//
+	// The operand indices of the destination operands is in DstOpIndex[0 to DstOpCount-1]
+	// The operand indices of the source operands is in SrcOpIndex[0 to SrcOpCount-1]
+	//
+	// These are used both for instructions like xadd/xchg (where both operands are source/destination)
+	// and to represent implicit registers (e.g., cmpxchg)
+
+	U8 SrcOpIndex[3];
+	U8 DstOpIndex[3];
+
+	// Addressing mode:
+	// If DstRegAddressing = TRUE, then these apply to DstReg
+	// If SrcRegAddressing = TRUE, then this applies to SrcReg[AddressIndex]
+	// If both are false, then SrcReg and DstReg are not addresses
+	X86_REGISTER BaseRegister;
+	X86_REGISTER IndexRegister;
+	
+	U8 Scale;
+	U8 HasDefault64Operand : 1;
+	U8 HasOperandSizePrefix : 1;
+	U8 HasAddressSizePrefix : 1;
+	U8 HasSegmentOverridePrefix : 1;
+	U8 HasLockPrefix : 1;
+	U8 HasRepeatWhileEqualPrefix : 1;
+	U8 HasRepeatWhileNotEqualPrefix : 1;
+	U8 HasBranchTakenPrefix : 1;
+	U8 HasBranchNotTakenPrefix : 1;
+	U8 HasDstAddressing : 1;
+	U8 HasSrcAddressing : 1; 
+	U8 HasModRM : 1;
+	U8 HasBaseRegister : 1;
+	U8 HasIndexRegister : 1;
+	U8 HasFullDisplacement : 1;
+	U8 HasDstSegment : 1; // used for ins/cmps/scas/movs/etc which have 2 segments
+	U8 DstAddressIndex : 2; // DstOpIndex[DstAddressIndex]
+	U8 SrcAddressIndex : 2; // SrcOpIndex[SrcAddressIndex]
+	U8 DstOpCount : 2;
+	U8 SrcOpCount : 2;
+	U8 OperandSize : 4;
+	U8 AddressSize : 4;
+	U8 Relative : 1;
+	U8 HasSelector : 1; // segment is actually a selector
+	U8 Group : 5;
+
+	S64 Displacement;
+
+} X86_INSTRUCTION;
+
+////////////////////////////////////////////////////////////////////////////////////
+// Exported functions
+////////////////////////////////////////////////////////////////////////////////////
+
+extern ARCHITECTURE_FORMAT_FUNCTIONS X86;
+
+// Instruction setup
+BOOL X86_InitInstruction(struct _INSTRUCTION *Instruction);
+void X86_CloseInstruction(struct _INSTRUCTION *Instruction);
+
+// Instruction translator
+BOOL X86_TranslateInstruction(struct _INSTRUCTION *Instruction, BOOL Verbose);
+
+// Instruction decoder
+BOOL X86_GetInstruction(struct _INSTRUCTION *Instruction, U8 *Address, U32 Flags);
+
+// Function finding
+U8 *X86_FindFunctionByPrologue(struct _INSTRUCTION *Instruction, U8 *StartAddress, U8 *EndAddress, U32 Flags);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // X86_DISASM_H
+
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86_tables.h b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86_tables.h
new file mode 100644
index 0000000..9ddb3f4
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/disasm_x86_tables.h
@@ -0,0 +1,3654 @@
+// Copyright (C) 2004, Matt Conover (mconover@gmail.com)
+//
+// The opcode tables in this file are based off the Intel Instruction Set Reference
+// and an assortment of disassemblers, primarily libdisasm (by mammon)
+
+#ifndef DISASM_X86_TABLES
+#define DISASM_X86_TABLES
+
+#define X86_GET_REG(val) ((val) & 7)
+#define X86_GET_REG64(val) ((GET_REX_B(X86Instruction->rex_b) << 3) | ((val) & 7))
+
+#define GET_MODRM_MOD(a) (((a) >> 6) & 3) // bits 6, 7
+#define GET_MODRM_REG(a) (((a) >> 3) & 7) // bits 3, 4, 5
+#define GET_MODRM_EXT(a) (((a) >> 3) & 7) // bits 3, 4, 5
+#define GET_MODRM_RM(a)	 ((a) & 7) // bits 0, 1, 2
+
+#define GET_SIB_SCALE(a) (((a) >> 6) & 3) // bits 6, 7
+#define GET_SIB_INDEX(a) (((a) >> 3) & 7) // bits 3, 4, 5
+#define GET_SIB_BASE(a)  ((a) & 7) // bits 0, 1, 2
+
+#define REX_PREFIX_START 0x40
+#define REX_PREFIX_END 0x4F
+#define GET_REX_W(r) (((r) & 8) >> 3) // bit 3
+#define GET_REX_R(r) (((r) & 4) >> 2) // bit 2
+#define GET_REX_X(r) (((r) & 2) >> 1) // bit 1
+#define GET_REX_B(r) ((r) & 1)        // bit 0
+#define REX_MASK(n) ((n >> 16) & 0x0F) // bits 0-3
+
+// Groupings to make the opcode table more readible
+#define NOARGS { 0, 0, 0 }
+#define NOCOND 0
+#define NOGROUP NULL
+#define NOACTION 0
+#define NOCHANGE 0
+#define IGNORED 0
+#define NOINSTR NOGROUP, CPU_UNKNOWN, 0, "", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED
+#define GROUP CPU_UNKNOWN, 0, "", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED
+#define PREFIX NOGROUP, CPU_UNKNOWN, ITYPE_EXT_PREFIX, "", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED
+#define EXT_FPU CPU_UNKNOWN, ITYPE_EXT_FPU, "", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED 
+#define EXT_64 CPU_UNKNOWN, ITYPE_EXT_64, "", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED 
+#define EXT_SUFFIX(a, b, c) CPU_UNKNOWN, ITYPE_EXT_SUFFIX, "", { a, b, c }, NOCOND, NOCHANGE, NOACTION, IGNORED
+#define EXT_MODRM CPU_UNKNOWN, ITYPE_EXT_MODRM, "", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED
+
+#define SET_MODRM(modrm, src) \
+{ \
+	(modrm).mod = GET_MODRM_MOD(src); \
+	(modrm).reg = GET_MODRM_REG(src); \
+	(modrm).rm = GET_MODRM_RM(src); \
+}
+
+#define SET_REX_MODRM(rex_modrm, rex, modrm) \
+{ \
+	(rex_modrm).rm = ((rex).b << 3) | (modrm).rm; \
+	(rex_modrm).reg = ((rex).r << 3) | (modrm).reg; \
+}
+
+#define SET_SIB(sib, src) \
+{ \
+	(sib).scale = GET_SIB_SCALE(src); \
+	(sib).index = GET_SIB_INDEX(src); \
+	(sib).base =  GET_SIB_BASE(src); \
+}
+
+#define SET_REX_SIB(rex_sib, rex, sib) \
+{ \
+	(rex_sib).index = ((rex).x << 3) | (sib).index; \
+	(rex_sib).base = ((rex).b << 3) | (sib).base; \
+}
+
+#define SET_REX(rex, src) \
+{ \
+	(rex).w = GET_REX_W(src);	\
+	(rex).r = GET_REX_R(src);	\
+	(rex).x = GET_REX_X(src);	\
+	(rex).b = GET_REX_B(src); \
+}
+
+// Addressing modes
+#define AMODE_A    0x00010000   
+#define AMODE_C    0x00020000
+#define AMODE_D    0x00030000
+#define AMODE_E    0x00040000
+#define AMODE_G    0x00050000
+#define AMODE_I    0x00060000
+#define AMODE_J    0x00070000
+#define AMODE_M    0x00080000
+#define AMODE_O    0x00090000
+#define AMODE_P    0x000A0000
+#define AMODE_Q    0x000B0000
+#define AMODE_R    0x000C0000
+#define AMODE_S    0x000D0000
+#define AMODE_T    0x000E0000
+#define AMODE_V    0x000F0000
+#define AMODE_W    0x00100000
+#define AMODE_X    0x00110000
+#define AMODE_Y    0x00120000
+#define AMODE_PR   0x00130000
+#define AMODE_VR   0x00140000
+#define AMODE_xlat 0x00150000
+
+// Operand types
+#define OPTYPE_a    0x01000000
+#define OPTYPE_b    0x02000000
+#define OPTYPE_d    0x03000000
+#define OPTYPE_p    0x04000000
+#define OPTYPE_q    0x05000000
+#define OPTYPE_dt   0x06000000
+#define OPTYPE_v    0x07000000
+#define OPTYPE_w    0x08000000
+#define OPTYPE_ps   0x09000000 // packed 128-bit single real
+#define OPTYPE_pd   0x0A000000 // packed 128-bit double real
+#define OPTYPE_pb   0x0B000000 // packed BCD (10 bytes, 18-bit precision)
+#define OPTYPE_ss   0x0C000000 // scalar single real
+#define OPTYPE_sd   0x0D000000 // scalar double real
+#define OPTYPE_se   0x0E000000 // scalar extended real
+#define OPTYPE_fev  0x0F000000 // FPU environment (28 bytes if 32-bit modes, 14 bytes in 16-bit mode)
+#define OPTYPE_fst1 0x10000000 // FPU state (108 bytes in 32-bit modes, 94 bytes in 16-bit real mode)
+#define OPTYPE_fst2 0x11000000 // FPU/MMX/XMM/MXCSR state (512 bytes)
+#define OPTYPE_z    0x12000000
+#define OPTYPE_o    0x13000000
+#define OPTYPE_dq   0x14000000 // OPTYPE_d or OPTYPE_o
+#define OPTYPE_mw   0x15000000 // word if memory, register size otherwise
+#define OPTYPE_sso  0x16000000 // OPTYPE_ss or OPTYPE_o
+#define OPTYPE_sdo  0x17000000 // OPTYPE_ss or OPTYPE_o
+#define OPTYPE_cpu  0x18000000 // pointer to CPU state structure
+#define OPTYPE_lea  0x19000000 // size set by other operand
+// NOTE: if you change this, you must also update OptypeHandlers[] in disasm_x86.c
+// Be sure to preserve the ordering
+
+//////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// Registers
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+static char *Addressing16[8] = {"bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"};
+static char *MMX_Registers[8] = {"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7"};
+static char *SSE_Registers[8] = {"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
+static char *DR_Registers[8] = {"dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7"};
+static char *CR_Registers[8] = {"cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7"};
+static char *TR_Registers[8] = {"tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7"};
+static char *FPU_Registers[8] = {"st(0)", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)"};
+static char *Segments[8] = {"es", "cs", "ss", "ds", "fs", "gs", "ERROR", "ERROR"};
+static char *Registers8[8] = {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" };
+static char *Registers16[8] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
+static char *Registers32[8] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi" };
+static char *REX_Registers8[16] = {"al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" };
+static char *REX_Registers16[16] = {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" };
+static char *REX_Registers32[16] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" };
+static char *REX_Registers64[16] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" };
+static char *DataSizes[8+1] = {"byte ptr", "word ptr", "dword ptr", "6_byte ptr", "qword ptr", "10_byte ptr", "INVALID PTR", "INVALID PTR", "oword ptr"};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// FPU constants
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+BYTE float_0[10]   = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+BYTE float_1[10] =   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0x3F };
+BYTE float_l2t[10] = { 0xFE, 0x8A, 0x1B, 0xCD, 0x4B, 0x78, 0x9A, 0xD4, 0x00, 0x40 };
+BYTE float_l2e[10] = { 0xBC, 0xF0, 0x17, 0x5C, 0x29, 0x3B, 0xAA, 0xB8, 0xFF, 0x3F };
+BYTE float_pi[10]  = { 0x35, 0xC2, 0x68, 0x21, 0xA2, 0xDA, 0x0F, 0xC9, 0x00, 0x40 };
+BYTE float_lg2[10] = { 0x99, 0xF7, 0xCF, 0xFB, 0x84, 0x9A, 0x20, 0x9A, 0xFD, 0x3F };
+BYTE float_ln2[10] = { 0xAC, 0x79, 0xCF, 0xD1, 0xF7, 0x17, 0x72, 0xB1, 0xFE, 0x3F };
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// Tables
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+extern X86_OPCODE X86_Opcodes_2[0x100];
+extern X86_OPCODE X86_Group_1_80[8], X86_Group_1_81[8], X86_Group_1_82[8], X86_Group_1_83[8], X86_Group_2_C0[8], X86_Group_2_C1[8], X86_Group_2_D0[8], X86_Group_2_D1[8], X86_Group_2_D2[8], X86_Group_2_D3[8], X86_Group_3_F6[8], X86_Group_3_F7[8], X86_Group_4[8], X86_Group_5[8], X86_Group_6[8], X86_Group_7[8], X86_Group_8[8], X86_Group_9[8], X86_Group_10[8], X86_Group_11[8], X86_Group_12_C6[8], X86_Group_12_C7[8], X86_Group_13[8], X86_Group_14[8], X86_Group_15[8], X86_Group_16[8], X86_Group_17[8], X86_Group_P[8];
+extern X86_OPCODE X86_SSE[0x300], X86_SSE2_Group_13[24], X86_SSE2_Group_14[24], X86_SSE2_Group_15[24];
+extern X86_OPCODE X86_ESC_0[0x48], X86_ESC_1[0x48], X86_ESC_2[0x48], X86_ESC_3[0x48], X86_ESC_3[0x48], X86_ESC_4[0x48], X86_ESC_5[0x48], X86_ESC_6[0x48], X86_ESC_7[0x48];
+extern X86_OPCODE X86_3DNOW_0F[0x100];
+extern X86_OPCODE X86_0F01_ModRM[0x100];
+extern X86_OPCODE X86_Opcode_63[2], X86_Opcode_0F05[2];
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// Opcode tables
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+X86_OPCODE X86_Opcodes_1[0x100] = // 1 byte opcodes
+{
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OPTYPE_ES | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OPTYPE_ES | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x08 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x09 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x0A */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x0B */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x0C */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x0D */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OPTYPE_CS | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x0E */
+	{ X86_Opcodes_2, GROUP }, /* 0x0F */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x10 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x11 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x12 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x13 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x14 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x15 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OPTYPE_SS | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x16 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OPTYPE_SS | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x17 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x18 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x19 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x1A */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x1B */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x1C */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x1D */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OPTYPE_DS | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x1E */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OPTYPE_DS | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x1F */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x20 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x21 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x22 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x23 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x24 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x25 */
+	{ PREFIX }, /* 0x26 */
+	{ NOGROUP, CPU_I386, ITYPE_BCDCONV, "daa", { OPTYPE_REG_AL | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_AF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x27 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x28 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x29 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x2A */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x2B */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x2C */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x2D */
+	{ PREFIX }, /* 0x2E */
+	{ NOGROUP, CPU_I386, ITYPE_BCDCONV, "das", { OPTYPE_REG_AL | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_AF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x2F */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x30 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x31 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x32 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x33 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x34 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x35 */
+	{ PREFIX }, /* 0x36 */
+	{ NOGROUP, CPU_I386, ITYPE_BCDCONV, "aaa", { OPTYPE_REG_AL | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_AF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x37 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_E | OPTYPE_b | OP_SRC, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x38 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x39 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_G | OPTYPE_b | OP_SRC, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x3A */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_G | OPTYPE_v | OP_SRC, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x3B */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { OPTYPE_REG_AL | OP_SIGNED | OP_SRC, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x3C */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { OPTYPE_REG_xAX_BIG | OP_SIGNED | OP_SRC, AMODE_I | OPTYPE_z | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x3D */
+	{ PREFIX }, /* 0x3E */
+	{ NOGROUP, CPU_I386, ITYPE_BCDCONV, "aas", { OPTYPE_REG_AL | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_AF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x3F */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x40 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x41 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x42 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x43 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x44 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x45 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x46 */
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x47 */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x48 */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x49 */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x4A */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x4B */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x4C */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x4D */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x4E */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x4F */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x50 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x51 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x52 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x53 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x54 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x55 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x56 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OP_REG | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x57 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x58 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x59 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5A */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5B */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5C */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5D */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5E */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OP_REG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5F */
+	{ NOGROUP, CPU_I386, ITYPE_PUSHA, "pushad", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x60 */
+	{ NOGROUP, CPU_I386, ITYPE_POPA, "popad", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x61 */
+	{ NOGROUP, CPU_I386, ITYPE_BOUNDS, "bound", { AMODE_G | OPTYPE_v | OP_SRC, AMODE_M | OPTYPE_a | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x62 */
+	{ X86_Opcode_63, EXT_64 }, /* 0x63 */
+	{ PREFIX }, /* 0x64 */
+	{ PREFIX }, /* 0x65 */ 
+	{ PREFIX }, /* 0x66 */
+	{ PREFIX }, /* 0x67 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { AMODE_I | OPTYPE_z | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x68 */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "imul", { AMODE_G | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, AMODE_I | OPTYPE_z | OP_SIGNED | OP_SRC }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x69 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x6A */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "imul", { AMODE_G | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x6B */
+	{ NOGROUP, CPU_I386, ITYPE_IN, "insb", { AMODE_Y | OPTYPE_b | OP_DST, OPTYPE_REG_DX | OP_SYS | OP_SRC, 0 }, COND_D, NOCHANGE, xDI_DEC | xCX_REP_DEC, xDI_INC | xCX_REP_DEC }, /* 0x6C */
+	{ NOGROUP, CPU_I386, ITYPE_IN, "insd", { AMODE_Y | OPTYPE_z | OP_DST, OPTYPE_REG_DX | OP_SYS | OP_SRC, 0 }, COND_D, NOCHANGE, xDI_DECx | xCX_REP_DEC, xDI_INCx | xCX_REP_DEC }, /* 0x6D */
+	{ NOGROUP, CPU_I386, ITYPE_OUT, "outsb", { OPTYPE_REG_DX | OP_SYS | OP_DST, AMODE_X | OPTYPE_b | OP_SRC, 0 }, COND_D, NOCHANGE, xSI_DEC | xCX_REP_DEC, xSI_INC  | xCX_REP_DEC }, /* 0x6E */
+	{ NOGROUP, CPU_I386, ITYPE_OUT, "outsd", { OPTYPE_REG_DX | OP_SYS | OP_DST, AMODE_X | OPTYPE_z | OP_SRC, 0 }, COND_D, NOCHANGE, xSI_DECx | xCX_REP_DEC, xSI_INCx  | xCX_REP_DEC}, /* 0x6F */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jo", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_O, NOCHANGE, OP1_DST, NOACTION }, /* 0x70 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jno", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NO, NOCHANGE, OP1_DST, NOACTION }, /* 0x71 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jb", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_C, NOCHANGE, OP1_DST, NOACTION }, /* 0x72 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jnb", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NC, NOCHANGE, OP1_DST, NOACTION }, /* 0x73 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jz", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_Z, NOCHANGE, OP1_DST, NOACTION }, /* 0x74 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jnz", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NZ, NOCHANGE, OP1_DST, NOACTION }, /* 0x75 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jbe", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_BE, NOCHANGE, OP1_DST, NOACTION }, /* 0x76 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "ja", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_A, NOCHANGE, OP1_DST, NOACTION }, /* 0x77 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "js", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_S, NOCHANGE, OP1_DST, NOACTION }, /* 0x78 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jns", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NS, NOCHANGE, OP1_DST, NOACTION }, /* 0x79 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jpe", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_PE, NOCHANGE, OP1_DST, NOACTION }, /* 0x7A */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jpo", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_PO, NOCHANGE, OP1_DST, NOACTION }, /* 0x7B */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jl", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_L, NOCHANGE, OP1_DST, NOACTION }, /* 0x7C */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jge", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_GE, NOCHANGE, OP1_DST, NOACTION }, /* 0x7D */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jle", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_LE, NOCHANGE, OP1_DST, NOACTION }, /* 0x7E */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jg", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_G, NOCHANGE, OP1_DST, NOACTION }, /* 0x7F */
+	{ X86_Group_1_80, GROUP }, /* 0x80 Eb Ib */
+	{ X86_Group_1_81, GROUP }, /* 0x81 Ev Iz */
+	{ X86_Group_1_82, GROUP }, /* 0x82 Eb Ib */
+	{ X86_Group_1_83, GROUP }, /* 0x83 Ev Ib */
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { AMODE_E | OPTYPE_b | OP_SRC, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x84 */
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x85 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { AMODE_E | OPTYPE_b | OP_SRC | OP_DST, AMODE_G | OPTYPE_b | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x86 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, AMODE_G | OPTYPE_v | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x87 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_E | OPTYPE_b | OP_DST, AMODE_G | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x88 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x89 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_G | OPTYPE_b | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x8A */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x8B */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_E | OPTYPE_mw | OP_DST, AMODE_S | OPTYPE_w | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x8C */
+	{ NOGROUP, CPU_I386, ITYPE_LEA, "lea", { AMODE_G | OPTYPE_v | OP_DST, AMODE_M | OPTYPE_lea | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x8D */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_S | OPTYPE_w | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x8E */
+	{ X86_Group_10, GROUP }, /* 0x8F */
+	{ NOGROUP, CPU_I386, ITYPE_NOP, "nop", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x90 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x91 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x92 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x93 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x94 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x95 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x96 */
+	{ NOGROUP, CPU_I386, ITYPE_XCHG, "xchg", { OPTYPE_REG_xAX_BIG | OP_SRC | OP_DST, OP_REG | OP_SRC | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x97 */
+	{ NOGROUP, CPU_I386, ITYPE_SZCONV, "cwde", { OPTYPE_REG_xAX_BIG | OP_SIGNED | OP_DST, OPTYPE_REG_xAX_SMALL | OP_SIGNED | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x98 */
+	{ NOGROUP, CPU_I386, ITYPE_SZCONV, "cdq", { OPTYPE_xDX_HI_xAX_LO | OP_SIGNED | OP_DST, OPTYPE_REG_xAX_BIG | OP_SIGNED | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x99 */
+	{ NOGROUP, CPU_I386, ITYPE_CALL, "call", { AMODE_A | OPTYPE_p | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x9A */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "wait", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x9B */
+	{ NOGROUP, CPU_I386, ITYPE_PUSHF, "pushf", { OPTYPE_xFLAGS | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x9C */
+	{ NOGROUP, CPU_I386, ITYPE_POPF, "popf", { OPTYPE_xFLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_ALL_MOD, NOACTION, IGNORED }, /* 0x9D */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "sahf", { OPTYPE_FLAGS | OP_DST, OPTYPE_REG_AH | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_AF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x9E */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "lahf", { OPTYPE_REG_AH | OP_DST, OPTYPE_FLAGS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x9F */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG_AL | OP_DST, AMODE_O | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA0 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_O | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA1 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_O | OPTYPE_b | OP_DST, OPTYPE_REG_AL | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA2 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_O | OPTYPE_v | OP_DST, OPTYPE_REG_xAX_BIG | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA3 */
+	{ NOGROUP, CPU_I386, ITYPE_STRMOV, "movsb", { AMODE_Y | OPTYPE_b | OP_DST, AMODE_X | OPTYPE_b | OP_SRC, 0 }, COND_D, NOCHANGE, xDI_DEC | xSI_DEC | xCX_REP_DEC, xDI_INC | xSI_INC | xCX_REP_DEC}, /* 0xA4 */
+	{ NOGROUP, CPU_I386, ITYPE_STRMOV, "movsd", { AMODE_Y | OPTYPE_z | OP_DST, AMODE_X | OPTYPE_z | OP_SRC, 0 }, COND_D, NOCHANGE, xDI_DECx | xSI_DECx| xCX_REP_DEC, xDI_INCx | xSI_INCx | xCX_REP_DEC }, /* 0xA5 */
+	{ NOGROUP, CPU_I386, ITYPE_STRCMP, "cmpsb", { AMODE_X | OPTYPE_b | OP_SRC, AMODE_Y | OPTYPE_b | OP_SRC, 0 }, COND_D, FLAG_COMMON_MOD, xDI_DEC | xSI_DEC | xCX_REP_DEC, xDI_INC | xSI_INC | xCX_REP_DEC }, /* 0xA6 */
+	{ NOGROUP, CPU_I386, ITYPE_STRCMP, "cmpsd", { AMODE_X | OPTYPE_z | OP_SRC, AMODE_Y | OPTYPE_z | OP_SRC, 0 }, COND_D, FLAG_COMMON_MOD, xDI_DECx | xSI_DECx | xCX_REP_DEC, xDI_INCx | xSI_INCx | xCX_REP_DEC}, /* 0xA7 */
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { OPTYPE_REG_AL | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0xA8 */
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { OPTYPE_REG_xAX_BIG | OP_SRC, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0xA9 */
+	{ NOGROUP, CPU_I386, ITYPE_STRSTOR, "stosb", { AMODE_Y | OPTYPE_b | OP_DST, OPTYPE_REG_AL | OP_SRC, 0 }, COND_D, NOCHANGE, xDI_DEC | xSI_DEC | xCX_REP_DEC, xDI_INC | xSI_INC | xCX_REP_DEC }, /* 0xAA */
+	{ NOGROUP, CPU_I386, ITYPE_STRSTOR, "stosd", { AMODE_Y | OPTYPE_z | OP_DST, OPTYPE_REG_xAX_BIG | OP_SRC, 0 }, COND_D, NOCHANGE, xDI_DECx | xSI_DECx | xCX_REP_DEC, xDI_INCx | xSI_INCx | xCX_REP_DEC }, /* 0xAB */
+	{ NOGROUP, CPU_I386, ITYPE_STRLOAD, "lodsb", { OPTYPE_REG_AL | OP_DST, AMODE_X | OPTYPE_b | OP_SRC, 0 }, COND_D, NOCHANGE, xSI_DEC | xCX_REP_DEC, xSI_INC | xCX_REP_DEC }, /* 0xAC */
+	{ NOGROUP, CPU_I386, ITYPE_STRLOAD, "lodsd", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_X | OPTYPE_z | OP_SRC, 0 }, COND_D, NOCHANGE, xSI_DECx | xCX_REP_DEC, xSI_INCx | xCX_REP_DEC }, /* 0xAD */
+	{ NOGROUP, CPU_I386, ITYPE_STRCMP, "scasb", { OPTYPE_REG_AL | OP_SRC, AMODE_Y | OPTYPE_b | OP_SRC, 0 }, COND_D, FLAG_COMMON_MOD, xDI_DEC | xCX_REP_DEC, xDI_INC | xCX_REP_DEC }, /* 0xAE */
+	{ NOGROUP, CPU_I386, ITYPE_STRCMP, "scasd", { OPTYPE_REG_xAX_BIG | OP_SRC, AMODE_Y | OPTYPE_z | OP_SRC, 0 }, COND_D, FLAG_COMMON_MOD, xDI_DECx, xDI_INCx }, /* 0xAF */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB0 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB1 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB2 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB3 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB4 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB5 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB6 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OPTYPE_REG8 | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB7 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB8 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB9 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBA */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBB */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBC */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBD */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBE */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { OP_REG | OP_DST, AMODE_I | OPTYPE_v | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBF */
+	{ X86_Group_2_C0, GROUP }, /* 0xC0 Eb Ib */
+	{ X86_Group_2_C1, GROUP }, /* 0xC1 Ev Ib */
+	{ NOGROUP, CPU_I386, ITYPE_RET, "ret", { AMODE_I | OPTYPE_w | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC2 */
+	{ NOGROUP, CPU_I386, ITYPE_RET, "ret", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC3 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "les", { AMODE_G | OPTYPE_z | OP_DST, AMODE_M | OPTYPE_p | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC4 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "lds", { AMODE_G | OPTYPE_z | OP_DST, AMODE_M | OPTYPE_p | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC5 */
+	{ X86_Group_12_C6, GROUP }, /* 0xC6 Eb Ib */
+	{ X86_Group_12_C7, GROUP }, /* 0xC7 Ev Iz */
+	{ NOGROUP, CPU_I386, ITYPE_ENTER, "enter", { OPTYPE_REG_xBP | OP_SRC | OP_DST, AMODE_I | OPTYPE_w | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC8 */
+	{ NOGROUP, CPU_I386, ITYPE_LEAVE, "leave", { OPTYPE_REG_xBP | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC9 */
+	{ NOGROUP, CPU_I386, ITYPE_RET, "retf", { AMODE_I | OPTYPE_w | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCA */
+	{ NOGROUP, CPU_I386, ITYPE_RET, "retf", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCB */
+	{ NOGROUP, CPU_I386, ITYPE_DEBUG, "int3", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCC */
+	{ NOGROUP, CPU_I386, ITYPE_TRAP, "int", { AMODE_I | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCD */
+	{ NOGROUP, CPU_I386, ITYPE_OFLOW, "into", NOARGS, NOCOND, NOCHANGE, NOACTION, NOACTION }, /* 0xCE */
+	{ NOGROUP, CPU_I386, ITYPE_TRAPRET, "iret", NOARGS, NOCOND, FLAG_ALL_MOD, NOACTION, IGNORED }, /* 0xCF */
+	{ X86_Group_2_D0, GROUP }, /* 0xD0 Eb, 1 */
+	{ X86_Group_2_D1, GROUP }, /* 0xD1 Ev, 1 */
+	{ X86_Group_2_D2, GROUP }, /* 0xD2 Eb, CL */
+	{ X86_Group_2_D3, GROUP }, /* 0xD3 Ev, CL */
+	{ NOGROUP, CPU_I386, ITYPE_BCDCONV, "aam", { OPTYPE_REG_AX | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD, NOACTION, IGNORED }, /* 0xD4 */
+	{ NOGROUP, CPU_I386, ITYPE_BCDCONV, "aad", { OPTYPE_REG_AX | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD, NOACTION, IGNORED }, /* 0xD5 */
+	{ NOGROUP, CPU_I386, ITYPE_ARITH, "salc", { OPTYPE_REG_AL | OP_DST, OPTYPE_FF | OP_SRC, OPTYPE_0 | OP_SRC }, COND_C, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0xD6 */
+	{ NOGROUP, CPU_I386, ITYPE_XLAT, "xlat", { OPTYPE_REG_AL | OP_DST, AMODE_xlat | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD7 */
+	{ X86_ESC_0, EXT_FPU }, /* 0xD8 */
+	{ X86_ESC_1, EXT_FPU }, /* 0xD9 */
+	{ X86_ESC_2, EXT_FPU }, /* 0xDA */
+	{ X86_ESC_3, EXT_FPU }, /* 0xDB */
+	{ X86_ESC_4, EXT_FPU }, /* 0xDC */
+	{ X86_ESC_5, EXT_FPU }, /* 0xDD */
+	{ X86_ESC_6, EXT_FPU }, /* 0xDE */
+	{ X86_ESC_7, EXT_FPU }, /* 0xDF */
+	{ NOGROUP, CPU_I386, ITYPE_LOOPCC, "loopnz", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_REG_xCX_BIG_NZ | COND_NZ, NOCHANGE, OP1_DST | xCX_DEC, NOACTION }, /* 0xE0 */
+	{ NOGROUP, CPU_I386, ITYPE_LOOPCC, "loopz", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_REG_xCX_BIG_NZ | COND_Z, NOCHANGE, OP1_DST | xCX_DEC, NOACTION }, /* 0xE1 */
+	{ NOGROUP, CPU_I386, ITYPE_LOOPCC, "loop", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_REG_xCX_BIG_NZ, NOCHANGE, OP1_DST | xCX_DEC, NOACTION }, /* 0xE2 */
+	{ NOGROUP, CPU_I386, ITYPE_LOOPCC, "jecxz", { AMODE_J | OPTYPE_b | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_REG_xCX_BIG_Z, NOCHANGE, OP1_DST, NOACTION }, /* 0xE3 */
+	{ NOGROUP, CPU_I386, ITYPE_IN, "in", { OPTYPE_REG_AL | OP_DST, AMODE_I | OPTYPE_b | OP_SYS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, NOACTION }, /* 0xE4 */
+	{ NOGROUP, CPU_I386, ITYPE_IN, "in", { OPTYPE_REG_xAX_BIG | OP_DST, AMODE_I | OPTYPE_b | OP_SYS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, NOACTION }, /* 0xE5 */
+	{ NOGROUP, CPU_I386, ITYPE_OUT, "out", { AMODE_I | OPTYPE_b | OP_SYS | OP_DST, OPTYPE_REG_AL | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, NOACTION }, /* 0xE6 */
+	{ NOGROUP, CPU_I386, ITYPE_OUT, "out", { AMODE_I | OPTYPE_b | OP_SYS | OP_DST, OPTYPE_REG_xAX_BIG | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, NOACTION }, /* 0xE7 */
+	{ NOGROUP, CPU_I386, ITYPE_CALL, "call", { AMODE_J | OPTYPE_z | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE8 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCH, "jmp", { AMODE_J | OPTYPE_z | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE9 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCH, "jmp", { AMODE_A | OPTYPE_p | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEA */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCH, "jmp", { AMODE_J | OPTYPE_b | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEB */
+	{ NOGROUP, CPU_I386, ITYPE_IN, "in", { OPTYPE_REG_AL | OP_DST, OPTYPE_REG_DX | OP_SYS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEC */
+	{ NOGROUP, CPU_I386, ITYPE_IN, "in", { OPTYPE_REG_xAX_BIG | OP_DST, OPTYPE_REG_DX | OP_SYS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xED */
+	{ NOGROUP, CPU_I386, ITYPE_OUT, "out", { OPTYPE_REG_DX | OP_SYS | OP_DST, OPTYPE_REG_AL | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEE */
+	{ NOGROUP, CPU_I386, ITYPE_OUT, "out", { OPTYPE_REG_DX | OP_SYS | OP_DST, OPTYPE_REG_xAX_BIG | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEF */
+	{ PREFIX }, /* 0xF0 */
+	{ NOGROUP, CPU_I386, ITYPE_DEBUG, "int1", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, // aka icebp /* 0xF1 */
+	{ PREFIX }, /* 0xF2 */
+	{ PREFIX }, /* 0xF3 */
+	{ NOGROUP, CPU_I386, ITYPE_HALT, "hlt", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF4 */
+	{ NOGROUP, CPU_I386, ITYPE_TOGCF, "cmc", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_CF_TOG, IGNORED }, /* 0xF5 */
+	{ X86_Group_3_F6, GROUP }, /* 0xF6 Eb */
+	{ X86_Group_3_F7, GROUP }, /* 0xF7 Ev */
+	{ NOGROUP, CPU_I386, ITYPE_CLEARCF, "clc", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_CF_CLR, NOACTION, IGNORED }, /* 0xF8 */
+	{ NOGROUP, CPU_I386, ITYPE_SETCF, "stc", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_CF_SET, NOACTION, IGNORED }, /* 0xF9 */
+	{ NOGROUP, CPU_I386, ITYPE_CLEARIF, "cli", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_IF_CLR, NOACTION, IGNORED }, /* 0xFA */
+	{ NOGROUP, CPU_I386, ITYPE_SETIF, "sti", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_IF_SET, NOACTION, IGNORED }, /* 0xFB */
+	{ NOGROUP, CPU_I386, ITYPE_CLEARDF, "cld", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_DF_CLR, NOACTION, IGNORED }, /* 0xFC */
+	{ NOGROUP, CPU_I386, ITYPE_SETDF, "std", { OPTYPE_FLAGS | OP_DST, 0, 0 }, NOCOND, FLAG_DF_SET, NOACTION, IGNORED }, /* 0xFD */
+	{ X86_Group_4, GROUP }, /* 0xFE */
+	{ X86_Group_5, GROUP }, /* 0xFF */
+};
+
+X86_OPCODE X86_Opcodes_2[0x100] = // 2 byte opcodes
+{
+	{ X86_Group_6, GROUP }, /* 0x00 */
+	{ X86_0F01_ModRM, EXT_MODRM }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "lar", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "lsl", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ X86_Opcode_0F05, EXT_64 }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "clts", { OPTYPE_CR0 | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_SYSCALLRET, "sysret", { OPTYPE_STAR_MSR | OP_MSR | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+	// 0F 07 could also be this undocumented instruction on older CPUs:
+	// { NOGROUP, CPU_I386, ITYPE_SYSTEM, "loadall", { AMODE_Y | OPTYPE_cpu | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+	{ NOGROUP, CPU_I486, ITYPE_SYSTEM, "invd", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x08 */
+	{ NOGROUP, CPU_I486, ITYPE_SYSTEM, "wbinvd", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x09 */
+	{ NOINSTR }, /* 0x0A */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_INVALID, "undef" /* aka UD2 */, NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x0B */
+	{ NOINSTR }, /* 0x0C */
+	{ X86_Group_P, GROUP }, /* 0x0D */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "femms", { OPTYPE_FPU_TAG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x0E */
+	{ X86_3DNOW_0F, EXT_SUFFIX(AMODE_P | OPTYPE_q, AMODE_Q | OPTYPE_q, 0) }, /* 0x0F */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movups", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x10 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movups", { AMODE_W | OPTYPE_ps | OP_DST, AMODE_V | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x11 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movlps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x12 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movlps", { AMODE_M | OPTYPE_q | OP_DST, AMODE_V | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x13 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "unpcklps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x14 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "unpckhps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x15 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movhps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x16 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movhps", { AMODE_M | OPTYPE_q | OP_DST, AMODE_V | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x17 */
+	{ X86_Group_17, GROUP }, /* 0x18 */
+	{ NOINSTR }, /* 0x19 */
+	{ NOINSTR }, /* 0x1A */
+	{ NOINSTR }, /* 0x1B */
+	{ NOINSTR }, /* 0x1C */
+	{ NOINSTR }, /* 0x1D */
+	{ NOINSTR }, /* 0x1E */
+	{ NOINSTR }, /* 0x1F */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_R | OPTYPE_dq | OP_DST, AMODE_C | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x20 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_R | OPTYPE_dq | OP_DST, AMODE_D | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x21 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_C | OPTYPE_dq | OP_DST, AMODE_R | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x22 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_D | OPTYPE_dq | OP_DST, AMODE_R | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x23 */
+	{ NOINSTR }, /* 0x24 */ 
+	//{ NOGROUP, CPU_I486, ITYPE_MOV, "mov", { AMODE_R | OPTYPE_d | OP_DST, AMODE_T | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x24 */
+	{ NOINSTR }, /* 0x25 */
+	{ NOINSTR }, /* 0x26 */
+	//{ NOGROUP, CPU_I486, ITYPE_MOV, "mov", { AMODE_T | OPTYPE_d | OP_DST, AMODE_R | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x26 */
+	{ NOINSTR }, /* 0x27 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movaps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x28 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movaps", { AMODE_W | OPTYPE_ps | OP_DST, AMODE_V | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x29 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "cvtpi2ps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x2A */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movntps", { AMODE_M | OPTYPE_o | OP_DST, AMODE_V | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x2B */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "cvttps2pi", { AMODE_P | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x2C */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "cvtps2pi", { AMODE_P | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x2D */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_CMP, "ucomiss", { AMODE_V | OPTYPE_ss | OP_SRC, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_CF_MOD | FLAG_PF_MOD | FLAG_OF_CLR | FLAG_SF_CLR | FLAG_AF_CLR, NOACTION, IGNORED }, /* 0x2E */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_CMP, "comiss", { AMODE_V | OPTYPE_ps | OP_SRC, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_CF_MOD | FLAG_PF_MOD | FLAG_OF_CLR | FLAG_SF_CLR | FLAG_AF_CLR, NOACTION, IGNORED }, /* 0x2F */
+	{ NOGROUP, CPU_PENTIUM, ITYPE_SYSTEM, "wrmsr", { OPTYPE_REG_ECX | OP_MSR | OP_DST, OPTYPE_EDX_HI_EAX_LO | OP_SRC, 0 } , NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x30 */
+	{ NOGROUP, CPU_PENTIUM, ITYPE_SYSTEM, "rdtsc", { OPTYPE_EDX_HI_EAX_LO | OP_DST, OPTYPE_TSC | OP_MSR | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x31 */
+	{ NOGROUP, CPU_PENTIUM, ITYPE_SYSTEM, "rdmsr", { OPTYPE_EDX_HI_EAX_LO | OP_DST, OPTYPE_REG_ECX | OP_MSR | OP_SRC, 0 } , NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x32 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_OTHER, "rdpmc", { OPTYPE_EDX_HI_EAX_LO | OP_DST, OPTYPE_REG_ECX | OP_SYS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x33 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSCALL, "sysenter", { OPTYPE_CS_MSR | OP_MSR | OP_SRC, OPTYPE_EIP_MSR | OP_MSR | OP_SRC, OPTYPE_ESP_MSR | OP_MSR | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x34 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSCALLRET, "sysexit", { OPTYPE_CS_MSR | OP_MSR | OP_SRC, OPTYPE_EIP_MSR | OP_MSR | OP_SRC, OPTYPE_ESP_MSR | OP_MSR | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x35 */
+	{ NOINSTR }, /* 0x36 */
+	{ NOINSTR }, /* 0x37 */
+	{ NOINSTR }, /* 0x38 */
+	{ NOINSTR }, /* 0x39 */
+	{ NOINSTR }, /* 0x3A */
+	{ NOINSTR }, /* 0x3B */
+	{ NOINSTR }, /* 0x3C */
+	{ NOINSTR }, /* 0x3D */
+	{ NOINSTR }, /* 0x3E */
+	{ NOINSTR }, /* 0x3F */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovo", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_O, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x40 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovno", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_NO, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x41 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovc", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_C, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x42 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovnc", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_NC, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x43 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovz", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_Z, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x44 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovnz", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_NZ, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x45 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovbe", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_BE, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x46 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmova", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_A, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x47 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovs", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_S, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x48 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovns", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_NS, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x49 */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovpe", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_PE, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x4A */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovpo", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_PO, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x4B */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovl", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_L, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x4C */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovge", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_GE, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x4D */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovle", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_LE, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x4E */
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_MOVCC, "cmovg", { AMODE_G | OPTYPE_v | OP_COND_DST, AMODE_E | OPTYPE_v | OP_COND_SRC, 0 }, COND_G, NOCHANGE, OP1_DST | OP2_SRC, NOACTION }, /* 0x4F */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "movmskps", { AMODE_G | OPTYPE_d | OP_DST, AMODE_VR | OPTYPE_ps| OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x50 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "sqrtps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x51 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "rsqrtps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x52 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "rcpps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x53 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_AND, "andps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x54 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_AND, "andnps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x55 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_OR, "orps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x56 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_XOR, "xorps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x57 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_ADD, "addps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x58 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MUL, "mulps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x59 */
+	{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtps2pd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5A */
+	{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtdq2ps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5B */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_SUB, "subps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5C */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "minps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5D */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_DIV, "divps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5E */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "maxps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x5F */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "punpcklbw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x60 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "punpcklwd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x61 */	
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "punpckldq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x62 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "packsswb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x63 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_CMP, "pcmpgtb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x64 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_CMP, "pcmpgtw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x65 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_CMP, "pcmpgtd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x66 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "packuswb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x67 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "punpckhbw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x68 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "punpckhwd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x69 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "punpckhdq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_d | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x6A */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "packssdw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x6B */
+	{ NOINSTR }, /* 0x6C */
+	{ NOINSTR }, /* 0x6D */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_MOV, "movd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_E | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x6E */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_MOV, "movq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x6F */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "pshufw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x70 */
+	{ X86_Group_13, GROUP }, /* 0x71 */
+	{ X86_Group_14, GROUP }, /* 0x72 */
+	{ X86_Group_15, GROUP }, /* 0x73 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_CMP, "pcmpeqb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x74 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_CMP, "pcmpeqw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x75 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_CMP, "pcmpeqd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x76 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "emms", { OPTYPE_FPU_TAG | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x77 */
+	{ NOINSTR }, /* 0x78 */
+	{ NOINSTR }, /* 0x79 */
+	{ NOINSTR }, /* 0x7A */
+	{ NOINSTR }, /* 0x7B */
+	{ NOINSTR }, /* 0x7C */
+	{ NOINSTR }, /* 0x7D */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_MOV, "movd", { AMODE_E | OPTYPE_dq | OP_DST, AMODE_P | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x7E */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_MOV, "movq", { AMODE_Q | OPTYPE_q | OP_DST, AMODE_P | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x7F */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jo", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_O, NOCHANGE, OP1_DST, NOACTION }, /* 0x80 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jno", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NO, NOCHANGE, OP1_DST, NOACTION }, /* 0x81 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jb", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_C, NOCHANGE, OP1_DST, NOACTION }, /* 0x82 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jnb", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NC, NOCHANGE, OP1_DST, NOACTION }, /* 0x83 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jz", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_Z, NOCHANGE, OP1_DST, NOACTION }, /* 0x84 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jnz", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NZ, NOCHANGE, OP1_DST, NOACTION }, /* 0x85 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jbe", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_BE, NOCHANGE, OP1_DST, NOACTION }, /* 0x86 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "ja", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_A, NOCHANGE, OP1_DST, NOACTION }, /* 0x87 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "js", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_S, NOCHANGE, OP1_DST, NOACTION }, /* 0x88 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jns", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_NS, NOCHANGE, OP1_DST, NOACTION }, /* 0x89 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jpe", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_PE, NOCHANGE, OP1_DST, NOACTION }, /* 0x8A */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jpo", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_PO, NOCHANGE, OP1_DST, NOACTION }, /* 0x8B */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jl", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_L, NOCHANGE, OP1_DST, NOACTION }, /* 0x8C */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jge", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_GE, NOCHANGE, OP1_DST, NOACTION }, /* 0x8D */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jle", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_LE, NOCHANGE, OP1_DST, NOACTION }, /* 0x8E */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCHCC, "jg", { AMODE_J | OPTYPE_z | OP_SRC | OP_COND_EXEC, 0, 0 }, COND_G, NOCHANGE, OP1_DST, NOACTION }, /* 0x8F */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "seto", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_O, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x90 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setno", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_NO, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x91 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setb", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_C, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x92 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setnb", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_NC, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x93 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "sete", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_Z, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x94 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setne", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_NZ, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x95 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setbe", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_BE, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x96 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "seta", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_A, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x97 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "sets", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_S, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x98 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setns", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_NS, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x99 */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setpe", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_PE, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x9A */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setpo", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_PO, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x9B */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setl", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_L, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x9C */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setge", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_GE, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x9D */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setle", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_LE, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x9E */
+	{ NOGROUP, CPU_I386, ITYPE_MOVCC, "setg", { AMODE_E | OPTYPE_b | OP_COND_DST, OPTYPE_1 | OP_COND_SRC, OPTYPE_0 | OP_COND_SRC }, COND_G, NOCHANGE, OP1_DST | OP2_SRC, OP1_DST | OP3_SRC }, /* 0x9F */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OPTYPE_FS | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA0 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OPTYPE_FS | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA1 */
+	{ NOGROUP, CPU_PENTIUM, ITYPE_CPUID, "cpuid", { OPTYPE_EDX_ECX_EBX_EAX | OP_DST, OPTYPE_REG_xAX_BIG | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA2 */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "bt", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xA3 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shld", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xA4 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shld", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, OPTYPE_REG_CL | OP_SRC }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xA5 */
+	{ NOINSTR }, /* 0xA6 */
+	{ NOINSTR }, /* 0xA7 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { OPTYPE_GS | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA8 */
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { OPTYPE_GS | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xA9 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "rsm", NOARGS, NOCOND, FLAG_ALL_MOD, NOACTION, IGNORED }, /* 0xAA */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "bts", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xAB */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shrd", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xAC */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shrd", { AMODE_E | OPTYPE_v | OP_DST, AMODE_G | OPTYPE_v | OP_SRC, OPTYPE_REG_CL | OP_SRC }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xAD */
+	{ X86_Group_16, GROUP }, /* 0xAE */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "imul", { AMODE_G | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xAF */
+	{ NOGROUP, CPU_I486, ITYPE_XCHGCC, "cmpxchg", { AMODE_E | OPTYPE_b | OP_SRC | OP_COND_DST, OPTYPE_REG_AL | OP_SRC | OP_COND_DST, AMODE_G | OPTYPE_b | OP_COND_SRC }, COND_OP1_EQ_OP2, FLAG_COMMON_MOD, OP1_DST | OP3_SRC, OP2_DST | OP1_SRC }, /* 0xB0 */
+	{ NOGROUP, CPU_I486, ITYPE_XCHGCC, "cmpxchg", { AMODE_E | OPTYPE_v | OP_SRC | OP_COND_DST, OPTYPE_REG_xAX_BIG | OP_SRC | OP_COND_DST, AMODE_G | OPTYPE_v | OP_COND_SRC }, COND_OP1_EQ_OP2, FLAG_COMMON_MOD, OP1_DST | OP3_SRC, OP2_DST | OP1_SRC }, /* 0xB1 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "lss", { AMODE_G | OPTYPE_z | OP_DST, AMODE_M | OPTYPE_p | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB2 */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "btr", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xB3 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "lfs", { AMODE_G | OPTYPE_z | OP_DST, AMODE_M | OPTYPE_p | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB4 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "lgs", { AMODE_G | OPTYPE_z | OP_DST, AMODE_M | OPTYPE_p | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB5 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "movzx", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB6 */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "movzx", { AMODE_G | OPTYPE_v | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xB7 */
+	{ NOINSTR }, /* 0xB8 */
+	{ X86_Group_11, GROUP }, /* 0xB9 */
+	{ X86_Group_8, GROUP }, /* 0xBA */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "btc", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_G | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0xBB */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "bsf", { AMODE_G | OPTYPE_v | OP_SRC, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, /* 0xBC */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "bsr", { AMODE_G | OPTYPE_v | OP_SRC, AMODE_E | OPTYPE_v | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, /* 0xBD */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "movsx", { AMODE_G | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBE */
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "movsx", { AMODE_G | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xBF */
+	{ NOGROUP, CPU_I486, ITYPE_XCHGADD, "xadd", { AMODE_E | OPTYPE_b | OP_SRC | OP_DST, AMODE_G | OPTYPE_b | OP_SRC | OP_DST, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0xC0 */
+	{ NOGROUP, CPU_I486, ITYPE_XCHGADD, "xadd", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, AMODE_G | OPTYPE_v | OP_SRC | OP_DST, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0xC1 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_CMP, "cmpps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0xC2 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movnti", { AMODE_M | OPTYPE_dq | OP_DST, AMODE_G | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC3 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pinsrw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC4 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pextrw", { AMODE_G | OPTYPE_d | OP_DST, AMODE_PR | OPTYPE_q | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC5 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "shufps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC6 */
+	{ X86_Group_9, GROUP }, /* 0xC7 */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC8 */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC9 */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCA */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCB */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCC */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCD */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCE */
+	{ NOGROUP, CPU_I486, ITYPE_XCHG, "bswap", { OP_REG | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xCF */
+	{ NOINSTR }, /* 0xD0 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrlw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD1 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrld", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD2 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrlq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD3 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_ADD, "paddq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD4 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_MUL, "pmullw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD5 */
+	{ NOINSTR }, /* 0xD6 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pmovmskb", { AMODE_G | OPTYPE_d | OP_DST, AMODE_PR | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD7 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubusb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD8 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubusw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xD9 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pminub", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xDA */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_AND, "pand", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xDB */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddusb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xDC */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddusw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xDD */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pmaxub", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xDE */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_AND, "pandn", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xDF */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pavgb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE0 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psraw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE1 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrad", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE2 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pavgw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE3 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MUL, "pmulhuw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE4 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_MUL, "pmulhw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE5 */
+	{ NOINSTR }, /* 0xE6 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MOV, "movntq", { AMODE_M | OPTYPE_q | OP_DST, AMODE_P | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE7 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubsb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE8 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubsw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xE9 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pminsw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEA */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_OR, "por", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEB */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddsb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEC */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddsw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xED */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "pmaxsw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEE */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_XOR, "pxor", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xEF */
+	{ NOINSTR }, /* 0xF0 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psllw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF1 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "pslld", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF2 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psllq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF3 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_MUL, "pmuludq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF4 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "pmaddwd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF5 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "psadbw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF6 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "maskmovq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_PR | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF7 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF8 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xF9 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_SUB, "psubd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xFA */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE_SUB, "psubq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xFB */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xFC */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xFD */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX_ADD, "paddd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xFE */
+	{ NOINSTR } /* 0xFF */, 
+};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// Groups
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+X86_OPCODE X86_Group_1_80[8] = // 80
+{
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_E | OPTYPE_b | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_1_81[8] = // 81
+{
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_1_82[8] = // 82
+{
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_1_83[8] = // 83
+{
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "add", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_OR, "or", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ADD, "adc", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sbb", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_AND, "and", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SUB, "sub", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_XOR, "xor", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_CMP, "cmp", { AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, AMODE_I | OPTYPE_b | OP_SIGNED | OP_SRC, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_2_C0[8] = // C0
+{
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rol", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "ror", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rcl", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "rcr", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shl", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shr", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "sal", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "sar", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_2_C1[8] = // C1
+{
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rol", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "ror", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rcl", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "rcr", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shl", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shr", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "sal", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "sar", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_2_D0[8] = // D0
+{
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rol", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "ror", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rcl", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "rcr", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shl", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shr", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "sal", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "sar", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_2_D1[8] = // D1
+{
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rol", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "ror", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rcl", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "rcr", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shl", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shr", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "sal", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "sar", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_1 | OP_SRC, 0 }, NOCOND, FLAG_OF_MOD | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_2_D2[8] = // D2
+{
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rol", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "ror", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rcl", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "rcr", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shl", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shr", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "sal", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "sar", { AMODE_E | OPTYPE_b | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_2_D3[8] = // D3
+{
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rol", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "ror", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_ROL, "rcl", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_ROR, "rcr", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "shl", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "shr", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SHL, "sal", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_SHR, "sar", { AMODE_E | OPTYPE_v | OP_DST, OPTYPE_REG_CL | OP_SRC, 0 }, NOCOND, FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_3_F6[8] = // F6
+{
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { AMODE_E | OPTYPE_b | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { AMODE_E | OPTYPE_b | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_NOT, "not", { AMODE_E | OPTYPE_b | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_NEG, "neg", { AMODE_E | OPTYPE_b | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "mul", { OPTYPE_REG_AX | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, OPTYPE_REG_AL | OP_SRC }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "imul", { OPTYPE_REG_AX | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_b | OP_SIGNED | OP_SRC, OPTYPE_REG_AL | OP_SIGNED | OP_SRC }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_DIV, "div", { OPTYPE_REG_AX | OP_DST, AMODE_E | OPTYPE_b | OP_SRC, OPTYPE_REG_AX | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_DIV, "idiv", { OPTYPE_REG_AX | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_b | OP_SIGNED | OP_SRC, OPTYPE_REG_AX | OP_SIGNED | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED } /* 0x07 */,
+};
+
+X86_OPCODE X86_Group_3_F7[8] = // F7
+{
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_TEST, "test", { AMODE_E | OPTYPE_v | OP_SRC, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, FLAG_OF_CLR | FLAG_SF_MOD | FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_CLR, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_NOT, "not", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_NEG, "neg", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "mul", { OPTYPE_xDX_HI_xAX_LO | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, OPTYPE_REG_xAX_BIG | OP_SRC }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_MUL, "imul", { OPTYPE_xDX_HI_xAX_LO | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, OPTYPE_REG_xAX_BIG | OP_SRC }, NOCOND, FLAG_OF_MOD | FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_DIV, "div", { OPTYPE_xDX_HI_xAX_LO | OP_DST, AMODE_E | OPTYPE_v | OP_SRC, OPTYPE_REG_xAX_BIG | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_DIV, "idiv", { OPTYPE_xDX_HI_xAX_LO | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_v | OP_SIGNED | OP_SRC, OPTYPE_REG_xAX_BIG | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_4[8] = // FE
+{
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { AMODE_E | OPTYPE_b | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { AMODE_E | OPTYPE_b | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOINSTR }, /* 0x06 */
+	{ NOINSTR } /* 0x07 */
+};
+
+X86_OPCODE X86_Group_5[8] = // FF
+{
+	{ NOGROUP, CPU_I386, ITYPE_INC, "inc", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_DEC, "dec", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, 0, 0 }, NOCOND, FLAG_OF_MOD|FLAG_SF_MOD|FLAG_ZF_MOD|FLAG_AF_MOD|FLAG_PF_MOD, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_CALL, "call", { AMODE_E | OPTYPE_v | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_CALL, "call", { AMODE_E | OPTYPE_p | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCH, "jmp", { AMODE_E | OPTYPE_v | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_BRANCH, "jmp", { AMODE_E | OPTYPE_p | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_PUSH, "push", { AMODE_E | OPTYPE_v | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_6[8] = // 0F 00
+{
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "sldt", { AMODE_E | OPTYPE_mw | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "str", { AMODE_E | OPTYPE_mw | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "lldt", { AMODE_E | OPTYPE_w | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "ltr", { AMODE_E | OPTYPE_w | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "verr", { AMODE_E | OPTYPE_w | OP_SRC, 0, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "verw", { AMODE_E | OPTYPE_w | OP_SRC, 0, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_IA64, ITYPE_BRANCH, "jmpe", { AMODE_E | OPTYPE_v | OP_SRC | OP_EXEC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOINSTR } /* 0x07 */
+};
+
+X86_OPCODE X86_Group_7[8] = // 0F 01
+{
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "sgdt", { AMODE_M | OPTYPE_dt | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "sidt", { AMODE_M | OPTYPE_dt | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "lgdt", { AMODE_M | OPTYPE_dt | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "lidt", { AMODE_M | OPTYPE_dt | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "smsw", { AMODE_E | OPTYPE_mw | OP_DST, OPTYPE_CR0 | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "lmsw", { OPTYPE_CR0 | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I486, ITYPE_SYSTEM, "invlpg", { AMODE_M | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_8[8] = // 0F BA
+{
+	{ NOINSTR }, /* 0x00 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOINSTR }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "bt", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "bts", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "btr", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_BITTEST, "btc", { AMODE_E | OPTYPE_v | OP_SRC | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, FLAG_CF_MOD, NOACTION, IGNORED }, /* 0x07 */ 
+};
+
+X86_OPCODE X86_Group_9[8] = // 0F C7
+{
+	{ NOINSTR }, /* 0x00 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_XCHGCC, "cmpxchg8b", { AMODE_M | OPTYPE_q | OP_SRC | OP_COND_DST, OPTYPE_xDX_HI_xAX_LO | OP_SRC | OP_COND_DST, OPTYPE_xCX_HI_xBX_LO | OP_COND_SRC }, COND_OP1_EQ_OP2, FLAG_ZF_MOD, OP1_DST | OP3_SRC, OP2_DST | OP1_SRC }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOINSTR }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_10[8] = // 8F (NOTE: AMD64 labels this Group 1A)
+{
+	{ NOGROUP, CPU_I386, ITYPE_POP, "pop", { AMODE_E | OPTYPE_v | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOINSTR }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOINSTR }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_11[8] = // 0F B9 (NOTE: AMD64 labels this Group 10)
+{
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_I386, ITYPE_INVALID, "undef", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED } /* 0x07 */
+};
+
+X86_OPCODE X86_Group_12_C6[8] = // C6 (NOTE: AMD64 labels this Group 11)
+{
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_E | OPTYPE_b | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0xC6 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOINSTR }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOINSTR }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_12_C7[8] = // C7 (NOTE: AMD64 labels this Group 11)
+{
+	{ NOGROUP, CPU_I386, ITYPE_MOV, "mov", { AMODE_E | OPTYPE_v | OP_DST, AMODE_I | OPTYPE_z | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOINSTR }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOINSTR }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+// NOTE: the X86_SSE2_* is only followed if it is a 3-byte opcode (e.g., prefix is 66, F2, or F3)
+X86_OPCODE X86_Group_13[8] = // 0F 71 (NOTE: AMD64 labels this Group 12)
+{
+	{ NOINSTR }, /* 0x00 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrlw", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psraw", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psllw", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_14[8] = // 0F 72 (NOTE: AMD64 labels this Group 13)
+{
+	{ NOINSTR }, /* 0x00 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrld", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrad", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "pslld", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_15[8] = // 0F 73 (NOTE: AMD64 labels this Group 14)
+{
+	{ NOINSTR }, /* 0x00 */
+	{ NOINSTR }, /* 0x01 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrlq", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psrldq", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "psllq", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */ 
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_MMX, "pslldq", { AMODE_PR | OPTYPE_q | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED } /* 0x07 */ 
+};
+
+X86_OPCODE X86_Group_16[8] = // 0F AE (NOTE: AMD64 labels this Group 15)
+{
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_FPU, "fxsave", { AMODE_M | OPTYPE_fst2 | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_FPU, "fxrstor", { AMODE_M | OPTYPE_fst2 | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "ldmxcsr", { AMODE_M | OPTYPE_d | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "stmxcsr", { AMODE_M | OPTYPE_d | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "lfence", NOARGS, NOCOND, NOCHANGE, SERIALIZE_READ, IGNORED }, /* 0x05 */ 
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "mfence", NOARGS, NOCOND, NOCHANGE, SERIALIZE_ALL, IGNORED }, /* 0x06 */ 
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "sfence", NOARGS, NOCOND, NOCHANGE, SERIALIZE_WRITE, IGNORED } /* 0x07 */
+};
+
+X86_OPCODE X86_Group_17[8] = // 0F 18 (NOTE: AMD64 labels this Group 16)
+{
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "prefetchnta", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x00 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "prefetcht0", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "prefetcht1", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "prefetcht2", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "hintnop", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "hintnop", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x05 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "hintnop", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+	{ NOGROUP, CPU_PENTIUM2, ITYPE_SYSTEM, "hintnop", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+};
+
+X86_OPCODE X86_Group_P[8] = // 0F 0D
+{
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "prefetch", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x01 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "prefetchw", { AMODE_E | OPTYPE_b | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+	{ NOINSTR }, /* 0x03 */
+	{ NOINSTR }, /* 0x04 */
+	{ NOINSTR }, /* 0x05 */
+	{ NOINSTR }, /* 0x06 */
+	{ NOINSTR }, /* 0x07 */
+};
+
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// FPU (ESC) opcodes
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+
+X86_OPCODE X86_ESC_0[0x48] = // D8 
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x00
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x01
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { AMODE_M | OPTYPE_ss | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // 0x02
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { AMODE_M | OPTYPE_ss | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // 0x03
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x04
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x05
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x06
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_ss | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x07
+
+	//
+	// ModRM >= C0: ST(0) <- ST(0) + ST(i)
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// C8-CF
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	// D0-D7
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x7
+	// D8-DF
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xF
+	// E0-E7
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xF
+	// F0-F7
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// F8-FF
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }  // xF
+};
+
+
+X86_OPCODE X86_ESC_1[0x48] = // D9
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { AMODE_M | OPTYPE_ss | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // 0x00
+	{ NOINSTR }, // 0x01
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { AMODE_M | OPTYPE_ss | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x02
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { AMODE_M | OPTYPE_ss | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x03
+	{ NOGROUP, CPU_I287, ITYPE_FLOADENV, "fldenv", { AMODE_M | OPTYPE_fev | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // 0x04
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldcw", { OPTYPE_FPU_CONTROL | OP_DST, AMODE_M | OPTYPE_w | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // 0x05
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstenv", { AMODE_M | OPTYPE_fev | OP_DST, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // 0x06
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fnstcw", { AMODE_M | OPTYPE_w | OP_DST, OPTYPE_FPU_CONTROL | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // 0x07
+
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { OPTYPE_STx | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x7
+	// C8-CF
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FEXCH, "fxch", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_STx | OP_SRC | OP_DST, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xF
+	// D0-D7
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fnop", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// D8-DF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }, // xF
+	// E0-E7
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fchs", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fabs", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3 
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ftst", { OPTYPE_ST0 | OP_SRC, OPTYPE_FLDZ | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fxam", { OPTYPE_ST0 | OP_SRC, 0, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld1", { OPTYPE_FLD1 | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldl2t", { OPTYPE_FLDL2T | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldl2e", { OPTYPE_FLDL2E | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldpi", { OPTYPE_FLDPI | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldlg2", { OPTYPE_FLDLG2| OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldln2", { OPTYPE_FLDLN2 | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fldz", { OPTYPE_FLDZ | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // xE
+	{ NOINSTR }, // xF
+	// F0-F7
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "f2xm1", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fyl2x", { OPTYPE_ST1 | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fptan", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD|FPU_C2_MOD, FPU_STACK_PUSH, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fpatan", { OPTYPE_ST1 | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC , 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fxtract", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_ST1 | OP_DST, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x4
+	{ NOGROUP, CPU_I387, ITYPE_FPU, "fprem1", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_ST1 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fdecstp", NOARGS, NOCOND, FPU_C1_MOD, FPU_STACK_DEC, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fincstp", NOARGS, NOCOND, FPU_C1_MOD, FPU_STACK_INC, IGNORED }, // x7
+	// F8-FF
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fprem", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_ST1 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fyl2xp1", { OPTYPE_ST1 | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fsqrt", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fsincos", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD|FPU_C2_MOD, FPU_STACK_PUSH, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "frndint", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fscale", { OPTYPE_ST0 | OP_SRC | OP_DST, OPTYPE_ST1 | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fsin", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD|FPU_C2_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fcos", { OPTYPE_ST0 | OP_SRC | OP_DST, 0, 0 }, NOCOND, FPU_C1_MOD|FPU_C2_MOD, NOACTION, IGNORED } // xF
+};
+
+
+X86_OPCODE X86_ESC_2[0x48] = // DA
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fiadd", { OPTYPE_ST0 | OP_SIGNED | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fimul", { OPTYPE_ST0 | OP_SIGNED | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "ficom", { AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, OPTYPE_ST0 | OP_SRC | OP_DST, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "ficomp", { AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, OPTYPE_ST0 | OP_SRC | OP_DST, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fisub", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fisubr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fidiv", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fidivr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x0
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x1
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x2
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x3
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x4
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x5
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x6
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_B, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x7
+	// C8-CF
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x8
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x9
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xA
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xB
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xC
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xD
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xE
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmove", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_E, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xF
+	// D0-D7
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x0
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x1
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x2
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x3
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x4
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x5
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x6
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_BE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x7
+	// D8-DF
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x8
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x9
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xA
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xB
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xC
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xD
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xE
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FMOVCC, "fcmovu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_COND_SRC, 0 }, COND_U, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xF
+	// E0-E7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// E8-EF
+	{ NOINSTR }, // x8
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucompp", { OPTYPE_ST1 | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP2, IGNORED }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }, // xF
+	// F0-F7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// F8-FF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }  // xF
+};
+
+
+
+X86_OPCODE X86_ESC_3[0x48] = // DB
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fild", { AMODE_M | OPTYPE_d | OP_SIGNED | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // 0x00
+	{ NOGROUP, CPU_PENTIUM4, ITYPE_FSTORE, "fisttp", { AMODE_M | OPTYPE_d | OP_SIGNED | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x01
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fist", { AMODE_M | OPTYPE_d | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x02
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fistp", { AMODE_M | OPTYPE_d | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x03
+	{ NOINSTR }, // 0x04
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { AMODE_M | OPTYPE_se | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // 0x05
+	{ NOINSTR }, // 0x06
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { AMODE_M | OPTYPE_se | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x07
+	
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x0
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x1
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x2
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x3
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x4
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x5
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x6
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnb", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NB, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x7
+	// C8-CF
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x8
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x9
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xA
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xB
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xC
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xD
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xE
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovne", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xF
+	// D0-D7
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x0
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x1
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x2
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x3
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x4
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x5
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x6
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnbe", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NBE, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x7
+	// D8-DF
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x8
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // x9
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xA
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xB
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xC
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xD
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xE
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FPU, "fcmovnu", { OPTYPE_ST0 | OP_COND_DST, OPTYPE_STx | OP_SRC, 0 }, COND_NU, FPU_C1_MOD, OP1_DST | OP2_SRC, NOACTION }, // xF
+	// E0-E7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "fnclex", { OPTYPE_FPU_STATUS | OP_DST, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "finit", { OPTYPE_FPU_STATUS | OP_DST, 0, 0 }, NOCOND, FPU_ALL_CLR, NOACTION, IGNORED }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // xF
+	// F0-F7
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomi", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, NOACTION, IGNORED }, // x7
+	// F8-FF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }  // xF
+};
+
+X86_OPCODE X86_ESC_4[0x48] = // DC
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x00
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x01
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcom", { AMODE_M | OPTYPE_sd | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // 0x02
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcomp", { AMODE_M | OPTYPE_sd | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // 0x03
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x04
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x05
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x06
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x07
+
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fadd", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// C8-CF
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmul", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xF
+	// D0-D7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// D8-DF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }, // xF
+	// E0-E7
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsub", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xF
+	// F0-F7
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivr", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// F8-FF
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdiv", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED } // xF
+};
+
+
+X86_OPCODE X86_ESC_5[0x48] = // DD
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	// 
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fld", { AMODE_M | OPTYPE_sd | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // x0
+	{ NOGROUP, CPU_PENTIUM4, ITYPE_FSTORE, "fisttp", { AMODE_M | OPTYPE_d | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { AMODE_M | OPTYPE_sd | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { AMODE_M | OPTYPE_sd | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FRESTORE, "frstor", { AMODE_M | OPTYPE_fst1 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x4
+	{ NOINSTR }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FSAVE, "fsave", { AMODE_M | OPTYPE_fst1 | OP_DST, 0 }, NOCOND, FPU_ALL_CLR, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fnstsw", { AMODE_M | OPTYPE_w | OP_DST, OPTYPE_FPU_STATUS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FPU, "ffree", { OPTYPE_FPU_TAG | OP_DST, OPTYPE_STx | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	// C8-CF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }, // xF
+	// D0-D7
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fst", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // x7
+	// D8-DF
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fstp", { OPTYPE_STx | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xF
+	// E0-E7
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x0
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x1
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x2
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x3
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x4
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x5
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x6
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucom", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_I387, ITYPE_FCOMP, "fucomp", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xF
+	// F0-F7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// F8-FF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }  // xF
+};
+
+
+X86_OPCODE X86_ESC_6[0x48] = // DE
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "fiadd", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x00
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fimul", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x01
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "ficom", { AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, NOACTION, IGNORED }, // 0x02
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "ficomp", { AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // 0x03
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fisub", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x04
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fisubr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x05
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fidiv", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x06
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fidivr", { OPTYPE_ST0 | OP_SRC | OP_DST, AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x07
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+
+	// C0-C7
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FADD, "faddp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x7
+	// C8-CF
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FMUL, "fmulp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xF
+	// D0-D7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// D8-DF
+	{ NOINSTR }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FCOMP, "fcompp", { OPTYPE_ST1 | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_ALL_MOD, FPU_STACK_POP2, IGNORED }, // x9
+	{ NOINSTR }, // 0xA
+	{ NOINSTR }, // 0xB
+	{ NOINSTR }, // 0xC
+	{ NOINSTR }, // 0xD
+	{ NOINSTR }, // 0xE
+	{ NOINSTR }, // 0xF
+	// E0-E7
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FSUB, "fsubp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xF
+	// F0-F7
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x0
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x1
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x2
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x4
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x5
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x6
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivrp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x7
+	// F8-FF
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_I287, ITYPE_FDIV, "fdivp", { OPTYPE_STx | OP_SRC | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }  // xF
+};
+
+
+X86_OPCODE X86_ESC_7[0x48] = // DF
+{
+	//
+	// ModRM < C0
+	// Index 0x00-0x07 = opcode extension
+	//
+
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fild", { AMODE_M | OPTYPE_w | OP_SIGNED | OP_SRC, 0, 0}, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // 0x00
+	{ NOGROUP, CPU_PENTIUM4, ITYPE_FSTORE, "fisttp", { AMODE_M | OPTYPE_w | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x01
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fist", { AMODE_M | OPTYPE_w | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, NOACTION, IGNORED }, // 0x02
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fistp", { AMODE_M | OPTYPE_w | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x03
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fbld", { AMODE_M | OPTYPE_pb | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // 0x04
+	{ NOGROUP, CPU_I287, ITYPE_FLOAD, "fild", { AMODE_M | OPTYPE_q | OP_SIGNED | OP_SRC, 0, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_PUSH, IGNORED }, // 0x05
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fbstp", { AMODE_M | OPTYPE_pb | OP_DST, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x06
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fistp", { AMODE_M | OPTYPE_q | OP_SIGNED | OP_DST, OPTYPE_ST0 | OP_SRC, 0}, NOCOND, FPU_C1_MOD, FPU_STACK_POP, IGNORED }, // 0x07
+
+	//
+	// ModRM >= C0
+	// Index 0x08-0x47 = ModRM 0xC0-0xFF
+	//
+	// C0-C7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// C8-CF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }, // xF
+	// D0-D7
+	{ NOINSTR }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// D8-DF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }, // xF
+	// E0-E7
+	{ NOGROUP, CPU_I287, ITYPE_FSTORE, "fnstsw", { OPTYPE_REG_AX | OP_DST, OPTYPE_FPU_STATUS | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	{ NOINSTR }, // x1
+	{ NOINSTR }, // x2
+	{ NOINSTR }, // x3
+	{ NOINSTR }, // x4
+	{ NOINSTR }, // x5
+	{ NOINSTR }, // x6
+	{ NOINSTR }, // x7
+	// E8-EF
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x8
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x9
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xA
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xB
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xC
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xD
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xE
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fucomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // xF
+	// F0-F7
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x0
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x1
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x2
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x3
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x4
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x5
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x6
+	{ NOGROUP, CPU_PENTIUM_PRO, ITYPE_FCOMP, "fcomip", { OPTYPE_STx | OP_SRC, OPTYPE_ST0 | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_PF_MOD | FLAG_CF_MOD | FPU_ALL_MOD, FPU_STACK_POP, IGNORED }, // x7
+	// F8-FF
+	{ NOINSTR }, // x8
+	{ NOINSTR }, // x9
+	{ NOINSTR }, // xA
+	{ NOINSTR }, // xB
+	{ NOINSTR }, // xC
+	{ NOINSTR }, // xD
+	{ NOINSTR }, // xE
+	{ NOINSTR }  // xF
+};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// SSE opcodes
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+X86_OPCODE X86_SSE[0x300] =
+{
+	// prefix 0x66 (operand size)
+		/* 0x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 1x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movupd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movupd", { AMODE_W | OPTYPE_pd | OP_DST, AMODE_V | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movlpd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_M | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movlpd", { AMODE_M | OPTYPE_q | OP_DST, AMODE_V | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "unpcklpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "unpckhpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movhpd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_M | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "mpvhpd", { AMODE_M | OPTYPE_q | OP_DST, AMODE_V | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 2x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movapd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movapd", { AMODE_W | OPTYPE_o | OP_DST, AMODE_V | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtpi2pd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movntpd", { AMODE_M | OPTYPE_o | OP_DST, AMODE_V | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvttpd2pi", { AMODE_P | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtpd2pi", { AMODE_P | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "ucomisd", { AMODE_V | OPTYPE_sd | OP_SRC, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_CF_MOD | FLAG_PF_MOD | FLAG_OF_CLR | FLAG_SF_CLR | FLAG_AF_CLR, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "comisd", { AMODE_V | OPTYPE_pd | OP_SRC, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD | FLAG_CF_MOD | FLAG_PF_MOD | FLAG_OF_CLR | FLAG_SF_CLR | FLAG_AF_CLR, NOACTION, IGNORED }, // xF
+	
+		/* 3x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 4x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 5x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "movmskpd", { AMODE_G | OPTYPE_d | OP_DST, AMODE_VR | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "sqrtpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_AND, "andpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_AND, "andnpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_OR, "orpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_XOR, "xorpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "addpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "mulpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtpd2ps", { AMODE_V | OPTYPE_ps | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtps2dq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "subpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "minpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_DIV, "divpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "maxpd", { AMODE_V | OPTYPE_pd | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 6x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpcklbw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpcklwd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpckldq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "packsswb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pcmpgtb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pcmpgtw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pcmpgtd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "packuswb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpckhbw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpckhwd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpckhdq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "packssdw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpcklqdq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "punpckhqdq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_E | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movdqa", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 7x */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pshufd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { X86_SSE2_Group_13, GROUP }, // x1
+	  { X86_SSE2_Group_14, GROUP }, // x2
+	  { X86_SSE2_Group_15, GROUP }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "pcmpeqb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "pcmpeqw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "pcmpeqd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_ADD, "haddpd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_SUB, "hsubpd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movd", { AMODE_E | OPTYPE_dq | OP_DST, AMODE_V | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movdqa", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 8x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 9x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Ax */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Bx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Cx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "cmppd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, // x2
+	  { NOINSTR }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pinsrw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_E | OPTYPE_w | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pextrw", { AMODE_G | OPTYPE_d | OP_DST, AMODE_VR| OPTYPE_o | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "shufpd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Dx */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3, "addsubpd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrlw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrld", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrlq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "pmullw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movq", { AMODE_W | OPTYPE_q | OP_DST, AMODE_V | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pmovmskb", { AMODE_G | OPTYPE_d | OP_DST, AMODE_VR| OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubusb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubusw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pminub", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_AND, "pand", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddusb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddusw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pmaxub", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_AND, "pandn", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* Ex */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pavgb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psraw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrad", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pavgw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "pmulhuw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "pmulhw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvttpd2dq", { AMODE_V | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movntdq", { AMODE_M | OPTYPE_o | OP_DST, AMODE_V | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubsb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubsw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pminsw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_OR, "por", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddsb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddsw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pmaxuw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_XOR, "pxor", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* Fx */
+	  { NOINSTR }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psllw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pslld", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psllq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "pmuludq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x4
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "pmaddwd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psadbw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "maskmovdqu", { AMODE_V | OPTYPE_o | OP_DST, AMODE_VR| OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "psubq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddb", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddw", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "paddd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOINSTR }, // xF
+
+	// prefix 0xf2 (repne)
+		/* 0x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 1x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movsd", { AMODE_V | OPTYPE_sdo | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movsd", { AMODE_W | OPTYPE_sd | OP_DST, AMODE_V | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_MOV, "movddup", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 2x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtsi2sd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_E | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOINSTR }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvttsd2si", { AMODE_G | OPTYPE_dq | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtsd2si", { AMODE_G | OPTYPE_dq | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 3x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 4x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 5x */
+	  { NOINSTR }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "sqrtsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "addsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "mulsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtsd2ss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOINSTR }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "subsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "minsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_DIV, "divsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "maxsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 6x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movdqa", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 7x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pshuflw", { AMODE_V | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_ADD, "haddps", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_SUB, "hsubps", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 8x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 9x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Ax */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Bx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Cx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_CMP, "cmpsd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_sd | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Dx */
+	  { NOGROUP, CPU_PENTIUM3, ITYPE_SSE3, "addsubps", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movdq2q", { AMODE_P | OPTYPE_q | OP_DST, AMODE_VR | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Ex */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtpd2dq", { AMODE_V | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_pd | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Fx */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3, "lddqu", { AMODE_V | OPTYPE_o | OP_DST, AMODE_M | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+
+	// prefix 0xf3 (rep)
+		/* 0x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 1x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movss", { AMODE_V | OPTYPE_sso | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movss", { AMODE_W | OPTYPE_ss | OP_DST, AMODE_V | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_MOV, "movsldup", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE3_MOV, "movshdup", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 2x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "cvtsi2ss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_E | OPTYPE_dq | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOINSTR }, // xB
+	  { NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "cvttss2si", { AMODE_G | OPTYPE_dq | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM3, ITYPE_SSE, "cvtss2si", { AMODE_G | OPTYPE_dq | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 3x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 4x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 5x */
+	  { NOINSTR }, // x0
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "sqrtss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x1
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "rsqrtss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x2
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "rcpss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_ADD, "addss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MUL, "mulss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x9
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtss2sd", { AMODE_V | OPTYPE_sd | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xA
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvttps2dq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_ps | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xB
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_SUB, "subss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xC
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "minss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_DIV, "divss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "maxss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 6x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movdqu", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 7x */
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pshufhw", { AMODE_V | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movq", { AMODE_V | OPTYPE_q | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xE
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movdqu", { AMODE_W | OPTYPE_o | OP_DST, AMODE_V | OPTYPE_o | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // xF
+	
+		/* 8x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* 9x */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Ax */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Bx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Cx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOGROUP, CPU_PENTIUM3, ITYPE_SSE_CMP, "cmpss", { AMODE_V | OPTYPE_ss | OP_DST, AMODE_W | OPTYPE_ss | OP_SRC, AMODE_I | OPTYPE_b | OP_SRC }, NOCOND, FLAG_COMMON_MOD, NOACTION, IGNORED }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Dx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2_MOV, "movq2dq", { AMODE_V | OPTYPE_o | OP_DST, AMODE_PR | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Ex */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "cvtdq2pd", { AMODE_V | OPTYPE_o | OP_DST, AMODE_W | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR }, // xF
+	
+		/* Fx */
+	  { NOINSTR }, // x0
+	  { NOINSTR }, // x1
+	  { NOINSTR }, // x2
+	  { NOINSTR }, // x3
+	  { NOINSTR }, // x4
+	  { NOINSTR }, // x5
+	  { NOINSTR }, // x6
+	  { NOINSTR }, // x7
+	  { NOINSTR }, // x8
+	  { NOINSTR }, // x9
+	  { NOINSTR }, // xA
+	  { NOINSTR }, // xB
+	  { NOINSTR }, // xC
+	  { NOINSTR }, // xD
+	  { NOINSTR }, // xE
+	  { NOINSTR } // xF
+};
+
+X86_OPCODE X86_SSE2_Group_13[24] = // 66/F2/F3 0F 71
+{
+	// prefix 0x66 (operand size)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrlw", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psraw", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psllw", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+
+	// prefix 0xf2 (repne)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOINSTR }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOINSTR }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+
+	// prefix 0xf3 (rep)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOINSTR }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOINSTR }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_SSE2_Group_14[24] = // 66/F2/F3 0F 72
+{
+	// prefix 0x66 (operand size)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrld", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrad", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pslld", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+
+	// prefix 0xf2 (repne)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOINSTR }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOINSTR }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+
+	// prefix 0xf3 (rep)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOINSTR }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOINSTR }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+};
+
+X86_OPCODE X86_SSE2_Group_15[24] =
+{
+	// prefix 0x66 (operand size)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrlq", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x02 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psrldq", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "psllq", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x06 */
+		{ NOGROUP, CPU_PENTIUM4, ITYPE_SSE2, "pslldq", { AMODE_VR | OPTYPE_o | OP_DST, AMODE_I | OPTYPE_b | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0x07 */
+
+	// prefix 0xf2 (repne)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOINSTR }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOINSTR }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+
+	// prefix 0xf3 (rep)
+		{ NOINSTR }, /* 0x00 */
+		{ NOINSTR }, /* 0x01 */
+		{ NOINSTR }, /* 0x02 */
+		{ NOINSTR }, /* 0x03 */
+		{ NOINSTR }, /* 0x04 */
+		{ NOINSTR }, /* 0x05 */
+		{ NOINSTR }, /* 0x06 */
+		{ NOINSTR }, /* 0x07 */
+};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// 3DNow opcodes
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+X86_OPCODE X86_3DNOW_0F[0x100] =
+{
+	{ NOINSTR }, /* 00 */
+	{ NOINSTR }, /* 01 */
+	{ NOINSTR }, /* 02 */
+	{ NOINSTR }, /* 03 */
+	{ NOINSTR }, /* 04 */
+	{ NOINSTR }, /* 05 */
+	{ NOINSTR }, /* 06 */
+	{ NOINSTR }, /* 07 */
+	{ NOINSTR }, /* 08 */
+	{ NOINSTR }, /* 09 */
+	{ NOINSTR }, /* 0A */
+	{ NOINSTR }, /* 0B */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pi2fw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0C */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pi2fd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 0D */
+	{ NOINSTR }, /* 0E */
+	{ NOINSTR }, /* 0F */
+	{ NOINSTR }, /* 10 */
+	{ NOINSTR }, /* 11 */
+	{ NOINSTR }, /* 12 */
+	{ NOINSTR }, /* 13 */
+	{ NOINSTR }, /* 14 */
+	{ NOINSTR }, /* 15 */
+	{ NOINSTR }, /* 16 */
+	{ NOINSTR }, /* 17 */
+	{ NOINSTR }, /* 18 */
+	{ NOINSTR }, /* 19 */
+	{ NOINSTR }, /* 1A */
+	{ NOINSTR }, /* 1B */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pf2iw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 1C */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pf2id", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 1D */
+	{ NOINSTR }, /* 1E */
+	{ NOINSTR }, /* 1F */
+	{ NOINSTR }, /* 20 */
+	{ NOINSTR }, /* 21 */
+	{ NOINSTR }, /* 22 */
+	{ NOINSTR }, /* 23 */
+	{ NOINSTR }, /* 24 */
+	{ NOINSTR }, /* 25 */
+	{ NOINSTR }, /* 26 */
+	{ NOINSTR }, /* 27 */
+	{ NOINSTR }, /* 28 */
+	{ NOINSTR }, /* 29 */
+	{ NOINSTR }, /* 2A */
+	{ NOINSTR }, /* 2B */
+	{ NOINSTR }, /* 2C */
+	{ NOINSTR }, /* 2D */
+	{ NOINSTR }, /* 2E */
+	{ NOINSTR }, /* 2F */
+	{ NOINSTR }, /* 30 */
+	{ NOINSTR }, /* 31 */
+	{ NOINSTR }, /* 32 */
+	{ NOINSTR }, /* 33 */
+	{ NOINSTR }, /* 34 */
+	{ NOINSTR }, /* 35 */
+	{ NOINSTR }, /* 36 */
+	{ NOINSTR }, /* 37 */
+	{ NOINSTR }, /* 38 */
+	{ NOINSTR }, /* 39 */
+	{ NOINSTR }, /* 3A */
+	{ NOINSTR }, /* 3B */
+	{ NOINSTR }, /* 3C */
+	{ NOINSTR }, /* 3D */
+	{ NOINSTR }, /* 3E */
+	{ NOINSTR }, /* 3F */
+	{ NOINSTR }, /* 40 */
+	{ NOINSTR }, /* 41 */
+	{ NOINSTR }, /* 42 */
+	{ NOINSTR }, /* 43 */
+	{ NOINSTR }, /* 44 */
+	{ NOINSTR }, /* 45 */
+	{ NOINSTR }, /* 46 */
+	{ NOINSTR }, /* 47 */
+	{ NOINSTR }, /* 48 */
+	{ NOINSTR }, /* 49 */
+	{ NOINSTR }, /* 4A */
+	{ NOINSTR }, /* 4B */
+	{ NOINSTR }, /* 4C */
+	{ NOINSTR }, /* 4D */
+	{ NOINSTR }, /* 4E */
+	{ NOINSTR }, /* 4F */
+	{ NOINSTR }, /* 50 */
+	{ NOINSTR }, /* 51 */
+	{ NOINSTR }, /* 52 */
+	{ NOINSTR }, /* 53 */
+	{ NOINSTR }, /* 54 */
+	{ NOINSTR }, /* 55 */
+	{ NOINSTR }, /* 56 */
+	{ NOINSTR }, /* 57 */
+	{ NOINSTR }, /* 58 */
+	{ NOINSTR }, /* 59 */
+	{ NOINSTR }, /* 5A */
+	{ NOINSTR }, /* 5B */
+	{ NOINSTR }, /* 5C */
+	{ NOINSTR }, /* 5D */
+	{ NOINSTR }, /* 5E */
+	{ NOINSTR }, /* 5F */
+	{ NOINSTR }, /* 60 */
+	{ NOINSTR }, /* 61 */
+	{ NOINSTR }, /* 62 */
+	{ NOINSTR }, /* 63 */
+	{ NOINSTR }, /* 64 */
+	{ NOINSTR }, /* 65 */
+	{ NOINSTR }, /* 66 */
+	{ NOINSTR }, /* 67 */
+	{ NOINSTR }, /* 68 */
+	{ NOINSTR }, /* 69 */
+	{ NOINSTR }, /* 6A */
+	{ NOINSTR }, /* 6B */
+	{ NOINSTR }, /* 6C */
+	{ NOINSTR }, /* 6D */
+	{ NOINSTR }, /* 6E */
+	{ NOINSTR }, /* 6F */
+	{ NOINSTR }, /* 70 */
+	{ NOINSTR }, /* 71 */
+	{ NOINSTR }, /* 72 */
+	{ NOINSTR }, /* 73 */
+	{ NOINSTR }, /* 74 */
+	{ NOINSTR }, /* 75 */
+	{ NOINSTR }, /* 76 */
+	{ NOINSTR }, /* 77 */
+	{ NOINSTR }, /* 78 */
+	{ NOINSTR }, /* 79 */
+	{ NOINSTR }, /* 7A */
+	{ NOINSTR }, /* 7B */
+	{ NOINSTR }, /* 7C */
+	{ NOINSTR }, /* 7D */
+	{ NOINSTR }, /* 7E */
+	{ NOINSTR }, /* 7F */
+	{ NOINSTR }, /* 80 */
+	{ NOINSTR }, /* 81 */
+	{ NOINSTR }, /* 82 */
+	{ NOINSTR }, /* 83 */
+	{ NOINSTR }, /* 84 */
+	{ NOINSTR }, /* 85 */
+	{ NOINSTR }, /* 86 */
+	{ NOINSTR }, /* 87 */
+	{ NOINSTR }, /* 88 */
+	{ NOINSTR }, /* 89 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfnacc", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 8A */
+	{ NOINSTR }, /* 8B */
+	{ NOINSTR }, /* 8C */
+	{ NOINSTR }, /* 8D */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfpnacc", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 8E */
+	{ NOINSTR }, /* 8F */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_CMP, "pfcmpge", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 90 */
+	{ NOINSTR }, /* 91 */
+	{ NOINSTR }, /* 92 */
+	{ NOINSTR }, /* 93 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfmin", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 94 */
+	{ NOINSTR }, /* 95 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfrcp", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 96 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfrsqrt", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 97 */
+	{ NOINSTR }, /* 98 */
+	{ NOINSTR }, /* 99 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_SUB, "pfsub", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 9A */
+	{ NOINSTR }, /* 9B */
+	{ NOINSTR }, /* 9C */
+	{ NOINSTR }, /* 9D */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_ADD, "pfadd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* 9E */
+	{ NOINSTR }, /* 9F */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_CMP, "pfcmpgt", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* A0 */
+	{ NOINSTR }, /* A1 */
+	{ NOINSTR }, /* A2 */
+	{ NOINSTR }, /* A3 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfmax", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* A4 */
+	{ NOINSTR }, /* A5 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfrcpit1", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* A6 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfrsqit1", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* A7 */
+	{ NOINSTR }, /* A8 */
+	{ NOINSTR }, /* A9 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_SUB, "pfsubr", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* AA */
+	{ NOINSTR }, /* AB */
+	{ NOINSTR }, /* AC */
+	{ NOINSTR }, /* AD */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfacc", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* AE */
+	{ NOINSTR }, /* AF */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_CMP, "pfcmpeq", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* B0 */
+	{ NOINSTR }, /* B1 */
+	{ NOINSTR }, /* B2 */
+	{ NOINSTR }, /* B3 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_MUL, "pfmul", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* B4 */
+	{ NOINSTR }, /* B5 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pfrcpit2", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* B6 */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_MUL, "pmulhrw", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* B7 */
+	{ NOINSTR },		 /* B8 */
+	{ NOINSTR }, /* B9 */
+	{ NOINSTR }, /* BA */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW_XCHG, "pswapd", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* BB */
+	{ NOINSTR }, /* BC */
+	{ NOINSTR }, /* BD */
+	{ NOINSTR }, /* BE */
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_3DNOW, "pavgb", { AMODE_P | OPTYPE_q | OP_DST, AMODE_Q | OPTYPE_q | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, /* BF */
+	{ NOINSTR }, /* C0 */
+	{ NOINSTR }, /* C1 */
+	{ NOINSTR }, /* C2 */
+	{ NOINSTR }, /* C3 */
+	{ NOINSTR }, /* C4 */
+	{ NOINSTR }, /* C5 */
+	{ NOINSTR }, /* C6 */
+	{ NOINSTR }, /* C7 */
+	{ NOINSTR }, /* C8 */
+	{ NOINSTR }, /* C9 */
+	{ NOINSTR }, /* CA */
+	{ NOINSTR }, /* CB */
+	{ NOINSTR }, /* CC */
+	{ NOINSTR }, /* CD */
+	{ NOINSTR }, /* CE */
+	{ NOINSTR }, /* CF */
+	{ NOINSTR }, /* D0 */
+	{ NOINSTR }, /* D1 */
+	{ NOINSTR }, /* D2 */
+	{ NOINSTR }, /* D3 */
+	{ NOINSTR }, /* D4 */
+	{ NOINSTR }, /* D5 */
+	{ NOINSTR }, /* D6 */
+	{ NOINSTR }, /* D7 */
+	{ NOINSTR }, /* D8 */
+	{ NOINSTR }, /* D9 */
+	{ NOINSTR }, /* DA */
+	{ NOINSTR }, /* DB */
+	{ NOINSTR }, /* DC */
+	{ NOINSTR }, /* DD */
+	{ NOINSTR }, /* DE */
+	{ NOINSTR }, /* DF */
+	{ NOINSTR }, /* E0 */
+	{ NOINSTR }, /* E1 */
+	{ NOINSTR }, /* E2 */
+	{ NOINSTR }, /* E3 */
+	{ NOINSTR }, /* E4 */
+	{ NOINSTR }, /* E5 */
+	{ NOINSTR }, /* E6 */
+	{ NOINSTR }, /* E7 */
+	{ NOINSTR }, /* E8 */
+	{ NOINSTR }, /* E9 */
+	{ NOINSTR }, /* EA */
+	{ NOINSTR }, /* EB */
+	{ NOINSTR }, /* EC */
+	{ NOINSTR }, /* ED */
+	{ NOINSTR }, /* EE */
+	{ NOINSTR }, /* EF */
+	{ NOINSTR }, /* F0 */
+	{ NOINSTR }, /* F1 */
+	{ NOINSTR }, /* F2 */
+	{ NOINSTR }, /* F3 */
+	{ NOINSTR }, /* F4 */
+	{ NOINSTR }, /* F5 */
+	{ NOINSTR }, /* F6 */
+	{ NOINSTR }, /* F7 */
+	{ NOINSTR }, /* F8 */
+	{ NOINSTR }, /* F9 */
+	{ NOINSTR }, /* FA */
+	{ NOINSTR }, /* FB */
+	{ NOINSTR }, /* FC */
+	{ NOINSTR }, /* FD */
+	{ NOINSTR }, /* FE */
+	{ NOINSTR }	/* FF */
+};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// 64-bit replacement opcodes
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+X86_OPCODE X86_Opcode_63[2] =
+{
+	{ NOGROUP, CPU_I386, ITYPE_SYSTEM, "arpl", { AMODE_E | OPTYPE_w | OP_SRC, AMODE_G | OPTYPE_w | OP_SRC, 0 }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, // !ARCH_AMD64
+	{ NOGROUP, CPU_AMD64, ITYPE_MOV, "movsxd", { AMODE_G | OPTYPE_v | OP_SIGNED | OP_DST, AMODE_E | OPTYPE_d | OP_SIGNED | OP_SRC, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED } // ARCH_AMD64
+};
+
+X86_OPCODE X86_Opcode_0F05[2] =
+{
+	{ NOGROUP, CPU_AMD_K6_2, ITYPE_SYSCALL, "syscall", { OPTYPE_STAR_MSR | OP_MSR | OP_SRC, OPTYPE_CSTAR_MSR | OP_MSR | OP_SRC, OPTYPE_FMASK_MSR | OP_MSR | OP_SRC }, NOCOND, FLAG_ZF_MOD, NOACTION, IGNORED }, // !ARCH_AMD64
+	{ NOGROUP, CPU_AMD64, ITYPE_SYSCALL, "syscall", { OPTYPE_STAR_MSR | OP_MSR | OP_SRC, OPTYPE_LSTAR_MSR | OP_MSR | OP_SRC, OPTYPE_FMASK_MSR | OP_MSR | OP_SRC }, NOCOND, NOCHANGE, NOACTION, IGNORED } // ARCH_AMD64
+};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// Other 3 byte opcodes
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+// Three byte opcodes where the third opcode byte is ModRM
+X86_OPCODE X86_0F01_ModRM[0x100] = 
+{
+	/* 0x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 1x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 2x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 3x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 4x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 5x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 6x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 7x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 8x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* 9x */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* Ax */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* Bx */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* Cx */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { NOGROUP, CPU_PRESCOTT, ITYPE_SYSTEM, "monitor", NOARGS, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+  { NOGROUP, CPU_PRESCOTT, ITYPE_SYSTEM, "mwait", NOARGS, NOCOND, NOCHANGE, SERIALIZE_ALL, IGNORED }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* Dx */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* Ex */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { X86_Group_7, GROUP }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }, // xF
+
+	/* Fx */
+  { X86_Group_7, GROUP }, // x0
+  { X86_Group_7, GROUP }, // x1
+  { X86_Group_7, GROUP }, // x2
+  { X86_Group_7, GROUP }, // x3
+  { X86_Group_7, GROUP }, // x4
+  { X86_Group_7, GROUP }, // x5
+  { X86_Group_7, GROUP }, // x6
+  { X86_Group_7, GROUP }, // x7
+  { NOGROUP, CPU_AMD64, ITYPE_SYSTEM, "swapgs", { OPTYPE_KERNELBASE_MSR | OP_MSR | OP_SRC, 0, 0 }, NOCOND, NOCHANGE, NOACTION, IGNORED }, // x8
+  { X86_Group_7, GROUP }, // x9
+  { X86_Group_7, GROUP }, // xA
+  { X86_Group_7, GROUP }, // xB
+  { X86_Group_7, GROUP }, // xC
+  { X86_Group_7, GROUP }, // xD
+  { X86_Group_7, GROUP }, // xE
+  { X86_Group_7, GROUP }  // xF
+};
+
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+// Sanity checking tables
+/////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////
+
+#define S2 1 // SSE2
+#define S3 2 // SSE3
+BYTE X86_ModRM_1[0x100] =
+{
+  //      x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
+  /* 0x */ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
+  /* 1x */ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
+  /* 2x */ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
+  /* 3x */ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 
+  /* 4x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* 5x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* 6x */ 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 
+  /* 7x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* 8x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* 9x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* Ax */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* Bx */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* Cx */ 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* Dx */ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* Ex */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* Fx */ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1
+};
+BYTE X86_ModRM_2[0x100] =
+{
+  //      x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF
+  /* 0x */ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 
+  /* 1x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
+  /* 2x */ 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* 3x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* 4x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* 6x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* 7x */ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
+  /* 8x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* 9x */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* Ax */ 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 
+  /* Bx */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 
+  /* Cx */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
+  /* Dx */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* Ex */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
+  /* Fx */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0
+};
+
+BYTE X86_SSE_2[0x100] = 
+{
+  /*      x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF        */
+  /* 0x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 1x */ 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 2x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0,
+  /* 3x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 4x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 5x */ 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+  /* 6x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1,
+  /* 7x */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
+  /* 8x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* 9x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* Ax */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* Bx */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* Cx */ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* Dx */ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* Ex */ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  /* Fx */ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+// Indicates if a LOCK prefix is allowed
+// The following are allowed:
+// add, adc, and, btc, btr, bts, cmpxchg, cmpxchg8, dec, inc, 
+// neg, not, or, sbb, sub, xor, xadd, xchg
+#define GR 2
+BYTE X86_LockPrefix_1[0x100] =
+{
+  //       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF
+  /* 0x */  1,  1,  1,  1,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0, 
+  /* 1x */  1,  1,  1,  1,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0, 
+  /* 2x */  1,  1,  1,  1,  0,  0,  0,  0,  1,  1,  1,  1,  0,  0,  0,  0, 
+  /* 3x */  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 8x */ GR, GR, GR, GR,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Cx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Dx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Fx */  0,  0,  0,  0,  0,  0, GR, GR,  0,  0,  0,  0,  0,  0, GR, GR
+};
+
+BYTE X86_LockPrefix_2[0x100] =
+{
+  //       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF
+  /* 0x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 1x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 2x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 3x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 8x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0, 
+  /* Bx */  1,  1,  0,  1,  0,  0,  0,  0,  0,  0, GR,  1,  0,  0,  0,  0, 
+  /* Cx */  1,  1,  0,  0,  0,  0,  0, GR,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Dx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 
+  /* Fx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
+};
+
+BYTE X86_LockPrefix_Groups[17][8] =
+{
+//  x0  x1  x2  x3  x4  x5  x6  x7
+	{  1,  1,  1,  1,  1,  1,  1,  0 }, // group 1
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 2
+	{  0,  0,  1,  1,  0,  0,  0,  0 }, // group 3
+	{  1,  1,  0,  0,  0,  0,  0,  0 }, // group 4
+	{  1,  1,  0,  0,  0,  0,  0,  0 }, // group 5
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 6
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 7
+	{  0,  0,  0,  0,  1,  1,  1,  1 }, // group 8
+	{  0,  1,  0,  0,  0,  0,  0,  0 }, // group 9
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 10
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 11
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 12
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 13
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 14
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 15
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 16
+	{  0,  0,  0,  0,  0,  0,  0,  0 }, // group 17
+};
+
+#define X86_MAX_GROUP 19
+BYTE X86_Groups_1[0x100] = // one-byte opcodes
+{
+	/*       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF */
+	/* 0x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0x */
+	/* 1x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1x */
+	/* 2x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 2x */
+	/* 3x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 3x */
+	/* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 4x */
+	/* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 5x */
+	/* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 6x */
+	/* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 7x */
+	/* 8x */  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, /* 8x */
+	/* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 9x */
+	/* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ax */
+	/* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Bx */
+	/* Cx */  2,  2,  0,  0,  0,  0, 12, 12,  0,  0,  0,  0,  0,  0,  0,  0, /* Cx */
+	/* Dx */  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Dx */
+	/* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ex */
+	/* Fx */  0,  0,  0,  0,  0,  0,  3,  3,  0,  0,  0,  0,  0,  0,  4,  5  /* Fx */
+};
+
+// 19 = Group P
+// 20 = 3DNow
+BYTE X86_Groups_2[0x100] = // two-byte opcodes
+{
+	/*       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF */
+	/* 0x */  6,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 18,  0, 19, /* 0x */
+	/* 1x */  0,  0,  0,  0,  0,  0,  0,  0, 17,  0,  0,  0,  0,  0,  0,  0, /* 1x */
+	/* 2x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 2x */
+	/* 3x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 3x */
+	/* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 4x */
+	/* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 5x */
+	/* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 6x */
+	/* 7x */  0, 13, 14, 15,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 7x */
+	/* 8x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 8x */
+	/* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 9x */
+	/* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 16,  0, /* Ax */
+	/* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0, 11,  8,  0,  0,  0,  0,  0, /* Bx */
+	/* Cx */  0,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0, /* Cx */
+	/* Dx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Dx */
+	/* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ex */
+	/* Fx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0  /* Fx */
+};
+
+// Indicate which 1-byte opcodes are invalid with a 16-bit operand size
+BYTE X86_Invalid_Op16_1[0x100] = 
+{
+	/*       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF */
+	/* 0x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0x */
+	/* 1x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1x */
+	/* 2x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 2x */
+	/* 3x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 3x */
+	/* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 4x */
+	/* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 5x */
+	/* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 6x */
+	/* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 7x */
+	/* 8x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 8x */
+	/* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 9x */
+	/* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ax */
+	/* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Bx */
+	/* Cx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Cx */
+	/* Dx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Dx */
+	/* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ex */
+	/* Fx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0  /* Fx */
+};
+
+// Indicate which 2-byte opcodes are invalid with a 16-bit operand size
+BYTE X86_Invalid_Op16_2[0x100] =
+{
+	/*       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF */
+	/* 0x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0x */
+	/* 1x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1x */
+	/* 2x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 2x */
+	/* 3x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 3x */
+	/* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 4x */
+	/* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 5x */
+	/* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 6x */
+	/* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 7x */
+	/* 8x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 8x */
+	/* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 9x */
+	/* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ax */
+	/* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Bx */
+	/* Cx */  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1, /* Cx */
+	/* Dx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Dx */
+	/* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ex */
+	/* Fx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0  /* Fx */
+};
+
+// Indicate which 1-byte opcodes are invalid with a 64-bit address size
+BYTE X86_Invalid_Addr64_1[0x100] =
+{
+	/*       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF */
+	/* 0x */  0,  0,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  1,  0, /* 0x */
+	/* 1x */  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1,  0, /* 1x */
+	/* 2x */  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1, /* 2x */
+	/* 3x */  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  1, /* 3x */
+	/* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 4x */
+	/* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 5x */
+	/* 6x */  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 6x */
+	/* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 7x */
+	/* 8x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 8x */
+	/* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0, /* 9x */
+	/* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ax */
+	/* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Bx */
+	/* Cx */  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0, /* Cx */
+	/* Dx */  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Dx */
+	/* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0, /* Ex */
+	/* Fx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0  /* Fx */
+};
+
+// Indicate which 2-byte opcodes are invalid with a 64-bit address size
+BYTE X86_Invalid_Addr64_2[0x100] =
+{
+	/*       x0  x1  x2  x3  x4  x5  x6  x7  x8  x9  xA  xB  xC  xD  xE  xF */
+	/* 0x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0x */
+	/* 1x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1x */
+	/* 2x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 2x */
+	/* 3x */  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 3x */
+	/* 4x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 4x */
+	/* 5x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 5x */
+	/* 6x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 6x */
+	/* 7x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 7x */
+	/* 8x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 8x */
+	/* 9x */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 9x */
+	/* Ax */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ax */
+	/* Bx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Bx */
+	/* Cx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Cx */
+	/* Dx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Dx */
+	/* Ex */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* Ex */
+	/* Fx */  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0  /* Fx */
+};
+
+#endif // DISASM_X86_TABLES
\ No newline at end of file
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/misc.c b/tools/glave/src/thirdparty/mhook/disasm-lib/misc.c
new file mode 100644
index 0000000..c5b0ac6
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/misc.c
@@ -0,0 +1,185 @@
+// Copyright (C) 2002, Matt Conover (mconover@gmail.com)
+#include "misc.h"
+
+BOOL IsHexChar(BYTE ch)
+{
+	switch (ch)
+	{
+		case '0': case '1': case '2': case '3': 
+		case '4': case '5': case '6': case '7': 
+		case '8': case '9': 
+		case 'A': case 'a': case 'B': case 'b':
+		case 'C': case 'c': case 'D': case 'd':
+		case 'E': case 'e': case 'F': case 'f':
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
+// NOTE: caller must free the buffer returned
+BYTE *HexToBinary(char *Input, DWORD InputLength, DWORD *OutputLength)
+{
+	DWORD i, j, ByteCount = 0;
+	char temp_byte[3];
+	BYTE *p, *ByteString = NULL;
+
+	if (!InputLength || !OutputLength) return NULL;
+	else *OutputLength = 0;
+
+	while (*Input && isspace(*Input)) { Input++; InputLength--; }
+	if (!*Input) return NULL;
+	if (Input[0] == '\"') { Input++; InputLength--; }
+	p = (BYTE *)strchr(Input, '\"');
+	if (p) InputLength--;
+
+	if (InputLength > 2 && Input[2] == ' ') // assume spaces
+	{
+		for (i = 0; i < InputLength; i += 3)
+		{
+			while (i < InputLength && isspace(Input[i])) i++; // skip over extra space, \r, and \n
+			if (i >= InputLength) break;
+
+			if (!IsHexChar(Input[i]))
+			{
+				//fprintf(stderr, "ERROR: invalid hex character at offset %lu (0x%04x)\n", i, i);
+				goto abort;
+			}
+
+			if (i+1 >= InputLength || !Input[i+1])
+			{
+				//fprintf(stderr, "ERROR: hex string terminates unexpectedly at offset %lu (0x%04x)\n", i+1, i+1);
+				goto abort;
+			}
+
+			if (i+2 < InputLength && Input[i+2] && !isspace(Input[i+2]))
+			{
+				//fprintf(stderr, "ERROR: Hex string is malformed at offset %lu (0x%04x)\n", i, i);
+				//fprintf(stderr, "Found '%c' (0x%02x) instead of space\n", Input[i+2], Input[i+2]);
+				goto abort;
+			}
+
+			ByteCount++;
+		}
+
+		if (!ByteCount)
+		{
+			//fprintf(stderr, "Error: no input (byte count = 0)\n");
+			goto abort;
+		}
+
+		ByteString = malloc(ByteCount+1);
+		if (!ByteString)
+		{
+			//fprintf(stderr, "ERROR: failed to allocate %lu bytes\n", ByteCount);
+			goto abort;
+		}
+			
+		memset(ByteString, 0, ByteCount+1);
+		for (i = 0, j = 0; j < ByteCount; i += 3, j++)
+		{			
+			while (isspace(Input[i])) i++; // skip over extra space, \r, and \n
+			temp_byte[0] = Input[i];
+			temp_byte[1] = Input[i+1];
+			temp_byte[2] = 0;
+			ByteString[j] = (BYTE)strtoul(temp_byte, NULL, 16);
+		}
+	}
+	else if (InputLength > 2 && Input[0] == '\\')
+	{
+		for (i = 0; i < InputLength; i += 2)
+		{
+			if (Input[i] != '\\' || (Input[i+1] != 'x' && Input[i+1] != '0'))
+			{
+				//fprintf(stderr, "ERROR: invalid hex character at offset %lu (0x%04x)\n", i, i);
+				goto abort;
+			}
+			i += 2;
+
+			if (!IsHexChar(Input[i]))
+			{
+				//fprintf(stderr, "ERROR: invalid hex character at offset %lu (0x%04x)\n", i, i);
+				goto abort;
+			}
+			if (i+1 >= InputLength || !Input[i+1])
+			{
+				//fprintf(stderr, "ERROR: hex string terminates unexpectedly at offset %lu (0x%04x)\n", i+1, i+1);
+				goto abort;
+			}
+
+			ByteCount++;
+		}
+
+		if (!ByteCount)
+		{
+			//fprintf(stderr, "Error: no input (byte count = 0)\n");
+			goto abort;
+		}
+
+		ByteString = malloc(ByteCount+1);
+		if (!ByteString)
+		{
+			//fprintf(stderr, "ERROR: failed to allocate %lu bytes\n", ByteCount);
+			goto abort;
+		}
+			
+		memset(ByteString, 0, ByteCount+1);
+		for (i = j = 0; j < ByteCount; i += 2, j++)
+		{
+			i += 2;
+			temp_byte[0] = Input[i];
+			temp_byte[1] = Input[i+1];
+			temp_byte[2] = 0;
+			ByteString[j] = (BYTE)strtoul(temp_byte, NULL, 16);
+		}
+	}
+	else // assume it is a hex string with no spaces with 2 bytes per character
+	{
+		for (i = 0; i < InputLength; i += 2)
+		{
+				if (!IsHexChar(Input[i]))
+			{
+				//fprintf(stderr, "ERROR: invalid hex character at offset %lu (0x%04x)\n", i, i);
+				goto abort;
+			}
+			if (i+1 >= InputLength || !Input[i+1])
+			{
+				//fprintf(stderr, "ERROR: hex string terminates unexpectedly at offset %lu (0x%04x)\n", i+1, i+1);
+				goto abort;
+			}
+
+			ByteCount++;
+		}
+
+		if (!ByteCount)
+		{
+			//fprintf(stderr, "Error: no input (byte count = 0)\n");
+			goto abort;
+		}
+
+		ByteString = malloc(ByteCount+1);
+		if (!ByteString)
+		{
+			//fprintf(stderr, "ERROR: failed to allocate %lu bytes\n", ByteCount);
+			goto abort;
+		}
+			
+		memset(ByteString, 0, ByteCount+1);
+		for (i = 0, j = 0; j < ByteCount; i += 2, j++)
+		{
+			temp_byte[0] = Input[i];
+			temp_byte[1] = Input[i+1];
+			temp_byte[2] = 0;
+			ByteString[j] = (BYTE)strtoul(temp_byte, NULL, 16);
+		}
+	}
+
+	*OutputLength = ByteCount;
+	return ByteString;
+
+abort:
+	if (OutputLength) *OutputLength = 0;
+	if (ByteString) free(ByteString);
+	return NULL;
+}
+
diff --git a/tools/glave/src/thirdparty/mhook/disasm-lib/misc.h b/tools/glave/src/thirdparty/mhook/disasm-lib/misc.h
new file mode 100644
index 0000000..9c6783b
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/disasm-lib/misc.h
@@ -0,0 +1,56 @@
+// Copyright (C) 2002, Matt Conover (mconover@gmail.com)
+#ifndef MISC_H
+#define MISC_H
+#include "wintypes.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#ifdef __linux__
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#endif
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+// NOTE: start is inclusive, end is exclusive (as in start <= x < end)
+#define IS_IN_RANGE(x, s, e) \
+( \
+	((ULONG_PTR)(x) == (ULONG_PTR)(s) && (ULONG_PTR)(x) == (ULONG_PTR)(e)) || \
+	((ULONG_PTR)(x) >= (ULONG_PTR)(s) && (ULONG_PTR)(x) < (ULONG_PTR)(e)) \
+)
+
+#if _MSC_VER >= 1400
+#pragma warning(disable:4996)
+#endif
+
+#if defined(_WIN64)
+	#define VALID_ADDRESS_MAX 0x7FFEFFFFFFFFFFFF // Win64 specific
+	typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
+#else
+	#define VALID_ADDRESS_MAX 0x7FFEFFFF // Win32 specific
+	typedef unsigned long ULONG_PTR, *PULONG_PTR;
+#endif
+
+#ifndef DECLSPEC_ALIGN
+	#if (_MSC_VER >= 1300) && !defined(MIDL_PASS)
+		#define DECLSPEC_ALIGN(x) __declspec(align(x))
+	#else
+		#define DECLSPEC_ALIGN(x)
+	#endif
+#endif
+
+#define VALID_ADDRESS_MIN 0x10000    // Win32 specific
+#define IS_VALID_ADDRESS(a) IS_IN_RANGE(a, VALID_ADDRESS_MIN, VALID_ADDRESS_MAX+1)
+
+BOOL IsHexChar(BYTE ch);
+BYTE *HexToBinary(char *Input, DWORD InputLength, DWORD *OutputLength);
+
+#ifdef __cplusplus
+}
+#endif
+#endif // MISC_H
diff --git a/tools/glave/src/thirdparty/mhook/mhook-lib/CMakeLists.txt b/tools/glave/src/thirdparty/mhook/mhook-lib/CMakeLists.txt
new file mode 100644
index 0000000..bb84735
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/mhook-lib/CMakeLists.txt
@@ -0,0 +1,31 @@
+project(mhook)
+cmake_minimum_required(VERSION 2.8)
+
+include("${SRC_DIR}/build_options.cmake")
+
+include_directories(
+    ${SRC_DIR}/thirdparty/mhook/mhook-lib
+    ${SRC_DIR}/thirdparty/mhook/disasm-lib
+    ${SRC_DIR}/glvcommon
+)
+
+set(SRC_LIST
+    mhook.c
+    mhook.h
+)
+
+set_source_files_properties( ${SRC_LIST} PROPERTIES LANGUAGE C)
+
+if (NOT MSVC)
+    add_compiler_flag("-fPIC")
+endif()
+
+
+add_library(${PROJECT_NAME} STATIC ${SRC_LIST})
+target_link_libraries(${PROJECT_NAME} 
+    disasm
+)
+
+build_options_finalize()
+
+set_target_properties(mhook PROPERTIES LINKER_LANGUAGE C)
diff --git a/tools/glave/src/thirdparty/mhook/mhook-lib/mhook.c b/tools/glave/src/thirdparty/mhook/mhook-lib/mhook.c
new file mode 100644
index 0000000..0d96d82
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/mhook-lib/mhook.c
@@ -0,0 +1,1076 @@
+//Copyright (c) 2007-2008, Marton Anka
+//
+//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 <wintypes.h>
+#if defined(WIN32)
+#include <tlhelp32.h>
+#elif defined(__linux__)
+#include <pthread.h>
+#include <wchar.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#define PAGE_EXECUTE_READWRITE (PROT_READ | PROT_EXEC | PROT_WRITE)
+#else
+#error unsupported platform
+#endif
+
+#include <stdio.h>
+#include "mhook.h"
+#include "../disasm-lib/disasm.h"
+
+//=========================================================================
+#ifndef cntof
+#define cntof(a) (sizeof(a)/sizeof(a[0]))
+#endif
+
+//=========================================================================
+#ifndef GOOD_HANDLE
+#define GOOD_HANDLE(a) ((a!=INVALID_HANDLE_VALUE)&&(a!=NULL))
+#endif
+
+//=========================================================================
+unsigned int gle()
+{
+#if defined(WIN32)
+    return GetLastError();
+#else
+    return errno;
+#endif
+}
+
+//=========================================================================
+#ifndef ODPRINTF
+
+#ifdef _DEBUG
+#define ODPRINTF(a) odprintf a
+#else
+#define ODPRINTF(a)
+#endif
+
+#ifdef __linux__
+inline void odprintf(PCSTR format, ...) {
+	va_list	args;
+	va_start(args, format);
+	vprintf(format, args);
+        printf("\n");
+	va_end(args);
+}
+
+#else
+void __cdecl odprintf(char* format, ...) {
+	va_list	args;
+	int len;
+	PSTR buf;
+	va_start(args, format);
+	len = _vscprintf(format, args);
+	if (len > 0) {
+		len += (1 + 2);
+		buf = (PSTR) malloc(len);
+		if (buf) {
+			len = vsprintf_s(buf, len, format, args);
+			if (len > 0) {
+				while (len && isspace(buf[len-1])) len--;
+				buf[len++] = '\r';
+				buf[len++] = '\n';
+				buf[len] = 0;
+				OutputDebugString(buf);
+			}
+			free(buf);
+		}
+		va_end(args);
+	}
+}
+#endif
+#endif //#ifndef ODPRINTF
+
+//=========================================================================
+#define MHOOKS_MAX_CODE_BYTES	32
+#define MHOOKS_MAX_RIPS			 4
+
+//=========================================================================
+// The trampoline structure - stores every bit of info about a hook
+struct MHOOKS_TRAMPOLINE;
+typedef struct MHOOKS_TRAMPOLINE MHOOKS_TRAMPOLINE;
+struct MHOOKS_TRAMPOLINE {
+	PBYTE	pSystemFunction;								// the original system function
+	DWORD	cbOverwrittenCode;								// number of bytes overwritten by the jump
+	PBYTE	pHookFunction;									// the hook function that we provide
+	BYTE	codeJumpToHookFunction[MHOOKS_MAX_CODE_BYTES];	// placeholder for code that jumps to the hook function
+	BYTE	codeTrampoline[MHOOKS_MAX_CODE_BYTES];			// placeholder for code that holds the first few
+															//   bytes from the system function and a jump to the remainder
+															//   in the original location
+	BYTE	codeUntouched[MHOOKS_MAX_CODE_BYTES];			// placeholder for unmodified original code
+															//   (we patch IP-relative addressing)
+	MHOOKS_TRAMPOLINE* pPrevTrampoline;						// When in the free list, thess are pointers to the prev and next entry.
+	MHOOKS_TRAMPOLINE* pNextTrampoline;						// When not in the free list, this is a pointer to the prev and next trampoline in use.
+};
+
+//=========================================================================
+// The patch data structures - store info about rip-relative instructions
+// during hook placement
+struct MHOOKS_RIPINFO;
+typedef struct MHOOKS_RIPINFO MHOOKS_RIPINFO;
+struct MHOOKS_RIPINFO
+{
+	DWORD	dwOffset;
+	S64		nDisplacement;
+};
+
+struct MHOOKS_PATCHDATA;
+typedef struct MHOOKS_PATCHDATA MHOOKS_PATCHDATA;
+struct MHOOKS_PATCHDATA
+{
+	S64				nLimitUp;
+	S64				nLimitDown;
+	DWORD			nRipCnt;
+	MHOOKS_RIPINFO	rips[MHOOKS_MAX_RIPS];
+};
+
+//=========================================================================
+// Global vars
+static BOOL g_bVarsInitialized = FALSE;
+#if defined(__linux__)
+static pthread_mutex_t g_cs;
+static void* g_hThreadHandles = NULL;
+#elif defined(WIN32)
+static CRITICAL_SECTION g_cs;
+static HANDLE* g_hThreadHandles = NULL;
+#endif
+static MHOOKS_TRAMPOLINE* g_pHooks = NULL;
+static MHOOKS_TRAMPOLINE* g_pFreeList = NULL;
+static DWORD g_nHooksInUse = 0;
+static DWORD g_nThreadHandles = 0;
+static BOOL g_bSuspendThreads = TRUE;
+static BOOL g_bMustGrabCritSec = TRUE;
+
+#define MHOOK_JMPSIZE 5
+#define MHOOK_MINALLOCSIZE 4096
+
+#ifdef WIN32
+//=========================================================================
+// Toolhelp defintions so the functions can be dynamically bound to
+typedef HANDLE (WINAPI * _CreateToolhelp32Snapshot)(
+	DWORD dwFlags,	   
+	DWORD th32ProcessID  
+	);
+
+typedef BOOL (WINAPI * _Thread32First)(
+									   HANDLE hSnapshot,	 
+									   LPTHREADENTRY32 lpte
+									   );
+
+typedef BOOL (WINAPI * _Thread32Next)(
+									  HANDLE hSnapshot,	 
+									  LPTHREADENTRY32 lpte
+									  );
+
+//=========================================================================
+// Bring in the toolhelp functions from kernel32
+_CreateToolhelp32Snapshot fnCreateToolhelp32Snapshot = NULL;//(_CreateToolhelp32Snapshot) GetProcAddress(GetModuleHandle("kernel32"), "CreateToolhelp32Snapshot");
+_Thread32First fnThread32First = NULL;//(_Thread32First) GetProcAddress(GetModuleHandle("kernel32"), "Thread32First");
+_Thread32Next fnThread32Next = NULL;//(_Thread32Next) GetProcAddress(GetModuleHandle("kernel32"), "Thread32Next");
+
+void Mhook_Initialize()
+{
+	fnCreateToolhelp32Snapshot = (_CreateToolhelp32Snapshot) GetProcAddress(GetModuleHandle("kernel32"), "CreateToolhelp32Snapshot");
+	fnThread32First = (_Thread32First) GetProcAddress(GetModuleHandle("kernel32"), "Thread32First");
+	fnThread32Next = (_Thread32Next) GetProcAddress(GetModuleHandle("kernel32"), "Thread32Next");
+}
+#endif
+//=========================================================================
+// Internal function:
+//
+// Remove the trampoline from the specified list, updating the head pointer
+// if necessary.
+//=========================================================================
+static VOID ListRemove(MHOOKS_TRAMPOLINE** pListHead, MHOOKS_TRAMPOLINE* pNode) {
+	if (pNode->pPrevTrampoline) {
+		pNode->pPrevTrampoline->pNextTrampoline = pNode->pNextTrampoline;
+	}
+
+	if (pNode->pNextTrampoline) {
+		pNode->pNextTrampoline->pPrevTrampoline = pNode->pPrevTrampoline;
+	}
+
+	if ((*pListHead) == pNode) {
+		(*pListHead) = pNode->pNextTrampoline;
+		assert((*pListHead)->pPrevTrampoline == NULL);
+	}
+
+	pNode->pPrevTrampoline = NULL;
+	pNode->pNextTrampoline = NULL;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Prepend the trampoline from the specified list and update the head pointer.
+//=========================================================================
+static VOID ListPrepend(MHOOKS_TRAMPOLINE** pListHead, MHOOKS_TRAMPOLINE* pNode) {
+	pNode->pPrevTrampoline = NULL;
+	pNode->pNextTrampoline = (*pListHead);
+	if ((*pListHead)) {
+		(*pListHead)->pPrevTrampoline = pNode;
+	}
+	(*pListHead) = pNode;
+}
+
+//=========================================================================
+static VOID EnterCritSec() {
+	if (!g_bVarsInitialized) {
+#if defined(WIN32)
+		InitializeCriticalSection(&g_cs);
+#elif defined(__linux__)
+		pthread_mutex_init(&g_cs, NULL);
+#endif
+
+		g_bVarsInitialized = TRUE;
+	}
+#if defined(WIN32)
+	EnterCriticalSection(&g_cs);
+#elif defined(__linux__)
+	pthread_mutex_lock(&g_cs );
+#endif
+}
+
+//=========================================================================
+static VOID LeaveCritSec()
+{
+#if defined(WIN32)
+	LeaveCriticalSection(&g_cs);
+#elif defined(__linux__)
+	pthread_mutex_unlock(&g_cs );
+#endif
+}
+
+//=========================================================================
+static size_t GetAllocGranularity()
+{
+	// Always allocate in bulk, in case the system actually has a smaller allocation granularity than MINALLOCSIZE.
+#if defined(WIN32)
+	SYSTEM_INFO sSysInfo =  {0};
+	GetSystemInfo(&sSysInfo);
+
+	return max(sSysInfo.dwAllocationGranularity, MHOOK_MINALLOCSIZE);
+#elif defined(__linux__)
+	// There is no situation where the allocation granularity is higher than the page size of the system
+	// on Linux, so you should be able to safely use PAGE_SIZE
+	return max(getpagesize(), MHOOK_MINALLOCSIZE);
+#endif
+}
+
+//=========================================================================
+//  return of NULL means fatal  error, return of (void *) -1 means couldn't alloc
+//  the size at the requested area)
+static void * MapVirtualMem(const size_t allocSize, void * pbAlloc)
+{
+#if defined(WIN32)
+	// determine current state
+	MEMORY_BASIC_INFORMATION mbi;
+	ODPRINTF(("mhooks: BlockAlloc: Looking at address %p", pbAlloc));
+	if (!VirtualQuery(pbAlloc, &mbi, sizeof(mbi)))
+		return NULL;
+	// free & large enough?
+	if (mbi.State == MEM_FREE && mbi.RegionSize >= (unsigned)allocSize) {
+		// and then try to allocate it
+		return VirtualAlloc(pbAlloc, allocSize, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+	} else {
+		return (void *) -1;
+	}
+#elif defined(__linux__)
+	return mmap(pbAlloc, allocSize, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#endif
+}
+
+//=========================================================================
+// Internal function:
+// 
+// Skip over jumps that lead to the real function. Gets around import
+// jump tables, etc.
+//=========================================================================
+static PBYTE SkipJumps(PBYTE pbCode) {
+#ifdef _M_IX86_X64
+	if (pbCode[0] == 0xff && pbCode[1] == 0x25) {
+#ifdef _M_IX86
+		// on x86 we have an absolute pointer...
+		PBYTE pbTarget = *(PBYTE *)&pbCode[2];
+		// ... that shows us an absolute pointer.
+		return SkipJumps(*(PBYTE *)pbTarget);
+#elif defined _M_IX86_X64
+		// on x64 we have a 32-bit offset...
+		INT32 lOffset = *(INT32 *)&pbCode[2];
+		// ... that shows us an absolute pointer
+		return SkipJumps(*(PBYTE*)(pbCode + 6 + lOffset));
+#endif
+	} else if (pbCode[0] == 0xe9) {
+		// here the behavior is identical, we have...
+		// ...a 32-bit offset to the destination.
+		return SkipJumps(pbCode + 5 + *(INT32 *)&pbCode[1]);
+	} else if (pbCode[0] == 0xeb) {
+		// and finally an 8-bit offset to the destination
+		return SkipJumps(pbCode + 2 + *(CHAR *)&pbCode[1]);
+	}
+#else
+#error unsupported platform
+#endif
+	return pbCode;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Writes code at pbCode that jumps to pbJumpTo. Will attempt to do this
+// in as few bytes as possible. Important on x64 where the long jump
+// (0xff 0x25 ....) can take up 14 bytes.
+//=========================================================================
+static PBYTE EmitJump(PBYTE pbCode, PBYTE pbJumpTo) {
+#ifdef _M_IX86_X64
+	PBYTE pbJumpFrom = pbCode + 5;
+	SIZE_T cbDiff = pbJumpFrom > pbJumpTo ? pbJumpFrom - pbJumpTo : pbJumpTo - pbJumpFrom;
+	ODPRINTF(("mhooks: EmitJump: Jumping from %p to %p, diff is %p", pbJumpFrom, pbJumpTo, cbDiff));
+	if (cbDiff <= 0x7fff0000) {
+		pbCode[0] = 0xe9;
+		pbCode += 1;
+		*((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbJumpTo - pbJumpFrom);
+		pbCode += sizeof(DWORD);
+	} else {
+		pbCode[0] = 0xff;
+		pbCode[1] = 0x25;
+		pbCode += 2;
+#ifdef _M_IX86
+		// on x86 we write an absolute address (just behind the instruction)
+		*((PDWORD)pbCode) = (DWORD)(DWORD_PTR)(pbCode + sizeof(DWORD));
+#elif defined _M_X64
+		// on x64 we write the relative address of the same location
+		*((PDWORD)pbCode) = (DWORD)0;
+#endif
+		pbCode += sizeof(DWORD);
+		*((PDWORD_PTR)pbCode) = (DWORD_PTR)(pbJumpTo);
+		pbCode += sizeof(DWORD_PTR);
+	}
+#else 
+#error unsupported platform
+#endif
+	return pbCode;
+}
+
+
+//=========================================================================
+// Internal function:
+//
+// Round down to the next multiple of rndDown
+//=========================================================================
+static size_t RoundDown(size_t addr, size_t rndDown)
+{
+	return (addr / rndDown) * rndDown;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Will attempt allocate a block of memory within the specified range, as 
+// near as possible to the specified function.
+//=========================================================================
+static MHOOKS_TRAMPOLINE* BlockAlloc(PBYTE pSystemFunction, PBYTE pbLower, PBYTE pbUpper) {
+	ptrdiff_t cAllocSize, bytesToOffset;
+	PBYTE pModuleGuess;
+	PBYTE pbAlloc;
+	MHOOKS_TRAMPOLINE* pRetVal = NULL;
+	int loopCount = 0;
+
+	cAllocSize = GetAllocGranularity();
+
+	pModuleGuess = (PBYTE) RoundDown((size_t)pSystemFunction, cAllocSize);
+
+	for (pbAlloc = pModuleGuess; pbLower < pbAlloc && pbAlloc < pbUpper; ++loopCount) {
+	pRetVal = (MHOOKS_TRAMPOLINE*) MapVirtualMem(cAllocSize, pbAlloc);
+	if(!pRetVal)
+		break;
+	if (pRetVal != (void *) -1) {
+		size_t s;
+		size_t trampolineCount = cAllocSize / sizeof(MHOOKS_TRAMPOLINE);
+		ODPRINTF(("mhooks: BlockAlloc: Allocated block at %p as %d trampolines", pRetVal, trampolineCount));
+
+		pRetVal[0].pPrevTrampoline = NULL;
+		pRetVal[0].pNextTrampoline = &pRetVal[1];
+
+		// prepare them by having them point down the line at the next entry
+		for (s = 1; s < trampolineCount; ++s) {
+			pRetVal[s].pPrevTrampoline = &pRetVal[s - 1];
+			pRetVal[s].pNextTrampoline = &pRetVal[s + 1];
+		}
+
+		// last entry points to the current head of the free list
+		pRetVal[trampolineCount - 1].pNextTrampoline = g_pFreeList;
+		break;
+	    }
+				
+	    // This is a spiral, should be -1, 1, -2, 2, -3, 3, etc. (* cAllocSize)
+	    bytesToOffset = (cAllocSize * (loopCount + 1) * ((loopCount % 2 == 0) ? -1 : 1));
+	    pbAlloc = pbAlloc + bytesToOffset;
+	}
+	
+	return pRetVal;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Will try to allocate a big block of memory inside the required range. 
+//=========================================================================
+static MHOOKS_TRAMPOLINE* FindTrampolineInRange(PBYTE pLower, PBYTE pUpper) {
+
+	// This is a standard free list, except we're doubly linked to deal with soem return shenanigans.
+	MHOOKS_TRAMPOLINE* curEntry = g_pFreeList;
+	if (!g_pFreeList) {
+		return NULL;
+	}
+
+	while (curEntry) {
+		if ((MHOOKS_TRAMPOLINE*) pLower < curEntry && curEntry < (MHOOKS_TRAMPOLINE*) pUpper) {
+			ListRemove(&g_pFreeList, curEntry);
+
+			return curEntry;
+		}
+
+		curEntry = curEntry->pNextTrampoline;
+	}
+
+	return NULL;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Will try to allocate the trampoline structure within 2 gigabytes of
+// the target function. 
+//=========================================================================
+static MHOOKS_TRAMPOLINE* TrampolineAlloc(PBYTE pSystemFunction, S64 nLimitUp, S64 nLimitDown) {
+
+	MHOOKS_TRAMPOLINE* pTrampoline = NULL;
+	PBYTE pUpper;
+	// determine lower and upper bounds for the allocation locations.
+	// in the basic scenario this is +/- 2GB but IP-relative instructions
+	// found in the original code may require a smaller window.
+	PBYTE pLower = pSystemFunction + nLimitUp;
+	pLower = pLower < (PBYTE)(DWORD_PTR)0x0000000080000000 ? 
+						(PBYTE)(0x1) : (PBYTE)(pLower - (PBYTE)0x7fff0000);
+	pUpper = pSystemFunction + nLimitDown;
+	pUpper = pUpper < (PBYTE)(DWORD_PTR)0xffffffff80000000 ? 
+		(PBYTE)(pUpper + 0x7ff80000) : (PBYTE)(DWORD_PTR)0xfffffffffff80000;
+	ODPRINTF(("mhooks: TrampolineAlloc: Allocating for %p between %p and %p", pSystemFunction, pLower, pUpper));
+
+	// try to find a trampoline in the specified range
+	pTrampoline = FindTrampolineInRange(pLower, pUpper);
+	if (!pTrampoline) {
+		// if it we can't find it, then we need to allocate a new block and 
+		// try again. Just fail if that doesn't work 
+		g_pFreeList = BlockAlloc(pSystemFunction, pLower, pUpper);
+		pTrampoline = FindTrampolineInRange(pLower, pUpper);
+	}
+
+	// found and allocated a trampoline?
+	if (pTrampoline) {
+		ListPrepend(&g_pHooks, pTrampoline);
+	}
+
+	return pTrampoline;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Return the internal trampoline structure that belongs to a hooked function.
+//=========================================================================
+static MHOOKS_TRAMPOLINE* TrampolineGet(PBYTE pHookedFunction) {
+	MHOOKS_TRAMPOLINE* pCurrent = g_pHooks;
+
+	while (pCurrent) {
+		if (pCurrent->pHookFunction == pHookedFunction) {
+			return pCurrent;
+		}
+
+		pCurrent = pCurrent->pNextTrampoline;
+	}
+
+	return NULL;
+}
+
+static void * GetCurProcess()
+{
+#ifdef WIN32
+	return (void *) GetCurrentProcess();
+#else
+	return(NULL);
+#endif
+}
+
+static void FlushCache(void * process, void * address, size_t size)
+{
+#if defined(WIN32)
+	FlushInstructionCache(process, address, size);
+#elif defined(__linux__)
+	// TODO do we really need to flush the Instruction cache on x86 on Linux?
+#else
+#error unsupported platform  
+#endif
+}
+
+static BOOL MemProtect(void * process, void * address, size_t size, DWORD newProtect, DWORD *oldProtect)
+{
+#if defined(WIN32)
+	return (VirtualProtectEx(process, address, size, newProtect, oldProtect));
+#elif defined(__linux__)
+	*oldProtect = PROT_READ | PROT_EXEC;
+	if (mprotect(address, size, newProtect))
+		return TRUE;
+	else
+		return FALSE;
+#else
+#error unsupported platform  
+#endif
+}
+//=========================================================================
+// Internal function:
+//
+// Free a trampoline structure.
+//=========================================================================
+static VOID TrampolineFree(MHOOKS_TRAMPOLINE* pTrampoline, BOOL bNeverUsed) {
+	ListRemove(&g_pHooks, pTrampoline);
+
+	// If a thread could feasinbly have some of our trampoline code 
+	// on its stack and we yank the region from underneath it then it will
+	// surely crash upon returning. So instead of freeing the 
+	// memory we just let it leak. Ugly, but safe.
+	if (bNeverUsed) {
+		ListPrepend(&g_pFreeList, pTrampoline);
+	}
+
+	g_nHooksInUse--;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Suspend a given thread and try to make sure that its instruction
+// pointer is not in the given range.
+//=========================================================================
+static HANDLE SuspendOneThread(DWORD dwThreadId, PBYTE pbCode, DWORD cbBytes) {
+	// open the thread
+	HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadId);
+	if (GOOD_HANDLE(hThread)) {
+		// attempt suspension
+		DWORD dwSuspendCount = SuspendThread(hThread);
+		if (dwSuspendCount != -1) {
+			// see where the IP is
+			CONTEXT ctx;
+			int nTries = 0;
+			ctx.ContextFlags = CONTEXT_CONTROL;
+
+			while (GetThreadContext(hThread, &ctx)) {
+#ifdef _M_IX86
+				PBYTE pIp = (PBYTE)(DWORD_PTR)ctx.Eip;
+#elif defined _M_X64
+				PBYTE pIp = (PBYTE)(DWORD_PTR)ctx.Rip;
+#endif
+				if (pIp >= pbCode && pIp < (pbCode + cbBytes)) {
+					if (nTries < 3) {
+						// oops - we should try to get the instruction pointer out of here. 
+						ODPRINTF(("mhooks: SuspendOneThread: suspended thread %d - IP is at %p - IS COLLIDING WITH CODE", dwThreadId, pIp));
+						ResumeThread(hThread);
+						Sleep(100);
+						SuspendThread(hThread);
+						nTries++;
+					} else {
+						// we gave it all we could. (this will probably never 
+						// happen - unless the thread has already been suspended 
+						// to begin with)
+						ODPRINTF(("mhooks: SuspendOneThread: suspended thread %d - IP is at %p - IS COLLIDING WITH CODE - CAN'T FIX", dwThreadId, pIp));
+						ResumeThread(hThread);
+						CloseHandle(hThread);
+						hThread = NULL;
+						break;
+					}
+				} else {
+					// success, the IP is not conflicting
+					ODPRINTF(("mhooks: SuspendOneThread: Successfully suspended thread %d - IP is at %p", dwThreadId, pIp));
+					break;
+				}
+			}
+		} else {
+			// couldn't suspend
+			CloseHandle(hThread);
+			hThread = NULL;
+		}
+	}
+	return hThread;
+}
+
+//=========================================================================
+// Internal function:
+//
+// Resumes all previously suspended threads in the current process.
+//=========================================================================
+static VOID ResumeOtherThreads() {
+	DWORD i;
+	// make sure things go as fast as possible
+	INT nOriginalPriority = GetThreadPriority(GetCurrentThread());
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+	// go through our list
+	for (i=0; i<g_nThreadHandles; i++) {
+		// and resume & close thread handles
+		ResumeThread(g_hThreadHandles[i]);
+		CloseHandle(g_hThreadHandles[i]);
+	}
+	// clean up
+	free(g_hThreadHandles);
+	g_hThreadHandles = NULL;
+	g_nThreadHandles = 0;
+	SetThreadPriority(GetCurrentThread(), nOriginalPriority);
+}
+
+//=========================================================================
+// Internal function:
+//
+// Suspend all threads in this process while trying to make sure that their 
+// instruction pointer is not in the given range.
+//=========================================================================
+static BOOL SuspendOtherThreads(PBYTE pbCode, DWORD cbBytes) {
+	BOOL bRet = FALSE;
+	HANDLE hSnap;
+	// make sure we're the most important thread in the process
+	INT nOriginalPriority = GetThreadPriority(GetCurrentThread());
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+	// get a view of the threads in the system
+	hSnap = fnCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
+	if (GOOD_HANDLE(hSnap)) {
+		THREADENTRY32 te;
+		DWORD nThreadsInProcess;
+		te.dwSize = sizeof(te);
+		// count threads in this process (except for ourselves)
+		nThreadsInProcess = 0;
+		if (fnThread32First(hSnap, &te)) {
+			do {
+				if (te.th32OwnerProcessID == GetCurrentProcessId()) {
+					if (te.th32ThreadID != GetCurrentThreadId()) {
+						nThreadsInProcess++;
+					}
+				}
+				te.dwSize = sizeof(te);
+			} while(fnThread32Next(hSnap, &te));
+		}
+		ODPRINTF(("mhooks: SuspendOtherThreads: counted %d other threads", nThreadsInProcess));
+		if (nThreadsInProcess) {
+			// alloc buffer for the handles we really suspended
+			g_hThreadHandles = (HANDLE*)malloc(nThreadsInProcess*sizeof(HANDLE));
+			if (g_hThreadHandles) {
+				DWORD nCurrentThread = 0;
+				BOOL bFailed = FALSE;
+
+				ZeroMemory(g_hThreadHandles, nThreadsInProcess*sizeof(HANDLE));
+				te.dwSize = sizeof(te);
+				// go through every thread
+				if (fnThread32First(hSnap, &te)) {
+					do {
+						if (te.th32OwnerProcessID == GetCurrentProcessId()) {
+							if (te.th32ThreadID != GetCurrentThreadId()) {
+								// attempt to suspend it
+								g_hThreadHandles[nCurrentThread] = SuspendOneThread(te.th32ThreadID, pbCode, cbBytes);
+								if (GOOD_HANDLE(g_hThreadHandles[nCurrentThread])) {
+									ODPRINTF(("mhooks: SuspendOtherThreads: successfully suspended %d", te.th32ThreadID));
+									nCurrentThread++;
+								} else {
+									ODPRINTF(("mhooks: SuspendOtherThreads: error while suspending thread %d: %d", te.th32ThreadID, gle()));
+									// TODO: this might not be the wisest choice
+									// but we can choose to ignore failures on
+									// thread suspension. It's pretty unlikely that
+									// we'll fail - and even if we do, the chances
+									// of a thread's IP being in the wrong place
+									// is pretty small.
+									// bFailed = TRUE;
+								}
+							}
+						}
+						te.dwSize = sizeof(te);
+					} while(fnThread32Next(hSnap, &te) && !bFailed);
+				}
+				g_nThreadHandles = nCurrentThread;
+				bRet = !bFailed;
+			}
+		}
+		CloseHandle(hSnap);
+		//TODO: we might want to have another pass to make sure all threads
+		// in the current process (including those that might have been
+		// created since we took the original snapshot) have been 
+		// suspended.
+	} else {
+		ODPRINTF(("mhooks: SuspendOtherThreads: can't CreateToolhelp32Snapshot: %d", gle()));
+	}
+	SetThreadPriority(GetCurrentThread(), nOriginalPriority);
+	if (!bRet) {
+		ODPRINTF(("mhooks: SuspendOtherThreads: Had a problem (or not running multithreaded), resuming all threads."));
+		ResumeOtherThreads();
+	}
+	return bRet;
+}
+
+//=========================================================================
+// if IP-relative addressing has been detected, fix up the code so the
+// offset points to the original location
+static void FixupIPRelativeAddressing(PBYTE pbNew, PBYTE pbOriginal, MHOOKS_PATCHDATA* pdata)
+{
+#if defined _M_X64
+	S64 diff = pbNew - pbOriginal;
+		DWORD i;
+	for (i = 0; i < pdata->nRipCnt; i++) {
+		DWORD dwNewDisplacement = (DWORD)(pdata->rips[i].nDisplacement - diff);
+		ODPRINTF(("mhooks: fixing up RIP instruction operand for code at 0x%p: "
+			"old displacement: 0x%8.8x, new displacement: 0x%8.8x", 
+			pbNew + pdata->rips[i].dwOffset, 
+			(DWORD)pdata->rips[i].nDisplacement, 
+			dwNewDisplacement));
+		*(PDWORD)(pbNew + pdata->rips[i].dwOffset) = dwNewDisplacement;
+	}
+#endif
+}
+
+//=========================================================================
+// Examine the machine code at the target function's entry point, and
+// skip bytes in a way that we'll always end on an instruction boundary.
+// We also detect branches and subroutine calls (as well as returns)
+// at which point disassembly must stop.
+// Finally, detect and collect information on IP-relative instructions
+// that we can patch.
+static DWORD DisassembleAndSkip(PVOID pFunction, DWORD dwMinLen, MHOOKS_PATCHDATA* pdata) {
+	DWORD dwRet = 0;
+
+#ifdef _M_IX86
+	ARCHITECTURE_TYPE arch = ARCH_X86;
+#elif defined _M_IX86_X64
+	ARCHITECTURE_TYPE arch = ARCH_X64;
+#else
+	#error unsupported platform
+#endif
+	DISASSEMBLER dis;
+	pdata->nLimitDown = 0;
+	pdata->nLimitUp = 0;
+	pdata->nRipCnt = 0;
+	if (InitDisassembler(&dis, arch)) {
+		INSTRUCTION* pins = NULL;
+		U8* pLoc = (U8*)pFunction;
+		DWORD dwFlags = DISASM_DECODE | DISASM_DISASSEMBLE | DISASM_ALIGNOUTPUT;
+
+		ODPRINTF(("mhooks: DisassembleAndSkip: Disassembling %p", pLoc));
+		while ( (dwRet < dwMinLen) && (pins = GetInstruction(&dis, (ULONG_PTR)pLoc, pLoc, dwFlags)) ) {
+#if defined _M_IX86_X64
+			BOOL bProcessRip;
+#endif
+			ODPRINTF(("mhooks: DisassembleAndSkip: %p: %s", pLoc, pins->String));
+			if (pins->Type == ITYPE_RET		) break;
+			if (pins->Type == ITYPE_BRANCH	) break;
+			if (pins->Type == ITYPE_BRANCHCC) break;
+			if (pins->Type == ITYPE_CALL	) break;
+			if (pins->Type == ITYPE_CALLCC	) break;
+
+			#if defined _M_IX86_X64
+				bProcessRip = FALSE;
+				// mov or lea to register from rip+imm32
+				if ((pins->Type == ITYPE_MOV || pins->Type == ITYPE_LEA) && (pins->X86.Relative) && 
+					(pins->X86.OperandSize == 8) && (pins->OperandCount == 2) &&
+					(pins->Operands[1].Flags & OP_IPREL) && (pins->Operands[1].Register == AMD64_REG_RIP))
+				{
+					// rip-addressing "mov reg, [rip+imm32]"
+					ODPRINTF(("mhooks: DisassembleAndSkip: found OP_IPREL on operand %d with displacement 0x%x (in memory: 0x%x)", 1, pins->X86.Displacement, *(PDWORD)(pLoc+3)));
+					bProcessRip = TRUE;
+				}
+				// mov or lea to rip+imm32 from register
+				else if ((pins->Type == ITYPE_MOV || pins->Type == ITYPE_LEA) && (pins->X86.Relative) && 
+					(pins->X86.OperandSize == 8) && (pins->OperandCount == 2) &&
+					(pins->Operands[0].Flags & OP_IPREL) && (pins->Operands[0].Register == AMD64_REG_RIP))
+				{
+					// rip-addressing "mov [rip+imm32], reg"
+					ODPRINTF(("mhooks: DisassembleAndSkip: found OP_IPREL on operand %d with displacement 0x%x (in memory: 0x%x)", 0, pins->X86.Displacement, *(PDWORD)(pLoc+3)));
+					bProcessRip = TRUE;
+				}
+				else if ( (pins->OperandCount >= 1) && (pins->Operands[0].Flags & OP_IPREL) )
+				{
+					DWORD i;
+					// unsupported rip-addressing
+					ODPRINTF(("mhooks: DisassembleAndSkip: found unsupported OP_IPREL on operand %d", 0));
+					// dump instruction bytes to the debug output
+					for (i=0; i<pins->Length; i++) {
+						ODPRINTF(("mhooks: DisassembleAndSkip: instr byte %2.2d: 0x%2.2x", i, pLoc[i]));
+					}
+					break;
+				}
+				else if ( (pins->OperandCount >= 2) && (pins->Operands[1].Flags & OP_IPREL) )
+				{
+					DWORD i;
+					// unsupported rip-addressing
+					ODPRINTF(("mhooks: DisassembleAndSkip: found unsupported OP_IPREL on operand %d", 1));
+					// dump instruction bytes to the debug output
+					for (i=0; i<pins->Length; i++) {
+						ODPRINTF(("mhooks: DisassembleAndSkip: instr byte %2.2d: 0x%2.2x", i, pLoc[i]));
+					}
+					break;
+				}
+				else if ( (pins->OperandCount >= 3) && (pins->Operands[2].Flags & OP_IPREL) )
+				{
+					DWORD i;
+					// unsupported rip-addressing
+					ODPRINTF(("mhooks: DisassembleAndSkip: found unsupported OP_IPREL on operand %d", 2));
+					// dump instruction bytes to the debug output
+					for (i=0; i<pins->Length; i++) {
+						ODPRINTF(("mhooks: DisassembleAndSkip: instr byte %2.2d: 0x%2.2x", i, pLoc[i]));
+					}
+					break;
+				}
+				// follow through with RIP-processing if needed
+				if (bProcessRip) {
+					// calculate displacement relative to function start
+					S64 nAdjustedDisplacement = pins->X86.Displacement + (pLoc - (U8*)pFunction);
+					// store displacement values furthest from zero (both positive and negative)
+					if (nAdjustedDisplacement < pdata->nLimitDown)
+						pdata->nLimitDown = nAdjustedDisplacement;
+					if (nAdjustedDisplacement > pdata->nLimitUp)
+						pdata->nLimitUp = nAdjustedDisplacement;
+					// store patch info
+					if (pdata->nRipCnt < MHOOKS_MAX_RIPS) {
+						pdata->rips[pdata->nRipCnt].dwOffset = dwRet + 3;
+						pdata->rips[pdata->nRipCnt].nDisplacement = pins->X86.Displacement;
+						pdata->nRipCnt++;
+					} else {
+						// no room for patch info, stop disassembly
+						break;
+					}
+				}
+			#endif
+
+			dwRet += pins->Length;
+			pLoc  += pins->Length;
+		}
+
+		CloseDisassembler(&dis);
+	}
+
+	return dwRet;
+}
+
+//=========================================================================
+BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction) {
+	DWORD dwInstructionLength;
+	MHOOKS_TRAMPOLINE* pTrampoline = NULL;
+	PVOID pSystemFunction = *ppSystemFunction;
+	MHOOKS_PATCHDATA patchdata;
+	patchdata.nLimitDown= 0;
+	patchdata.nLimitUp = 0;
+	patchdata.nRipCnt = 0;
+
+	// ensure thread-safety
+	if (g_bMustGrabCritSec) {
+		EnterCritSec();
+	}
+	ODPRINTF(("mhooks: Mhook_SetHook: Started on the job: %p / %p", pSystemFunction, pHookFunction));
+	// find the real functions (jump over jump tables, if any)
+	pSystemFunction = SkipJumps((PBYTE)pSystemFunction);
+	pHookFunction   = SkipJumps((PBYTE)pHookFunction);
+	ODPRINTF(("mhooks: Mhook_SetHook: Started on the job: %p / %p", pSystemFunction, pHookFunction));
+	// figure out the length of the overwrite zone
+
+	dwInstructionLength = DisassembleAndSkip(pSystemFunction, MHOOK_JMPSIZE, &patchdata);
+	if (dwInstructionLength >= MHOOK_JMPSIZE) {
+		ODPRINTF(("mhooks: Mhook_SetHook: disassembly signals %d bytes", dwInstructionLength));
+		// suspend every other thread in this process, and make sure their IP 
+		// is not in the code we're about to overwrite.
+		// Note: The caller might've told us not to worry about this, if they're sure no other threads
+		// could be running--for example when hooking functions in a suspended process.
+		if (g_bSuspendThreads) {
+			SuspendOtherThreads((PBYTE)pSystemFunction, dwInstructionLength);
+		}
+		// allocate a trampoline structure (TODO: it is pretty wasteful to get
+		// VirtualAlloc to grab chunks of memory smaller than 100 bytes)
+		pTrampoline = TrampolineAlloc((PBYTE)pSystemFunction, patchdata.nLimitUp, patchdata.nLimitDown);
+		if (pTrampoline) {
+			// open ourselves so we can VirtualProtectEx
+			void * hProc = GetCurProcess();
+			DWORD dwOldProtectSystemFunction = 0;
+			DWORD dwOldProtectTrampolineFunction = 0;
+			ODPRINTF(("mhooks: Mhook_SetHook: allocated structure at %p", pTrampoline));
+			// set the system function to PAGE_EXECUTE_READWRITE
+			if (MemProtect(hProc, pSystemFunction, dwInstructionLength, PAGE_EXECUTE_READWRITE, &dwOldProtectSystemFunction)) {
+				ODPRINTF(("mhooks: Mhook_SetHook: readwrite set on system function"));
+				// mark our trampoline buffer to PAGE_EXECUTE_READWRITE
+				if (MemProtect(hProc, pTrampoline, sizeof(MHOOKS_TRAMPOLINE), PAGE_EXECUTE_READWRITE, &dwOldProtectTrampolineFunction)) {
+					PBYTE pbCode;
+					DWORD i;
+					DWORD_PTR dwDistance;
+					ODPRINTF(("mhooks: Mhook_SetHook: readwrite set on trampoline structure"));
+
+					// create our trampoline function
+					pbCode = pTrampoline->codeTrampoline;
+					// save original code..
+					for (i = 0; i<dwInstructionLength; i++) {
+						pTrampoline->codeUntouched[i] = pbCode[i] = ((PBYTE)pSystemFunction)[i];
+					}
+					pbCode += dwInstructionLength;
+					// plus a jump to the continuation in the original location
+					pbCode = EmitJump(pbCode, ((PBYTE)pSystemFunction) + dwInstructionLength);
+					ODPRINTF(("mhooks: Mhook_SetHook: updated the trampoline"));
+
+					// fix up any IP-relative addressing in the code
+					FixupIPRelativeAddressing(pTrampoline->codeTrampoline, (PBYTE)pSystemFunction, &patchdata);
+
+					dwDistance = (PBYTE)pHookFunction < (PBYTE)pSystemFunction ? 
+						(PBYTE)pSystemFunction - (PBYTE)pHookFunction : (PBYTE)pHookFunction - (PBYTE)pSystemFunction;
+					if (dwDistance > 0x7fff0000) {
+						// create a stub that jumps to the replacement function.
+						// we need this because jumping from the API to the hook directly 
+						// will be a long jump, which is 14 bytes on x64, and we want to 
+						// avoid that - the API may or may not have room for such stuff. 
+						// (remember, we only have 5 bytes guaranteed in the API.)
+						// on the other hand we do have room, and the trampoline will always be
+						// within +/- 2GB of the API, so we do the long jump in there. 
+						// the API will jump to the "reverse trampoline" which
+						// will jump to the user's hook code.
+						pbCode = pTrampoline->codeJumpToHookFunction;
+						pbCode = EmitJump(pbCode, (PBYTE)pHookFunction);
+						ODPRINTF(("mhooks: Mhook_SetHook: created reverse trampoline"));
+						FlushCache(hProc, pTrampoline->codeJumpToHookFunction, 
+							pbCode - pTrampoline->codeJumpToHookFunction);
+
+						// update the API itself
+						pbCode = (PBYTE)pSystemFunction;
+						pbCode = EmitJump(pbCode, pTrampoline->codeJumpToHookFunction);
+					} else {
+						// the jump will be at most 5 bytes so we can do it directly
+						// update the API itself
+						pbCode = (PBYTE)pSystemFunction;
+						pbCode = EmitJump(pbCode, (PBYTE)pHookFunction);
+					}
+
+					// update data members
+					pTrampoline->cbOverwrittenCode = dwInstructionLength;
+					pTrampoline->pSystemFunction = (PBYTE)pSystemFunction;
+					pTrampoline->pHookFunction = (PBYTE)pHookFunction;
+
+					// flush instruction cache and restore original protection
+					FlushCache(hProc, pTrampoline->codeTrampoline, dwInstructionLength);
+					MemProtect(hProc, pTrampoline, sizeof(MHOOKS_TRAMPOLINE), dwOldProtectTrampolineFunction, &dwOldProtectTrampolineFunction);
+				} else {
+					ODPRINTF(("mhooks: Mhook_SetHook: failed VirtualProtectEx 2: %d", gle()));
+				}
+				// flush instruction cache and restore original protection
+				FlushCache(hProc, pSystemFunction, dwInstructionLength);
+				MemProtect(hProc, pSystemFunction, dwInstructionLength, dwOldProtectSystemFunction, &dwOldProtectSystemFunction);
+			} else {
+				ODPRINTF(("mhooks: Mhook_SetHook: failed VirtualProtectEx 1: %d", gle()));
+			}
+			if (pTrampoline->pSystemFunction) {
+				// this is what the application will use as the entry point
+				// to the "original" unhooked function.
+				*ppSystemFunction = pTrampoline->codeTrampoline;
+				ODPRINTF(("mhooks: Mhook_SetHook: Hooked the function!"));
+			} else {
+				// if we failed discard the trampoline (forcing VirtualFree)
+				TrampolineFree(pTrampoline, TRUE);
+				pTrampoline = NULL;
+			}
+		}
+		// resume everybody else
+        if (g_bSuspendThreads) {
+		    ResumeOtherThreads();
+        }
+	} else {
+		ODPRINTF(("mhooks: disassembly signals %u bytes (unacceptable)", dwInstructionLength));
+	}
+	if (g_bMustGrabCritSec) {
+		LeaveCritSec();
+	}
+	return (pTrampoline != NULL);
+}
+
+//=========================================================================
+BOOL Mhook_Unhook(PVOID *ppHookedFunction) {
+	BOOL bRet = FALSE;
+	MHOOKS_TRAMPOLINE* pTrampoline;
+	ODPRINTF(("mhooks: Mhook_Unhook: %p", *ppHookedFunction));
+	if (g_bMustGrabCritSec) {
+		EnterCritSec();
+	}
+	// get the trampoline structure that corresponds to our function
+	pTrampoline = TrampolineGet((PBYTE)*ppHookedFunction);
+	if (pTrampoline) {
+		void * hProc;
+		DWORD dwOldProtectSystemFunction;
+		// make sure nobody's executing code where we're about to overwrite a few bytes
+		if (g_bSuspendThreads) {
+			SuspendOtherThreads(pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode);
+		}
+		ODPRINTF(("mhooks: Mhook_Unhook: found struct at %p", pTrampoline));
+		// open ourselves so we can VirtualProtectEx
+		hProc = GetCurProcess();
+		dwOldProtectSystemFunction = 0;
+		// make memory writable
+		if (MemProtect(hProc, pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode, PAGE_EXECUTE_READWRITE, &dwOldProtectSystemFunction)) {
+			DWORD i;
+			PBYTE pbCode = (PBYTE)pTrampoline->pSystemFunction;
+			ODPRINTF(("mhooks: Mhook_Unhook: readwrite set on system function"));
+			for (i = 0; i<pTrampoline->cbOverwrittenCode; i++) {
+				pbCode[i] = pTrampoline->codeUntouched[i];
+			}
+			// flush instruction cache and make memory unwritable
+			FlushCache(hProc, pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode);
+			MemProtect(hProc, pTrampoline->pSystemFunction, pTrampoline->cbOverwrittenCode, dwOldProtectSystemFunction, &dwOldProtectSystemFunction);
+			// return the original function pointer
+			*ppHookedFunction = pTrampoline->pSystemFunction;
+			bRet = TRUE;
+			ODPRINTF(("mhooks: Mhook_Unhook: sysfunc: %p", *ppHookedFunction));
+			// free the trampoline while not really discarding it from memory
+			TrampolineFree(pTrampoline, FALSE);
+			ODPRINTF(("mhooks: Mhook_Unhook: unhook successful"));
+		} else {
+			ODPRINTF(("mhooks: Mhook_Unhook: failed VirtualProtectEx 1: %d", gle()));
+		}
+		if (g_bSuspendThreads) {
+		    // make the other guys runnable
+		    ResumeOtherThreads();
+		}
+	}
+	if (g_bMustGrabCritSec) {
+		LeaveCritSec();
+	}
+	return bRet;
+}
+
+//=========================================================================
+VOID Mhook_BeginMultiOperation(BOOL bStillSuspendThreads)
+{
+	EnterCritSec();
+	g_bSuspendThreads = bStillSuspendThreads;
+	g_bMustGrabCritSec = FALSE;
+}
+
+VOID Mhook_EndMultiOperation()
+{
+	g_bMustGrabCritSec = TRUE;
+	g_bSuspendThreads = TRUE;
+	LeaveCritSec();
+}
diff --git a/tools/glave/src/thirdparty/mhook/mhook-lib/mhook.h b/tools/glave/src/thirdparty/mhook/mhook-lib/mhook.h
new file mode 100644
index 0000000..d4ce638
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/mhook-lib/mhook.h
@@ -0,0 +1,56 @@
+//Copyright (c) 2007-2008, Marton Anka
+//
+//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.
+#pragma once
+ 
+#if defined(__linux__)
+#if defined(__i386__)
+#define _M_IX86
+#elif defined(__x86_64__)
+#define _M_IX86_X64
+#endif
+#elif defined(WIN32)
+#ifdef _M_IX86
+#define _M_IX86_X64
+#elif defined _M_X64
+#define _M_IX86_X64
+#endif
+#endif
+
+#include "wintypes.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void Mhook_Initialize();
+
+BOOL Mhook_SetHook(PVOID *ppSystemFunction, PVOID pHookFunction);
+BOOL Mhook_Unhook(PVOID *ppHookedFunction);
+
+// If you'll be hooking (or unhooking) a large number of functions, you can
+// make it faster by wrapping them all with one call to Begin/End MultiOperation
+// bStillSuspendThreads should be true if you need each call to SetHook to try
+// and suspend other threads, and FALSE if you know the other threads will already
+// be suspended.
+VOID Mhook_BeginMultiOperation(BOOL bStillSuspendThreads);
+VOID Mhook_EndMultiOperation();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tools/glave/src/thirdparty/mhook/mhook-test.cpp b/tools/glave/src/thirdparty/mhook/mhook-test.cpp
new file mode 100644
index 0000000..79dc767
--- /dev/null
+++ b/tools/glave/src/thirdparty/mhook/mhook-test.cpp
@@ -0,0 +1,218 @@
+//Copyright (c) 2007-2008, Marton Anka
+//
+//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 "stdafx.h"
+#include "mhook-lib/mhook.h"
+
+//=========================================================================
+// Define _NtOpenProcess so we can dynamically bind to the function
+//
+typedef struct _CLIENT_ID {
+	DWORD_PTR UniqueProcess;
+	DWORD_PTR UniqueThread;
+} CLIENT_ID, *PCLIENT_ID;
+
+typedef ULONG (WINAPI* _NtOpenProcess)(OUT PHANDLE ProcessHandle, 
+	     IN ACCESS_MASK AccessMask, IN PVOID ObjectAttributes, 
+		 IN PCLIENT_ID ClientId ); 
+
+//=========================================================================
+// Define _SelectObject so we can dynamically bind to the function
+typedef HGDIOBJ (WINAPI* _SelectObject)(HDC hdc, HGDIOBJ hgdiobj); 
+
+//=========================================================================
+// Define _getaddrinfo so we can dynamically bind to the function
+typedef int (WSAAPI* _getaddrinfo)(const char* nodename, const char* servname, const struct addrinfo* hints, struct addrinfo** res);
+
+//=========================================================================
+// Define _HeapAlloc so we can dynamically bind to the function
+typedef LPVOID (WINAPI *_HeapAlloc)(HANDLE, DWORD, SIZE_T);
+
+//=========================================================================
+// Define _NtClose so we can dynamically bind to the function
+typedef ULONG (WINAPI* _NtClose)(IN HANDLE Handle);
+
+//=========================================================================
+// Get the current (original) address to the functions to be hooked
+//
+_NtOpenProcess TrueNtOpenProcess = (_NtOpenProcess)
+	GetProcAddress(GetModuleHandle(L"ntdll"), "NtOpenProcess");
+
+_SelectObject TrueSelectObject = (_SelectObject)
+	GetProcAddress(GetModuleHandle(L"gdi32"), "SelectObject");
+
+_getaddrinfo Truegetaddrinfo = (_getaddrinfo)GetProcAddress(GetModuleHandle(L"ws2_32"), "getaddrinfo");
+
+_HeapAlloc TrueHeapAlloc = (_HeapAlloc)GetProcAddress(GetModuleHandle(L"kernel32"), "HeapAlloc");
+
+_NtClose TrueNtClose = (_NtClose)GetProcAddress(GetModuleHandle(L"ntdll"), "NtClose");
+
+//=========================================================================
+// This is the function that will replace NtOpenProcess once the hook 
+// is in place
+//
+ULONG WINAPI HookNtOpenProcess(OUT PHANDLE ProcessHandle, 
+							   IN ACCESS_MASK AccessMask, 
+							   IN PVOID ObjectAttributes, 
+							   IN PCLIENT_ID ClientId)
+{
+	printf("***** Call to open process %d\n", ClientId->UniqueProcess);
+	return TrueNtOpenProcess(ProcessHandle, AccessMask, 
+		ObjectAttributes, ClientId);
+}
+
+//=========================================================================
+// This is the function that will replace SelectObject once the hook 
+// is in place
+//
+HGDIOBJ WINAPI HookSelectobject(HDC hdc, HGDIOBJ hgdiobj)
+{
+	printf("***** Call to SelectObject(0x%p, 0x%p)\n", hdc, hgdiobj);
+	return TrueSelectObject(hdc, hgdiobj);
+}
+
+//=========================================================================
+// This is the function that will replace SelectObject once the hook 
+// is in place
+//
+int WSAAPI Hookgetaddrinfo(const char* nodename, const char* servname, const struct addrinfo* hints, struct addrinfo** res)
+{
+	printf("***** Call to getaddrinfo(0x%p, 0x%p, 0x%p, 0x%p)\n", nodename, servname, hints, res);
+	return Truegetaddrinfo(nodename, servname, hints, res);
+}
+
+//=========================================================================
+// This is the function that will replace HeapAlloc once the hook 
+// is in place
+//
+LPVOID WINAPI HookHeapAlloc(HANDLE a_Handle, DWORD a_Bla, SIZE_T a_Bla2) {
+	printf("***** Call to HeapAlloc(0x%p, %u, 0x%p)\n", a_Handle, a_Bla, a_Bla2);
+	return TrueHeapAlloc(a_Handle, a_Bla, a_Bla2);
+}
+
+//=========================================================================
+// This is the function that will replace NtClose once the hook 
+// is in place
+//
+ULONG WINAPI HookNtClose(HANDLE hHandle) {
+	printf("***** Call to NtClose(0x%p)\n", hHandle);
+	return TrueNtClose(hHandle);
+}
+
+//=========================================================================
+// This is where the work gets done.
+//
+int wmain(int argc, WCHAR* argv[])
+{
+	HANDLE hProc = NULL;
+
+	// Set the hook
+	if (Mhook_SetHook((PVOID*)&TrueNtOpenProcess, HookNtOpenProcess)) {
+		// Now call OpenProcess and observe NtOpenProcess being redirected
+		// under the hood.
+		hProc = OpenProcess(PROCESS_ALL_ACCESS, 
+			FALSE, GetCurrentProcessId());
+		if (hProc) {
+			printf("Successfully opened self: %p\n", hProc);
+			CloseHandle(hProc);
+		} else {
+			printf("Could not open self: %d\n", GetLastError());
+		}
+		// Remove the hook
+		Mhook_Unhook((PVOID*)&TrueNtOpenProcess);
+	}
+
+	// Call OpenProces again - this time there won't be a redirection as
+	// the hook has bee removed.
+	hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());
+	if (hProc) {
+		printf("Successfully opened self: %p\n", hProc);
+		CloseHandle(hProc);
+	} else {
+		printf("Could not open self: %d\n", GetLastError());
+	}
+
+	// Test another hook, this time in SelectObject
+	// (SelectObject is interesting in that on XP x64, the second instruction
+	// in the trampoline uses IP-relative addressing and we need to do some
+	// extra work under the hood to make things work properly. This really
+	// is more of a test case rather than a demo.)
+	printf("Testing SelectObject.\n");
+	if (Mhook_SetHook((PVOID*)&TrueSelectObject, HookSelectobject)) {
+		// error checking omitted for brevity. doesn't matter much 
+		// in this context anyway.
+		HDC hdc = GetDC(NULL);
+		HDC hdcMem = CreateCompatibleDC(hdc);
+		HBITMAP hbm = CreateCompatibleBitmap(hdc, 32, 32);
+		HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbm);
+		SelectObject(hdcMem, hbmOld);
+		DeleteObject(hbm);
+		DeleteDC(hdcMem);
+		ReleaseDC(NULL, hdc);
+		// Remove the hook
+		Mhook_Unhook((PVOID*)&TrueSelectObject);
+	}
+
+	printf("Testing getaddrinfo.\n");
+	if (Mhook_SetHook((PVOID*)&Truegetaddrinfo, Hookgetaddrinfo)) {
+		// error checking omitted for brevity. doesn't matter much 
+		// in this context anyway.
+		WSADATA wd = {0};
+		WSAStartup(MAKEWORD(2, 2), &wd);
+		char* ip = "localhost";
+		struct addrinfo aiHints;
+		struct addrinfo *res = NULL;
+		memset(&aiHints, 0, sizeof(aiHints));
+		aiHints.ai_family = PF_UNSPEC;
+		aiHints.ai_socktype = SOCK_STREAM;
+		if (getaddrinfo(ip, NULL, &aiHints, &res)) {
+			printf("getaddrinfo failed\n");
+		} else {
+			int n = 0;
+			while(res) {
+				res = res->ai_next;
+				n++;
+			}
+			printf("got %d addresses\n", n);
+		}
+		WSACleanup();
+		// Remove the hook
+		Mhook_Unhook((PVOID*)&Truegetaddrinfo);
+	}
+
+	printf("Testing HeapAlloc.\n");
+	if (Mhook_SetHook((PVOID*)&TrueHeapAlloc, HookHeapAlloc))
+	{
+		free(malloc(10));
+		// Remove the hook
+		Mhook_Unhook((PVOID*)&TrueHeapAlloc);
+	}
+
+	printf("Testing NtClose.\n");
+	if (Mhook_SetHook((PVOID*)&TrueNtClose, HookNtClose))
+	{
+		CloseHandle(NULL);
+		// Remove the hook
+		Mhook_Unhook((PVOID*)&TrueNtClose);
+	}
+
+	return 0;
+}
+