Merge remote-tracking branch 'mesa-public/master' into vulkan
authorJason Ekstrand <jason.ekstrand@intel.com>
Sat, 14 Nov 2015 15:56:10 +0000 (07:56 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Sat, 14 Nov 2015 15:56:10 +0000 (07:56 -0800)
This pulls in Matt's big compiler refactor.

108 files changed:
README.intel-vulkan.txt [new file with mode: 0644]
configure.ac
include/vulkan/vk_ext_khr_device_swapchain.h [new file with mode: 0644]
include/vulkan/vk_ext_khr_swapchain.h [new file with mode: 0644]
include/vulkan/vk_platform.h [new file with mode: 0644]
include/vulkan/vulkan.h [new file with mode: 0644]
include/vulkan/vulkan_intel.h [new file with mode: 0644]
src/Makefile.am
src/glsl/.gitignore
src/glsl/Makefile.am
src/glsl/Makefile.sources
src/glsl/ast_to_hir.cpp
src/glsl/glsl_parser_extras.cpp
src/glsl/ir_clone.cpp
src/glsl/link_uniform_initializers.cpp
src/glsl/nir/glsl_to_nir.cpp
src/glsl/nir/glsl_types.cpp
src/glsl/nir/glsl_types.h
src/glsl/nir/nir.h
src/glsl/nir/nir_builder.h
src/glsl/nir/nir_gather_info.c [new file with mode: 0644]
src/glsl/nir/nir_intrinsics.h
src/glsl/nir/nir_lower_samplers.cpp [new file with mode: 0644]
src/glsl/nir/nir_opt_algebraic.py
src/glsl/nir/nir_spirv.h [new file with mode: 0644]
src/glsl/nir/nir_types.cpp
src/glsl/nir/nir_types.h
src/glsl/nir/spirv.h [new file with mode: 0644]
src/glsl/nir/spirv2nir.c [new file with mode: 0644]
src/glsl/nir/spirv_glsl450.h [new file with mode: 0644]
src/glsl/nir/spirv_glsl450_to_nir.c [new file with mode: 0644]
src/glsl/nir/spirv_to_nir.c [new file with mode: 0644]
src/glsl/nir/spirv_to_nir_private.h [new file with mode: 0644]
src/glsl/standalone_scaffolding.cpp
src/mesa/drivers/dri/i965/Makefile.sources
src/mesa/drivers/dri/i965/brw_compiler.h
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_device_info.c
src/mesa/drivers/dri/i965/brw_device_info.h
src/mesa/drivers/dri/i965/brw_draw.c
src/mesa/drivers/dri/i965/brw_fs.cpp
src/mesa/drivers/dri/i965/brw_fs_nir.cpp
src/mesa/drivers/dri/i965/brw_nir.c
src/mesa/drivers/dri/i965/brw_nir.h
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/drivers/dri/i965/brw_shader.h
src/mesa/drivers/dri/i965/brw_surface_formats.c
src/mesa/drivers/dri/i965/brw_surface_formats.h [new file with mode: 0644]
src/mesa/drivers/dri/i965/brw_util.c
src/mesa/drivers/dri/i965/brw_vec4_nir.cpp
src/mesa/drivers/dri/i965/brw_vec4_visitor.cpp
src/mesa/main/mtypes.h
src/mesa/program/ir_to_mesa.cpp
src/util/list.h
src/vulkan/.gitignore [new file with mode: 0644]
src/vulkan/Makefile.am [new file with mode: 0644]
src/vulkan/anv_allocator.c [new file with mode: 0644]
src/vulkan/anv_aub.h [new file with mode: 0644]
src/vulkan/anv_batch_chain.c [new file with mode: 0644]
src/vulkan/anv_cmd_buffer.c [new file with mode: 0644]
src/vulkan/anv_device.c [new file with mode: 0644]
src/vulkan/anv_dump.c [new file with mode: 0644]
src/vulkan/anv_entrypoints_gen.py [new file with mode: 0644]
src/vulkan/anv_formats.c [new file with mode: 0644]
src/vulkan/anv_gem.c [new file with mode: 0644]
src/vulkan/anv_gem_stubs.c [new file with mode: 0644]
src/vulkan/anv_icd.json.in [new file with mode: 0644]
src/vulkan/anv_image.c [new file with mode: 0644]
src/vulkan/anv_intel.c [new file with mode: 0644]
src/vulkan/anv_meta.c [new file with mode: 0644]
src/vulkan/anv_meta.h [new file with mode: 0644]
src/vulkan/anv_meta_clear.c [new file with mode: 0644]
src/vulkan/anv_meta_clear.h [new file with mode: 0644]
src/vulkan/anv_nir.h [new file with mode: 0644]
src/vulkan/anv_nir_apply_dynamic_offsets.c [new file with mode: 0644]
src/vulkan/anv_nir_apply_pipeline_layout.c [new file with mode: 0644]
src/vulkan/anv_nir_builder.h [new file with mode: 0644]
src/vulkan/anv_nir_lower_push_constants.c [new file with mode: 0644]
src/vulkan/anv_pass.c [new file with mode: 0644]
src/vulkan/anv_pipeline.c [new file with mode: 0644]
src/vulkan/anv_private.h [new file with mode: 0644]
src/vulkan/anv_query.c [new file with mode: 0644]
src/vulkan/anv_util.c [new file with mode: 0644]
src/vulkan/anv_wsi.c [new file with mode: 0644]
src/vulkan/anv_wsi.h [new file with mode: 0644]
src/vulkan/anv_wsi_wayland.c [new file with mode: 0644]
src/vulkan/anv_wsi_x11.c [new file with mode: 0644]
src/vulkan/gen75_pack.h [new file with mode: 0644]
src/vulkan/gen7_cmd_buffer.c [new file with mode: 0644]
src/vulkan/gen7_pack.h [new file with mode: 0644]
src/vulkan/gen7_pipeline.c [new file with mode: 0644]
src/vulkan/gen7_state.c [new file with mode: 0644]
src/vulkan/gen8_cmd_buffer.c [new file with mode: 0644]
src/vulkan/gen8_pack.h [new file with mode: 0644]
src/vulkan/gen8_pipeline.c [new file with mode: 0644]
src/vulkan/gen8_state.c [new file with mode: 0644]
src/vulkan/isl.c [new file with mode: 0644]
src/vulkan/isl.h [new file with mode: 0644]
src/vulkan/isl_format_layout.csv [new file with mode: 0644]
src/vulkan/isl_format_layout_gen.bash [new file with mode: 0755]
src/vulkan/tests/.gitignore [new file with mode: 0644]
src/vulkan/tests/Makefile.am [new file with mode: 0644]
src/vulkan/tests/block_pool_no_free.c [new file with mode: 0644]
src/vulkan/tests/state_pool.c [new file with mode: 0644]
src/vulkan/tests/state_pool_free_list_only.c [new file with mode: 0644]
src/vulkan/tests/state_pool_no_free.c [new file with mode: 0644]
src/vulkan/tests/state_pool_test_helper.h [new file with mode: 0644]

diff --git a/README.intel-vulkan.txt b/README.intel-vulkan.txt
new file mode 100644 (file)
index 0000000..f89314e
--- /dev/null
@@ -0,0 +1,129 @@
+Intel's Open Source Vulkan Driver
+Vulkan API Version: 0.170.2
+SPIR-V Version: 32
+
+Intro
+=====
+The Open Source Technology Center 3D graphics team at Intel has
+been working on a Vulkan implementation based on the Mesa open source
+OpenGL implementation. At this point we're ready to share what we have
+with our Khronos friends, in the hope that an early preview will be
+useful.
+
+When the Vulkan specification goes public, we will continue the work
+in the Mesa public git repository, but in the interim we will share
+our progress on the 'vulkan' branch in the 'mesa' repository in
+Khronos gitlab.
+
+The Mesa project source and our driver implementation is under the MIT
+license [1], but is also covered by the Khronos IP framework as it
+pertains to a specification under construction [2].
+
+We welcome all feedback and contibutions, as long as the contributions
+are MIT licensed and can be open sourced with the driver.
+
+[1] https://opensource.org/licenses/MIT
+[2] https://www.khronos.org/members/ip-framework
+
+
+Maintainers
+===========
+Kristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
+Jason Ekstrand <jason.ekstrand@intel.com>
+Chad Versace <chad.versace@intel.com>
+
+
+Supported Hardware
+==================
+- Broadwell, main development focus
+- Ivybridge, early experimental support
+
+
+Supported OS Platforms
+======================
+ - Linux, tested on Fedora 22 with kernel >= 4.1
+     - X11 with DRI3
+     - Wayland
+ - Android
+     - TODO
+
+
+Building and Installing
+=======================
+This driver is intended to be used directly from the build tree. Installing the
+driver into a system location is not yet fully supported. If you require support
+for system-wide installation, please contact a maintainer.
+
+Throughout the instructions, MESA_TOP refers to the top of the Mesa repository.
+
+First, install the usual dependencies needed to build Mesa.
+
+        Fedora:
+            $ sudo yum builddep mesa
+        Ubunutu:
+            $ FINISHME
+
+Next, configure and build. The below commands will build Mesa in release mode.
+If you wish to build Mesa in debug mode, add option '--enable-debug' to the
+configure command.
+
+        $ cd $MESA_TOP
+        $ autoreconf -vfi
+        $ ./configure --with-dri-drivers=i965 --with-gallium-drivers=
+        $ make
+
+To use the driver's libvulkan.so directly, without LunarG's loader, you must set
+an environment variable before running your Vulkan application:
+
+        $ export LD_LIBRARY_PATH="$MESA_TOP/lib"
+        $ your-vk-app
+
+Alternatively, to use the driver with LunarG's loader:
+
+        $ export VK_ICD_FILENAMES="$MESA_TOP/src/vulkan/anv_icd.json"
+        $ your-vk-app
+
+
+File Structure and Naming
+=========================
+The core code of Intel's Mesa Vulkan driver lives in src/vulkan. Files prefixed
+with "gen8" support Broadwell; files prefixed with "gen7" support Ivybridge;
+files prefixed with "anv" are common to all hardware generations.
+
+Mesa is an umbrella open source project containing many drivers for multiple
+APIs. The codename for Intel's Mesa Vulkan driver is "Anvil", hence the filename
+prefix "anv".
+
+
+Feature Status
+==============
+The driver is still a work-in-progress. We do our best to keep the below list of
+features up-to-date.
+
+Supported Features:
+  - Index buffers, instanced draw, indirect draw
+  - Nested command buffers
+  - Consumes SPIR-V (no GLSL "backdoor")
+  - Fragment, vertex, and geometry shaders
+  - Uniform buffers, sampled images, dynamic uniform buffers
+  - Push constants (to the extent they're supported by SPIR-V v32)
+  - Color, depth and stencil attachments
+  - 1D, 2D, 3D textures, texture arrays
+  - Memory barrier
+  - Optionally integrates with LunarGs loader
+  - WSI extension for X11
+  - Fences
+  - Most copy/blit commands for color and depth buffers,
+    vkCmdCopyImageToBuffer for stencil buffers
+  - Occlution query and timestamps
+
+Unsupported Features:
+   - Shader storage buffers
+   - Shader specialization
+   - Storage images
+   - Compute and tesselation stages
+   - Sparse resources
+   - MSAA
+   - VkkSemaphore and VkEvent
+   - vkCmdClear commands
+   - Input attachments
index 3f15881a18ef401fd4fa34a3cd438e02f06b0e94..758751c4b9446a65aca8c5b1a463d41aaea0de07 100644 (file)
@@ -99,6 +99,7 @@ AM_PROG_CC_C_O
 AM_PROG_AS
 AX_CHECK_GNU_MAKE
 AC_CHECK_PROGS([PYTHON2], [python2 python])
+AC_CHECK_PROGS([PYTHON3], [python3])
 AC_PROG_SED
 AC_PROG_MKDIR_P
 
@@ -1551,6 +1552,8 @@ GBM_PC_LIB_PRIV="$DLOPEN_LIBS"
 AC_SUBST([GBM_PC_REQ_PRIV])
 AC_SUBST([GBM_PC_LIB_PRIV])
 
+AM_CONDITIONAL(HAVE_VULKAN, true)
+
 dnl
 dnl EGL configuration
 dnl
@@ -2342,6 +2345,13 @@ AC_SUBST([XA_MINOR], $XA_MINOR)
 AC_SUBST([XA_TINY], $XA_TINY)
 AC_SUBST([XA_VERSION], "$XA_MAJOR.$XA_MINOR.$XA_TINY")
 
+PKG_CHECK_MODULES(VALGRIND, [valgrind],
+                  [have_valgrind=yes], [have_valgrind=no])
+if test "x$have_valgrind" = "xyes"; then
+    AC_DEFINE([HAVE_VALGRIND], 1,
+              [Use valgrind intrinsics to suppress false warnings])
+fi
+
 dnl Restore LDFLAGS and CPPFLAGS
 LDFLAGS="$_SAVE_LDFLAGS"
 CPPFLAGS="$_SAVE_CPPFLAGS"
@@ -2454,6 +2464,9 @@ AC_CONFIG_FILES([Makefile
                src/mesa/drivers/osmesa/osmesa.pc
                src/mesa/drivers/x11/Makefile
                src/mesa/main/tests/Makefile
+               src/vulkan/Makefile
+               src/vulkan/anv_icd.json
+               src/vulkan/tests/Makefile
                src/util/Makefile
                src/util/tests/hash_table/Makefile])
 
@@ -2573,6 +2586,7 @@ if test "x$MESA_LLVM" = x1; then
     echo ""
 fi
 echo "        PYTHON2:         $PYTHON2"
+echo "        PYTHON3:         $PYTHON3"
 
 echo ""
 echo "        Run '${MAKE-make}' to build Mesa"
diff --git a/include/vulkan/vk_ext_khr_device_swapchain.h b/include/vulkan/vk_ext_khr_device_swapchain.h
new file mode 100644 (file)
index 0000000..3bf73c8
--- /dev/null
@@ -0,0 +1,210 @@
+//
+// File: vk_ext_khr_device_swapchain.h
+//
+/*
+** Copyright (c) 2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __VK_EXT_KHR_DEVICE_SWAPCHAIN_H__
+#define __VK_EXT_KHR_DEVICE_SWAPCHAIN_H__
+
+#include "vulkan.h"
+
+#define VK_EXT_KHR_DEVICE_SWAPCHAIN_REVISION         53
+#define VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER 2
+#define VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME   "VK_EXT_KHR_device_swapchain"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+// ------------------------------------------------------------------------------------------------
+// Objects
+
+VK_DEFINE_NONDISP_HANDLE(VkSwapchainKHR);
+
+// ------------------------------------------------------------------------------------------------
+// Enumeration constants
+
+#define VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(type,id)    ((type)((int)0xc0000000 - VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER * -1024 + (id)))
+#define VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM_POSITIVE(type,id)    ((type)((int)0x40000000 + (VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NUMBER - 1) * 1024 + (id)))
+
+// Extend VkStructureType enum with extension specific constants
+#define VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkStructureType, 0)
+#define VK_STRUCTURE_TYPE_PRESENT_INFO_KHR VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkStructureType, 1)
+
+// Extend VkImageLayout enum with extension specific constants
+#define VK_IMAGE_LAYOUT_PRESENT_SOURCE_KHR VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkImageLayout, 2)
+
+// Extend VkResult enum with extension specific constants
+//  Return codes for successful operation execution
+#define VK_SUBOPTIMAL_KHR           VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM_POSITIVE(VkResult, 3)
+//  Error codes
+#define VK_ERROR_OUT_OF_DATE_KHR    VK_EXT_KHR_DEVICE_SWAPCHAIN_ENUM(VkResult, 4)
+
+// ------------------------------------------------------------------------------------------------
+// Enumerations
+
+typedef enum {
+    VK_PRESENT_MODE_IMMEDIATE_KHR = 0,
+    VK_PRESENT_MODE_MAILBOX_KHR = 1,
+    VK_PRESENT_MODE_FIFO_KHR = 2,
+    VK_PRESENT_MODE_BEGIN_RANGE_KHR = VK_PRESENT_MODE_IMMEDIATE_KHR,
+    VK_PRESENT_MODE_END_RANGE_KHR = VK_PRESENT_MODE_FIFO_KHR,
+    VK_PRESENT_MODE_NUM = (VK_PRESENT_MODE_FIFO_KHR - VK_PRESENT_MODE_IMMEDIATE_KHR + 1),
+    VK_PRESENT_MODE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPresentModeKHR;
+
+typedef enum {
+    VK_COLORSPACE_SRGB_NONLINEAR_KHR = 0x00000000,
+    VK_COLORSPACE_NUM = (VK_COLORSPACE_SRGB_NONLINEAR_KHR - VK_COLORSPACE_SRGB_NONLINEAR_KHR + 1),
+    VK_COLORSPACE_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkColorSpaceKHR;
+
+// ------------------------------------------------------------------------------------------------
+// Flags
+
+// ------------------------------------------------------------------------------------------------
+// Structures
+
+typedef struct {
+    uint32_t                                minImageCount;      // Supported minimum number of images for the surface
+    uint32_t                                maxImageCount;      // Supported maximum number of images for the surface, 0 for unlimited
+
+    VkExtent2D                              currentExtent;      // Current image width and height for the surface, (-1, -1) if undefined
+    VkExtent2D                              minImageExtent;     // Supported minimum image width and height for the surface
+    VkExtent2D                              maxImageExtent;     // Supported maximum image width and height for the surface
+
+    VkSurfaceTransformFlagsKHR              supportedTransforms;// 1 or more bits representing the transforms supported
+    VkSurfaceTransformKHR                   currentTransform;   // The surface's current transform relative to the device's natural orientation
+
+    uint32_t                                maxImageArraySize;  // Supported maximum number of image layers for the surface
+
+    VkImageUsageFlags                       supportedUsageFlags;// Supported image usage flags for the surface
+} VkSurfacePropertiesKHR;
+
+typedef struct {
+    VkFormat                                format;             // Supported pair of rendering format
+    VkColorSpaceKHR                         colorSpace;         // and colorspace for the surface
+} VkSurfaceFormatKHR;
+
+typedef struct {
+    VkStructureType                          sType;             // Must be VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR
+    const void*                              pNext;             // Pointer to next structure
+
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription;// describes the swap chain's target surface
+
+    uint32_t                                 minImageCount;     // Minimum number of presentation images the application needs
+    VkFormat                                 imageFormat;       // Format of the presentation images
+    VkColorSpaceKHR                          imageColorSpace;   // Colorspace of the presentation images
+    VkExtent2D                               imageExtent;       // Dimensions of the presentation images
+    VkImageUsageFlags                        imageUsageFlags;   // Bits indicating how the presentation images will be used
+    VkSurfaceTransformKHR                    preTransform;      // The transform, relative to the device's natural orientation, applied to the image content prior to presentation
+    uint32_t                                 imageArraySize;    // Determines the number of views for multiview/stereo presentation
+
+    VkSharingMode                            sharingMode;       // Sharing mode used for the presentation images
+    uint32_t                                 queueFamilyCount;  // Number of queue families having access to the images in case of concurrent sharing mode
+    const uint32_t*                          pQueueFamilyIndices; // Array of queue family indices having access to the images in case of concurrent sharing mode
+
+    VkPresentModeKHR                         presentMode;       // Which presentation mode to use for presents on this swap chain
+
+    VkSwapchainKHR                           oldSwapchain;      // Existing swap chain to replace, if any
+
+    VkBool32                                 clipped;           // Specifies whether presentable images may be affected by window clip regions
+} VkSwapchainCreateInfoKHR;
+
+typedef struct {
+    VkStructureType                          sType;             // Must be VK_STRUCTURE_TYPE_PRESENT_INFO_KHR
+    const void*                              pNext;             // Pointer to next structure
+    uint32_t                                 swapchainCount;    // Number of swap chains to present in this call
+    const VkSwapchainKHR*                    swapchains;        // Swap chains to present an image from
+    const uint32_t*                          imageIndices;      // Indices of which swapchain images to present
+} VkPresentInfoKHR;
+
+// ------------------------------------------------------------------------------------------------
+// Function types
+
+typedef VkResult (VKAPI *PFN_vkGetSurfacePropertiesKHR)(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, VkSurfacePropertiesKHR* pSurfaceProperties);
+typedef VkResult (VKAPI *PFN_vkGetSurfaceFormatsKHR)(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, uint32_t* pCount, VkSurfaceFormatKHR* pSurfaceFormats);
+typedef VkResult (VKAPI *PFN_vkGetSurfacePresentModesKHR)(VkDevice device, const VkSurfaceDescriptionKHR* pSurfaceDescription, uint32_t* pCount, VkPresentModeKHR* pPresentModes);
+typedef VkResult (VKAPI *PFN_vkCreateSwapchainKHR)(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkSwapchainKHR* pSwapchain);
+typedef VkResult (VKAPI *PFN_vkDestroySwapchainKHR)(VkDevice device, VkSwapchainKHR swapchain);
+typedef VkResult (VKAPI *PFN_vkGetSwapchainImagesKHR)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pCount, VkImage* pSwapchainImages);
+typedef VkResult (VKAPI *PFN_vkAcquireNextImageKHR)(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, uint32_t* pImageIndex);
+typedef VkResult (VKAPI *PFN_vkQueuePresentKHR)(VkQueue queue, VkPresentInfoKHR* pPresentInfo);
+
+// ------------------------------------------------------------------------------------------------
+// Function prototypes
+
+#ifdef VK_PROTOTYPES
+
+VkResult VKAPI vkGetSurfacePropertiesKHR(
+    VkDevice                                 device,
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
+    VkSurfacePropertiesKHR*                  pSurfaceProperties);
+
+VkResult VKAPI vkGetSurfaceFormatsKHR(
+    VkDevice                                 device,
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
+    uint32_t*                                pCount,
+    VkSurfaceFormatKHR*                      pSurfaceFormats);
+
+VkResult VKAPI vkGetSurfacePresentModesKHR(
+    VkDevice                                 device,
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
+    uint32_t*                                pCount,
+    VkPresentModeKHR*                        pPresentModes);
+
+VkResult VKAPI vkCreateSwapchainKHR(
+    VkDevice                                 device,
+    const VkSwapchainCreateInfoKHR*          pCreateInfo,
+    VkSwapchainKHR*                          pSwapchain);
+
+VkResult VKAPI vkDestroySwapchainKHR(
+    VkDevice                                 device,
+    VkSwapchainKHR                           swapchain);
+
+VkResult VKAPI vkGetSwapchainImagesKHR(
+    VkDevice                                 device,
+    VkSwapchainKHR                           swapchain,
+    uint32_t*                                pCount,
+    VkImage*                                 pSwapchainImages);
+
+VkResult VKAPI vkAcquireNextImageKHR(
+    VkDevice                                 device,
+    VkSwapchainKHR                           swapchain,
+    uint64_t                                 timeout,
+    VkSemaphore                              semaphore,
+    uint32_t*                                pImageIndex);
+
+VkResult VKAPI vkQueuePresentKHR(
+    VkQueue                                  queue,
+    VkPresentInfoKHR*                        pPresentInfo);
+
+#endif // VK_PROTOTYPES
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // __VK_EXT_KHR_SWAPCHAIN_H__
diff --git a/include/vulkan/vk_ext_khr_swapchain.h b/include/vulkan/vk_ext_khr_swapchain.h
new file mode 100644 (file)
index 0000000..862b4d5
--- /dev/null
@@ -0,0 +1,153 @@
+//
+// File: vk_ext_khr_swapchain.h
+//
+/*
+** Copyright (c) 2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#ifndef __VK_EXT_KHR_SWAPCHAIN_H__
+#define __VK_EXT_KHR_SWAPCHAIN_H__
+
+#include "vulkan.h"
+
+#define VK_EXT_KHR_SWAPCHAIN_REVISION         17
+#define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER 1
+#define VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME   "VK_EXT_KHR_swapchain"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+// ------------------------------------------------------------------------------------------------
+// Objects
+
+// ------------------------------------------------------------------------------------------------
+// Enumeration constants
+
+#define VK_EXT_KHR_SWAPCHAIN_ENUM(type,id)    ((type)((int)0xc0000000 - VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER * -1024 + (id)))
+#define VK_EXT_KHR_SWAPCHAIN_ENUM_POSITIVE(type,id)    ((type)((int)0x40000000 + (VK_EXT_KHR_SWAPCHAIN_EXTENSION_NUMBER - 1) * 1024 + (id)))
+
+// Extend VkStructureType enum with extension specific constants
+#define VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR            VK_EXT_KHR_SWAPCHAIN_ENUM(VkStructureType, 0)
+
+// ------------------------------------------------------------------------------------------------
+// Enumerations
+
+typedef enum {
+    VK_SURFACE_TRANSFORM_NONE_KHR = 0,
+    VK_SURFACE_TRANSFORM_ROT90_KHR = 1,
+    VK_SURFACE_TRANSFORM_ROT180_KHR = 2,
+    VK_SURFACE_TRANSFORM_ROT270_KHR = 3,
+    VK_SURFACE_TRANSFORM_HMIRROR_KHR = 4,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT90_KHR = 5,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT180_KHR = 6,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT270_KHR = 7,
+    VK_SURFACE_TRANSFORM_INHERIT_KHR = 8,
+} VkSurfaceTransformKHR;
+
+typedef enum {
+    VK_SURFACE_TRANSFORM_NONE_BIT_KHR = 0x00000001,
+    VK_SURFACE_TRANSFORM_ROT90_BIT_KHR = 0x00000002,
+    VK_SURFACE_TRANSFORM_ROT180_BIT_KHR = 0x00000004,
+    VK_SURFACE_TRANSFORM_ROT270_BIT_KHR = 0x00000008,
+    VK_SURFACE_TRANSFORM_HMIRROR_BIT_KHR = 0x00000010,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT90_BIT_KHR = 0x00000020,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT180_BIT_KHR = 0x00000040,
+    VK_SURFACE_TRANSFORM_HMIRROR_ROT270_BIT_KHR = 0x00000080,
+    VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR = 0x00000100,
+} VkSurfaceTransformFlagBitsKHR;
+typedef VkFlags VkSurfaceTransformFlagsKHR;
+
+typedef enum {
+    VK_PLATFORM_WIN32_KHR = 0,
+    VK_PLATFORM_X11_KHR = 1,
+    VK_PLATFORM_XCB_KHR = 2,
+    VK_PLATFORM_ANDROID_KHR = 3,
+    VK_PLATFORM_WAYLAND_KHR = 4,
+    VK_PLATFORM_MIR_KHR = 5,
+    VK_PLATFORM_BEGIN_RANGE_KHR = VK_PLATFORM_WIN32_KHR,
+    VK_PLATFORM_END_RANGE_KHR = VK_PLATFORM_MIR_KHR,
+    VK_PLATFORM_NUM_KHR = (VK_PLATFORM_MIR_KHR - VK_PLATFORM_WIN32_KHR + 1),
+    VK_PLATFORM_MAX_ENUM_KHR = 0x7FFFFFFF
+} VkPlatformKHR;
+
+// ------------------------------------------------------------------------------------------------
+// Flags
+
+// ------------------------------------------------------------------------------------------------
+// Structures
+
+// Placeholder structure header for the different types of surface description structures
+typedef struct {
+    VkStructureType                          sType;             // Can be any of the VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_XXX_KHR constants
+    const void*                              pNext;             // Pointer to next structure
+} VkSurfaceDescriptionKHR;
+
+// Surface description structure for a native platform window surface
+typedef struct {
+    VkStructureType                         sType;              // Must be VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR
+    const void*                             pNext;              // Pointer to next structure
+    VkPlatformKHR                           platform;           // e.g. VK_PLATFORM_*_KHR
+    void*                                   pPlatformHandle;
+    void*                                   pPlatformWindow;
+} VkSurfaceDescriptionWindowKHR;
+
+// pPlatformHandle points to this struct when platform is VK_PLATFORM_X11_KHR
+#ifdef _X11_XLIB_H_
+typedef struct {
+    Display*                                 dpy;               // Display connection to an X server
+    Window                                   root;              // To identify the X screen
+} VkPlatformHandleX11KHR;
+#endif /* _X11_XLIB_H_ */
+
+// pPlatformHandle points to this struct when platform is VK_PLATFORM_XCB_KHR
+#ifdef __XCB_H__
+typedef struct {
+    xcb_connection_t*                        connection;        // XCB connection to an X server
+    xcb_window_t                             root;              // To identify the X screen
+} VkPlatformHandleXcbKHR;
+#endif /* __XCB_H__ */
+
+// ------------------------------------------------------------------------------------------------
+// Function types
+
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceSurfaceSupportKHR)(VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceDescriptionKHR* pSurfaceDescription, VkBool32* pSupported);
+
+// ------------------------------------------------------------------------------------------------
+// Function prototypes
+
+#ifdef VK_PROTOTYPES
+
+VkResult VKAPI vkGetPhysicalDeviceSurfaceSupportKHR(
+    VkPhysicalDevice                        physicalDevice,
+    uint32_t                                queueFamilyIndex,
+    const VkSurfaceDescriptionKHR*          pSurfaceDescription,
+    VkBool32*                               pSupported);
+
+#endif // VK_PROTOTYPES
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // __VK_EXT_KHR_SWAPCHAIN_H__
diff --git a/include/vulkan/vk_platform.h b/include/vulkan/vk_platform.h
new file mode 100644 (file)
index 0000000..7ba8d77
--- /dev/null
@@ -0,0 +1,90 @@
+//
+// File: vk_platform.h
+//
+/*
+** Copyright (c) 2014-2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+
+#ifndef __VK_PLATFORM_H__
+#define __VK_PLATFORM_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+/*
+***************************************************************************************************
+*   Platform-specific directives and type declarations
+***************************************************************************************************
+*/
+
+#if defined(_WIN32)
+    // On Windows, VKAPI should equate to the __stdcall convention
+    #define VKAPI   __stdcall
+#elif defined(__GNUC__)
+    // On other platforms using GCC, VKAPI stays undefined
+    #define VKAPI
+#else
+    // Unsupported Platform!
+    #error "Unsupported OS Platform detected!"
+#endif
+
+#include <stddef.h>
+
+#if !defined(VK_NO_STDINT_H)
+    #if defined(_MSC_VER) && (_MSC_VER < 1600)
+        typedef signed   __int8  int8_t;
+        typedef unsigned __int8  uint8_t;
+        typedef signed   __int16 int16_t;
+        typedef unsigned __int16 uint16_t;
+        typedef signed   __int32 int32_t;
+        typedef unsigned __int32 uint32_t;
+        typedef signed   __int64 int64_t;
+        typedef unsigned __int64 uint64_t;
+    #else
+        #include <stdint.h>
+    #endif
+#endif // !defined(VK_NO_STDINT_H)
+
+typedef uint64_t   VkDeviceSize;
+typedef uint32_t   VkBool32;
+
+typedef uint32_t   VkSampleMask;
+typedef uint32_t   VkFlags;
+
+#if (UINTPTR_MAX >= UINT64_MAX)
+    #define VK_UINTPTRLEAST64_MAX UINTPTR_MAX
+
+    typedef uintptr_t VkUintPtrLeast64;
+#else
+    #define VK_UINTPTRLEAST64_MAX UINT64_MAX
+
+    typedef uint64_t  VkUintPtrLeast64;
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // __VK_PLATFORM_H__
diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
new file mode 100644 (file)
index 0000000..03bcefe
--- /dev/null
@@ -0,0 +1,3034 @@
+#ifndef __vulkan_h_
+#define __vulkan_h_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+/*
+** This header is generated from the Khronos Vulkan XML API Registry.
+**
+*/
+
+
+#define VK_VERSION_1_0 1
+#include "vk_platform.h"
+
+#define VK_MAKE_VERSION(major, minor, patch) \
+    ((major << 22) | (minor << 12) | patch)
+
+// Vulkan API version supported by this file
+#define VK_API_VERSION VK_MAKE_VERSION(0, 170, 2)
+
+
+#if defined(__cplusplus) && (_MSC_VER >= 1800 || __cplusplus >= 201103L)
+    #define VK_NULL_HANDLE nullptr
+#else
+    #define VK_NULL_HANDLE 0
+#endif
+
+
+#define VK_DEFINE_HANDLE(obj) typedef struct obj##_T* obj;
+
+
+#if defined(__cplusplus)
+    #if ((defined(_MSC_VER) && _MSC_VER >= 1800) || __cplusplus >= 201103L)
+        // The bool operator only works if there are no implicit conversions from an obj to
+        // a bool-compatible type, which can then be used to unintentionally violate type safety.
+        // C++11 and above supports the "explicit" keyword on conversion operators to stop this
+        // from happening. Otherwise users of C++ below C++11 won't get direct access to evaluating
+        // the object handle as a bool in expressions like:
+        //     if (obj) vkDestroy(obj);
+        #define VK_NONDISP_HANDLE_OPERATOR_BOOL() explicit operator bool() const { return handle != 0; }
+        #define VK_NONDISP_HANDLE_CONSTRUCTOR_FROM_UINT64(obj) \
+            explicit obj(uint64_t x) : handle(x) { } \
+            obj(decltype(nullptr)) : handle(0) { }
+    #else
+        #define VK_NONDISP_HANDLE_OPERATOR_BOOL()
+        #define VK_NONDISP_HANDLE_CONSTRUCTOR_FROM_UINT64(obj) \
+            obj(uint64_t x) : handle(x) { }
+    #endif
+    #define VK_DEFINE_NONDISP_HANDLE(obj) \
+        struct obj { \
+            obj() : handle(0) { } \
+            VK_NONDISP_HANDLE_CONSTRUCTOR_FROM_UINT64(obj) \
+            obj& operator =(uint64_t x) { handle = x; return *this; } \
+            bool operator==(const obj& other) const { return handle == other.handle; } \
+            bool operator!=(const obj& other) const { return handle != other.handle; } \
+            bool operator!() const { return !handle; } \
+            VK_NONDISP_HANDLE_OPERATOR_BOOL() \
+            uint64_t handle; \
+        };
+#else
+    #define VK_DEFINE_NONDISP_HANDLE(obj) typedef struct obj##_T { uint64_t handle; } obj;
+#endif
+        
+
+
+typedef uint32_t VkBool32;
+typedef uint32_t VkFlags;
+typedef uint64_t VkDeviceSize;
+typedef uint32_t VkSampleMask;
+
+VK_DEFINE_HANDLE(VkInstance)
+VK_DEFINE_HANDLE(VkPhysicalDevice)
+VK_DEFINE_HANDLE(VkDevice)
+VK_DEFINE_HANDLE(VkQueue)
+VK_DEFINE_HANDLE(VkCmdBuffer)
+VK_DEFINE_NONDISP_HANDLE(VkFence)
+VK_DEFINE_NONDISP_HANDLE(VkDeviceMemory)
+VK_DEFINE_NONDISP_HANDLE(VkBuffer)
+VK_DEFINE_NONDISP_HANDLE(VkImage)
+VK_DEFINE_NONDISP_HANDLE(VkSemaphore)
+VK_DEFINE_NONDISP_HANDLE(VkEvent)
+VK_DEFINE_NONDISP_HANDLE(VkQueryPool)
+VK_DEFINE_NONDISP_HANDLE(VkBufferView)
+VK_DEFINE_NONDISP_HANDLE(VkImageView)
+VK_DEFINE_NONDISP_HANDLE(VkShaderModule)
+VK_DEFINE_NONDISP_HANDLE(VkShader)
+VK_DEFINE_NONDISP_HANDLE(VkPipelineCache)
+VK_DEFINE_NONDISP_HANDLE(VkPipelineLayout)
+VK_DEFINE_NONDISP_HANDLE(VkRenderPass)
+VK_DEFINE_NONDISP_HANDLE(VkPipeline)
+VK_DEFINE_NONDISP_HANDLE(VkDescriptorSetLayout)
+VK_DEFINE_NONDISP_HANDLE(VkSampler)
+VK_DEFINE_NONDISP_HANDLE(VkDescriptorPool)
+VK_DEFINE_NONDISP_HANDLE(VkDescriptorSet)
+VK_DEFINE_NONDISP_HANDLE(VkFramebuffer)
+VK_DEFINE_NONDISP_HANDLE(VkCmdPool)
+
+#define VK_LOD_CLAMP_NONE                 1000.0f
+#define VK_REMAINING_MIP_LEVELS           (~0U)
+#define VK_REMAINING_ARRAY_LAYERS         (~0U)
+#define VK_WHOLE_SIZE                     (~0ULL)
+#define VK_ATTACHMENT_UNUSED              (~0U)
+#define VK_TRUE                           1
+#define VK_FALSE                          0
+#define VK_QUEUE_FAMILY_IGNORED           (~0U)
+#define VK_SUBPASS_EXTERNAL               (~0U)
+#define VK_MAX_PHYSICAL_DEVICE_NAME       256
+#define VK_UUID_LENGTH                    16
+#define VK_MAX_MEMORY_TYPES               32
+#define VK_MAX_MEMORY_HEAPS               16
+#define VK_MAX_EXTENSION_NAME             256
+#define VK_MAX_DESCRIPTION                256
+
+
+typedef enum {
+    VK_SUCCESS = 0,
+    VK_UNSUPPORTED = 1,
+    VK_NOT_READY = 2,
+    VK_TIMEOUT = 3,
+    VK_EVENT_SET = 4,
+    VK_EVENT_RESET = 5,
+    VK_INCOMPLETE = 6,
+    VK_ERROR_OUT_OF_HOST_MEMORY = -1,
+    VK_ERROR_OUT_OF_DEVICE_MEMORY = -2,
+    VK_ERROR_INITIALIZATION_FAILED = -3,
+    VK_ERROR_DEVICE_LOST = -4,
+    VK_ERROR_MEMORY_MAP_FAILED = -5,
+    VK_ERROR_LAYER_NOT_PRESENT = -6,
+    VK_ERROR_EXTENSION_NOT_PRESENT = -7,
+    VK_ERROR_INCOMPATIBLE_DRIVER = -8,
+    VK_RESULT_BEGIN_RANGE = VK_ERROR_INCOMPATIBLE_DRIVER,
+    VK_RESULT_END_RANGE = VK_INCOMPLETE,
+    VK_RESULT_NUM = (VK_INCOMPLETE - VK_ERROR_INCOMPATIBLE_DRIVER + 1),
+    VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+} VkResult;
+
+typedef enum {
+    VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
+    VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 1,
+    VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO = 2,
+    VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 3,
+    VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 4,
+    VK_STRUCTURE_TYPE_SHADER_CREATE_INFO = 5,
+    VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 6,
+    VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 7,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 8,
+    VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO = 9,
+    VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
+    VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 11,
+    VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 12,
+    VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 13,
+    VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 14,
+    VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 15,
+    VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 16,
+    VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 17,
+    VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 18,
+    VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 19,
+    VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO = 20,
+    VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 21,
+    VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 22,
+    VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 23,
+    VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 24,
+    VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 25,
+    VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 26,
+    VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 27,
+    VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO = 28,
+    VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 29,
+    VK_STRUCTURE_TYPE_MEMORY_BARRIER = 30,
+    VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 31,
+    VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 32,
+    VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
+    VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 34,
+    VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 35,
+    VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 36,
+    VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 37,
+    VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 38,
+    VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 39,
+    VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION = 40,
+    VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION = 41,
+    VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY = 42,
+    VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
+    VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO = 44,
+    VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 45,
+    VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 46,
+    VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
+    VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+    VK_STRUCTURE_TYPE_NUM = (VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
+    VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkStructureType;
+
+typedef enum {
+    VK_SYSTEM_ALLOC_TYPE_API_OBJECT = 0,
+    VK_SYSTEM_ALLOC_TYPE_INTERNAL = 1,
+    VK_SYSTEM_ALLOC_TYPE_INTERNAL_TEMP = 2,
+    VK_SYSTEM_ALLOC_TYPE_INTERNAL_SHADER = 3,
+    VK_SYSTEM_ALLOC_TYPE_DEBUG = 4,
+    VK_SYSTEM_ALLOC_TYPE_BEGIN_RANGE = VK_SYSTEM_ALLOC_TYPE_API_OBJECT,
+    VK_SYSTEM_ALLOC_TYPE_END_RANGE = VK_SYSTEM_ALLOC_TYPE_DEBUG,
+    VK_SYSTEM_ALLOC_TYPE_NUM = (VK_SYSTEM_ALLOC_TYPE_DEBUG - VK_SYSTEM_ALLOC_TYPE_API_OBJECT + 1),
+    VK_SYSTEM_ALLOC_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkSystemAllocType;
+
+typedef enum {
+    VK_FORMAT_UNDEFINED = 0,
+    VK_FORMAT_R4G4_UNORM = 1,
+    VK_FORMAT_R4G4_USCALED = 2,
+    VK_FORMAT_R4G4B4A4_UNORM = 3,
+    VK_FORMAT_R4G4B4A4_USCALED = 4,
+    VK_FORMAT_R5G6B5_UNORM = 5,
+    VK_FORMAT_R5G6B5_USCALED = 6,
+    VK_FORMAT_R5G5B5A1_UNORM = 7,
+    VK_FORMAT_R5G5B5A1_USCALED = 8,
+    VK_FORMAT_R8_UNORM = 9,
+    VK_FORMAT_R8_SNORM = 10,
+    VK_FORMAT_R8_USCALED = 11,
+    VK_FORMAT_R8_SSCALED = 12,
+    VK_FORMAT_R8_UINT = 13,
+    VK_FORMAT_R8_SINT = 14,
+    VK_FORMAT_R8_SRGB = 15,
+    VK_FORMAT_R8G8_UNORM = 16,
+    VK_FORMAT_R8G8_SNORM = 17,
+    VK_FORMAT_R8G8_USCALED = 18,
+    VK_FORMAT_R8G8_SSCALED = 19,
+    VK_FORMAT_R8G8_UINT = 20,
+    VK_FORMAT_R8G8_SINT = 21,
+    VK_FORMAT_R8G8_SRGB = 22,
+    VK_FORMAT_R8G8B8_UNORM = 23,
+    VK_FORMAT_R8G8B8_SNORM = 24,
+    VK_FORMAT_R8G8B8_USCALED = 25,
+    VK_FORMAT_R8G8B8_SSCALED = 26,
+    VK_FORMAT_R8G8B8_UINT = 27,
+    VK_FORMAT_R8G8B8_SINT = 28,
+    VK_FORMAT_R8G8B8_SRGB = 29,
+    VK_FORMAT_R8G8B8A8_UNORM = 30,
+    VK_FORMAT_R8G8B8A8_SNORM = 31,
+    VK_FORMAT_R8G8B8A8_USCALED = 32,
+    VK_FORMAT_R8G8B8A8_SSCALED = 33,
+    VK_FORMAT_R8G8B8A8_UINT = 34,
+    VK_FORMAT_R8G8B8A8_SINT = 35,
+    VK_FORMAT_R8G8B8A8_SRGB = 36,
+    VK_FORMAT_R10G10B10A2_UNORM = 37,
+    VK_FORMAT_R10G10B10A2_SNORM = 38,
+    VK_FORMAT_R10G10B10A2_USCALED = 39,
+    VK_FORMAT_R10G10B10A2_SSCALED = 40,
+    VK_FORMAT_R10G10B10A2_UINT = 41,
+    VK_FORMAT_R10G10B10A2_SINT = 42,
+    VK_FORMAT_R16_UNORM = 43,
+    VK_FORMAT_R16_SNORM = 44,
+    VK_FORMAT_R16_USCALED = 45,
+    VK_FORMAT_R16_SSCALED = 46,
+    VK_FORMAT_R16_UINT = 47,
+    VK_FORMAT_R16_SINT = 48,
+    VK_FORMAT_R16_SFLOAT = 49,
+    VK_FORMAT_R16G16_UNORM = 50,
+    VK_FORMAT_R16G16_SNORM = 51,
+    VK_FORMAT_R16G16_USCALED = 52,
+    VK_FORMAT_R16G16_SSCALED = 53,
+    VK_FORMAT_R16G16_UINT = 54,
+    VK_FORMAT_R16G16_SINT = 55,
+    VK_FORMAT_R16G16_SFLOAT = 56,
+    VK_FORMAT_R16G16B16_UNORM = 57,
+    VK_FORMAT_R16G16B16_SNORM = 58,
+    VK_FORMAT_R16G16B16_USCALED = 59,
+    VK_FORMAT_R16G16B16_SSCALED = 60,
+    VK_FORMAT_R16G16B16_UINT = 61,
+    VK_FORMAT_R16G16B16_SINT = 62,
+    VK_FORMAT_R16G16B16_SFLOAT = 63,
+    VK_FORMAT_R16G16B16A16_UNORM = 64,
+    VK_FORMAT_R16G16B16A16_SNORM = 65,
+    VK_FORMAT_R16G16B16A16_USCALED = 66,
+    VK_FORMAT_R16G16B16A16_SSCALED = 67,
+    VK_FORMAT_R16G16B16A16_UINT = 68,
+    VK_FORMAT_R16G16B16A16_SINT = 69,
+    VK_FORMAT_R16G16B16A16_SFLOAT = 70,
+    VK_FORMAT_R32_UINT = 71,
+    VK_FORMAT_R32_SINT = 72,
+    VK_FORMAT_R32_SFLOAT = 73,
+    VK_FORMAT_R32G32_UINT = 74,
+    VK_FORMAT_R32G32_SINT = 75,
+    VK_FORMAT_R32G32_SFLOAT = 76,
+    VK_FORMAT_R32G32B32_UINT = 77,
+    VK_FORMAT_R32G32B32_SINT = 78,
+    VK_FORMAT_R32G32B32_SFLOAT = 79,
+    VK_FORMAT_R32G32B32A32_UINT = 80,
+    VK_FORMAT_R32G32B32A32_SINT = 81,
+    VK_FORMAT_R32G32B32A32_SFLOAT = 82,
+    VK_FORMAT_R64_SFLOAT = 83,
+    VK_FORMAT_R64G64_SFLOAT = 84,
+    VK_FORMAT_R64G64B64_SFLOAT = 85,
+    VK_FORMAT_R64G64B64A64_SFLOAT = 86,
+    VK_FORMAT_R11G11B10_UFLOAT = 87,
+    VK_FORMAT_R9G9B9E5_UFLOAT = 88,
+    VK_FORMAT_D16_UNORM = 89,
+    VK_FORMAT_D24_UNORM_X8 = 90,
+    VK_FORMAT_D32_SFLOAT = 91,
+    VK_FORMAT_S8_UINT = 92,
+    VK_FORMAT_D16_UNORM_S8_UINT = 93,
+    VK_FORMAT_D24_UNORM_S8_UINT = 94,
+    VK_FORMAT_D32_SFLOAT_S8_UINT = 95,
+    VK_FORMAT_BC1_RGB_UNORM = 96,
+    VK_FORMAT_BC1_RGB_SRGB = 97,
+    VK_FORMAT_BC1_RGBA_UNORM = 98,
+    VK_FORMAT_BC1_RGBA_SRGB = 99,
+    VK_FORMAT_BC2_UNORM = 100,
+    VK_FORMAT_BC2_SRGB = 101,
+    VK_FORMAT_BC3_UNORM = 102,
+    VK_FORMAT_BC3_SRGB = 103,
+    VK_FORMAT_BC4_UNORM = 104,
+    VK_FORMAT_BC4_SNORM = 105,
+    VK_FORMAT_BC5_UNORM = 106,
+    VK_FORMAT_BC5_SNORM = 107,
+    VK_FORMAT_BC6H_UFLOAT = 108,
+    VK_FORMAT_BC6H_SFLOAT = 109,
+    VK_FORMAT_BC7_UNORM = 110,
+    VK_FORMAT_BC7_SRGB = 111,
+    VK_FORMAT_ETC2_R8G8B8_UNORM = 112,
+    VK_FORMAT_ETC2_R8G8B8_SRGB = 113,
+    VK_FORMAT_ETC2_R8G8B8A1_UNORM = 114,
+    VK_FORMAT_ETC2_R8G8B8A1_SRGB = 115,
+    VK_FORMAT_ETC2_R8G8B8A8_UNORM = 116,
+    VK_FORMAT_ETC2_R8G8B8A8_SRGB = 117,
+    VK_FORMAT_EAC_R11_UNORM = 118,
+    VK_FORMAT_EAC_R11_SNORM = 119,
+    VK_FORMAT_EAC_R11G11_UNORM = 120,
+    VK_FORMAT_EAC_R11G11_SNORM = 121,
+    VK_FORMAT_ASTC_4x4_UNORM = 122,
+    VK_FORMAT_ASTC_4x4_SRGB = 123,
+    VK_FORMAT_ASTC_5x4_UNORM = 124,
+    VK_FORMAT_ASTC_5x4_SRGB = 125,
+    VK_FORMAT_ASTC_5x5_UNORM = 126,
+    VK_FORMAT_ASTC_5x5_SRGB = 127,
+    VK_FORMAT_ASTC_6x5_UNORM = 128,
+    VK_FORMAT_ASTC_6x5_SRGB = 129,
+    VK_FORMAT_ASTC_6x6_UNORM = 130,
+    VK_FORMAT_ASTC_6x6_SRGB = 131,
+    VK_FORMAT_ASTC_8x5_UNORM = 132,
+    VK_FORMAT_ASTC_8x5_SRGB = 133,
+    VK_FORMAT_ASTC_8x6_UNORM = 134,
+    VK_FORMAT_ASTC_8x6_SRGB = 135,
+    VK_FORMAT_ASTC_8x8_UNORM = 136,
+    VK_FORMAT_ASTC_8x8_SRGB = 137,
+    VK_FORMAT_ASTC_10x5_UNORM = 138,
+    VK_FORMAT_ASTC_10x5_SRGB = 139,
+    VK_FORMAT_ASTC_10x6_UNORM = 140,
+    VK_FORMAT_ASTC_10x6_SRGB = 141,
+    VK_FORMAT_ASTC_10x8_UNORM = 142,
+    VK_FORMAT_ASTC_10x8_SRGB = 143,
+    VK_FORMAT_ASTC_10x10_UNORM = 144,
+    VK_FORMAT_ASTC_10x10_SRGB = 145,
+    VK_FORMAT_ASTC_12x10_UNORM = 146,
+    VK_FORMAT_ASTC_12x10_SRGB = 147,
+    VK_FORMAT_ASTC_12x12_UNORM = 148,
+    VK_FORMAT_ASTC_12x12_SRGB = 149,
+    VK_FORMAT_B4G4R4A4_UNORM = 150,
+    VK_FORMAT_B5G5R5A1_UNORM = 151,
+    VK_FORMAT_B5G6R5_UNORM = 152,
+    VK_FORMAT_B5G6R5_USCALED = 153,
+    VK_FORMAT_B8G8R8_UNORM = 154,
+    VK_FORMAT_B8G8R8_SNORM = 155,
+    VK_FORMAT_B8G8R8_USCALED = 156,
+    VK_FORMAT_B8G8R8_SSCALED = 157,
+    VK_FORMAT_B8G8R8_UINT = 158,
+    VK_FORMAT_B8G8R8_SINT = 159,
+    VK_FORMAT_B8G8R8_SRGB = 160,
+    VK_FORMAT_B8G8R8A8_UNORM = 161,
+    VK_FORMAT_B8G8R8A8_SNORM = 162,
+    VK_FORMAT_B8G8R8A8_USCALED = 163,
+    VK_FORMAT_B8G8R8A8_SSCALED = 164,
+    VK_FORMAT_B8G8R8A8_UINT = 165,
+    VK_FORMAT_B8G8R8A8_SINT = 166,
+    VK_FORMAT_B8G8R8A8_SRGB = 167,
+    VK_FORMAT_B10G10R10A2_UNORM = 168,
+    VK_FORMAT_B10G10R10A2_SNORM = 169,
+    VK_FORMAT_B10G10R10A2_USCALED = 170,
+    VK_FORMAT_B10G10R10A2_SSCALED = 171,
+    VK_FORMAT_B10G10R10A2_UINT = 172,
+    VK_FORMAT_B10G10R10A2_SINT = 173,
+    VK_FORMAT_BEGIN_RANGE = VK_FORMAT_UNDEFINED,
+    VK_FORMAT_END_RANGE = VK_FORMAT_B10G10R10A2_SINT,
+    VK_FORMAT_NUM = (VK_FORMAT_B10G10R10A2_SINT - VK_FORMAT_UNDEFINED + 1),
+    VK_FORMAT_MAX_ENUM = 0x7FFFFFFF
+} VkFormat;
+
+typedef enum {
+    VK_IMAGE_TYPE_1D = 0,
+    VK_IMAGE_TYPE_2D = 1,
+    VK_IMAGE_TYPE_3D = 2,
+    VK_IMAGE_TYPE_BEGIN_RANGE = VK_IMAGE_TYPE_1D,
+    VK_IMAGE_TYPE_END_RANGE = VK_IMAGE_TYPE_3D,
+    VK_IMAGE_TYPE_NUM = (VK_IMAGE_TYPE_3D - VK_IMAGE_TYPE_1D + 1),
+    VK_IMAGE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageType;
+
+typedef enum {
+    VK_IMAGE_TILING_LINEAR = 0,
+    VK_IMAGE_TILING_OPTIMAL = 1,
+    VK_IMAGE_TILING_BEGIN_RANGE = VK_IMAGE_TILING_LINEAR,
+    VK_IMAGE_TILING_END_RANGE = VK_IMAGE_TILING_OPTIMAL,
+    VK_IMAGE_TILING_NUM = (VK_IMAGE_TILING_OPTIMAL - VK_IMAGE_TILING_LINEAR + 1),
+    VK_IMAGE_TILING_MAX_ENUM = 0x7FFFFFFF
+} VkImageTiling;
+
+typedef enum {
+    VK_PHYSICAL_DEVICE_TYPE_OTHER = 0,
+    VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU = 1,
+    VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU = 2,
+    VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU = 3,
+    VK_PHYSICAL_DEVICE_TYPE_CPU = 4,
+    VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE = VK_PHYSICAL_DEVICE_TYPE_OTHER,
+    VK_PHYSICAL_DEVICE_TYPE_END_RANGE = VK_PHYSICAL_DEVICE_TYPE_CPU,
+    VK_PHYSICAL_DEVICE_TYPE_NUM = (VK_PHYSICAL_DEVICE_TYPE_CPU - VK_PHYSICAL_DEVICE_TYPE_OTHER + 1),
+    VK_PHYSICAL_DEVICE_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkPhysicalDeviceType;
+
+typedef enum {
+    VK_IMAGE_ASPECT_COLOR = 0,
+    VK_IMAGE_ASPECT_DEPTH = 1,
+    VK_IMAGE_ASPECT_STENCIL = 2,
+    VK_IMAGE_ASPECT_METADATA = 3,
+    VK_IMAGE_ASPECT_BEGIN_RANGE = VK_IMAGE_ASPECT_COLOR,
+    VK_IMAGE_ASPECT_END_RANGE = VK_IMAGE_ASPECT_METADATA,
+    VK_IMAGE_ASPECT_NUM = (VK_IMAGE_ASPECT_METADATA - VK_IMAGE_ASPECT_COLOR + 1),
+    VK_IMAGE_ASPECT_MAX_ENUM = 0x7FFFFFFF
+} VkImageAspect;
+
+typedef enum {
+    VK_QUERY_TYPE_OCCLUSION = 0,
+    VK_QUERY_TYPE_PIPELINE_STATISTICS = 1,
+    VK_QUERY_TYPE_BEGIN_RANGE = VK_QUERY_TYPE_OCCLUSION,
+    VK_QUERY_TYPE_END_RANGE = VK_QUERY_TYPE_PIPELINE_STATISTICS,
+    VK_QUERY_TYPE_NUM = (VK_QUERY_TYPE_PIPELINE_STATISTICS - VK_QUERY_TYPE_OCCLUSION + 1),
+    VK_QUERY_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkQueryType;
+
+typedef enum {
+    VK_SHARING_MODE_EXCLUSIVE = 0,
+    VK_SHARING_MODE_CONCURRENT = 1,
+    VK_SHARING_MODE_BEGIN_RANGE = VK_SHARING_MODE_EXCLUSIVE,
+    VK_SHARING_MODE_END_RANGE = VK_SHARING_MODE_CONCURRENT,
+    VK_SHARING_MODE_NUM = (VK_SHARING_MODE_CONCURRENT - VK_SHARING_MODE_EXCLUSIVE + 1),
+    VK_SHARING_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkSharingMode;
+
+typedef enum {
+    VK_IMAGE_LAYOUT_UNDEFINED = 0,
+    VK_IMAGE_LAYOUT_GENERAL = 1,
+    VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL = 2,
+    VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL = 3,
+    VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL = 4,
+    VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL = 5,
+    VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL = 6,
+    VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL = 7,
+    VK_IMAGE_LAYOUT_PREINITIALIZED = 8,
+    VK_IMAGE_LAYOUT_BEGIN_RANGE = VK_IMAGE_LAYOUT_UNDEFINED,
+    VK_IMAGE_LAYOUT_END_RANGE = VK_IMAGE_LAYOUT_PREINITIALIZED,
+    VK_IMAGE_LAYOUT_NUM = (VK_IMAGE_LAYOUT_PREINITIALIZED - VK_IMAGE_LAYOUT_UNDEFINED + 1),
+    VK_IMAGE_LAYOUT_MAX_ENUM = 0x7FFFFFFF
+} VkImageLayout;
+
+typedef enum {
+    VK_IMAGE_VIEW_TYPE_1D = 0,
+    VK_IMAGE_VIEW_TYPE_2D = 1,
+    VK_IMAGE_VIEW_TYPE_3D = 2,
+    VK_IMAGE_VIEW_TYPE_CUBE = 3,
+    VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,
+    VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,
+    VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6,
+    VK_IMAGE_VIEW_TYPE_BEGIN_RANGE = VK_IMAGE_VIEW_TYPE_1D,
+    VK_IMAGE_VIEW_TYPE_END_RANGE = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY,
+    VK_IMAGE_VIEW_TYPE_NUM = (VK_IMAGE_VIEW_TYPE_CUBE_ARRAY - VK_IMAGE_VIEW_TYPE_1D + 1),
+    VK_IMAGE_VIEW_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkImageViewType;
+
+typedef enum {
+    VK_CHANNEL_SWIZZLE_ZERO = 0,
+    VK_CHANNEL_SWIZZLE_ONE = 1,
+    VK_CHANNEL_SWIZZLE_R = 2,
+    VK_CHANNEL_SWIZZLE_G = 3,
+    VK_CHANNEL_SWIZZLE_B = 4,
+    VK_CHANNEL_SWIZZLE_A = 5,
+    VK_CHANNEL_SWIZZLE_BEGIN_RANGE = VK_CHANNEL_SWIZZLE_ZERO,
+    VK_CHANNEL_SWIZZLE_END_RANGE = VK_CHANNEL_SWIZZLE_A,
+    VK_CHANNEL_SWIZZLE_NUM = (VK_CHANNEL_SWIZZLE_A - VK_CHANNEL_SWIZZLE_ZERO + 1),
+    VK_CHANNEL_SWIZZLE_MAX_ENUM = 0x7FFFFFFF
+} VkChannelSwizzle;
+
+typedef enum {
+    VK_SHADER_STAGE_VERTEX = 0,
+    VK_SHADER_STAGE_TESS_CONTROL = 1,
+    VK_SHADER_STAGE_TESS_EVALUATION = 2,
+    VK_SHADER_STAGE_GEOMETRY = 3,
+    VK_SHADER_STAGE_FRAGMENT = 4,
+    VK_SHADER_STAGE_COMPUTE = 5,
+    VK_SHADER_STAGE_BEGIN_RANGE = VK_SHADER_STAGE_VERTEX,
+    VK_SHADER_STAGE_END_RANGE = VK_SHADER_STAGE_COMPUTE,
+    VK_SHADER_STAGE_NUM = (VK_SHADER_STAGE_COMPUTE - VK_SHADER_STAGE_VERTEX + 1),
+    VK_SHADER_STAGE_MAX_ENUM = 0x7FFFFFFF
+} VkShaderStage;
+
+typedef enum {
+    VK_VERTEX_INPUT_STEP_RATE_VERTEX = 0,
+    VK_VERTEX_INPUT_STEP_RATE_INSTANCE = 1,
+    VK_VERTEX_INPUT_STEP_RATE_BEGIN_RANGE = VK_VERTEX_INPUT_STEP_RATE_VERTEX,
+    VK_VERTEX_INPUT_STEP_RATE_END_RANGE = VK_VERTEX_INPUT_STEP_RATE_INSTANCE,
+    VK_VERTEX_INPUT_STEP_RATE_NUM = (VK_VERTEX_INPUT_STEP_RATE_INSTANCE - VK_VERTEX_INPUT_STEP_RATE_VERTEX + 1),
+    VK_VERTEX_INPUT_STEP_RATE_MAX_ENUM = 0x7FFFFFFF
+} VkVertexInputStepRate;
+
+typedef enum {
+    VK_PRIMITIVE_TOPOLOGY_POINT_LIST = 0,
+    VK_PRIMITIVE_TOPOLOGY_LINE_LIST = 1,
+    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP = 2,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST = 3,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP = 4,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN = 5,
+    VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ = 6,
+    VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ = 7,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ = 8,
+    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ = 9,
+    VK_PRIMITIVE_TOPOLOGY_PATCH = 10,
+    VK_PRIMITIVE_TOPOLOGY_BEGIN_RANGE = VK_PRIMITIVE_TOPOLOGY_POINT_LIST,
+    VK_PRIMITIVE_TOPOLOGY_END_RANGE = VK_PRIMITIVE_TOPOLOGY_PATCH,
+    VK_PRIMITIVE_TOPOLOGY_NUM = (VK_PRIMITIVE_TOPOLOGY_PATCH - VK_PRIMITIVE_TOPOLOGY_POINT_LIST + 1),
+    VK_PRIMITIVE_TOPOLOGY_MAX_ENUM = 0x7FFFFFFF
+} VkPrimitiveTopology;
+
+typedef enum {
+    VK_FILL_MODE_POINTS = 0,
+    VK_FILL_MODE_WIREFRAME = 1,
+    VK_FILL_MODE_SOLID = 2,
+    VK_FILL_MODE_BEGIN_RANGE = VK_FILL_MODE_POINTS,
+    VK_FILL_MODE_END_RANGE = VK_FILL_MODE_SOLID,
+    VK_FILL_MODE_NUM = (VK_FILL_MODE_SOLID - VK_FILL_MODE_POINTS + 1),
+    VK_FILL_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkFillMode;
+
+typedef enum {
+    VK_CULL_MODE_NONE = 0,
+    VK_CULL_MODE_FRONT = 1,
+    VK_CULL_MODE_BACK = 2,
+    VK_CULL_MODE_FRONT_AND_BACK = 3,
+    VK_CULL_MODE_BEGIN_RANGE = VK_CULL_MODE_NONE,
+    VK_CULL_MODE_END_RANGE = VK_CULL_MODE_FRONT_AND_BACK,
+    VK_CULL_MODE_NUM = (VK_CULL_MODE_FRONT_AND_BACK - VK_CULL_MODE_NONE + 1),
+    VK_CULL_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkCullMode;
+
+typedef enum {
+    VK_FRONT_FACE_CCW = 0,
+    VK_FRONT_FACE_CW = 1,
+    VK_FRONT_FACE_BEGIN_RANGE = VK_FRONT_FACE_CCW,
+    VK_FRONT_FACE_END_RANGE = VK_FRONT_FACE_CW,
+    VK_FRONT_FACE_NUM = (VK_FRONT_FACE_CW - VK_FRONT_FACE_CCW + 1),
+    VK_FRONT_FACE_MAX_ENUM = 0x7FFFFFFF
+} VkFrontFace;
+
+typedef enum {
+    VK_COMPARE_OP_NEVER = 0,
+    VK_COMPARE_OP_LESS = 1,
+    VK_COMPARE_OP_EQUAL = 2,
+    VK_COMPARE_OP_LESS_EQUAL = 3,
+    VK_COMPARE_OP_GREATER = 4,
+    VK_COMPARE_OP_NOT_EQUAL = 5,
+    VK_COMPARE_OP_GREATER_EQUAL = 6,
+    VK_COMPARE_OP_ALWAYS = 7,
+    VK_COMPARE_OP_BEGIN_RANGE = VK_COMPARE_OP_NEVER,
+    VK_COMPARE_OP_END_RANGE = VK_COMPARE_OP_ALWAYS,
+    VK_COMPARE_OP_NUM = (VK_COMPARE_OP_ALWAYS - VK_COMPARE_OP_NEVER + 1),
+    VK_COMPARE_OP_MAX_ENUM = 0x7FFFFFFF
+} VkCompareOp;
+
+typedef enum {
+    VK_STENCIL_OP_KEEP = 0,
+    VK_STENCIL_OP_ZERO = 1,
+    VK_STENCIL_OP_REPLACE = 2,
+    VK_STENCIL_OP_INC_CLAMP = 3,
+    VK_STENCIL_OP_DEC_CLAMP = 4,
+    VK_STENCIL_OP_INVERT = 5,
+    VK_STENCIL_OP_INC_WRAP = 6,
+    VK_STENCIL_OP_DEC_WRAP = 7,
+    VK_STENCIL_OP_BEGIN_RANGE = VK_STENCIL_OP_KEEP,
+    VK_STENCIL_OP_END_RANGE = VK_STENCIL_OP_DEC_WRAP,
+    VK_STENCIL_OP_NUM = (VK_STENCIL_OP_DEC_WRAP - VK_STENCIL_OP_KEEP + 1),
+    VK_STENCIL_OP_MAX_ENUM = 0x7FFFFFFF
+} VkStencilOp;
+
+typedef enum {
+    VK_LOGIC_OP_CLEAR = 0,
+    VK_LOGIC_OP_AND = 1,
+    VK_LOGIC_OP_AND_REVERSE = 2,
+    VK_LOGIC_OP_COPY = 3,
+    VK_LOGIC_OP_AND_INVERTED = 4,
+    VK_LOGIC_OP_NOOP = 5,
+    VK_LOGIC_OP_XOR = 6,
+    VK_LOGIC_OP_OR = 7,
+    VK_LOGIC_OP_NOR = 8,
+    VK_LOGIC_OP_EQUIV = 9,
+    VK_LOGIC_OP_INVERT = 10,
+    VK_LOGIC_OP_OR_REVERSE = 11,
+    VK_LOGIC_OP_COPY_INVERTED = 12,
+    VK_LOGIC_OP_OR_INVERTED = 13,
+    VK_LOGIC_OP_NAND = 14,
+    VK_LOGIC_OP_SET = 15,
+    VK_LOGIC_OP_BEGIN_RANGE = VK_LOGIC_OP_CLEAR,
+    VK_LOGIC_OP_END_RANGE = VK_LOGIC_OP_SET,
+    VK_LOGIC_OP_NUM = (VK_LOGIC_OP_SET - VK_LOGIC_OP_CLEAR + 1),
+    VK_LOGIC_OP_MAX_ENUM = 0x7FFFFFFF
+} VkLogicOp;
+
+typedef enum {
+    VK_BLEND_ZERO = 0,
+    VK_BLEND_ONE = 1,
+    VK_BLEND_SRC_COLOR = 2,
+    VK_BLEND_ONE_MINUS_SRC_COLOR = 3,
+    VK_BLEND_DEST_COLOR = 4,
+    VK_BLEND_ONE_MINUS_DEST_COLOR = 5,
+    VK_BLEND_SRC_ALPHA = 6,
+    VK_BLEND_ONE_MINUS_SRC_ALPHA = 7,
+    VK_BLEND_DEST_ALPHA = 8,
+    VK_BLEND_ONE_MINUS_DEST_ALPHA = 9,
+    VK_BLEND_CONSTANT_COLOR = 10,
+    VK_BLEND_ONE_MINUS_CONSTANT_COLOR = 11,
+    VK_BLEND_CONSTANT_ALPHA = 12,
+    VK_BLEND_ONE_MINUS_CONSTANT_ALPHA = 13,
+    VK_BLEND_SRC_ALPHA_SATURATE = 14,
+    VK_BLEND_SRC1_COLOR = 15,
+    VK_BLEND_ONE_MINUS_SRC1_COLOR = 16,
+    VK_BLEND_SRC1_ALPHA = 17,
+    VK_BLEND_ONE_MINUS_SRC1_ALPHA = 18,
+    VK_BLEND_BEGIN_RANGE = VK_BLEND_ZERO,
+    VK_BLEND_END_RANGE = VK_BLEND_ONE_MINUS_SRC1_ALPHA,
+    VK_BLEND_NUM = (VK_BLEND_ONE_MINUS_SRC1_ALPHA - VK_BLEND_ZERO + 1),
+    VK_BLEND_MAX_ENUM = 0x7FFFFFFF
+} VkBlend;
+
+typedef enum {
+    VK_BLEND_OP_ADD = 0,
+    VK_BLEND_OP_SUBTRACT = 1,
+    VK_BLEND_OP_REVERSE_SUBTRACT = 2,
+    VK_BLEND_OP_MIN = 3,
+    VK_BLEND_OP_MAX = 4,
+    VK_BLEND_OP_BEGIN_RANGE = VK_BLEND_OP_ADD,
+    VK_BLEND_OP_END_RANGE = VK_BLEND_OP_MAX,
+    VK_BLEND_OP_NUM = (VK_BLEND_OP_MAX - VK_BLEND_OP_ADD + 1),
+    VK_BLEND_OP_MAX_ENUM = 0x7FFFFFFF
+} VkBlendOp;
+
+typedef enum {
+    VK_DYNAMIC_STATE_VIEWPORT = 0,
+    VK_DYNAMIC_STATE_SCISSOR = 1,
+    VK_DYNAMIC_STATE_LINE_WIDTH = 2,
+    VK_DYNAMIC_STATE_DEPTH_BIAS = 3,
+    VK_DYNAMIC_STATE_BLEND_CONSTANTS = 4,
+    VK_DYNAMIC_STATE_DEPTH_BOUNDS = 5,
+    VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK = 6,
+    VK_DYNAMIC_STATE_STENCIL_WRITE_MASK = 7,
+    VK_DYNAMIC_STATE_STENCIL_REFERENCE = 8,
+    VK_DYNAMIC_STATE_BEGIN_RANGE = VK_DYNAMIC_STATE_VIEWPORT,
+    VK_DYNAMIC_STATE_END_RANGE = VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+    VK_DYNAMIC_STATE_NUM = (VK_DYNAMIC_STATE_STENCIL_REFERENCE - VK_DYNAMIC_STATE_VIEWPORT + 1),
+    VK_DYNAMIC_STATE_MAX_ENUM = 0x7FFFFFFF
+} VkDynamicState;
+
+typedef enum {
+    VK_TEX_FILTER_NEAREST = 0,
+    VK_TEX_FILTER_LINEAR = 1,
+    VK_TEX_FILTER_BEGIN_RANGE = VK_TEX_FILTER_NEAREST,
+    VK_TEX_FILTER_END_RANGE = VK_TEX_FILTER_LINEAR,
+    VK_TEX_FILTER_NUM = (VK_TEX_FILTER_LINEAR - VK_TEX_FILTER_NEAREST + 1),
+    VK_TEX_FILTER_MAX_ENUM = 0x7FFFFFFF
+} VkTexFilter;
+
+typedef enum {
+    VK_TEX_MIPMAP_MODE_BASE = 0,
+    VK_TEX_MIPMAP_MODE_NEAREST = 1,
+    VK_TEX_MIPMAP_MODE_LINEAR = 2,
+    VK_TEX_MIPMAP_MODE_BEGIN_RANGE = VK_TEX_MIPMAP_MODE_BASE,
+    VK_TEX_MIPMAP_MODE_END_RANGE = VK_TEX_MIPMAP_MODE_LINEAR,
+    VK_TEX_MIPMAP_MODE_NUM = (VK_TEX_MIPMAP_MODE_LINEAR - VK_TEX_MIPMAP_MODE_BASE + 1),
+    VK_TEX_MIPMAP_MODE_MAX_ENUM = 0x7FFFFFFF
+} VkTexMipmapMode;
+
+typedef enum {
+    VK_TEX_ADDRESS_MODE_WRAP = 0,
+    VK_TEX_ADDRESS_MODE_MIRROR = 1,
+    VK_TEX_ADDRESS_MODE_CLAMP = 2,
+    VK_TEX_ADDRESS_MODE_MIRROR_ONCE = 3,
+    VK_TEX_ADDRESS_MODE_CLAMP_BORDER = 4,
+    VK_TEX_ADDRESS_BEGIN_RANGE = VK_TEX_ADDRESS_MODE_WRAP,
+    VK_TEX_ADDRESS_END_RANGE = VK_TEX_ADDRESS_MODE_CLAMP_BORDER,
+    VK_TEX_ADDRESS_NUM = (VK_TEX_ADDRESS_MODE_CLAMP_BORDER - VK_TEX_ADDRESS_MODE_WRAP + 1),
+    VK_TEX_ADDRESS_MAX_ENUM = 0x7FFFFFFF
+} VkTexAddressMode;
+
+typedef enum {
+    VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK = 0,
+    VK_BORDER_COLOR_INT_TRANSPARENT_BLACK = 1,
+    VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK = 2,
+    VK_BORDER_COLOR_INT_OPAQUE_BLACK = 3,
+    VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE = 4,
+    VK_BORDER_COLOR_INT_OPAQUE_WHITE = 5,
+    VK_BORDER_COLOR_BEGIN_RANGE = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
+    VK_BORDER_COLOR_END_RANGE = VK_BORDER_COLOR_INT_OPAQUE_WHITE,
+    VK_BORDER_COLOR_NUM = (VK_BORDER_COLOR_INT_OPAQUE_WHITE - VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK + 1),
+    VK_BORDER_COLOR_MAX_ENUM = 0x7FFFFFFF
+} VkBorderColor;
+
+typedef enum {
+    VK_DESCRIPTOR_TYPE_SAMPLER = 0,
+    VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER = 1,
+    VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE = 2,
+    VK_DESCRIPTOR_TYPE_STORAGE_IMAGE = 3,
+    VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER = 4,
+    VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER = 5,
+    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER = 6,
+    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER = 7,
+    VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC = 8,
+    VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC = 9,
+    VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT = 10,
+    VK_DESCRIPTOR_TYPE_BEGIN_RANGE = VK_DESCRIPTOR_TYPE_SAMPLER,
+    VK_DESCRIPTOR_TYPE_END_RANGE = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
+    VK_DESCRIPTOR_TYPE_NUM = (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT - VK_DESCRIPTOR_TYPE_SAMPLER + 1),
+    VK_DESCRIPTOR_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorType;
+
+typedef enum {
+    VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT = 0,
+    VK_DESCRIPTOR_POOL_USAGE_DYNAMIC = 1,
+    VK_DESCRIPTOR_POOL_USAGE_BEGIN_RANGE = VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT,
+    VK_DESCRIPTOR_POOL_USAGE_END_RANGE = VK_DESCRIPTOR_POOL_USAGE_DYNAMIC,
+    VK_DESCRIPTOR_POOL_USAGE_NUM = (VK_DESCRIPTOR_POOL_USAGE_DYNAMIC - VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT + 1),
+    VK_DESCRIPTOR_POOL_USAGE_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorPoolUsage;
+
+typedef enum {
+    VK_DESCRIPTOR_SET_USAGE_ONE_SHOT = 0,
+    VK_DESCRIPTOR_SET_USAGE_STATIC = 1,
+    VK_DESCRIPTOR_SET_USAGE_BEGIN_RANGE = VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
+    VK_DESCRIPTOR_SET_USAGE_END_RANGE = VK_DESCRIPTOR_SET_USAGE_STATIC,
+    VK_DESCRIPTOR_SET_USAGE_NUM = (VK_DESCRIPTOR_SET_USAGE_STATIC - VK_DESCRIPTOR_SET_USAGE_ONE_SHOT + 1),
+    VK_DESCRIPTOR_SET_USAGE_MAX_ENUM = 0x7FFFFFFF
+} VkDescriptorSetUsage;
+
+typedef enum {
+    VK_ATTACHMENT_LOAD_OP_LOAD = 0,
+    VK_ATTACHMENT_LOAD_OP_CLEAR = 1,
+    VK_ATTACHMENT_LOAD_OP_DONT_CARE = 2,
+    VK_ATTACHMENT_LOAD_OP_BEGIN_RANGE = VK_ATTACHMENT_LOAD_OP_LOAD,
+    VK_ATTACHMENT_LOAD_OP_END_RANGE = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
+    VK_ATTACHMENT_LOAD_OP_NUM = (VK_ATTACHMENT_LOAD_OP_DONT_CARE - VK_ATTACHMENT_LOAD_OP_LOAD + 1),
+    VK_ATTACHMENT_LOAD_OP_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentLoadOp;
+
+typedef enum {
+    VK_ATTACHMENT_STORE_OP_STORE = 0,
+    VK_ATTACHMENT_STORE_OP_DONT_CARE = 1,
+    VK_ATTACHMENT_STORE_OP_BEGIN_RANGE = VK_ATTACHMENT_STORE_OP_STORE,
+    VK_ATTACHMENT_STORE_OP_END_RANGE = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+    VK_ATTACHMENT_STORE_OP_NUM = (VK_ATTACHMENT_STORE_OP_DONT_CARE - VK_ATTACHMENT_STORE_OP_STORE + 1),
+    VK_ATTACHMENT_STORE_OP_MAX_ENUM = 0x7FFFFFFF
+} VkAttachmentStoreOp;
+
+typedef enum {
+    VK_PIPELINE_BIND_POINT_COMPUTE = 0,
+    VK_PIPELINE_BIND_POINT_GRAPHICS = 1,
+    VK_PIPELINE_BIND_POINT_BEGIN_RANGE = VK_PIPELINE_BIND_POINT_COMPUTE,
+    VK_PIPELINE_BIND_POINT_END_RANGE = VK_PIPELINE_BIND_POINT_GRAPHICS,
+    VK_PIPELINE_BIND_POINT_NUM = (VK_PIPELINE_BIND_POINT_GRAPHICS - VK_PIPELINE_BIND_POINT_COMPUTE + 1),
+    VK_PIPELINE_BIND_POINT_MAX_ENUM = 0x7FFFFFFF
+} VkPipelineBindPoint;
+
+typedef enum {
+    VK_CMD_BUFFER_LEVEL_PRIMARY = 0,
+    VK_CMD_BUFFER_LEVEL_SECONDARY = 1,
+    VK_CMD_BUFFER_LEVEL_BEGIN_RANGE = VK_CMD_BUFFER_LEVEL_PRIMARY,
+    VK_CMD_BUFFER_LEVEL_END_RANGE = VK_CMD_BUFFER_LEVEL_SECONDARY,
+    VK_CMD_BUFFER_LEVEL_NUM = (VK_CMD_BUFFER_LEVEL_SECONDARY - VK_CMD_BUFFER_LEVEL_PRIMARY + 1),
+    VK_CMD_BUFFER_LEVEL_MAX_ENUM = 0x7FFFFFFF
+} VkCmdBufferLevel;
+
+typedef enum {
+    VK_INDEX_TYPE_UINT16 = 0,
+    VK_INDEX_TYPE_UINT32 = 1,
+    VK_INDEX_TYPE_BEGIN_RANGE = VK_INDEX_TYPE_UINT16,
+    VK_INDEX_TYPE_END_RANGE = VK_INDEX_TYPE_UINT32,
+    VK_INDEX_TYPE_NUM = (VK_INDEX_TYPE_UINT32 - VK_INDEX_TYPE_UINT16 + 1),
+    VK_INDEX_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkIndexType;
+
+typedef enum {
+    VK_TIMESTAMP_TYPE_TOP = 0,
+    VK_TIMESTAMP_TYPE_BOTTOM = 1,
+    VK_TIMESTAMP_TYPE_BEGIN_RANGE = VK_TIMESTAMP_TYPE_TOP,
+    VK_TIMESTAMP_TYPE_END_RANGE = VK_TIMESTAMP_TYPE_BOTTOM,
+    VK_TIMESTAMP_TYPE_NUM = (VK_TIMESTAMP_TYPE_BOTTOM - VK_TIMESTAMP_TYPE_TOP + 1),
+    VK_TIMESTAMP_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkTimestampType;
+
+typedef enum {
+    VK_RENDER_PASS_CONTENTS_INLINE = 0,
+    VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS = 1,
+    VK_RENDER_PASS_CONTENTS_BEGIN_RANGE = VK_RENDER_PASS_CONTENTS_INLINE,
+    VK_RENDER_PASS_CONTENTS_END_RANGE = VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS,
+    VK_RENDER_PASS_CONTENTS_NUM = (VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS - VK_RENDER_PASS_CONTENTS_INLINE + 1),
+    VK_RENDER_PASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF
+} VkRenderPassContents;
+
+
+typedef enum {
+    VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT = 0x00000001,
+    VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT = 0x00000002,
+    VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT = 0x00000004,
+    VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000008,
+    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT = 0x00000010,
+    VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT = 0x00000020,
+    VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT = 0x00000040,
+    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT = 0x00000080,
+    VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT = 0x00000100,
+    VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000200,
+    VK_FORMAT_FEATURE_BLIT_SOURCE_BIT = 0x00000400,
+    VK_FORMAT_FEATURE_BLIT_DESTINATION_BIT = 0x00000800,
+} VkFormatFeatureFlagBits;
+typedef VkFlags VkFormatFeatureFlags;
+
+typedef enum {
+    VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT = 0x00000001,
+    VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT = 0x00000002,
+    VK_IMAGE_USAGE_SAMPLED_BIT = 0x00000004,
+    VK_IMAGE_USAGE_STORAGE_BIT = 0x00000008,
+    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT = 0x00000010,
+    VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000020,
+    VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT = 0x00000040,
+    VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT = 0x00000080,
+} VkImageUsageFlagBits;
+typedef VkFlags VkImageUsageFlags;
+
+typedef enum {
+    VK_IMAGE_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+    VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+    VK_IMAGE_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+    VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT = 0x00000008,
+    VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT = 0x00000010,
+} VkImageCreateFlagBits;
+typedef VkFlags VkImageCreateFlags;
+
+typedef enum {
+    VK_SAMPLE_COUNT_1_BIT = 0x00000001,
+    VK_SAMPLE_COUNT_2_BIT = 0x00000002,
+    VK_SAMPLE_COUNT_4_BIT = 0x00000004,
+    VK_SAMPLE_COUNT_8_BIT = 0x00000008,
+    VK_SAMPLE_COUNT_16_BIT = 0x00000010,
+    VK_SAMPLE_COUNT_32_BIT = 0x00000020,
+    VK_SAMPLE_COUNT_64_BIT = 0x00000040,
+} VkSampleCountFlagBits;
+typedef VkFlags VkSampleCountFlags;
+
+typedef enum {
+    VK_QUEUE_GRAPHICS_BIT = 0x00000001,
+    VK_QUEUE_COMPUTE_BIT = 0x00000002,
+    VK_QUEUE_DMA_BIT = 0x00000004,
+    VK_QUEUE_SPARSE_MEMMGR_BIT = 0x00000008,
+    VK_QUEUE_EXTENDED_BIT = 0x40000000,
+} VkQueueFlagBits;
+typedef VkFlags VkQueueFlags;
+
+typedef enum {
+    VK_MEMORY_PROPERTY_DEVICE_ONLY = 0,
+    VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT = 0x00000001,
+    VK_MEMORY_PROPERTY_HOST_NON_COHERENT_BIT = 0x00000002,
+    VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT = 0x00000004,
+    VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT = 0x00000008,
+    VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT = 0x00000010,
+} VkMemoryPropertyFlagBits;
+typedef VkFlags VkMemoryPropertyFlags;
+
+typedef enum {
+    VK_MEMORY_HEAP_HOST_LOCAL_BIT = 0x00000001,
+} VkMemoryHeapFlagBits;
+typedef VkFlags VkMemoryHeapFlags;
+typedef VkFlags VkMemoryMapFlags;
+
+typedef enum {
+    VK_SPARSE_IMAGE_FMT_SINGLE_MIPTAIL_BIT = 0x00000001,
+    VK_SPARSE_IMAGE_FMT_ALIGNED_MIP_SIZE_BIT = 0x00000002,
+    VK_SPARSE_IMAGE_FMT_NONSTD_BLOCK_SIZE_BIT = 0x00000004,
+} VkSparseImageFormatFlagBits;
+typedef VkFlags VkSparseImageFormatFlags;
+
+typedef enum {
+    VK_SPARSE_MEMORY_BIND_REPLICATE_64KIB_BLOCK_BIT = 0x00000001,
+} VkSparseMemoryBindFlagBits;
+typedef VkFlags VkSparseMemoryBindFlags;
+
+typedef enum {
+    VK_FENCE_CREATE_SIGNALED_BIT = 0x00000001,
+} VkFenceCreateFlagBits;
+typedef VkFlags VkFenceCreateFlags;
+typedef VkFlags VkSemaphoreCreateFlags;
+typedef VkFlags VkEventCreateFlags;
+
+typedef enum {
+    VK_QUERY_PIPELINE_STATISTIC_IA_VERTICES_BIT = 0x00000001,
+    VK_QUERY_PIPELINE_STATISTIC_IA_PRIMITIVES_BIT = 0x00000002,
+    VK_QUERY_PIPELINE_STATISTIC_VS_INVOCATIONS_BIT = 0x00000004,
+    VK_QUERY_PIPELINE_STATISTIC_GS_INVOCATIONS_BIT = 0x00000008,
+    VK_QUERY_PIPELINE_STATISTIC_GS_PRIMITIVES_BIT = 0x00000010,
+    VK_QUERY_PIPELINE_STATISTIC_C_INVOCATIONS_BIT = 0x00000020,
+    VK_QUERY_PIPELINE_STATISTIC_C_PRIMITIVES_BIT = 0x00000040,
+    VK_QUERY_PIPELINE_STATISTIC_FS_INVOCATIONS_BIT = 0x00000080,
+    VK_QUERY_PIPELINE_STATISTIC_TCS_PATCHES_BIT = 0x00000100,
+    VK_QUERY_PIPELINE_STATISTIC_TES_INVOCATIONS_BIT = 0x00000200,
+    VK_QUERY_PIPELINE_STATISTIC_CS_INVOCATIONS_BIT = 0x00000400,
+} VkQueryPipelineStatisticFlagBits;
+typedef VkFlags VkQueryPipelineStatisticFlags;
+
+typedef enum {
+    VK_QUERY_RESULT_DEFAULT = 0,
+    VK_QUERY_RESULT_64_BIT = 0x00000001,
+    VK_QUERY_RESULT_WAIT_BIT = 0x00000002,
+    VK_QUERY_RESULT_WITH_AVAILABILITY_BIT = 0x00000004,
+    VK_QUERY_RESULT_PARTIAL_BIT = 0x00000008,
+} VkQueryResultFlagBits;
+typedef VkFlags VkQueryResultFlags;
+
+typedef enum {
+    VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT = 0x00000001,
+    VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT = 0x00000002,
+    VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT = 0x00000004,
+    VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT = 0x00000008,
+    VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT = 0x00000010,
+    VK_BUFFER_USAGE_STORAGE_BUFFER_BIT = 0x00000020,
+    VK_BUFFER_USAGE_INDEX_BUFFER_BIT = 0x00000040,
+    VK_BUFFER_USAGE_VERTEX_BUFFER_BIT = 0x00000080,
+    VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT = 0x00000100,
+} VkBufferUsageFlagBits;
+typedef VkFlags VkBufferUsageFlags;
+
+typedef enum {
+    VK_BUFFER_CREATE_SPARSE_BINDING_BIT = 0x00000001,
+    VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT = 0x00000002,
+    VK_BUFFER_CREATE_SPARSE_ALIASED_BIT = 0x00000004,
+} VkBufferCreateFlagBits;
+typedef VkFlags VkBufferCreateFlags;
+
+typedef enum {
+    VK_IMAGE_ASPECT_COLOR_BIT = 0x00000001,
+    VK_IMAGE_ASPECT_DEPTH_BIT = 0x00000002,
+    VK_IMAGE_ASPECT_STENCIL_BIT = 0x00000004,
+    VK_IMAGE_ASPECT_METADATA_BIT = 0x00000008,
+} VkImageAspectFlagBits;
+typedef VkFlags VkImageAspectFlags;
+
+typedef enum {
+    VK_IMAGE_VIEW_CREATE_READ_ONLY_DEPTH_BIT = 0x00000001,
+    VK_IMAGE_VIEW_CREATE_READ_ONLY_STENCIL_BIT = 0x00000002,
+} VkImageViewCreateFlagBits;
+typedef VkFlags VkImageViewCreateFlags;
+typedef VkFlags VkShaderModuleCreateFlags;
+typedef VkFlags VkShaderCreateFlags;
+
+typedef enum {
+    VK_CHANNEL_R_BIT = 0x00000001,
+    VK_CHANNEL_G_BIT = 0x00000002,
+    VK_CHANNEL_B_BIT = 0x00000004,
+    VK_CHANNEL_A_BIT = 0x00000008,
+} VkChannelFlagBits;
+typedef VkFlags VkChannelFlags;
+
+typedef enum {
+    VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT = 0x00000001,
+    VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT = 0x00000002,
+    VK_PIPELINE_CREATE_DERIVATIVE_BIT = 0x00000004,
+} VkPipelineCreateFlagBits;
+typedef VkFlags VkPipelineCreateFlags;
+
+typedef enum {
+    VK_SHADER_STAGE_VERTEX_BIT = 0x00000001,
+    VK_SHADER_STAGE_TESS_CONTROL_BIT = 0x00000002,
+    VK_SHADER_STAGE_TESS_EVALUATION_BIT = 0x00000004,
+    VK_SHADER_STAGE_GEOMETRY_BIT = 0x00000008,
+    VK_SHADER_STAGE_FRAGMENT_BIT = 0x00000010,
+    VK_SHADER_STAGE_COMPUTE_BIT = 0x00000020,
+    VK_SHADER_STAGE_ALL = 0x7FFFFFFF,
+} VkShaderStageFlagBits;
+typedef VkFlags VkShaderStageFlags;
+
+typedef enum {
+    VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT = 0x00000001,
+} VkAttachmentDescriptionFlagBits;
+typedef VkFlags VkAttachmentDescriptionFlags;
+
+typedef enum {
+    VK_SUBPASS_DESCRIPTION_NO_OVERDRAW_BIT = 0x00000001,
+} VkSubpassDescriptionFlagBits;
+typedef VkFlags VkSubpassDescriptionFlags;
+
+typedef enum {
+    VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT = 0x00000001,
+    VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT = 0x00000002,
+    VK_PIPELINE_STAGE_VERTEX_INPUT_BIT = 0x00000004,
+    VK_PIPELINE_STAGE_VERTEX_SHADER_BIT = 0x00000008,
+    VK_PIPELINE_STAGE_TESS_CONTROL_SHADER_BIT = 0x00000010,
+    VK_PIPELINE_STAGE_TESS_EVALUATION_SHADER_BIT = 0x00000020,
+    VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT = 0x00000040,
+    VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT = 0x00000080,
+    VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT = 0x00000100,
+    VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT = 0x00000200,
+    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT = 0x00000400,
+    VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT = 0x00000800,
+    VK_PIPELINE_STAGE_TRANSFER_BIT = 0x00001000,
+    VK_PIPELINE_STAGE_HOST_BIT = 0x00002000,
+    VK_PIPELINE_STAGE_ALL_GRAPHICS = 0x000007FF,
+    VK_PIPELINE_STAGE_ALL_GPU_COMMANDS = 0x00001FFF,
+} VkPipelineStageFlagBits;
+typedef VkFlags VkPipelineStageFlags;
+
+typedef enum {
+    VK_MEMORY_OUTPUT_HOST_WRITE_BIT = 0x00000001,
+    VK_MEMORY_OUTPUT_SHADER_WRITE_BIT = 0x00000002,
+    VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT = 0x00000004,
+    VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000008,
+    VK_MEMORY_OUTPUT_TRANSFER_BIT = 0x00000010,
+} VkMemoryOutputFlagBits;
+typedef VkFlags VkMemoryOutputFlags;
+
+typedef enum {
+    VK_MEMORY_INPUT_HOST_READ_BIT = 0x00000001,
+    VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT = 0x00000002,
+    VK_MEMORY_INPUT_INDEX_FETCH_BIT = 0x00000004,
+    VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT = 0x00000008,
+    VK_MEMORY_INPUT_UNIFORM_READ_BIT = 0x00000010,
+    VK_MEMORY_INPUT_SHADER_READ_BIT = 0x00000020,
+    VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT = 0x00000040,
+    VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT = 0x00000080,
+    VK_MEMORY_INPUT_INPUT_ATTACHMENT_BIT = 0x00000100,
+    VK_MEMORY_INPUT_TRANSFER_BIT = 0x00000200,
+} VkMemoryInputFlagBits;
+typedef VkFlags VkMemoryInputFlags;
+
+typedef enum {
+    VK_CMD_POOL_CREATE_TRANSIENT_BIT = 0x00000001,
+    VK_CMD_POOL_CREATE_RESET_COMMAND_BUFFER_BIT = 0x00000002,
+} VkCmdPoolCreateFlagBits;
+typedef VkFlags VkCmdPoolCreateFlags;
+
+typedef enum {
+    VK_CMD_POOL_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
+} VkCmdPoolResetFlagBits;
+typedef VkFlags VkCmdPoolResetFlags;
+typedef VkFlags VkCmdBufferCreateFlags;
+
+typedef enum {
+    VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT = 0x00000001,
+    VK_CMD_BUFFER_OPTIMIZE_PIPELINE_SWITCH_BIT = 0x00000002,
+    VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT = 0x00000004,
+    VK_CMD_BUFFER_OPTIMIZE_DESCRIPTOR_SET_SWITCH_BIT = 0x00000008,
+    VK_CMD_BUFFER_OPTIMIZE_NO_SIMULTANEOUS_USE_BIT = 0x00000010,
+} VkCmdBufferOptimizeFlagBits;
+typedef VkFlags VkCmdBufferOptimizeFlags;
+
+typedef enum {
+    VK_CMD_BUFFER_RESET_RELEASE_RESOURCES_BIT = 0x00000001,
+} VkCmdBufferResetFlagBits;
+typedef VkFlags VkCmdBufferResetFlags;
+
+typedef enum {
+    VK_STENCIL_FACE_NONE = 0,
+    VK_STENCIL_FACE_FRONT_BIT = 0x00000001,
+    VK_STENCIL_FACE_BACK_BIT = 0x00000002,
+} VkStencilFaceFlagBits;
+typedef VkFlags VkStencilFaceFlags;
+
+typedef enum {
+    VK_QUERY_CONTROL_CONSERVATIVE_BIT = 0x00000001,
+} VkQueryControlFlagBits;
+typedef VkFlags VkQueryControlFlags;
+
+typedef void* (VKAPI *PFN_vkAllocFunction)(
+    void*                           pUserData,
+    size_t                          size,
+    size_t                          alignment,
+    VkSystemAllocType               allocType);
+
+typedef void (VKAPI *PFN_vkFreeFunction)(
+    void*                           pUserData,
+    void*                           pMem);
+
+typedef void (VKAPI *PFN_vkVoidFunction)(void);
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    const char*                                 pAppName;
+    uint32_t                                    appVersion;
+    const char*                                 pEngineName;
+    uint32_t                                    engineVersion;
+    uint32_t                                    apiVersion;
+} VkApplicationInfo;
+
+typedef struct {
+    void*                                       pUserData;
+    PFN_vkAllocFunction                         pfnAlloc;
+    PFN_vkFreeFunction                          pfnFree;
+} VkAllocCallbacks;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    const VkApplicationInfo*                    pAppInfo;
+    const VkAllocCallbacks*                     pAllocCb;
+    uint32_t                                    layerCount;
+    const char*const*                           ppEnabledLayerNames;
+    uint32_t                                    extensionCount;
+    const char*const*                           ppEnabledExtensionNames;
+} VkInstanceCreateInfo;
+
+typedef struct {
+    VkBool32                                    robustBufferAccess;
+    VkBool32                                    fullDrawIndexUint32;
+    VkBool32                                    imageCubeArray;
+    VkBool32                                    independentBlend;
+    VkBool32                                    geometryShader;
+    VkBool32                                    tessellationShader;
+    VkBool32                                    sampleRateShading;
+    VkBool32                                    dualSourceBlend;
+    VkBool32                                    logicOp;
+    VkBool32                                    multiDrawIndirect;
+    VkBool32                                    depthClip;
+    VkBool32                                    depthBiasClamp;
+    VkBool32                                    fillModeNonSolid;
+    VkBool32                                    depthBounds;
+    VkBool32                                    wideLines;
+    VkBool32                                    largePoints;
+    VkBool32                                    textureCompressionETC2;
+    VkBool32                                    textureCompressionASTC_LDR;
+    VkBool32                                    textureCompressionBC;
+    VkBool32                                    occlusionQueryNonConservative;
+    VkBool32                                    pipelineStatisticsQuery;
+    VkBool32                                    vertexSideEffects;
+    VkBool32                                    tessellationSideEffects;
+    VkBool32                                    geometrySideEffects;
+    VkBool32                                    fragmentSideEffects;
+    VkBool32                                    shaderTessellationPointSize;
+    VkBool32                                    shaderGeometryPointSize;
+    VkBool32                                    shaderImageGatherExtended;
+    VkBool32                                    shaderStorageImageExtendedFormats;
+    VkBool32                                    shaderStorageImageMultisample;
+    VkBool32                                    shaderUniformBufferArrayDynamicIndexing;
+    VkBool32                                    shaderSampledImageArrayDynamicIndexing;
+    VkBool32                                    shaderStorageBufferArrayDynamicIndexing;
+    VkBool32                                    shaderStorageImageArrayDynamicIndexing;
+    VkBool32                                    shaderClipDistance;
+    VkBool32                                    shaderCullDistance;
+    VkBool32                                    shaderFloat64;
+    VkBool32                                    shaderInt64;
+    VkBool32                                    shaderInt16;
+    VkBool32                                    shaderResourceResidency;
+    VkBool32                                    shaderResourceMinLOD;
+    VkBool32                                    alphaToOne;
+    VkBool32                                    sparseBinding;
+    VkBool32                                    sparseResidencyBuffer;
+    VkBool32                                    sparseResidencyImage2D;
+    VkBool32                                    sparseResidencyImage3D;
+    VkBool32                                    sparseResidency2Samples;
+    VkBool32                                    sparseResidency4Samples;
+    VkBool32                                    sparseResidency8Samples;
+    VkBool32                                    sparseResidency16Samples;
+    VkBool32                                    sparseResidencyAliased;
+} VkPhysicalDeviceFeatures;
+
+typedef struct {
+    VkFormatFeatureFlags                        linearTilingFeatures;
+    VkFormatFeatureFlags                        optimalTilingFeatures;
+    VkFormatFeatureFlags                        bufferFeatures;
+} VkFormatProperties;
+
+typedef struct {
+    int32_t                                     width;
+    int32_t                                     height;
+    int32_t                                     depth;
+} VkExtent3D;
+
+typedef struct {
+    VkExtent3D                                  maxExtent;
+    uint32_t                                    maxMipLevels;
+    uint32_t                                    maxArraySize;
+    VkSampleCountFlags                          sampleCounts;
+    VkDeviceSize                                maxResourceSize;
+} VkImageFormatProperties;
+
+typedef struct {
+    uint32_t                                    maxImageDimension1D;
+    uint32_t                                    maxImageDimension2D;
+    uint32_t                                    maxImageDimension3D;
+    uint32_t                                    maxImageDimensionCube;
+    uint32_t                                    maxImageArrayLayers;
+    VkSampleCountFlags                          sampleCounts;
+    uint32_t                                    maxTexelBufferSize;
+    uint32_t                                    maxUniformBufferSize;
+    uint32_t                                    maxStorageBufferSize;
+    uint32_t                                    maxPushConstantsSize;
+    uint32_t                                    maxMemoryAllocationCount;
+    VkDeviceSize                                bufferImageGranularity;
+    VkDeviceSize                                sparseAddressSpaceSize;
+    uint32_t                                    maxBoundDescriptorSets;
+    uint32_t                                    maxDescriptorSets;
+    uint32_t                                    maxPerStageDescriptorSamplers;
+    uint32_t                                    maxPerStageDescriptorUniformBuffers;
+    uint32_t                                    maxPerStageDescriptorStorageBuffers;
+    uint32_t                                    maxPerStageDescriptorSampledImages;
+    uint32_t                                    maxPerStageDescriptorStorageImages;
+    uint32_t                                    maxDescriptorSetSamplers;
+    uint32_t                                    maxDescriptorSetUniformBuffers;
+    uint32_t                                    maxDescriptorSetUniformBuffersDynamic;
+    uint32_t                                    maxDescriptorSetStorageBuffers;
+    uint32_t                                    maxDescriptorSetStorageBuffersDynamic;
+    uint32_t                                    maxDescriptorSetSampledImages;
+    uint32_t                                    maxDescriptorSetStorageImages;
+    uint32_t                                    maxVertexInputAttributes;
+    uint32_t                                    maxVertexInputBindings;
+    uint32_t                                    maxVertexInputAttributeOffset;
+    uint32_t                                    maxVertexInputBindingStride;
+    uint32_t                                    maxVertexOutputComponents;
+    uint32_t                                    maxTessGenLevel;
+    uint32_t                                    maxTessPatchSize;
+    uint32_t                                    maxTessControlPerVertexInputComponents;
+    uint32_t                                    maxTessControlPerVertexOutputComponents;
+    uint32_t                                    maxTessControlPerPatchOutputComponents;
+    uint32_t                                    maxTessControlTotalOutputComponents;
+    uint32_t                                    maxTessEvaluationInputComponents;
+    uint32_t                                    maxTessEvaluationOutputComponents;
+    uint32_t                                    maxGeometryShaderInvocations;
+    uint32_t                                    maxGeometryInputComponents;
+    uint32_t                                    maxGeometryOutputComponents;
+    uint32_t                                    maxGeometryOutputVertices;
+    uint32_t                                    maxGeometryTotalOutputComponents;
+    uint32_t                                    maxFragmentInputComponents;
+    uint32_t                                    maxFragmentOutputBuffers;
+    uint32_t                                    maxFragmentDualSourceBuffers;
+    uint32_t                                    maxFragmentCombinedOutputResources;
+    uint32_t                                    maxComputeSharedMemorySize;
+    uint32_t                                    maxComputeWorkGroupCount[3];
+    uint32_t                                    maxComputeWorkGroupInvocations;
+    uint32_t                                    maxComputeWorkGroupSize[3];
+    uint32_t                                    subPixelPrecisionBits;
+    uint32_t                                    subTexelPrecisionBits;
+    uint32_t                                    mipmapPrecisionBits;
+    uint32_t                                    maxDrawIndexedIndexValue;
+    uint32_t                                    maxDrawIndirectInstanceCount;
+    VkBool32                                    primitiveRestartForPatches;
+    float                                       maxSamplerLodBias;
+    float                                       maxSamplerAnisotropy;
+    uint32_t                                    maxViewports;
+    uint32_t                                    maxViewportDimensions[2];
+    float                                       viewportBoundsRange[2];
+    uint32_t                                    viewportSubPixelBits;
+    uint32_t                                    minMemoryMapAlignment;
+    uint32_t                                    minTexelBufferOffsetAlignment;
+    uint32_t                                    minUniformBufferOffsetAlignment;
+    uint32_t                                    minStorageBufferOffsetAlignment;
+    uint32_t                                    minTexelOffset;
+    uint32_t                                    maxTexelOffset;
+    uint32_t                                    minTexelGatherOffset;
+    uint32_t                                    maxTexelGatherOffset;
+    float                                       minInterpolationOffset;
+    float                                       maxInterpolationOffset;
+    uint32_t                                    subPixelInterpolationOffsetBits;
+    uint32_t                                    maxFramebufferWidth;
+    uint32_t                                    maxFramebufferHeight;
+    uint32_t                                    maxFramebufferLayers;
+    uint32_t                                    maxFramebufferColorSamples;
+    uint32_t                                    maxFramebufferDepthSamples;
+    uint32_t                                    maxFramebufferStencilSamples;
+    uint32_t                                    maxColorAttachments;
+    uint32_t                                    maxSampledImageColorSamples;
+    uint32_t                                    maxSampledImageDepthSamples;
+    uint32_t                                    maxSampledImageIntegerSamples;
+    uint32_t                                    maxStorageImageSamples;
+    uint32_t                                    maxSampleMaskWords;
+    uint64_t                                    timestampFrequency;
+    uint32_t                                    maxClipDistances;
+    uint32_t                                    maxCullDistances;
+    uint32_t                                    maxCombinedClipAndCullDistances;
+    float                                       pointSizeRange[2];
+    float                                       lineWidthRange[2];
+    float                                       pointSizeGranularity;
+    float                                       lineWidthGranularity;
+} VkPhysicalDeviceLimits;
+
+typedef struct {
+    VkBool32                                    residencyStandard2DBlockShape;
+    VkBool32                                    residencyStandard2DMSBlockShape;
+    VkBool32                                    residencyStandard3DBlockShape;
+    VkBool32                                    residencyAlignedMipSize;
+    VkBool32                                    residencyNonResident;
+    VkBool32                                    residencyNonResidentStrict;
+} VkPhysicalDeviceSparseProperties;
+
+typedef struct {
+    uint32_t                                    apiVersion;
+    uint32_t                                    driverVersion;
+    uint32_t                                    vendorId;
+    uint32_t                                    deviceId;
+    VkPhysicalDeviceType                        deviceType;
+    char                                        deviceName[VK_MAX_PHYSICAL_DEVICE_NAME];
+    uint8_t                                     pipelineCacheUUID[VK_UUID_LENGTH];
+    VkPhysicalDeviceLimits                      limits;
+    VkPhysicalDeviceSparseProperties            sparseProperties;
+} VkPhysicalDeviceProperties;
+
+typedef struct {
+    VkQueueFlags                                queueFlags;
+    uint32_t                                    queueCount;
+    VkBool32                                    supportsTimestamps;
+} VkQueueFamilyProperties;
+
+typedef struct {
+    VkMemoryPropertyFlags                       propertyFlags;
+    uint32_t                                    heapIndex;
+} VkMemoryType;
+
+typedef struct {
+    VkDeviceSize                                size;
+    VkMemoryHeapFlags                           flags;
+} VkMemoryHeap;
+
+typedef struct {
+    uint32_t                                    memoryTypeCount;
+    VkMemoryType                                memoryTypes[VK_MAX_MEMORY_TYPES];
+    uint32_t                                    memoryHeapCount;
+    VkMemoryHeap                                memoryHeaps[VK_MAX_MEMORY_HEAPS];
+} VkPhysicalDeviceMemoryProperties;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    queueFamilyIndex;
+    uint32_t                                    queueCount;
+} VkDeviceQueueCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    queueRecordCount;
+    const VkDeviceQueueCreateInfo*              pRequestedQueues;
+    uint32_t                                    layerCount;
+    const char*const*                           ppEnabledLayerNames;
+    uint32_t                                    extensionCount;
+    const char*const*                           ppEnabledExtensionNames;
+    const VkPhysicalDeviceFeatures*             pEnabledFeatures;
+} VkDeviceCreateInfo;
+
+typedef struct {
+    char                                        extName[VK_MAX_EXTENSION_NAME];
+    uint32_t                                    specVersion;
+} VkExtensionProperties;
+
+typedef struct {
+    char                                        layerName[VK_MAX_EXTENSION_NAME];
+    uint32_t                                    specVersion;
+    uint32_t                                    implVersion;
+    char                                        description[VK_MAX_DESCRIPTION];
+} VkLayerProperties;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkDeviceSize                                allocationSize;
+    uint32_t                                    memoryTypeIndex;
+} VkMemoryAllocInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkDeviceMemory                              mem;
+    VkDeviceSize                                offset;
+    VkDeviceSize                                size;
+} VkMappedMemoryRange;
+
+typedef struct {
+    VkDeviceSize                                size;
+    VkDeviceSize                                alignment;
+    uint32_t                                    memoryTypeBits;
+} VkMemoryRequirements;
+
+typedef struct {
+    VkImageAspect                               aspect;
+    VkExtent3D                                  imageGranularity;
+    VkSparseImageFormatFlags                    flags;
+} VkSparseImageFormatProperties;
+
+typedef struct {
+    VkSparseImageFormatProperties               formatProps;
+    uint32_t                                    imageMipTailStartLOD;
+    VkDeviceSize                                imageMipTailSize;
+    VkDeviceSize                                imageMipTailOffset;
+    VkDeviceSize                                imageMipTailStride;
+} VkSparseImageMemoryRequirements;
+
+typedef struct {
+    VkDeviceSize                                rangeOffset;
+    VkDeviceSize                                rangeSize;
+    VkDeviceSize                                memOffset;
+    VkDeviceMemory                              mem;
+    VkSparseMemoryBindFlags                     flags;
+} VkSparseMemoryBindInfo;
+
+typedef struct {
+    VkImageAspect                               aspect;
+    uint32_t                                    mipLevel;
+    uint32_t                                    arrayLayer;
+} VkImageSubresource;
+
+typedef struct {
+    int32_t                                     x;
+    int32_t                                     y;
+    int32_t                                     z;
+} VkOffset3D;
+
+typedef struct {
+    VkImageSubresource                          subresource;
+    VkOffset3D                                  offset;
+    VkExtent3D                                  extent;
+    VkDeviceSize                                memOffset;
+    VkDeviceMemory                              mem;
+    VkSparseMemoryBindFlags                     flags;
+} VkSparseImageMemoryBindInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkFenceCreateFlags                          flags;
+} VkFenceCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkSemaphoreCreateFlags                      flags;
+} VkSemaphoreCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkEventCreateFlags                          flags;
+} VkEventCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkQueryType                                 queryType;
+    uint32_t                                    slots;
+    VkQueryPipelineStatisticFlags               pipelineStatistics;
+} VkQueryPoolCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkDeviceSize                                size;
+    VkBufferUsageFlags                          usage;
+    VkBufferCreateFlags                         flags;
+    VkSharingMode                               sharingMode;
+    uint32_t                                    queueFamilyCount;
+    const uint32_t*                             pQueueFamilyIndices;
+} VkBufferCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkBuffer                                    buffer;
+    VkFormat                                    format;
+    VkDeviceSize                                offset;
+    VkDeviceSize                                range;
+} VkBufferViewCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkImageType                                 imageType;
+    VkFormat                                    format;
+    VkExtent3D                                  extent;
+    uint32_t                                    mipLevels;
+    uint32_t                                    arraySize;
+    uint32_t                                    samples;
+    VkImageTiling                               tiling;
+    VkImageUsageFlags                           usage;
+    VkImageCreateFlags                          flags;
+    VkSharingMode                               sharingMode;
+    uint32_t                                    queueFamilyCount;
+    const uint32_t*                             pQueueFamilyIndices;
+    VkImageLayout                               initialLayout;
+} VkImageCreateInfo;
+
+typedef struct {
+    VkDeviceSize                                offset;
+    VkDeviceSize                                size;
+    VkDeviceSize                                rowPitch;
+    VkDeviceSize                                depthPitch;
+} VkSubresourceLayout;
+
+typedef struct {
+    VkChannelSwizzle                            r;
+    VkChannelSwizzle                            g;
+    VkChannelSwizzle                            b;
+    VkChannelSwizzle                            a;
+} VkChannelMapping;
+
+typedef struct {
+    VkImageAspectFlags                          aspectMask;
+    uint32_t                                    baseMipLevel;
+    uint32_t                                    mipLevels;
+    uint32_t                                    baseArrayLayer;
+    uint32_t                                    arraySize;
+} VkImageSubresourceRange;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkImage                                     image;
+    VkImageViewType                             viewType;
+    VkFormat                                    format;
+    VkChannelMapping                            channels;
+    VkImageSubresourceRange                     subresourceRange;
+    VkImageViewCreateFlags                      flags;
+} VkImageViewCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    size_t                                      codeSize;
+    const void*                                 pCode;
+    VkShaderModuleCreateFlags                   flags;
+} VkShaderModuleCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkShaderModule                              module;
+    const char*                                 pName;
+    VkShaderCreateFlags                         flags;
+    VkShaderStage                               stage;
+} VkShaderCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    size_t                                      initialSize;
+    const void*                                 initialData;
+    size_t                                      maxSize;
+} VkPipelineCacheCreateInfo;
+
+typedef struct {
+    uint32_t                                    constantId;
+    size_t                                      size;
+    uint32_t                                    offset;
+} VkSpecializationMapEntry;
+
+typedef struct {
+    uint32_t                                    mapEntryCount;
+    const VkSpecializationMapEntry*             pMap;
+    size_t                                      dataSize;
+    const void*                                 pData;
+} VkSpecializationInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkShaderStage                               stage;
+    VkShader                                    shader;
+    const VkSpecializationInfo*                 pSpecializationInfo;
+} VkPipelineShaderStageCreateInfo;
+
+typedef struct {
+    uint32_t                                    binding;
+    uint32_t                                    strideInBytes;
+    VkVertexInputStepRate                       stepRate;
+} VkVertexInputBindingDescription;
+
+typedef struct {
+    uint32_t                                    location;
+    uint32_t                                    binding;
+    VkFormat                                    format;
+    uint32_t                                    offsetInBytes;
+} VkVertexInputAttributeDescription;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    bindingCount;
+    const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
+    uint32_t                                    attributeCount;
+    const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
+} VkPipelineVertexInputStateCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkPrimitiveTopology                         topology;
+    VkBool32                                    primitiveRestartEnable;
+} VkPipelineInputAssemblyStateCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    patchControlPoints;
+} VkPipelineTessellationStateCreateInfo;
+
+typedef struct {
+    float                                       originX;
+    float                                       originY;
+    float                                       width;
+    float                                       height;
+    float                                       minDepth;
+    float                                       maxDepth;
+} VkViewport;
+
+typedef struct {
+    int32_t                                     x;
+    int32_t                                     y;
+} VkOffset2D;
+
+typedef struct {
+    int32_t                                     width;
+    int32_t                                     height;
+} VkExtent2D;
+
+typedef struct {
+    VkOffset2D                                  offset;
+    VkExtent2D                                  extent;
+} VkRect2D;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    viewportCount;
+    const VkViewport*                           pViewports;
+    uint32_t                                    scissorCount;
+    const VkRect2D*                             pScissors;
+} VkPipelineViewportStateCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkBool32                                    depthClipEnable;
+    VkBool32                                    rasterizerDiscardEnable;
+    VkFillMode                                  fillMode;
+    VkCullMode                                  cullMode;
+    VkFrontFace                                 frontFace;
+    VkBool32                                    depthBiasEnable;
+    float                                       depthBias;
+    float                                       depthBiasClamp;
+    float                                       slopeScaledDepthBias;
+    float                                       lineWidth;
+} VkPipelineRasterStateCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    rasterSamples;
+    VkBool32                                    sampleShadingEnable;
+    float                                       minSampleShading;
+    const VkSampleMask*                         pSampleMask;
+} VkPipelineMultisampleStateCreateInfo;
+
+typedef struct {
+    VkStencilOp                                 stencilFailOp;
+    VkStencilOp                                 stencilPassOp;
+    VkStencilOp                                 stencilDepthFailOp;
+    VkCompareOp                                 stencilCompareOp;
+    uint32_t                                    stencilCompareMask;
+    uint32_t                                    stencilWriteMask;
+    uint32_t                                    stencilReference;
+} VkStencilOpState;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkBool32                                    depthTestEnable;
+    VkBool32                                    depthWriteEnable;
+    VkCompareOp                                 depthCompareOp;
+    VkBool32                                    depthBoundsTestEnable;
+    VkBool32                                    stencilTestEnable;
+    VkStencilOpState                            front;
+    VkStencilOpState                            back;
+    float                                       minDepthBounds;
+    float                                       maxDepthBounds;
+} VkPipelineDepthStencilStateCreateInfo;
+
+typedef struct {
+    VkBool32                                    blendEnable;
+    VkBlend                                     srcBlendColor;
+    VkBlend                                     destBlendColor;
+    VkBlendOp                                   blendOpColor;
+    VkBlend                                     srcBlendAlpha;
+    VkBlend                                     destBlendAlpha;
+    VkBlendOp                                   blendOpAlpha;
+    VkChannelFlags                              channelWriteMask;
+} VkPipelineColorBlendAttachmentState;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkBool32                                    alphaToCoverageEnable;
+    VkBool32                                    alphaToOneEnable;
+    VkBool32                                    logicOpEnable;
+    VkLogicOp                                   logicOp;
+    uint32_t                                    attachmentCount;
+    const VkPipelineColorBlendAttachmentState*  pAttachments;
+    float                                       blendConst[4];
+} VkPipelineColorBlendStateCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    dynamicStateCount;
+    const VkDynamicState*                       pDynamicStates;
+} VkPipelineDynamicStateCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    stageCount;
+    const VkPipelineShaderStageCreateInfo*      pStages;
+    const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
+    const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
+    const VkPipelineTessellationStateCreateInfo* pTessellationState;
+    const VkPipelineViewportStateCreateInfo*    pViewportState;
+    const VkPipelineRasterStateCreateInfo*      pRasterState;
+    const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
+    const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
+    const VkPipelineColorBlendStateCreateInfo*  pColorBlendState;
+    const VkPipelineDynamicStateCreateInfo*     pDynamicState;
+    VkPipelineCreateFlags                       flags;
+    VkPipelineLayout                            layout;
+    VkRenderPass                                renderPass;
+    uint32_t                                    subpass;
+    VkPipeline                                  basePipelineHandle;
+    int32_t                                     basePipelineIndex;
+} VkGraphicsPipelineCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkPipelineShaderStageCreateInfo             stage;
+    VkPipelineCreateFlags                       flags;
+    VkPipelineLayout                            layout;
+    VkPipeline                                  basePipelineHandle;
+    int32_t                                     basePipelineIndex;
+} VkComputePipelineCreateInfo;
+
+typedef struct {
+    VkShaderStageFlags                          stageFlags;
+    uint32_t                                    start;
+    uint32_t                                    length;
+} VkPushConstantRange;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    descriptorSetCount;
+    const VkDescriptorSetLayout*                pSetLayouts;
+    uint32_t                                    pushConstantRangeCount;
+    const VkPushConstantRange*                  pPushConstantRanges;
+} VkPipelineLayoutCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkTexFilter                                 magFilter;
+    VkTexFilter                                 minFilter;
+    VkTexMipmapMode                             mipMode;
+    VkTexAddressMode                            addressModeU;
+    VkTexAddressMode                            addressModeV;
+    VkTexAddressMode                            addressModeW;
+    float                                       mipLodBias;
+    float                                       maxAnisotropy;
+    VkBool32                                    compareEnable;
+    VkCompareOp                                 compareOp;
+    float                                       minLod;
+    float                                       maxLod;
+    VkBorderColor                               borderColor;
+    VkBool32                                    unnormalizedCoordinates;
+} VkSamplerCreateInfo;
+
+typedef struct {
+    VkDescriptorType                            descriptorType;
+    uint32_t                                    arraySize;
+    VkShaderStageFlags                          stageFlags;
+    const VkSampler*                            pImmutableSamplers;
+} VkDescriptorSetLayoutBinding;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    count;
+    const VkDescriptorSetLayoutBinding*         pBinding;
+} VkDescriptorSetLayoutCreateInfo;
+
+typedef struct {
+    VkDescriptorType                            type;
+    uint32_t                                    count;
+} VkDescriptorTypeCount;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkDescriptorPoolUsage                       poolUsage;
+    uint32_t                                    maxSets;
+    uint32_t                                    count;
+    const VkDescriptorTypeCount*                pTypeCount;
+} VkDescriptorPoolCreateInfo;
+
+typedef struct {
+    VkBuffer                                    buffer;
+    VkDeviceSize                                offset;
+    VkDeviceSize                                range;
+} VkDescriptorBufferInfo;
+
+typedef struct {
+    VkBufferView                                bufferView;
+    VkSampler                                   sampler;
+    VkImageView                                 imageView;
+    VkImageLayout                               imageLayout;
+    VkDescriptorBufferInfo                      bufferInfo;
+} VkDescriptorInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkDescriptorSet                             destSet;
+    uint32_t                                    destBinding;
+    uint32_t                                    destArrayElement;
+    uint32_t                                    count;
+    VkDescriptorType                            descriptorType;
+    const VkDescriptorInfo*                     pDescriptors;
+} VkWriteDescriptorSet;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkDescriptorSet                             srcSet;
+    uint32_t                                    srcBinding;
+    uint32_t                                    srcArrayElement;
+    VkDescriptorSet                             destSet;
+    uint32_t                                    destBinding;
+    uint32_t                                    destArrayElement;
+    uint32_t                                    count;
+} VkCopyDescriptorSet;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkRenderPass                                renderPass;
+    uint32_t                                    attachmentCount;
+    const VkImageView*                          pAttachments;
+    uint32_t                                    width;
+    uint32_t                                    height;
+    uint32_t                                    layers;
+} VkFramebufferCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkFormat                                    format;
+    uint32_t                                    samples;
+    VkAttachmentLoadOp                          loadOp;
+    VkAttachmentStoreOp                         storeOp;
+    VkAttachmentLoadOp                          stencilLoadOp;
+    VkAttachmentStoreOp                         stencilStoreOp;
+    VkImageLayout                               initialLayout;
+    VkImageLayout                               finalLayout;
+    VkAttachmentDescriptionFlags                flags;
+} VkAttachmentDescription;
+
+typedef struct {
+    uint32_t                                    attachment;
+    VkImageLayout                               layout;
+} VkAttachmentReference;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkPipelineBindPoint                         pipelineBindPoint;
+    VkSubpassDescriptionFlags                   flags;
+    uint32_t                                    inputCount;
+    const VkAttachmentReference*                pInputAttachments;
+    uint32_t                                    colorCount;
+    const VkAttachmentReference*                pColorAttachments;
+    const VkAttachmentReference*                pResolveAttachments;
+    VkAttachmentReference                       depthStencilAttachment;
+    uint32_t                                    preserveCount;
+    const VkAttachmentReference*                pPreserveAttachments;
+} VkSubpassDescription;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    srcSubpass;
+    uint32_t                                    destSubpass;
+    VkPipelineStageFlags                        srcStageMask;
+    VkPipelineStageFlags                        destStageMask;
+    VkMemoryOutputFlags                         outputMask;
+    VkMemoryInputFlags                          inputMask;
+    VkBool32                                    byRegion;
+} VkSubpassDependency;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    attachmentCount;
+    const VkAttachmentDescription*              pAttachments;
+    uint32_t                                    subpassCount;
+    const VkSubpassDescription*                 pSubpasses;
+    uint32_t                                    dependencyCount;
+    const VkSubpassDependency*                  pDependencies;
+} VkRenderPassCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    uint32_t                                    queueFamilyIndex;
+    VkCmdPoolCreateFlags                        flags;
+} VkCmdPoolCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkCmdPool                                   cmdPool;
+    VkCmdBufferLevel                            level;
+    VkCmdBufferCreateFlags                      flags;
+} VkCmdBufferCreateInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkCmdBufferOptimizeFlags                    flags;
+    VkRenderPass                                renderPass;
+    uint32_t                                    subpass;
+    VkFramebuffer                               framebuffer;
+} VkCmdBufferBeginInfo;
+
+typedef struct {
+    VkDeviceSize                                srcOffset;
+    VkDeviceSize                                destOffset;
+    VkDeviceSize                                copySize;
+} VkBufferCopy;
+
+typedef struct {
+    VkImageAspect                               aspect;
+    uint32_t                                    mipLevel;
+    uint32_t                                    arrayLayer;
+    uint32_t                                    arraySize;
+} VkImageSubresourceCopy;
+
+typedef struct {
+    VkImageSubresourceCopy                      srcSubresource;
+    VkOffset3D                                  srcOffset;
+    VkImageSubresourceCopy                      destSubresource;
+    VkOffset3D                                  destOffset;
+    VkExtent3D                                  extent;
+} VkImageCopy;
+
+typedef struct {
+    VkImageSubresourceCopy                      srcSubresource;
+    VkOffset3D                                  srcOffset;
+    VkExtent3D                                  srcExtent;
+    VkImageSubresourceCopy                      destSubresource;
+    VkOffset3D                                  destOffset;
+    VkExtent3D                                  destExtent;
+} VkImageBlit;
+
+typedef struct {
+    VkDeviceSize                                bufferOffset;
+    uint32_t                                    bufferRowLength;
+    uint32_t                                    bufferImageHeight;
+    VkImageSubresourceCopy                      imageSubresource;
+    VkOffset3D                                  imageOffset;
+    VkExtent3D                                  imageExtent;
+} VkBufferImageCopy;
+
+typedef union {
+    float                                       float32[4];
+    int32_t                                     int32[4];
+    uint32_t                                    uint32[4];
+} VkClearColorValue;
+
+typedef struct {
+    float                                       depth;
+    uint32_t                                    stencil;
+} VkClearDepthStencilValue;
+
+typedef struct {
+    VkOffset3D                                  offset;
+    VkExtent3D                                  extent;
+} VkRect3D;
+
+typedef struct {
+    VkImageSubresourceCopy                      srcSubresource;
+    VkOffset3D                                  srcOffset;
+    VkImageSubresourceCopy                      destSubresource;
+    VkOffset3D                                  destOffset;
+    VkExtent3D                                  extent;
+} VkImageResolve;
+
+typedef union {
+    VkClearColorValue                           color;
+    VkClearDepthStencilValue                    depthStencil;
+} VkClearValue;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkRenderPass                                renderPass;
+    VkFramebuffer                               framebuffer;
+    VkRect2D                                    renderArea;
+    uint32_t                                    clearValueCount;
+    const VkClearValue*                         pClearValues;
+} VkRenderPassBeginInfo;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkMemoryOutputFlags                         outputMask;
+    VkMemoryInputFlags                          inputMask;
+    uint32_t                                    srcQueueFamilyIndex;
+    uint32_t                                    destQueueFamilyIndex;
+    VkBuffer                                    buffer;
+    VkDeviceSize                                offset;
+    VkDeviceSize                                size;
+} VkBufferMemoryBarrier;
+
+typedef struct {
+    uint32_t                                    x;
+    uint32_t                                    y;
+    uint32_t                                    z;
+} VkDispatchIndirectCmd;
+
+typedef struct {
+    uint32_t                                    indexCount;
+    uint32_t                                    instanceCount;
+    uint32_t                                    firstIndex;
+    int32_t                                     vertexOffset;
+    uint32_t                                    firstInstance;
+} VkDrawIndexedIndirectCmd;
+
+typedef struct {
+    uint32_t                                    vertexCount;
+    uint32_t                                    instanceCount;
+    uint32_t                                    firstVertex;
+    uint32_t                                    firstInstance;
+} VkDrawIndirectCmd;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkMemoryOutputFlags                         outputMask;
+    VkMemoryInputFlags                          inputMask;
+    VkImageLayout                               oldLayout;
+    VkImageLayout                               newLayout;
+    uint32_t                                    srcQueueFamilyIndex;
+    uint32_t                                    destQueueFamilyIndex;
+    VkImage                                     image;
+    VkImageSubresourceRange                     subresourceRange;
+} VkImageMemoryBarrier;
+
+typedef struct {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+    VkMemoryOutputFlags                         outputMask;
+    VkMemoryInputFlags                          inputMask;
+} VkMemoryBarrier;
+
+
+typedef VkResult (VKAPI *PFN_vkCreateInstance)(const VkInstanceCreateInfo* pCreateInfo, VkInstance* pInstance);
+typedef void (VKAPI *PFN_vkDestroyInstance)(VkInstance instance);
+typedef VkResult (VKAPI *PFN_vkEnumeratePhysicalDevices)(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceFeatures)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures* pFeatures);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties* pFormatProperties);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceQueueFamilyProperties)(VkPhysicalDevice physicalDevice, uint32_t* pCount, VkQueueFamilyProperties* pQueueFamilyProperties);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceMemoryProperties)(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties);
+typedef PFN_vkVoidFunction (VKAPI *PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName);
+typedef PFN_vkVoidFunction (VKAPI *PFN_vkGetDeviceProcAddr)(VkDevice device, const char* pName);
+typedef VkResult (VKAPI *PFN_vkCreateDevice)(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, VkDevice* pDevice);
+typedef void (VKAPI *PFN_vkDestroyDevice)(VkDevice device);
+typedef VkResult (VKAPI *PFN_vkEnumerateInstanceExtensionProperties)(const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties);
+typedef VkResult (VKAPI *PFN_vkEnumerateDeviceExtensionProperties)(VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties);
+typedef VkResult (VKAPI *PFN_vkEnumerateInstanceLayerProperties)(uint32_t* pCount, VkLayerProperties* pProperties);
+typedef VkResult (VKAPI *PFN_vkEnumerateDeviceLayerProperties)(VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties);
+typedef VkResult (VKAPI *PFN_vkGetDeviceQueue)(VkDevice device, uint32_t queueFamilyIndex, uint32_t queueIndex, VkQueue* pQueue);
+typedef VkResult (VKAPI *PFN_vkQueueSubmit)(VkQueue queue, uint32_t cmdBufferCount, const VkCmdBuffer* pCmdBuffers, VkFence fence);
+typedef VkResult (VKAPI *PFN_vkQueueWaitIdle)(VkQueue queue);
+typedef VkResult (VKAPI *PFN_vkDeviceWaitIdle)(VkDevice device);
+typedef VkResult (VKAPI *PFN_vkAllocMemory)(VkDevice device, const VkMemoryAllocInfo* pAllocInfo, VkDeviceMemory* pMem);
+typedef void (VKAPI *PFN_vkFreeMemory)(VkDevice device, VkDeviceMemory mem);
+typedef VkResult (VKAPI *PFN_vkMapMemory)(VkDevice device, VkDeviceMemory mem, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData);
+typedef void (VKAPI *PFN_vkUnmapMemory)(VkDevice device, VkDeviceMemory mem);
+typedef VkResult (VKAPI *PFN_vkFlushMappedMemoryRanges)(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges);
+typedef VkResult (VKAPI *PFN_vkInvalidateMappedMemoryRanges)(VkDevice device, uint32_t memRangeCount, const VkMappedMemoryRange* pMemRanges);
+typedef VkResult (VKAPI *PFN_vkGetDeviceMemoryCommitment)(VkDevice device, VkDeviceMemory memory, VkDeviceSize* pCommittedMemoryInBytes);
+typedef VkResult (VKAPI *PFN_vkBindBufferMemory)(VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset);
+typedef VkResult (VKAPI *PFN_vkBindImageMemory)(VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset);
+typedef VkResult (VKAPI *PFN_vkGetBufferMemoryRequirements)(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements);
+typedef VkResult (VKAPI *PFN_vkGetImageMemoryRequirements)(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements);
+typedef VkResult (VKAPI *PFN_vkGetImageSparseMemoryRequirements)(VkDevice device, VkImage image, uint32_t* pNumRequirements, VkSparseImageMemoryRequirements* pSparseMemoryRequirements);
+typedef VkResult (VKAPI *PFN_vkGetPhysicalDeviceSparseImageFormatProperties)(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, uint32_t samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pNumProperties, VkSparseImageFormatProperties* pProperties);
+typedef VkResult (VKAPI *PFN_vkQueueBindSparseBufferMemory)(VkQueue queue, VkBuffer buffer, uint32_t numBindings, const VkSparseMemoryBindInfo* pBindInfo);
+typedef VkResult (VKAPI *PFN_vkQueueBindSparseImageOpaqueMemory)(VkQueue queue, VkImage image, uint32_t numBindings, const VkSparseMemoryBindInfo* pBindInfo);
+typedef VkResult (VKAPI *PFN_vkQueueBindSparseImageMemory)(VkQueue queue, VkImage image, uint32_t numBindings, const VkSparseImageMemoryBindInfo* pBindInfo);
+typedef VkResult (VKAPI *PFN_vkCreateFence)(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence);
+typedef void (VKAPI *PFN_vkDestroyFence)(VkDevice device, VkFence fence);
+typedef VkResult (VKAPI *PFN_vkResetFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences);
+typedef VkResult (VKAPI *PFN_vkGetFenceStatus)(VkDevice device, VkFence fence);
+typedef VkResult (VKAPI *PFN_vkWaitForFences)(VkDevice device, uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout);
+typedef VkResult (VKAPI *PFN_vkCreateSemaphore)(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, VkSemaphore* pSemaphore);
+typedef void (VKAPI *PFN_vkDestroySemaphore)(VkDevice device, VkSemaphore semaphore);
+typedef VkResult (VKAPI *PFN_vkQueueSignalSemaphore)(VkQueue queue, VkSemaphore semaphore);
+typedef VkResult (VKAPI *PFN_vkQueueWaitSemaphore)(VkQueue queue, VkSemaphore semaphore);
+typedef VkResult (VKAPI *PFN_vkCreateEvent)(VkDevice device, const VkEventCreateInfo* pCreateInfo, VkEvent* pEvent);
+typedef void (VKAPI *PFN_vkDestroyEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI *PFN_vkGetEventStatus)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI *PFN_vkSetEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI *PFN_vkResetEvent)(VkDevice device, VkEvent event);
+typedef VkResult (VKAPI *PFN_vkCreateQueryPool)(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, VkQueryPool* pQueryPool);
+typedef void (VKAPI *PFN_vkDestroyQueryPool)(VkDevice device, VkQueryPool queryPool);
+typedef VkResult (VKAPI *PFN_vkGetQueryPoolResults)(VkDevice device, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, size_t* pDataSize, void* pData, VkQueryResultFlags flags);
+typedef VkResult (VKAPI *PFN_vkCreateBuffer)(VkDevice device, const VkBufferCreateInfo* pCreateInfo, VkBuffer* pBuffer);
+typedef void (VKAPI *PFN_vkDestroyBuffer)(VkDevice device, VkBuffer buffer);
+typedef VkResult (VKAPI *PFN_vkCreateBufferView)(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView);
+typedef void (VKAPI *PFN_vkDestroyBufferView)(VkDevice device, VkBufferView bufferView);
+typedef VkResult (VKAPI *PFN_vkCreateImage)(VkDevice device, const VkImageCreateInfo* pCreateInfo, VkImage* pImage);
+typedef void (VKAPI *PFN_vkDestroyImage)(VkDevice device, VkImage image);
+typedef VkResult (VKAPI *PFN_vkGetImageSubresourceLayout)(VkDevice device, VkImage image, const VkImageSubresource* pSubresource, VkSubresourceLayout* pLayout);
+typedef VkResult (VKAPI *PFN_vkCreateImageView)(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView);
+typedef void (VKAPI *PFN_vkDestroyImageView)(VkDevice device, VkImageView imageView);
+typedef VkResult (VKAPI *PFN_vkCreateShaderModule)(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModule* pShaderModule);
+typedef void (VKAPI *PFN_vkDestroyShaderModule)(VkDevice device, VkShaderModule shaderModule);
+typedef VkResult (VKAPI *PFN_vkCreateShader)(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader);
+typedef void (VKAPI *PFN_vkDestroyShader)(VkDevice device, VkShader shader);
+typedef VkResult (VKAPI *PFN_vkCreatePipelineCache)(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, VkPipelineCache* pPipelineCache);
+typedef void (VKAPI *PFN_vkDestroyPipelineCache)(VkDevice device, VkPipelineCache pipelineCache);
+typedef size_t (VKAPI *PFN_vkGetPipelineCacheSize)(VkDevice device, VkPipelineCache pipelineCache);
+typedef VkResult (VKAPI *PFN_vkGetPipelineCacheData)(VkDevice device, VkPipelineCache pipelineCache, void* pData);
+typedef VkResult (VKAPI *PFN_vkMergePipelineCaches)(VkDevice device, VkPipelineCache destCache, uint32_t srcCacheCount, const VkPipelineCache* pSrcCaches);
+typedef VkResult (VKAPI *PFN_vkCreateGraphicsPipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines);
+typedef VkResult (VKAPI *PFN_vkCreateComputePipelines)(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkComputePipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines);
+typedef void (VKAPI *PFN_vkDestroyPipeline)(VkDevice device, VkPipeline pipeline);
+typedef VkResult (VKAPI *PFN_vkCreatePipelineLayout)(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout);
+typedef void (VKAPI *PFN_vkDestroyPipelineLayout)(VkDevice device, VkPipelineLayout pipelineLayout);
+typedef VkResult (VKAPI *PFN_vkCreateSampler)(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler);
+typedef void (VKAPI *PFN_vkDestroySampler)(VkDevice device, VkSampler sampler);
+typedef VkResult (VKAPI *PFN_vkCreateDescriptorSetLayout)(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout);
+typedef void (VKAPI *PFN_vkDestroyDescriptorSetLayout)(VkDevice device, VkDescriptorSetLayout descriptorSetLayout);
+typedef VkResult (VKAPI *PFN_vkCreateDescriptorPool)(VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool);
+typedef void (VKAPI *PFN_vkDestroyDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool);
+typedef VkResult (VKAPI *PFN_vkResetDescriptorPool)(VkDevice device, VkDescriptorPool descriptorPool);
+typedef VkResult (VKAPI *PFN_vkAllocDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets);
+typedef VkResult (VKAPI *PFN_vkFreeDescriptorSets)(VkDevice device, VkDescriptorPool descriptorPool, uint32_t count, const VkDescriptorSet* pDescriptorSets);
+typedef void (VKAPI *PFN_vkUpdateDescriptorSets)(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies);
+typedef VkResult (VKAPI *PFN_vkCreateFramebuffer)(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer);
+typedef void (VKAPI *PFN_vkDestroyFramebuffer)(VkDevice device, VkFramebuffer framebuffer);
+typedef VkResult (VKAPI *PFN_vkCreateRenderPass)(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass);
+typedef void (VKAPI *PFN_vkDestroyRenderPass)(VkDevice device, VkRenderPass renderPass);
+typedef VkResult (VKAPI *PFN_vkGetRenderAreaGranularity)(VkDevice device, VkRenderPass renderPass, VkExtent2D* pGranularity);
+typedef VkResult (VKAPI *PFN_vkCreateCommandPool)(VkDevice device, const VkCmdPoolCreateInfo* pCreateInfo, VkCmdPool* pCmdPool);
+typedef void (VKAPI *PFN_vkDestroyCommandPool)(VkDevice device, VkCmdPool cmdPool);
+typedef VkResult (VKAPI *PFN_vkResetCommandPool)(VkDevice device, VkCmdPool cmdPool, VkCmdPoolResetFlags flags);
+typedef VkResult (VKAPI *PFN_vkCreateCommandBuffer)(VkDevice device, const VkCmdBufferCreateInfo* pCreateInfo, VkCmdBuffer* pCmdBuffer);
+typedef void (VKAPI *PFN_vkDestroyCommandBuffer)(VkDevice device, VkCmdBuffer commandBuffer);
+typedef VkResult (VKAPI *PFN_vkBeginCommandBuffer)(VkCmdBuffer cmdBuffer, const VkCmdBufferBeginInfo* pBeginInfo);
+typedef VkResult (VKAPI *PFN_vkEndCommandBuffer)(VkCmdBuffer cmdBuffer);
+typedef VkResult (VKAPI *PFN_vkResetCommandBuffer)(VkCmdBuffer cmdBuffer, VkCmdBufferResetFlags flags);
+typedef void (VKAPI *PFN_vkCmdBindPipeline)(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline);
+typedef void (VKAPI *PFN_vkCmdSetViewport)(VkCmdBuffer cmdBuffer, uint32_t viewportCount, const VkViewport* pViewports);
+typedef void (VKAPI *PFN_vkCmdSetScissor)(VkCmdBuffer cmdBuffer, uint32_t scissorCount, const VkRect2D* pScissors);
+typedef void (VKAPI *PFN_vkCmdSetLineWidth)(VkCmdBuffer cmdBuffer, float lineWidth);
+typedef void (VKAPI *PFN_vkCmdSetDepthBias)(VkCmdBuffer cmdBuffer, float depthBias, float depthBiasClamp, float slopeScaledDepthBias);
+typedef void (VKAPI *PFN_vkCmdSetBlendConstants)(VkCmdBuffer cmdBuffer, const float blendConst[4]);
+typedef void (VKAPI *PFN_vkCmdSetDepthBounds)(VkCmdBuffer cmdBuffer, float minDepthBounds, float maxDepthBounds);
+typedef void (VKAPI *PFN_vkCmdSetStencilCompareMask)(VkCmdBuffer cmdBuffer, VkStencilFaceFlags faceMask, uint32_t stencilCompareMask);
+typedef void (VKAPI *PFN_vkCmdSetStencilWriteMask)(VkCmdBuffer cmdBuffer, VkStencilFaceFlags faceMask, uint32_t stencilWriteMask);
+typedef void (VKAPI *PFN_vkCmdSetStencilReference)(VkCmdBuffer cmdBuffer, VkStencilFaceFlags faceMask, uint32_t stencilReference);
+typedef void (VKAPI *PFN_vkCmdBindDescriptorSets)(VkCmdBuffer cmdBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint32_t firstSet, uint32_t setCount, const VkDescriptorSet* pDescriptorSets, uint32_t dynamicOffsetCount, const uint32_t* pDynamicOffsets);
+typedef void (VKAPI *PFN_vkCmdBindIndexBuffer)(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, VkIndexType indexType);
+typedef void (VKAPI *PFN_vkCmdBindVertexBuffers)(VkCmdBuffer cmdBuffer, uint32_t startBinding, uint32_t bindingCount, const VkBuffer* pBuffers, const VkDeviceSize* pOffsets);
+typedef void (VKAPI *PFN_vkCmdDraw)(VkCmdBuffer cmdBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance);
+typedef void (VKAPI *PFN_vkCmdDrawIndexed)(VkCmdBuffer cmdBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance);
+typedef void (VKAPI *PFN_vkCmdDrawIndirect)(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride);
+typedef void (VKAPI *PFN_vkCmdDrawIndexedIndirect)(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t count, uint32_t stride);
+typedef void (VKAPI *PFN_vkCmdDispatch)(VkCmdBuffer cmdBuffer, uint32_t x, uint32_t y, uint32_t z);
+typedef void (VKAPI *PFN_vkCmdDispatchIndirect)(VkCmdBuffer cmdBuffer, VkBuffer buffer, VkDeviceSize offset);
+typedef void (VKAPI *PFN_vkCmdCopyBuffer)(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkBuffer destBuffer, uint32_t regionCount, const VkBufferCopy* pRegions);
+typedef void (VKAPI *PFN_vkCmdCopyImage)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageCopy* pRegions);
+typedef void (VKAPI *PFN_vkCmdBlitImage)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageBlit* pRegions, VkTexFilter filter);
+typedef void (VKAPI *PFN_vkCmdCopyBufferToImage)(VkCmdBuffer cmdBuffer, VkBuffer srcBuffer, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkBufferImageCopy* pRegions);
+typedef void (VKAPI *PFN_vkCmdCopyImageToBuffer)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkBuffer destBuffer, uint32_t regionCount, const VkBufferImageCopy* pRegions);
+typedef void (VKAPI *PFN_vkCmdUpdateBuffer)(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize dataSize, const uint32_t* pData);
+typedef void (VKAPI *PFN_vkCmdFillBuffer)(VkCmdBuffer cmdBuffer, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize fillSize, uint32_t data);
+typedef void (VKAPI *PFN_vkCmdClearColorImage)(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
+typedef void (VKAPI *PFN_vkCmdClearDepthStencilImage)(VkCmdBuffer cmdBuffer, VkImage image, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rangeCount, const VkImageSubresourceRange* pRanges);
+typedef void (VKAPI *PFN_vkCmdClearColorAttachment)(VkCmdBuffer cmdBuffer, uint32_t colorAttachment, VkImageLayout imageLayout, const VkClearColorValue* pColor, uint32_t rectCount, const VkRect3D* pRects);
+typedef void (VKAPI *PFN_vkCmdClearDepthStencilAttachment)(VkCmdBuffer cmdBuffer, VkImageAspectFlags aspectMask, VkImageLayout imageLayout, const VkClearDepthStencilValue* pDepthStencil, uint32_t rectCount, const VkRect3D* pRects);
+typedef void (VKAPI *PFN_vkCmdResolveImage)(VkCmdBuffer cmdBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage destImage, VkImageLayout destImageLayout, uint32_t regionCount, const VkImageResolve* pRegions);
+typedef void (VKAPI *PFN_vkCmdSetEvent)(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask);
+typedef void (VKAPI *PFN_vkCmdResetEvent)(VkCmdBuffer cmdBuffer, VkEvent event, VkPipelineStageFlags stageMask);
+typedef void (VKAPI *PFN_vkCmdWaitEvents)(VkCmdBuffer cmdBuffer, uint32_t eventCount, const VkEvent* pEvents, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, uint32_t memBarrierCount, const void* const* ppMemBarriers);
+typedef void (VKAPI *PFN_vkCmdPipelineBarrier)(VkCmdBuffer cmdBuffer, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags destStageMask, VkBool32 byRegion, uint32_t memBarrierCount, const void* const* ppMemBarriers);
+typedef void (VKAPI *PFN_vkCmdBeginQuery)(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot, VkQueryControlFlags flags);
+typedef void (VKAPI *PFN_vkCmdEndQuery)(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t slot);
+typedef void (VKAPI *PFN_vkCmdResetQueryPool)(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount);
+typedef void (VKAPI *PFN_vkCmdWriteTimestamp)(VkCmdBuffer cmdBuffer, VkTimestampType timestampType, VkBuffer destBuffer, VkDeviceSize destOffset);
+typedef void (VKAPI *PFN_vkCmdCopyQueryPoolResults)(VkCmdBuffer cmdBuffer, VkQueryPool queryPool, uint32_t startQuery, uint32_t queryCount, VkBuffer destBuffer, VkDeviceSize destOffset, VkDeviceSize destStride, VkQueryResultFlags flags);
+typedef void (VKAPI *PFN_vkCmdPushConstants)(VkCmdBuffer cmdBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint32_t start, uint32_t length, const void* values);
+typedef void (VKAPI *PFN_vkCmdBeginRenderPass)(VkCmdBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, VkRenderPassContents contents);
+typedef void (VKAPI *PFN_vkCmdNextSubpass)(VkCmdBuffer cmdBuffer, VkRenderPassContents contents);
+typedef void (VKAPI *PFN_vkCmdEndRenderPass)(VkCmdBuffer cmdBuffer);
+typedef void (VKAPI *PFN_vkCmdExecuteCommands)(VkCmdBuffer cmdBuffer, uint32_t cmdBuffersCount, const VkCmdBuffer* pCmdBuffers);
+
+#ifdef VK_PROTOTYPES
+VkResult VKAPI vkCreateInstance(
+    const VkInstanceCreateInfo*                 pCreateInfo,
+    VkInstance*                                 pInstance);
+
+void VKAPI vkDestroyInstance(
+    VkInstance                                  instance);
+
+VkResult VKAPI vkEnumeratePhysicalDevices(
+    VkInstance                                  instance,
+    uint32_t*                                   pPhysicalDeviceCount,
+    VkPhysicalDevice*                           pPhysicalDevices);
+
+VkResult VKAPI vkGetPhysicalDeviceFeatures(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceFeatures*                   pFeatures);
+
+VkResult VKAPI vkGetPhysicalDeviceFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkFormatProperties*                         pFormatProperties);
+
+VkResult VKAPI vkGetPhysicalDeviceImageFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkImageType                                 type,
+    VkImageTiling                               tiling,
+    VkImageUsageFlags                           usage,
+    VkImageCreateFlags                          flags,
+    VkImageFormatProperties*                    pImageFormatProperties);
+
+VkResult VKAPI vkGetPhysicalDeviceProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceProperties*                 pProperties);
+
+VkResult VKAPI vkGetPhysicalDeviceQueueFamilyProperties(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pCount,
+    VkQueueFamilyProperties*                    pQueueFamilyProperties);
+
+VkResult VKAPI vkGetPhysicalDeviceMemoryProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceMemoryProperties*           pMemoryProperties);
+
+PFN_vkVoidFunction VKAPI vkGetInstanceProcAddr(
+    VkInstance                                  instance,
+    const char*                                 pName);
+
+PFN_vkVoidFunction VKAPI vkGetDeviceProcAddr(
+    VkDevice                                    device,
+    const char*                                 pName);
+
+VkResult VKAPI vkCreateDevice(
+    VkPhysicalDevice                            physicalDevice,
+    const VkDeviceCreateInfo*                   pCreateInfo,
+    VkDevice*                                   pDevice);
+
+void VKAPI vkDestroyDevice(
+    VkDevice                                    device);
+
+VkResult VKAPI vkEnumerateInstanceExtensionProperties(
+    const char*                                 pLayerName,
+    uint32_t*                                   pCount,
+    VkExtensionProperties*                      pProperties);
+
+VkResult VKAPI vkEnumerateDeviceExtensionProperties(
+    VkPhysicalDevice                            physicalDevice,
+    const char*                                 pLayerName,
+    uint32_t*                                   pCount,
+    VkExtensionProperties*                      pProperties);
+
+VkResult VKAPI vkEnumerateInstanceLayerProperties(
+    uint32_t*                                   pCount,
+    VkLayerProperties*                          pProperties);
+
+VkResult VKAPI vkEnumerateDeviceLayerProperties(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pCount,
+    VkLayerProperties*                          pProperties);
+
+VkResult VKAPI vkGetDeviceQueue(
+    VkDevice                                    device,
+    uint32_t                                    queueFamilyIndex,
+    uint32_t                                    queueIndex,
+    VkQueue*                                    pQueue);
+
+VkResult VKAPI vkQueueSubmit(
+    VkQueue                                     queue,
+    uint32_t                                    cmdBufferCount,
+    const VkCmdBuffer*                          pCmdBuffers,
+    VkFence                                     fence);
+
+VkResult VKAPI vkQueueWaitIdle(
+    VkQueue                                     queue);
+
+VkResult VKAPI vkDeviceWaitIdle(
+    VkDevice                                    device);
+
+VkResult VKAPI vkAllocMemory(
+    VkDevice                                    device,
+    const VkMemoryAllocInfo*                    pAllocInfo,
+    VkDeviceMemory*                             pMem);
+
+void VKAPI vkFreeMemory(
+    VkDevice                                    device,
+    VkDeviceMemory                              mem);
+
+VkResult VKAPI vkMapMemory(
+    VkDevice                                    device,
+    VkDeviceMemory                              mem,
+    VkDeviceSize                                offset,
+    VkDeviceSize                                size,
+    VkMemoryMapFlags                            flags,
+    void**                                      ppData);
+
+void VKAPI vkUnmapMemory(
+    VkDevice                                    device,
+    VkDeviceMemory                              mem);
+
+VkResult VKAPI vkFlushMappedMemoryRanges(
+    VkDevice                                    device,
+    uint32_t                                    memRangeCount,
+    const VkMappedMemoryRange*                  pMemRanges);
+
+VkResult VKAPI vkInvalidateMappedMemoryRanges(
+    VkDevice                                    device,
+    uint32_t                                    memRangeCount,
+    const VkMappedMemoryRange*                  pMemRanges);
+
+VkResult VKAPI vkGetDeviceMemoryCommitment(
+    VkDevice                                    device,
+    VkDeviceMemory                              memory,
+    VkDeviceSize*                               pCommittedMemoryInBytes);
+
+VkResult VKAPI vkBindBufferMemory(
+    VkDevice                                    device,
+    VkBuffer                                    buffer,
+    VkDeviceMemory                              mem,
+    VkDeviceSize                                memOffset);
+
+VkResult VKAPI vkBindImageMemory(
+    VkDevice                                    device,
+    VkImage                                     image,
+    VkDeviceMemory                              mem,
+    VkDeviceSize                                memOffset);
+
+VkResult VKAPI vkGetBufferMemoryRequirements(
+    VkDevice                                    device,
+    VkBuffer                                    buffer,
+    VkMemoryRequirements*                       pMemoryRequirements);
+
+VkResult VKAPI vkGetImageMemoryRequirements(
+    VkDevice                                    device,
+    VkImage                                     image,
+    VkMemoryRequirements*                       pMemoryRequirements);
+
+VkResult VKAPI vkGetImageSparseMemoryRequirements(
+    VkDevice                                    device,
+    VkImage                                     image,
+    uint32_t*                                   pNumRequirements,
+    VkSparseImageMemoryRequirements*            pSparseMemoryRequirements);
+
+VkResult VKAPI vkGetPhysicalDeviceSparseImageFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkImageType                                 type,
+    uint32_t                                    samples,
+    VkImageUsageFlags                           usage,
+    VkImageTiling                               tiling,
+    uint32_t*                                   pNumProperties,
+    VkSparseImageFormatProperties*              pProperties);
+
+VkResult VKAPI vkQueueBindSparseBufferMemory(
+    VkQueue                                     queue,
+    VkBuffer                                    buffer,
+    uint32_t                                    numBindings,
+    const VkSparseMemoryBindInfo*               pBindInfo);
+
+VkResult VKAPI vkQueueBindSparseImageOpaqueMemory(
+    VkQueue                                     queue,
+    VkImage                                     image,
+    uint32_t                                    numBindings,
+    const VkSparseMemoryBindInfo*               pBindInfo);
+
+VkResult VKAPI vkQueueBindSparseImageMemory(
+    VkQueue                                     queue,
+    VkImage                                     image,
+    uint32_t                                    numBindings,
+    const VkSparseImageMemoryBindInfo*          pBindInfo);
+
+VkResult VKAPI vkCreateFence(
+    VkDevice                                    device,
+    const VkFenceCreateInfo*                    pCreateInfo,
+    VkFence*                                    pFence);
+
+void VKAPI vkDestroyFence(
+    VkDevice                                    device,
+    VkFence                                     fence);
+
+VkResult VKAPI vkResetFences(
+    VkDevice                                    device,
+    uint32_t                                    fenceCount,
+    const VkFence*                              pFences);
+
+VkResult VKAPI vkGetFenceStatus(
+    VkDevice                                    device,
+    VkFence                                     fence);
+
+VkResult VKAPI vkWaitForFences(
+    VkDevice                                    device,
+    uint32_t                                    fenceCount,
+    const VkFence*                              pFences,
+    VkBool32                                    waitAll,
+    uint64_t                                    timeout);
+
+VkResult VKAPI vkCreateSemaphore(
+    VkDevice                                    device,
+    const VkSemaphoreCreateInfo*                pCreateInfo,
+    VkSemaphore*                                pSemaphore);
+
+void VKAPI vkDestroySemaphore(
+    VkDevice                                    device,
+    VkSemaphore                                 semaphore);
+
+VkResult VKAPI vkQueueSignalSemaphore(
+    VkQueue                                     queue,
+    VkSemaphore                                 semaphore);
+
+VkResult VKAPI vkQueueWaitSemaphore(
+    VkQueue                                     queue,
+    VkSemaphore                                 semaphore);
+
+VkResult VKAPI vkCreateEvent(
+    VkDevice                                    device,
+    const VkEventCreateInfo*                    pCreateInfo,
+    VkEvent*                                    pEvent);
+
+void VKAPI vkDestroyEvent(
+    VkDevice                                    device,
+    VkEvent                                     event);
+
+VkResult VKAPI vkGetEventStatus(
+    VkDevice                                    device,
+    VkEvent                                     event);
+
+VkResult VKAPI vkSetEvent(
+    VkDevice                                    device,
+    VkEvent                                     event);
+
+VkResult VKAPI vkResetEvent(
+    VkDevice                                    device,
+    VkEvent                                     event);
+
+VkResult VKAPI vkCreateQueryPool(
+    VkDevice                                    device,
+    const VkQueryPoolCreateInfo*                pCreateInfo,
+    VkQueryPool*                                pQueryPool);
+
+void VKAPI vkDestroyQueryPool(
+    VkDevice                                    device,
+    VkQueryPool                                 queryPool);
+
+VkResult VKAPI vkGetQueryPoolResults(
+    VkDevice                                    device,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount,
+    size_t*                                     pDataSize,
+    void*                                       pData,
+    VkQueryResultFlags                          flags);
+
+VkResult VKAPI vkCreateBuffer(
+    VkDevice                                    device,
+    const VkBufferCreateInfo*                   pCreateInfo,
+    VkBuffer*                                   pBuffer);
+
+void VKAPI vkDestroyBuffer(
+    VkDevice                                    device,
+    VkBuffer                                    buffer);
+
+VkResult VKAPI vkCreateBufferView(
+    VkDevice                                    device,
+    const VkBufferViewCreateInfo*               pCreateInfo,
+    VkBufferView*                               pView);
+
+void VKAPI vkDestroyBufferView(
+    VkDevice                                    device,
+    VkBufferView                                bufferView);
+
+VkResult VKAPI vkCreateImage(
+    VkDevice                                    device,
+    const VkImageCreateInfo*                    pCreateInfo,
+    VkImage*                                    pImage);
+
+void VKAPI vkDestroyImage(
+    VkDevice                                    device,
+    VkImage                                     image);
+
+VkResult VKAPI vkGetImageSubresourceLayout(
+    VkDevice                                    device,
+    VkImage                                     image,
+    const VkImageSubresource*                   pSubresource,
+    VkSubresourceLayout*                        pLayout);
+
+VkResult VKAPI vkCreateImageView(
+    VkDevice                                    device,
+    const VkImageViewCreateInfo*                pCreateInfo,
+    VkImageView*                                pView);
+
+void VKAPI vkDestroyImageView(
+    VkDevice                                    device,
+    VkImageView                                 imageView);
+
+VkResult VKAPI vkCreateShaderModule(
+    VkDevice                                    device,
+    const VkShaderModuleCreateInfo*             pCreateInfo,
+    VkShaderModule*                             pShaderModule);
+
+void VKAPI vkDestroyShaderModule(
+    VkDevice                                    device,
+    VkShaderModule                              shaderModule);
+
+VkResult VKAPI vkCreateShader(
+    VkDevice                                    device,
+    const VkShaderCreateInfo*                   pCreateInfo,
+    VkShader*                                   pShader);
+
+void VKAPI vkDestroyShader(
+    VkDevice                                    device,
+    VkShader                                    shader);
+
+VkResult VKAPI vkCreatePipelineCache(
+    VkDevice                                    device,
+    const VkPipelineCacheCreateInfo*            pCreateInfo,
+    VkPipelineCache*                            pPipelineCache);
+
+void VKAPI vkDestroyPipelineCache(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache);
+
+size_t VKAPI vkGetPipelineCacheSize(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache);
+
+VkResult VKAPI vkGetPipelineCacheData(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache,
+    void*                                       pData);
+
+VkResult VKAPI vkMergePipelineCaches(
+    VkDevice                                    device,
+    VkPipelineCache                             destCache,
+    uint32_t                                    srcCacheCount,
+    const VkPipelineCache*                      pSrcCaches);
+
+VkResult VKAPI vkCreateGraphicsPipelines(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache,
+    uint32_t                                    count,
+    const VkGraphicsPipelineCreateInfo*         pCreateInfos,
+    VkPipeline*                                 pPipelines);
+
+VkResult VKAPI vkCreateComputePipelines(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache,
+    uint32_t                                    count,
+    const VkComputePipelineCreateInfo*          pCreateInfos,
+    VkPipeline*                                 pPipelines);
+
+void VKAPI vkDestroyPipeline(
+    VkDevice                                    device,
+    VkPipeline                                  pipeline);
+
+VkResult VKAPI vkCreatePipelineLayout(
+    VkDevice                                    device,
+    const VkPipelineLayoutCreateInfo*           pCreateInfo,
+    VkPipelineLayout*                           pPipelineLayout);
+
+void VKAPI vkDestroyPipelineLayout(
+    VkDevice                                    device,
+    VkPipelineLayout                            pipelineLayout);
+
+VkResult VKAPI vkCreateSampler(
+    VkDevice                                    device,
+    const VkSamplerCreateInfo*                  pCreateInfo,
+    VkSampler*                                  pSampler);
+
+void VKAPI vkDestroySampler(
+    VkDevice                                    device,
+    VkSampler                                   sampler);
+
+VkResult VKAPI vkCreateDescriptorSetLayout(
+    VkDevice                                    device,
+    const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
+    VkDescriptorSetLayout*                      pSetLayout);
+
+void VKAPI vkDestroyDescriptorSetLayout(
+    VkDevice                                    device,
+    VkDescriptorSetLayout                       descriptorSetLayout);
+
+VkResult VKAPI vkCreateDescriptorPool(
+    VkDevice                                    device,
+    const VkDescriptorPoolCreateInfo*           pCreateInfo,
+    VkDescriptorPool*                           pDescriptorPool);
+
+void VKAPI vkDestroyDescriptorPool(
+    VkDevice                                    device,
+    VkDescriptorPool                            descriptorPool);
+
+VkResult VKAPI vkResetDescriptorPool(
+    VkDevice                                    device,
+    VkDescriptorPool                            descriptorPool);
+
+VkResult VKAPI vkAllocDescriptorSets(
+    VkDevice                                    device,
+    VkDescriptorPool                            descriptorPool,
+    VkDescriptorSetUsage                        setUsage,
+    uint32_t                                    count,
+    const VkDescriptorSetLayout*                pSetLayouts,
+    VkDescriptorSet*                            pDescriptorSets);
+
+VkResult VKAPI vkFreeDescriptorSets(
+    VkDevice                                    device,
+    VkDescriptorPool                            descriptorPool,
+    uint32_t                                    count,
+    const VkDescriptorSet*                      pDescriptorSets);
+
+void VKAPI vkUpdateDescriptorSets(
+    VkDevice                                    device,
+    uint32_t                                    writeCount,
+    const VkWriteDescriptorSet*                 pDescriptorWrites,
+    uint32_t                                    copyCount,
+    const VkCopyDescriptorSet*                  pDescriptorCopies);
+
+VkResult VKAPI vkCreateFramebuffer(
+    VkDevice                                    device,
+    const VkFramebufferCreateInfo*              pCreateInfo,
+    VkFramebuffer*                              pFramebuffer);
+
+void VKAPI vkDestroyFramebuffer(
+    VkDevice                                    device,
+    VkFramebuffer                               framebuffer);
+
+VkResult VKAPI vkCreateRenderPass(
+    VkDevice                                    device,
+    const VkRenderPassCreateInfo*               pCreateInfo,
+    VkRenderPass*                               pRenderPass);
+
+void VKAPI vkDestroyRenderPass(
+    VkDevice                                    device,
+    VkRenderPass                                renderPass);
+
+VkResult VKAPI vkGetRenderAreaGranularity(
+    VkDevice                                    device,
+    VkRenderPass                                renderPass,
+    VkExtent2D*                                 pGranularity);
+
+VkResult VKAPI vkCreateCommandPool(
+    VkDevice                                    device,
+    const VkCmdPoolCreateInfo*                  pCreateInfo,
+    VkCmdPool*                                  pCmdPool);
+
+void VKAPI vkDestroyCommandPool(
+    VkDevice                                    device,
+    VkCmdPool                                   cmdPool);
+
+VkResult VKAPI vkResetCommandPool(
+    VkDevice                                    device,
+    VkCmdPool                                   cmdPool,
+    VkCmdPoolResetFlags                         flags);
+
+VkResult VKAPI vkCreateCommandBuffer(
+    VkDevice                                    device,
+    const VkCmdBufferCreateInfo*                pCreateInfo,
+    VkCmdBuffer*                                pCmdBuffer);
+
+void VKAPI vkDestroyCommandBuffer(
+    VkDevice                                    device,
+    VkCmdBuffer                                 commandBuffer);
+
+VkResult VKAPI vkBeginCommandBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    const VkCmdBufferBeginInfo*                 pBeginInfo);
+
+VkResult VKAPI vkEndCommandBuffer(
+    VkCmdBuffer                                 cmdBuffer);
+
+VkResult VKAPI vkResetCommandBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkCmdBufferResetFlags                       flags);
+
+void VKAPI vkCmdBindPipeline(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineBindPoint                         pipelineBindPoint,
+    VkPipeline                                  pipeline);
+
+void VKAPI vkCmdSetViewport(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    viewportCount,
+    const VkViewport*                           pViewports);
+
+void VKAPI vkCmdSetScissor(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    scissorCount,
+    const VkRect2D*                             pScissors);
+
+void VKAPI vkCmdSetLineWidth(
+    VkCmdBuffer                                 cmdBuffer,
+    float                                       lineWidth);
+
+void VKAPI vkCmdSetDepthBias(
+    VkCmdBuffer                                 cmdBuffer,
+    float                                       depthBias,
+    float                                       depthBiasClamp,
+    float                                       slopeScaledDepthBias);
+
+void VKAPI vkCmdSetBlendConstants(
+    VkCmdBuffer                                 cmdBuffer,
+    const float                                 blendConst[4]);
+
+void VKAPI vkCmdSetDepthBounds(
+    VkCmdBuffer                                 cmdBuffer,
+    float                                       minDepthBounds,
+    float                                       maxDepthBounds);
+
+void VKAPI vkCmdSetStencilCompareMask(
+    VkCmdBuffer                                 cmdBuffer,
+    VkStencilFaceFlags                          faceMask,
+    uint32_t                                    stencilCompareMask);
+
+void VKAPI vkCmdSetStencilWriteMask(
+    VkCmdBuffer                                 cmdBuffer,
+    VkStencilFaceFlags                          faceMask,
+    uint32_t                                    stencilWriteMask);
+
+void VKAPI vkCmdSetStencilReference(
+    VkCmdBuffer                                 cmdBuffer,
+    VkStencilFaceFlags                          faceMask,
+    uint32_t                                    stencilReference);
+
+void VKAPI vkCmdBindDescriptorSets(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineBindPoint                         pipelineBindPoint,
+    VkPipelineLayout                            layout,
+    uint32_t                                    firstSet,
+    uint32_t                                    setCount,
+    const VkDescriptorSet*                      pDescriptorSets,
+    uint32_t                                    dynamicOffsetCount,
+    const uint32_t*                             pDynamicOffsets);
+
+void VKAPI vkCmdBindIndexBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    VkIndexType                                 indexType);
+
+void VKAPI vkCmdBindVertexBuffers(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    startBinding,
+    uint32_t                                    bindingCount,
+    const VkBuffer*                             pBuffers,
+    const VkDeviceSize*                         pOffsets);
+
+void VKAPI vkCmdDraw(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    vertexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstVertex,
+    uint32_t                                    firstInstance);
+
+void VKAPI vkCmdDrawIndexed(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    indexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstIndex,
+    int32_t                                     vertexOffset,
+    uint32_t                                    firstInstance);
+
+void VKAPI vkCmdDrawIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride);
+
+void VKAPI vkCmdDrawIndexedIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride);
+
+void VKAPI vkCmdDispatch(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    x,
+    uint32_t                                    y,
+    uint32_t                                    z);
+
+void VKAPI vkCmdDispatchIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    buffer,
+    VkDeviceSize                                offset);
+
+void VKAPI vkCmdCopyBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    srcBuffer,
+    VkBuffer                                    destBuffer,
+    uint32_t                                    regionCount,
+    const VkBufferCopy*                         pRegions);
+
+void VKAPI vkCmdCopyImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkImageCopy*                          pRegions);
+
+void VKAPI vkCmdBlitImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkImageBlit*                          pRegions,
+    VkTexFilter                                 filter);
+
+void VKAPI vkCmdCopyBufferToImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    srcBuffer,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkBufferImageCopy*                    pRegions);
+
+void VKAPI vkCmdCopyImageToBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkBuffer                                    destBuffer,
+    uint32_t                                    regionCount,
+    const VkBufferImageCopy*                    pRegions);
+
+void VKAPI vkCmdUpdateBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                dataSize,
+    const uint32_t*                             pData);
+
+void VKAPI vkCmdFillBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                fillSize,
+    uint32_t                                    data);
+
+void VKAPI vkCmdClearColorImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     image,
+    VkImageLayout                               imageLayout,
+    const VkClearColorValue*                    pColor,
+    uint32_t                                    rangeCount,
+    const VkImageSubresourceRange*              pRanges);
+
+void VKAPI vkCmdClearDepthStencilImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     image,
+    VkImageLayout                               imageLayout,
+    const VkClearDepthStencilValue*             pDepthStencil,
+    uint32_t                                    rangeCount,
+    const VkImageSubresourceRange*              pRanges);
+
+void VKAPI vkCmdClearColorAttachment(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    colorAttachment,
+    VkImageLayout                               imageLayout,
+    const VkClearColorValue*                    pColor,
+    uint32_t                                    rectCount,
+    const VkRect3D*                             pRects);
+
+void VKAPI vkCmdClearDepthStencilAttachment(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImageAspectFlags                          aspectMask,
+    VkImageLayout                               imageLayout,
+    const VkClearDepthStencilValue*             pDepthStencil,
+    uint32_t                                    rectCount,
+    const VkRect3D*                             pRects);
+
+void VKAPI vkCmdResolveImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkImageResolve*                       pRegions);
+
+void VKAPI vkCmdSetEvent(
+    VkCmdBuffer                                 cmdBuffer,
+    VkEvent                                     event,
+    VkPipelineStageFlags                        stageMask);
+
+void VKAPI vkCmdResetEvent(
+    VkCmdBuffer                                 cmdBuffer,
+    VkEvent                                     event,
+    VkPipelineStageFlags                        stageMask);
+
+void VKAPI vkCmdWaitEvents(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    eventCount,
+    const VkEvent*                              pEvents,
+    VkPipelineStageFlags                        srcStageMask,
+    VkPipelineStageFlags                        destStageMask,
+    uint32_t                                    memBarrierCount,
+    const void* const*                          ppMemBarriers);
+
+void VKAPI vkCmdPipelineBarrier(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineStageFlags                        srcStageMask,
+    VkPipelineStageFlags                        destStageMask,
+    VkBool32                                    byRegion,
+    uint32_t                                    memBarrierCount,
+    const void* const*                          ppMemBarriers);
+
+void VKAPI vkCmdBeginQuery(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    slot,
+    VkQueryControlFlags                         flags);
+
+void VKAPI vkCmdEndQuery(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    slot);
+
+void VKAPI vkCmdResetQueryPool(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount);
+
+void VKAPI vkCmdWriteTimestamp(
+    VkCmdBuffer                                 cmdBuffer,
+    VkTimestampType                             timestampType,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset);
+
+void VKAPI vkCmdCopyQueryPoolResults(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                destStride,
+    VkQueryResultFlags                          flags);
+
+void VKAPI vkCmdPushConstants(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineLayout                            layout,
+    VkShaderStageFlags                          stageFlags,
+    uint32_t                                    start,
+    uint32_t                                    length,
+    const void*                                 values);
+
+void VKAPI vkCmdBeginRenderPass(
+    VkCmdBuffer                                 cmdBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    VkRenderPassContents                        contents);
+
+void VKAPI vkCmdNextSubpass(
+    VkCmdBuffer                                 cmdBuffer,
+    VkRenderPassContents                        contents);
+
+void VKAPI vkCmdEndRenderPass(
+    VkCmdBuffer                                 cmdBuffer);
+
+void VKAPI vkCmdExecuteCommands(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    cmdBuffersCount,
+    const VkCmdBuffer*                          pCmdBuffers);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/vulkan/vulkan_intel.h b/include/vulkan/vulkan_intel.h
new file mode 100644 (file)
index 0000000..631e636
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __VULKAN_INTEL_H__
+#define __VULKAN_INTEL_H__
+
+#include "vulkan.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+
+#define VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL 1024
+typedef struct VkDmaBufImageCreateInfo_
+{
+    VkStructureType                             sType;                      // Must be VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL
+    const void*                                 pNext;                      // Pointer to next structure.
+    int                                         fd;
+    VkFormat                                    format;
+    VkExtent3D                                  extent;         // Depth must be 1
+    uint32_t                                    strideInBytes;
+} VkDmaBufImageCreateInfo;
+
+typedef VkResult (VKAPI *PFN_vkCreateDmaBufImageINTEL)(VkDevice device, const VkDmaBufImageCreateInfo* pCreateInfo, VkDeviceMemory* pMem, VkImage* pImage);
+
+#ifdef VK_PROTOTYPES
+
+VkResult VKAPI vkCreateDmaBufImageINTEL(
+    VkDevice                                    _device,
+    const VkDmaBufImageCreateInfo*             pCreateInfo,
+    VkDeviceMemory*                             pMem,
+    VkImage*                                    pImage);
+
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#endif // __VULKAN_INTEL_H__
index 0d49bcd19ed8768f5f8829d52ef9199fe5dac5c6..da638a811fbd2eec25c1814257071b3300b04730 100644 (file)
@@ -53,6 +53,10 @@ EXTRA_DIST = \
 AM_CFLAGS = $(VISIBILITY_CFLAGS)
 AM_CXXFLAGS = $(VISIBILITY_CXXFLAGS)
 
+if HAVE_VULKAN
+SUBDIRS += vulkan
+endif
+
 AM_CPPFLAGS = \
        -I$(top_srcdir)/include/ \
        -I$(top_srcdir)/src/mapi/ \
index dda423f83db6df30eded8a2aacf772e46de3d568..e80f8af6bfcf70450f7d024e7ea36a0c6ea12226 100644 (file)
@@ -4,6 +4,7 @@ glsl_parser.cpp
 glsl_parser.h
 glsl_parser.output
 glsl_test
+spirv2nir
 subtest-cr/
 subtest-lf/
 subtest-cr-lf/
index 33a34e4ccc8b50133a18d4d84c58ec6aa986ddea..8b0a73b250a768aa48bf40c622e85643a27efb18 100644 (file)
@@ -78,7 +78,7 @@ check_PROGRAMS =                                      \
        tests/sampler-types-test                        \
        tests/uniform-initializer-test
 
-noinst_PROGRAMS = glsl_compiler
+noinst_PROGRAMS = glsl_compiler spirv2nir
 
 tests_blob_test_SOURCES =                              \
        tests/blob_test.c
@@ -160,6 +160,16 @@ glsl_compiler_LDADD =                                      \
        $(top_builddir)/src/util/libmesautil.la         \
        $(PTHREAD_LIBS)
 
+spirv2nir_SOURCES = \
+       standalone_scaffolding.cpp \
+       standalone_scaffolding.h \
+       nir/spirv2nir.c
+
+spirv2nir_LDADD =                                      \
+       libglsl.la                                      \
+       $(top_builddir)/src/libglsl_util.la             \
+       $(PTHREAD_LIBS)
+
 glsl_test_SOURCES = \
        standalone_scaffolding.cpp \
        test.cpp \
index d4b02c17b0d6bd8f051a391422540448757a5209..957fd6b90ba17ad41cb5ad50e48a3db879b8879f 100644 (file)
@@ -32,6 +32,7 @@ NIR_FILES = \
        nir/nir_control_flow_private.h \
        nir/nir_dominance.c \
        nir/nir_from_ssa.c \
+       nir/nir_gather_info.c \
        nir/nir_gs_count_vertices.c \
        nir/nir_intrinsics.c \
        nir/nir_intrinsics.h \
@@ -74,6 +75,7 @@ NIR_FILES = \
        nir/nir_remove_dead_variables.c \
        nir/nir_search.c \
        nir/nir_search.h \
+       nir/nir_spirv.h \
        nir/nir_split_var_copies.c \
        nir/nir_sweep.c \
        nir/nir_to_ssa.c \
@@ -84,7 +86,9 @@ NIR_FILES = \
        nir/nir_worklist.h \
        nir/nir_types.cpp \
        nir/shader_enums.h \
-       nir/shader_enums.c
+       nir/shader_enums.c \
+       nir/spirv_to_nir.c \
+       nir/spirv_glsl450_to_nir.c
 
 # libglsl
 
index f5292435058c66425312b903082fb93d9674485e..65db2618895128d7ec50cf9b04ded846125904d7 100644 (file)
@@ -1088,6 +1088,7 @@ do_comparison(void *mem_ctx, int operation, ir_rvalue *op0, ir_rvalue *op1)
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_IMAGE:
    case GLSL_TYPE_INTERFACE:
+   case GLSL_TYPE_FUNCTION:
    case GLSL_TYPE_ATOMIC_UINT:
    case GLSL_TYPE_SUBROUTINE:
       /* I assume a comparison of a struct containing a sampler just
index 3ed116830620521511a96a988158a1570304e0f4..02584c62a4dbf0543d8dc07497b689cb503b291b 100644 (file)
@@ -87,6 +87,8 @@ _mesa_glsl_parse_state::_mesa_glsl_parse_state(struct gl_context *_ctx,
 
    this->extensions = &ctx->Extensions;
 
+   this->ARB_compute_shader_enable = true;
+
    this->Const.MaxLights = ctx->Const.MaxLights;
    this->Const.MaxClipPlanes = ctx->Const.MaxClipPlanes;
    this->Const.MaxTextureUnits = ctx->Const.MaxTextureUnits;
index a2cd672d5d61878a6216213119a5f73b553de393..d6b06eeec87e2d2939e0460d0a717e04eeb5be28 100644 (file)
@@ -364,6 +364,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
       return c;
    }
 
+   case GLSL_TYPE_FUNCTION:
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_IMAGE:
    case GLSL_TYPE_ATOMIC_UINT:
index 58d21e5125efe666e0e8f52e37adfec669dd9a89..cdc1d3ac7be96fe79e4ed9950bba155a12623065 100644 (file)
@@ -88,6 +88,7 @@ copy_constant_to_storage(union gl_constant_value *storage,
       case GLSL_TYPE_IMAGE:
       case GLSL_TYPE_ATOMIC_UINT:
       case GLSL_TYPE_INTERFACE:
+      case GLSL_TYPE_FUNCTION:
       case GLSL_TYPE_VOID:
       case GLSL_TYPE_SUBROUTINE:
       case GLSL_TYPE_ERROR:
index b10d1923e0a82aad621105e8a702f3e367204663..d8df3544f10f2c3d8ffc5b26da7163f2e9d753e2 100644 (file)
@@ -45,7 +45,7 @@ namespace {
 class nir_visitor : public ir_visitor
 {
 public:
-   nir_visitor(nir_shader *shader);
+   nir_visitor(nir_shader *shader, gl_shader *sh);
    ~nir_visitor();
 
    virtual void visit(ir_variable *);
@@ -85,6 +85,8 @@ private:
 
    bool supports_ints;
 
+   struct gl_shader *sh;
+
    nir_shader *shader;
    nir_function_impl *impl;
    nir_builder b;
@@ -138,7 +140,7 @@ glsl_to_nir(const struct gl_shader_program *shader_prog,
 
    nir_shader *shader = nir_shader_create(NULL, stage, options);
 
-   nir_visitor v1(shader);
+   nir_visitor v1(shader, sh);
    nir_function_visitor v2(&v1);
    v2.run(sh->ir);
    visit_exec_list(sh->ir, &v1);
@@ -206,10 +208,11 @@ glsl_to_nir(const struct gl_shader_program *shader_prog,
    return shader;
 }
 
-nir_visitor::nir_visitor(nir_shader *shader)
+nir_visitor::nir_visitor(nir_shader *shader, gl_shader *sh)
 {
    this->supports_ints = shader->options->native_integers;
    this->shader = shader;
+   this->sh = sh;
    this->is_global = true;
    this->var_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
                                              _mesa_key_pointer_equal);
@@ -395,6 +398,7 @@ nir_visitor::visit(ir_variable *ir)
    }
 
    var->data.index = ir->data.index;
+   var->data.descriptor_set = 0;
    var->data.binding = ir->data.binding;
    var->data.atomic.offset = ir->data.atomic.offset;
    var->data.image.read_only = ir->data.image_read_only;
@@ -1187,6 +1191,7 @@ nir_visitor::visit(ir_expression *ir)
       } else {
          op = nir_intrinsic_load_ubo_indirect;
       }
+
       nir_intrinsic_instr *load = nir_intrinsic_instr_create(this->shader, op);
       load->num_components = ir->type->vector_elements;
       load->const_index[0] = const_index ? const_index->value.u[0] : 0; /* base offset */
index 975b815b0cc1727aaef11002a49dcc7693ef3099..3e9d38f7707a8340ff2b86788a9e1895d4795eee 100644 (file)
@@ -32,6 +32,7 @@ mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
 hash_table *glsl_type::array_types = NULL;
 hash_table *glsl_type::record_types = NULL;
 hash_table *glsl_type::interface_types = NULL;
+hash_table *glsl_type::function_types = NULL;
 hash_table *glsl_type::subroutine_types = NULL;
 void *glsl_type::mem_ctx = NULL;
 
@@ -168,6 +169,39 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
    mtx_unlock(&glsl_type::mutex);
 }
 
+glsl_type::glsl_type(const glsl_type *return_type,
+                     const glsl_function_param *params, unsigned num_params) :
+   gl_type(0),
+   base_type(GLSL_TYPE_FUNCTION),
+   sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
+   sampler_type(0), interface_packing(0),
+   vector_elements(0), matrix_columns(0),
+   length(num_params)
+{
+   unsigned int i;
+
+   mtx_lock(&glsl_type::mutex);
+
+   init_ralloc_type_ctx();
+
+   this->fields.parameters = rzalloc_array(this->mem_ctx,
+                                           glsl_function_param, num_params + 1);
+
+   /* We store the return type as the first parameter */
+   this->fields.parameters[0].type = return_type;
+   this->fields.parameters[0].in = false;
+   this->fields.parameters[0].out = true;
+
+   /* We store the i'th parameter in slot i+1 */
+   for (i = 0; i < length; i++) {
+      this->fields.parameters[i + 1].type = params[i].type;
+      this->fields.parameters[i + 1].in = params[i].in;
+      this->fields.parameters[i + 1].out = params[i].out;
+   }
+
+   mtx_unlock(&glsl_type::mutex);
+}
+
 glsl_type::glsl_type(const char *subroutine_name) :
    gl_type(0),
    base_type(GLSL_TYPE_SUBROUTINE),
@@ -679,6 +713,93 @@ glsl_type::get_sampler_instance(enum glsl_sampler_dim dim,
    unreachable("switch statement above should be complete");
 }
 
+const glsl_type *
+glsl_type::get_image_instance(enum glsl_sampler_dim dim,
+                              bool array, glsl_base_type type)
+{
+   switch (type) {
+   case GLSL_TYPE_FLOAT:
+      switch (dim) {
+      case GLSL_SAMPLER_DIM_1D:
+         return (array ? image1DArray_type : image1D_type);
+      case GLSL_SAMPLER_DIM_2D:
+         return (array ? image2DArray_type : image2D_type);
+      case GLSL_SAMPLER_DIM_3D:
+         return image3D_type;
+      case GLSL_SAMPLER_DIM_CUBE:
+         return (array ? imageCubeArray_type : imageCube_type);
+      case GLSL_SAMPLER_DIM_RECT:
+         if (array)
+            return error_type;
+         else
+            return image2DRect_type;
+      case GLSL_SAMPLER_DIM_BUF:
+         if (array)
+            return error_type;
+         else
+            return imageBuffer_type;
+      case GLSL_SAMPLER_DIM_MS:
+         return (array ? image2DMSArray_type : image2DMS_type);
+      case GLSL_SAMPLER_DIM_EXTERNAL:
+         return error_type;
+      }
+   case GLSL_TYPE_INT:
+      switch (dim) {
+      case GLSL_SAMPLER_DIM_1D:
+         return (array ? iimage1DArray_type : iimage1D_type);
+      case GLSL_SAMPLER_DIM_2D:
+         return (array ? iimage2DArray_type : iimage2D_type);
+      case GLSL_SAMPLER_DIM_3D:
+         if (array)
+            return error_type;
+         return iimage3D_type;
+      case GLSL_SAMPLER_DIM_CUBE:
+         return (array ? iimageCubeArray_type : iimageCube_type);
+      case GLSL_SAMPLER_DIM_RECT:
+         if (array)
+            return error_type;
+         return iimage2DRect_type;
+      case GLSL_SAMPLER_DIM_BUF:
+         if (array)
+            return error_type;
+         return iimageBuffer_type;
+      case GLSL_SAMPLER_DIM_MS:
+         return (array ? iimage2DMSArray_type : iimage2DMS_type);
+      case GLSL_SAMPLER_DIM_EXTERNAL:
+         return error_type;
+      }
+   case GLSL_TYPE_UINT:
+      switch (dim) {
+      case GLSL_SAMPLER_DIM_1D:
+         return (array ? uimage1DArray_type : uimage1D_type);
+      case GLSL_SAMPLER_DIM_2D:
+         return (array ? uimage2DArray_type : uimage2D_type);
+      case GLSL_SAMPLER_DIM_3D:
+         if (array)
+            return error_type;
+         return uimage3D_type;
+      case GLSL_SAMPLER_DIM_CUBE:
+         return (array ? uimageCubeArray_type : uimageCube_type);
+      case GLSL_SAMPLER_DIM_RECT:
+         if (array)
+            return error_type;
+         return uimage2DRect_type;
+      case GLSL_SAMPLER_DIM_BUF:
+         if (array)
+            return error_type;
+         return uimageBuffer_type;
+      case GLSL_SAMPLER_DIM_MS:
+         return (array ? uimage2DMSArray_type : uimage2DMS_type);
+      case GLSL_SAMPLER_DIM_EXTERNAL:
+         return error_type;
+      }
+   default:
+      return error_type;
+   }
+
+   unreachable("switch statement above should be complete");
+}
+
 const glsl_type *
 glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
 {
@@ -923,6 +1044,74 @@ glsl_type::get_subroutine_instance(const char *subroutine_name)
 }
 
 
+static bool
+function_key_compare(const void *a, const void *b)
+{
+   const glsl_type *const key1 = (glsl_type *) a;
+   const glsl_type *const key2 = (glsl_type *) b;
+
+   if (key1->length != key2->length)
+      return 1;
+
+   return memcmp(key1->fields.parameters, key2->fields.parameters,
+                 (key1->length + 1) * sizeof(*key1->fields.parameters));
+}
+
+
+static uint32_t
+function_key_hash(const void *a)
+{
+   const glsl_type *const key = (glsl_type *) a;
+   char hash_key[128];
+   unsigned size = 0;
+
+   size = snprintf(hash_key, sizeof(hash_key), "%08x", key->length);
+
+   for (unsigned i = 0; i < key->length; i++) {
+      if (size >= sizeof(hash_key))
+        break;
+
+      size += snprintf(& hash_key[size], sizeof(hash_key) - size,
+                      "%p", (void *) key->fields.structure[i].type);
+   }
+
+   return _mesa_hash_string(hash_key);
+}
+
+const glsl_type *
+glsl_type::get_function_instance(const glsl_type *return_type,
+                                 const glsl_function_param *params,
+                                 unsigned num_params)
+{
+   const glsl_type key(return_type, params, num_params);
+
+   mtx_lock(&glsl_type::mutex);
+
+   if (function_types == NULL) {
+      function_types = _mesa_hash_table_create(NULL, function_key_hash,
+                                               function_key_compare);
+   }
+
+   struct hash_entry *entry = _mesa_hash_table_search(function_types, &key);
+   if (entry == NULL) {
+      mtx_unlock(&glsl_type::mutex);
+      const glsl_type *t = new glsl_type(return_type, params, num_params);
+      mtx_lock(&glsl_type::mutex);
+
+      entry = _mesa_hash_table_insert(function_types, t, (void *) t);
+   }
+
+   const glsl_type *t = (const glsl_type *)entry->data;
+
+   assert(t->base_type == GLSL_TYPE_FUNCTION);
+   assert(t->length == num_params);
+
+   mtx_unlock(&glsl_type::mutex);
+
+   return t;
+}
+
+
 const glsl_type *
 glsl_type::get_mul_type(const glsl_type *type_a, const glsl_type *type_b)
 {
@@ -1052,6 +1241,8 @@ glsl_type::component_slots() const
       return 1;
    case GLSL_TYPE_SUBROUTINE:
      return 1;
+
+   case GLSL_TYPE_FUNCTION:
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_ATOMIC_UINT:
    case GLSL_TYPE_VOID:
@@ -1682,6 +1873,7 @@ glsl_type::count_attribute_slots() const
    case GLSL_TYPE_ARRAY:
       return this->length * this->fields.array->count_attribute_slots();
 
+   case GLSL_TYPE_FUNCTION:
    case GLSL_TYPE_SAMPLER:
    case GLSL_TYPE_IMAGE:
    case GLSL_TYPE_ATOMIC_UINT:
index d841a3277db7c878ecf3884b81da23fe3a6a3016..14c2aa49f85e4c81d6e842d86c3cc5ae92092eaf 100644 (file)
@@ -56,6 +56,7 @@ enum glsl_base_type {
    GLSL_TYPE_IMAGE,
    GLSL_TYPE_ATOMIC_UINT,
    GLSL_TYPE_STRUCT,
+   GLSL_TYPE_FUNCTION,
    GLSL_TYPE_INTERFACE,
    GLSL_TYPE_ARRAY,
    GLSL_TYPE_VOID,
@@ -187,7 +188,7 @@ struct glsl_type {
     */
    union {
       const struct glsl_type *array;            /**< Type of array elements. */
-      const struct glsl_type *parameters;       /**< Parameters to function. */
+      struct glsl_function_param *parameters;   /**< Parameters to function. */
       struct glsl_struct_field *structure;      /**< List of struct fields. */
    } fields;
 
@@ -250,6 +251,8 @@ struct glsl_type {
                                                 bool array,
                                                 glsl_base_type type);
 
+   static const glsl_type *get_image_instance(enum glsl_sampler_dim dim,
+                                              bool array, glsl_base_type type);
 
    /**
     * Get the instance of an array type
@@ -277,6 +280,13 @@ struct glsl_type {
     */
    static const glsl_type *get_subroutine_instance(const char *subroutine_name);
 
+   /**
+    * Get the instance of a function type
+    */
+   static const glsl_type *get_function_instance(const struct glsl_type *return_type,
+                                                 const glsl_function_param *parameters,
+                                                 unsigned num_params);
+
    /**
     * Get the type resulting from a multiplication of \p type_a * \p type_b
     */
@@ -747,6 +757,10 @@ private:
    glsl_type(const glsl_struct_field *fields, unsigned num_fields,
             enum glsl_interface_packing packing, const char *name);
 
+   /** Constructor for interface types */
+   glsl_type(const glsl_type *return_type,
+             const glsl_function_param *params, unsigned num_params);
+
    /** Constructor for array types */
    glsl_type(const glsl_type *array, unsigned length);
 
@@ -765,6 +779,9 @@ private:
    /** Hash table containing the known subroutine types. */
    static struct hash_table *subroutine_types;
 
+   /** Hash table containing the known function types. */
+   static struct hash_table *function_types;
+
    static bool record_key_compare(const void *a, const void *b);
    static unsigned record_key_hash(const void *key);
 
@@ -792,6 +809,10 @@ private:
    /*@}*/
 };
 
+#undef DECL_TYPE
+#undef STRUCT_TYPE
+#endif /* __cplusplus */
+
 struct glsl_struct_field {
    const struct glsl_type *type;
    const char *name;
@@ -849,6 +870,7 @@ struct glsl_struct_field {
    unsigned image_volatile:1;
    unsigned image_restrict:1;
 
+#ifdef __cplusplus
    glsl_struct_field(const struct glsl_type *_type, const char *_name)
       : type(_type), name(_name), location(-1), interpolation(0), centroid(0),
         sample(0), matrix_layout(GLSL_MATRIX_LAYOUT_INHERITED), patch(0)
@@ -860,6 +882,14 @@ struct glsl_struct_field {
    {
       /* empty */
    }
+#endif
+};
+
+struct glsl_function_param {
+   const struct glsl_type *type;
+
+   bool in;
+   bool out;
 };
 
 static inline unsigned int
@@ -868,8 +898,4 @@ glsl_align(unsigned int a, unsigned int align)
    return (a + align - 1) / align * align;
 }
 
-#undef DECL_TYPE
-#undef STRUCT_TYPE
-#endif /* __cplusplus */
-
 #endif /* GLSL_TYPES_H */
index beabcafef4ec34e9404c169be8b7aafece707bbe..1215e58dfb8d285ff40746cc61f16b64ad22bd2b 100644 (file)
@@ -298,6 +298,11 @@ typedef struct {
        */
       int index;
 
+      /**
+       * Descriptor set binding for sampler or UBO.
+       */
+      int descriptor_set;
+
       /**
        * Initial binding point for a sampler or UBO.
        *
@@ -522,7 +527,11 @@ typedef struct nir_src {
    bool is_ssa;
 } nir_src;
 
-#define NIR_SRC_INIT (nir_src) { { NULL } }
+#ifdef __cplusplus
+#  define NIR_SRC_INIT nir_src()
+#else
+#  define NIR_SRC_INIT (nir_src) { { NULL } }
+#endif
 
 #define nir_foreach_use(reg_or_ssa_def, src) \
    list_for_each_entry(nir_src, src, &(reg_or_ssa_def)->uses, use_link)
@@ -545,7 +554,11 @@ typedef struct {
    bool is_ssa;
 } nir_dest;
 
-#define NIR_DEST_INIT (nir_dest) { { { NULL } } }
+#ifdef __cplusplus
+#  define NIR_DEST_INIT nir_dest()
+#else
+#  define NIR_DEST_INIT (nir_dest) { { { NULL } } }
+#endif
 
 #define nir_foreach_def(reg, dest) \
    list_for_each_entry(nir_dest, dest, &(reg)->defs, reg.def_link)
@@ -1438,6 +1451,7 @@ typedef struct nir_function {
 
 typedef struct nir_shader_compiler_options {
    bool lower_ffma;
+   bool lower_fdiv;
    bool lower_flrp;
    bool lower_fpow;
    bool lower_fsat;
@@ -1703,6 +1717,17 @@ typedef struct {
    };
 } nir_cursor;
 
+static inline nir_block *
+nir_cursor_current_block(nir_cursor cursor)
+{
+   if (cursor.option == nir_cursor_before_instr ||
+       cursor.option == nir_cursor_after_instr) {
+      return cursor.instr->block;
+   } else {
+      return cursor.block;
+   }
+}
+
 static inline nir_cursor
 nir_before_block(nir_block *block)
 {
@@ -1926,6 +1951,10 @@ bool nir_lower_locals_to_regs(nir_shader *shader);
 
 void nir_lower_outputs_to_temporaries(nir_shader *shader);
 
+void nir_lower_outputs_to_temporaries(nir_shader *shader);
+
+void nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint);
+
 void nir_assign_var_locations(struct exec_list *var_list,
                               unsigned *size,
                               int (*type_size)(const struct glsl_type *));
index 624329d0a8a6fe244e2af18eb190853f48dd351a..205aa067b0b8f3b578ebd556a950aa14c106ab4e 100644 (file)
@@ -58,6 +58,20 @@ nir_builder_cf_insert(nir_builder *build, nir_cf_node *cf)
    nir_cf_node_insert(build->cursor, cf);
 }
 
+static inline nir_ssa_def *
+nir_ssa_undef(nir_builder *build, unsigned num_components)
+{
+   nir_ssa_undef_instr *undef =
+      nir_ssa_undef_instr_create(build->shader, num_components);
+   if (!undef)
+      return NULL;
+
+   nir_instr_insert(nir_before_block(nir_start_block(build->impl)),
+                    &undef->instr);
+
+   return &undef->def;
+}
+
 static inline nir_ssa_def *
 nir_build_imm(nir_builder *build, unsigned num_components, nir_const_value value)
 {
@@ -249,6 +263,23 @@ nir_swizzle(nir_builder *build, nir_ssa_def *src, unsigned swiz[4],
                      nir_imov_alu(build, alu_src, num_components);
 }
 
+/* Selects the right fdot given the number of components in each source. */
+static inline nir_ssa_def *
+nir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1)
+{
+   assert(src0->num_components == src1->num_components);
+   switch (src0->num_components) {
+   case 1: return nir_fmul(build, src0, src1);
+   case 2: return nir_fdot2(build, src0, src1);
+   case 3: return nir_fdot3(build, src0, src1);
+   case 4: return nir_fdot4(build, src0, src1);
+   default:
+      unreachable("bad component size");
+   }
+
+   return NULL;
+}
+
 static inline nir_ssa_def *
 nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c)
 {
diff --git a/src/glsl/nir/nir_gather_info.c b/src/glsl/nir/nir_gather_info.c
new file mode 100644 (file)
index 0000000..c2413e3
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "nir.h"
+
+static void
+gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader)
+{
+   switch (instr->intrinsic) {
+   case nir_intrinsic_discard:
+      assert(shader->stage == MESA_SHADER_FRAGMENT);
+      shader->info.fs.uses_discard = true;
+      break;
+
+   case nir_intrinsic_load_front_face:
+   case nir_intrinsic_load_vertex_id:
+   case nir_intrinsic_load_vertex_id_zero_base:
+   case nir_intrinsic_load_base_vertex:
+   case nir_intrinsic_load_instance_id:
+   case nir_intrinsic_load_sample_id:
+   case nir_intrinsic_load_sample_pos:
+   case nir_intrinsic_load_sample_mask_in:
+   case nir_intrinsic_load_primitive_id:
+   case nir_intrinsic_load_invocation_id:
+   case nir_intrinsic_load_local_invocation_id:
+   case nir_intrinsic_load_work_group_id:
+   case nir_intrinsic_load_num_work_groups:
+      shader->info.system_values_read |=
+         (1 << nir_system_value_from_intrinsic(instr->intrinsic));
+      break;
+
+   case nir_intrinsic_end_primitive:
+      assert(shader->stage == MESA_SHADER_GEOMETRY);
+      shader->info.gs.uses_end_primitive = 1;
+      break;
+
+   default:
+      break;
+   }
+}
+
+static void
+gather_tex_info(nir_tex_instr *instr, nir_shader *shader)
+{
+   if (instr->op == nir_texop_tg4)
+      shader->info.uses_texture_gather = true;
+}
+
+static bool
+gather_info_block(nir_block *block, void *shader)
+{
+   nir_foreach_instr(block, instr) {
+      switch (instr->type) {
+      case nir_instr_type_intrinsic:
+         gather_intrinsic_info(nir_instr_as_intrinsic(instr), shader);
+         break;
+      case nir_instr_type_tex:
+         gather_tex_info(nir_instr_as_tex(instr), shader);
+         break;
+      case nir_instr_type_call:
+         assert(!"nir_shader_gather_info only works if functions are inlined");
+         break;
+      default:
+         break;
+      }
+   }
+
+   return true;
+}
+
+void
+nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint)
+{
+   shader->info.inputs_read = 0;
+   foreach_list_typed(nir_variable, var, node, &shader->inputs)
+      shader->info.inputs_read |= (1ull << var->data.location);
+
+   /* TODO: Some day we may need to add stream support to NIR */
+   shader->info.outputs_written = 0;
+   foreach_list_typed(nir_variable, var, node, &shader->outputs)
+      shader->info.outputs_written |= (1ull << var->data.location);
+
+   shader->info.system_values_read = 0;
+   foreach_list_typed(nir_variable, var, node, &shader->system_values)
+      shader->info.system_values_read |= (1ull << var->data.location);
+
+   nir_foreach_block(entrypoint, gather_info_block, shader);
+}
index b8d7d6c68cb51b9b7097831adb038c0ac5fe86bb..0a134aff211772186c31144a779d111fb7e2b60e 100644 (file)
@@ -175,6 +175,25 @@ INTRINSIC(image_size, 0, ARR(), true, 4, 1, 0,
 INTRINSIC(image_samples, 0, ARR(), true, 1, 1, 0,
           NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 
+/*
+ * Vulkan descriptor set intrinsic
+ *
+ * The Vulkan API uses a different binding model from GL.  In the Vulkan
+ * API, all external resources are represented by a tripple:
+ *
+ * (descriptor set, binding, array index)
+ *
+ * where the array index is the only thing allowed to be indirect.  The
+ * vulkan_surface_index intrinsic takes the descriptor set and binding as
+ * its first two indices and the array index as its source.  The third
+ * index is a nir_variable_mode in case that's useful to the backend.
+ *
+ * The intended usage is that the shader will call vulkan_surface_index to
+ * get an index and then pass that as the buffer index ubo/ssbo calls.
+ */
+INTRINSIC(vulkan_resource_index, 1, ARR(1), true, 1, 0, 3,
+          NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+
 /*
  * SSBO atomic intrinsics
  *
@@ -231,8 +250,9 @@ SYSTEM_VALUE(num_work_groups, 3, 0)
  * the first index is the base address and the second index is an offset that
  * should be added to the base address.  (This way you can determine in the
  * back-end which variable is being accessed even in an array.)  For inputs,
- * the one and only index corresponds to the attribute slot.  UBO loads also
- * have a single index which is the base address to load from.
+ * the one and only index corresponds to the attribute slot.  UBO loads
+ * have two indices the first of which is the descriptor set and the second
+ * is the base address to load from.
  *
  * UBO loads have a (possibly constant) source which is the UBO buffer index.
  * For each type of load, the _indirect variant has one additional source
@@ -251,12 +271,13 @@ SYSTEM_VALUE(num_work_groups, 3, 0)
              true, 0, 0, indices, flags)
 
 LOAD(uniform, 0, 2, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
-LOAD(ubo, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
+LOAD(ubo, 1, 2, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 LOAD(input, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 LOAD(per_vertex_input, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 LOAD(ssbo, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
 LOAD(output, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE)
 LOAD(per_vertex_output, 1, 1, NIR_INTRINSIC_CAN_ELIMINATE)
+LOAD(push_constant, 0, 1, NIR_INTRINSIC_CAN_ELIMINATE | NIR_INTRINSIC_CAN_REORDER)
 
 /*
  * Stores work the same way as loads, except now the first register input is
diff --git a/src/glsl/nir/nir_lower_samplers.cpp b/src/glsl/nir/nir_lower_samplers.cpp
new file mode 100644 (file)
index 0000000..438caac
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
+ * Copyright © 2014 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "nir.h"
+#include "../program.h"
+#include "program/hash_table.h"
+#include "ir_uniform.h"
+
+extern "C" {
+#include "main/compiler.h"
+#include "main/mtypes.h"
+#include "program/prog_parameter.h"
+#include "program/program.h"
+}
+
+static void
+add_indirect_to_tex(nir_tex_instr *instr, nir_src indirect)
+{
+   /* First, we have to resize the array of texture sources */
+   nir_tex_src *new_srcs = rzalloc_array(instr, nir_tex_src,
+                                         instr->num_srcs + 1);
+
+   for (unsigned i = 0; i < instr->num_srcs; i++) {
+      new_srcs[i].src_type = instr->src[i].src_type;
+      nir_instr_move_src(&instr->instr, &new_srcs[i].src, &instr->src[i].src);
+   }
+
+   ralloc_free(instr->src);
+   instr->src = new_srcs;
+
+   /* Now we can go ahead and move the source over to being a
+    * first-class texture source.
+    */
+   instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset;
+   instr->num_srcs++;
+   nir_instr_rewrite_src(&instr->instr, &instr->src[instr->num_srcs - 1].src,
+                         indirect);
+}
+
+static unsigned
+get_sampler_index(const struct gl_shader_program *shader_program,
+                  gl_shader_stage stage, const char *name)
+{
+   unsigned location;
+   if (!shader_program->UniformHash->get(location, name)) {
+      assert(!"failed to find sampler");
+      return 0;
+   }
+
+   if (!shader_program->UniformStorage[location].sampler[stage].active) {
+      assert(!"cannot return a sampler");
+      return 0;
+   }
+
+   return shader_program->UniformStorage[location].sampler[stage].index;
+}
+
+static void
+lower_sampler(nir_tex_instr *instr, const struct gl_shader_program *shader_program,
+              gl_shader_stage stage, void *mem_ctx)
+{
+   if (instr->sampler == NULL)
+      return;
+
+   /* Get the name and the offset */
+   instr->sampler_index = 0;
+   char *name = ralloc_strdup(mem_ctx, instr->sampler->var->name);
+
+   for (nir_deref *deref = &instr->sampler->deref;
+        deref->child; deref = deref->child) {
+      switch (deref->child->deref_type) {
+      case nir_deref_type_array: {
+         nir_deref_array *deref_array = nir_deref_as_array(deref->child);
+
+         assert(deref_array->deref_array_type != nir_deref_array_type_wildcard);
+
+         if (deref_array->deref.child) {
+            ralloc_asprintf_append(&name, "[%u]",
+               deref_array->deref_array_type == nir_deref_array_type_direct ?
+                  deref_array->base_offset : 0);
+         } else {
+            assert(deref->child->type->base_type == GLSL_TYPE_SAMPLER);
+            instr->sampler_index = deref_array->base_offset;
+         }
+
+         /* XXX: We're assuming here that the indirect is the last array
+          * thing we have.  This should be ok for now as we don't support
+          * arrays_of_arrays yet.
+          */
+         if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
+            /* First, we have to resize the array of texture sources */
+            nir_tex_src *new_srcs = rzalloc_array(instr, nir_tex_src,
+                                                  instr->num_srcs + 1);
+
+            for (unsigned i = 0; i < instr->num_srcs; i++) {
+               new_srcs[i].src_type = instr->src[i].src_type;
+               nir_instr_move_src(&instr->instr, &new_srcs[i].src,
+                                  &instr->src[i].src);
+            }
+
+            ralloc_free(instr->src);
+            instr->src = new_srcs;
+
+            /* Now we can go ahead and move the source over to being a
+             * first-class texture source.
+             */
+            instr->src[instr->num_srcs].src_type = nir_tex_src_sampler_offset;
+            instr->num_srcs++;
+            nir_instr_move_src(&instr->instr,
+                               &instr->src[instr->num_srcs - 1].src,
+                               &deref_array->indirect);
+
+            instr->sampler_array_size = glsl_get_length(deref->type);
+         }
+         break;
+      }
+
+      case nir_deref_type_struct: {
+         nir_deref_struct *deref_struct = nir_deref_as_struct(deref->child);
+         const char *field = glsl_get_struct_elem_name(deref->type,
+                                                       deref_struct->index);
+         ralloc_asprintf_append(&name, ".%s", field);
+         break;
+      }
+
+      default:
+         unreachable("Invalid deref type");
+         break;
+      }
+   }
+
+   instr->sampler_index += get_sampler_index(shader_program, stage, name);
+
+   instr->sampler = NULL;
+}
+
+typedef struct {
+   void *mem_ctx;
+   const struct gl_shader_program *shader_program;
+   gl_shader_stage stage;
+} lower_state;
+
+static bool
+lower_block_cb(nir_block *block, void *_state)
+{
+   lower_state *state = (lower_state *) _state;
+
+   nir_foreach_instr(block, instr) {
+      if (instr->type == nir_instr_type_tex) {
+         nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
+         lower_sampler(tex_instr, state->shader_program, state->stage,
+                       state->mem_ctx);
+      }
+   }
+
+   return true;
+}
+
+static void
+lower_impl(nir_function_impl *impl, const struct gl_shader_program *shader_program,
+           gl_shader_stage stage)
+{
+   lower_state state;
+
+   state.mem_ctx = ralloc_parent(impl);
+   state.shader_program = shader_program;
+   state.stage = stage;
+
+   nir_foreach_block(impl, lower_block_cb, &state);
+}
+
+extern "C" void
+nir_lower_samplers(nir_shader *shader,
+                   const struct gl_shader_program *shader_program)
+{
+   nir_foreach_overload(shader, overload) {
+      if (overload->impl)
+         lower_impl(overload->impl, shader_program, shader->stage);
+   }
+}
+
+static bool
+lower_samplers_for_vk_block(nir_block *block, void *data)
+{
+   nir_foreach_instr(block, instr) {
+      if (instr->type != nir_instr_type_tex)
+         continue;
+
+      nir_tex_instr *tex = nir_instr_as_tex(instr);
+
+      assert(tex->sampler);
+
+      tex->sampler_set = tex->sampler->var->data.descriptor_set;
+      tex->sampler_index = tex->sampler->var->data.binding;
+
+      if (tex->sampler->deref.child) {
+         assert(tex->sampler->deref.child->deref_type == nir_deref_type_array);
+         nir_deref_array *arr = nir_deref_as_array(tex->sampler->deref.child);
+
+         /* Only one-level arrays are allowed in vulkan */
+         assert(arr->deref.child == NULL);
+
+         tex->sampler_index += arr->base_offset;
+         if (arr->deref_array_type == nir_deref_array_type_indirect) {
+            add_indirect_to_tex(tex, arr->indirect);
+            nir_instr_rewrite_src(instr, &arr->indirect, NIR_SRC_INIT);
+
+            tex->sampler_array_size = glsl_get_length(tex->sampler->deref.type);
+         }
+      }
+
+      tex->sampler = NULL;
+   }
+
+   return true;
+}
+
+extern "C" void
+nir_lower_samplers_for_vk(nir_shader *shader)
+{
+   nir_foreach_overload(shader, overload) {
+      if (overload->impl) {
+         nir_foreach_block(overload->impl, lower_samplers_for_vk_block, NULL);
+      }
+   }
+}
index 6aa8b1f6caeb1bd6b4e41738f2f3a85f45c556fe..30ede52b146713598b273a3b782a05e953b2eb67 100644 (file)
@@ -70,6 +70,7 @@ optimizations = [
    (('imul', a, 1), a),
    (('fmul', a, -1.0), ('fneg', a)),
    (('imul', a, -1), ('ineg', a)),
+   (('fdiv', a, b), ('fmul', a, ('frcp', b)), 'options->lower_fdiv'),
    (('ffma', 0.0, a, b), b),
    (('ffma', a, 0.0, b), b),
    (('ffma', a, b, 0.0), ('fmul', a, b)),
diff --git a/src/glsl/nir/nir_spirv.h b/src/glsl/nir/nir_spirv.h
new file mode 100644 (file)
index 0000000..1f09174
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Jason Ekstrand (jason@jlekstrand.net)
+ *
+ */
+
+#pragma once
+
+#ifndef _NIR_SPIRV_H_
+#define _NIR_SPIRV_H_
+
+#include "nir.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+nir_shader *spirv_to_nir(const uint32_t *words, size_t word_count,
+                         gl_shader_stage stage,
+                         const nir_shader_compiler_options *options);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NIR_SPIRV_H_ */
index 135591ab97d2d4d17984b1b1ff0a26b81f3063c5..27db5793a602c87c46c96c29466b057c41836771 100644 (file)
@@ -70,6 +70,18 @@ glsl_get_struct_field(const glsl_type *type, unsigned index)
    return type->fields.structure[index].type;
 }
 
+const glsl_type *
+glsl_get_function_return_type(const glsl_type *type)
+{
+   return type->fields.parameters[0].type;
+}
+
+const glsl_function_param *
+glsl_get_function_param(const glsl_type *type, unsigned index)
+{
+   return &type->fields.parameters[index + 1];
+}
+
 const struct glsl_type *
 glsl_get_column_type(const struct glsl_type *type)
 {
@@ -118,6 +130,20 @@ glsl_get_struct_elem_name(const struct glsl_type *type, unsigned index)
    return type->fields.structure[index].name;
 }
 
+glsl_sampler_dim
+glsl_get_sampler_dim(const struct glsl_type *type)
+{
+   assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
+   return (glsl_sampler_dim)type->sampler_dimensionality;
+}
+
+glsl_base_type
+glsl_get_sampler_result_type(const struct glsl_type *type)
+{
+   assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
+   return (glsl_base_type)type->sampler_type;
+}
+
 unsigned
 glsl_get_record_location_offset(const struct glsl_type *type,
                                 unsigned length)
@@ -155,6 +181,44 @@ glsl_type_is_matrix(const struct glsl_type *type)
    return type->is_matrix();
 }
 
+bool
+glsl_type_is_array(const struct glsl_type *type)
+{
+   return type->is_array();
+}
+
+bool
+glsl_type_is_struct(const struct glsl_type *type)
+{
+   return type->is_record() || type->is_interface();
+}
+
+bool
+glsl_type_is_sampler(const struct glsl_type *type)
+{
+   return type->is_sampler();
+}
+
+bool
+glsl_type_is_image(const struct glsl_type *type)
+{
+   return type->is_image();
+}
+
+bool
+glsl_sampler_type_is_shadow(const struct glsl_type *type)
+{
+   assert(glsl_type_is_sampler(type));
+   return type->sampler_shadow;
+}
+
+bool
+glsl_sampler_type_is_array(const struct glsl_type *type)
+{
+   assert(glsl_type_is_sampler(type) || glsl_type_is_image(type));
+   return type->sampler_array;
+}
+
 const glsl_type *
 glsl_void_type(void)
 {
@@ -168,9 +232,9 @@ glsl_float_type(void)
 }
 
 const glsl_type *
-glsl_vec4_type(void)
+glsl_int_type(void)
 {
-   return glsl_type::vec4_type;
+   return glsl_type::int_type;
 }
 
 const glsl_type *
@@ -179,8 +243,75 @@ glsl_uint_type(void)
    return glsl_type::uint_type;
 }
 
+const glsl_type *
+glsl_bool_type(void)
+{
+   return glsl_type::bool_type;
+}
+
+const glsl_type *
+glsl_vec4_type(void)
+{
+   return glsl_type::vec4_type;
+}
+
+const glsl_type *
+glsl_scalar_type(enum glsl_base_type base_type)
+{
+   return glsl_type::get_instance(base_type, 1, 1);
+}
+
+const glsl_type *
+glsl_vector_type(enum glsl_base_type base_type, unsigned components)
+{
+   assert(components > 1 && components <= 4);
+   return glsl_type::get_instance(base_type, components, 1);
+}
+
+const glsl_type *
+glsl_matrix_type(enum glsl_base_type base_type, unsigned rows, unsigned columns)
+{
+   assert(rows > 1 && rows <= 4 && columns >= 1 && columns <= 4);
+   return glsl_type::get_instance(base_type, rows, columns);
+}
+
 const glsl_type *
 glsl_array_type(const glsl_type *base, unsigned elements)
 {
    return glsl_type::get_array_instance(base, elements);
 }
+
+const glsl_type *
+glsl_struct_type(const glsl_struct_field *fields,
+                 unsigned num_fields, const char *name)
+{
+   return glsl_type::get_record_instance(fields, num_fields, name);
+}
+
+const struct glsl_type *
+glsl_sampler_type(enum glsl_sampler_dim dim, bool is_shadow, bool is_array,
+                  enum glsl_base_type base_type)
+{
+   return glsl_type::get_sampler_instance(dim, is_shadow, is_array, base_type);
+}
+
+const struct glsl_type *
+glsl_image_type(enum glsl_sampler_dim dim, bool is_array,
+                enum glsl_base_type base_type)
+{
+   return glsl_type::get_image_instance(dim, is_array, base_type);
+}
+
+const glsl_type *
+glsl_function_type(const glsl_type *return_type,
+                   const glsl_function_param *params, unsigned num_params)
+{
+   return glsl_type::get_function_instance(return_type, params, num_params);
+}
+
+const glsl_type *
+glsl_transposed_type(const struct glsl_type *type)
+{
+   return glsl_type::get_instance(type->base_type, type->matrix_columns,
+                                  type->vector_elements);
+}
index b0b51842a43028651fa1c6ebc85f28babe68d5f9..9cc71e899d7fd016767cee1b413af86f4f7aa819 100644 (file)
@@ -49,6 +49,12 @@ const struct glsl_type *glsl_get_array_element(const struct glsl_type *type);
 
 const struct glsl_type *glsl_get_column_type(const struct glsl_type *type);
 
+const struct glsl_type *
+glsl_get_function_return_type(const struct glsl_type *type);
+
+const struct glsl_function_param *
+glsl_get_function_param(const struct glsl_type *type, unsigned index);
+
 enum glsl_base_type glsl_get_base_type(const struct glsl_type *type);
 
 unsigned glsl_get_vector_elements(const struct glsl_type *type);
@@ -64,6 +70,9 @@ unsigned glsl_get_aoa_size(const struct glsl_type *type);
 const char *glsl_get_struct_elem_name(const struct glsl_type *type,
                                       unsigned index);
 
+enum glsl_sampler_dim glsl_get_sampler_dim(const struct glsl_type *type);
+enum glsl_base_type glsl_get_sampler_result_type(const struct glsl_type *type);
+
 unsigned glsl_get_record_location_offset(const struct glsl_type *type,
                                          unsigned length);
 
@@ -72,13 +81,40 @@ bool glsl_type_is_vector(const struct glsl_type *type);
 bool glsl_type_is_scalar(const struct glsl_type *type);
 bool glsl_type_is_vector_or_scalar(const struct glsl_type *type);
 bool glsl_type_is_matrix(const struct glsl_type *type);
+bool glsl_type_is_array(const struct glsl_type *type);
+bool glsl_type_is_struct(const struct glsl_type *type);
+bool glsl_type_is_sampler(const struct glsl_type *type);
+bool glsl_type_is_image(const struct glsl_type *type);
+bool glsl_sampler_type_is_shadow(const struct glsl_type *type);
+bool glsl_sampler_type_is_array(const struct glsl_type *type);
 
 const struct glsl_type *glsl_void_type(void);
 const struct glsl_type *glsl_float_type(void);
-const struct glsl_type *glsl_vec4_type(void);
+const struct glsl_type *glsl_int_type(void);
 const struct glsl_type *glsl_uint_type(void);
+const struct glsl_type *glsl_bool_type(void);
+
+const struct glsl_type *glsl_vec4_type(void);
+const struct glsl_type *glsl_scalar_type(enum glsl_base_type base_type);
+const struct glsl_type *glsl_vector_type(enum glsl_base_type base_type,
+                                         unsigned components);
+const struct glsl_type *glsl_matrix_type(enum glsl_base_type base_type,
+                                         unsigned rows, unsigned columns);
 const struct glsl_type *glsl_array_type(const struct glsl_type *base,
                                         unsigned elements);
+const struct glsl_type *glsl_struct_type(const struct glsl_struct_field *fields,
+                                         unsigned num_fields, const char *name);
+const struct glsl_type *glsl_sampler_type(enum glsl_sampler_dim dim,
+                                          bool is_shadow, bool is_array,
+                                          enum glsl_base_type base_type);
+const struct glsl_type *glsl_image_type(enum glsl_sampler_dim dim,
+                                        bool is_array,
+                                        enum glsl_base_type base_type);
+const struct glsl_type * glsl_function_type(const struct glsl_type *return_type,
+                                            const struct glsl_function_param *params,
+                                            unsigned num_params);
+
+const struct glsl_type *glsl_transposed_type(const struct glsl_type *type);
 
 #ifdef __cplusplus
 }
diff --git a/src/glsl/nir/spirv.h b/src/glsl/nir/spirv.h
new file mode 100644 (file)
index 0000000..e9e5397
--- /dev/null
@@ -0,0 +1,867 @@
+/*
+** Copyright (c) 2014-2015 The Khronos Group Inc.
+** 
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and/or associated documentation files (the "Materials"),
+** to deal in the Materials without restriction, including without limitation
+** the rights to use, copy, modify, merge, publish, distribute, sublicense,
+** and/or sell copies of the Materials, and to permit persons to whom the
+** Materials are 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 Materials.
+** 
+** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
+** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
+** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ 
+** 
+** THE MATERIALS ARE 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 MATERIALS OR THE USE OR OTHER DEALINGS
+** IN THE MATERIALS.
+*/
+
+/*
+** This header is automatically generated by the same tool that creates
+** the Binary Section of the SPIR-V specification.
+*/
+
+/*
+** Specification revision 33.
+** Enumeration tokens for SPIR-V, in various styles:
+**   C, C++, C++11, JSON, Lua, Python
+** 
+** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL
+** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL
+** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL
+** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL
+** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL']
+** 
+** Some tokens act like mask values, which can be OR'd together,
+** while others are mutually exclusive.  The mask-like ones have
+** "Mask" in their name, and a parallel enum that has the shift
+** amount (1 << x) for each corresponding enumerant.
+*/
+
+#ifndef spirv_H
+#define spirv_H
+
+typedef unsigned int SpvId;
+
+static const unsigned int SpvMagicNumber = 0x07230203;
+static const unsigned int SpvVersion = 99;
+static const unsigned int SpvRevision = 33;
+static const unsigned int SpvOpCodeMask = 0xffff;
+static const unsigned int SpvWordCountShift = 16;
+
+typedef enum SpvSourceLanguage_ {
+    SpvSourceLanguageUnknown = 0,
+    SpvSourceLanguageESSL = 1,
+    SpvSourceLanguageGLSL = 2,
+    SpvSourceLanguageOpenCL = 3,
+} SpvSourceLanguage;
+
+typedef enum SpvExecutionModel_ {
+    SpvExecutionModelVertex = 0,
+    SpvExecutionModelTessellationControl = 1,
+    SpvExecutionModelTessellationEvaluation = 2,
+    SpvExecutionModelGeometry = 3,
+    SpvExecutionModelFragment = 4,
+    SpvExecutionModelGLCompute = 5,
+    SpvExecutionModelKernel = 6,
+} SpvExecutionModel;
+
+typedef enum SpvAddressingModel_ {
+    SpvAddressingModelLogical = 0,
+    SpvAddressingModelPhysical32 = 1,
+    SpvAddressingModelPhysical64 = 2,
+} SpvAddressingModel;
+
+typedef enum SpvMemoryModel_ {
+    SpvMemoryModelSimple = 0,
+    SpvMemoryModelGLSL450 = 1,
+    SpvMemoryModelOpenCL = 2,
+} SpvMemoryModel;
+
+typedef enum SpvExecutionMode_ {
+    SpvExecutionModeInvocations = 0,
+    SpvExecutionModeSpacingEqual = 1,
+    SpvExecutionModeSpacingFractionalEven = 2,
+    SpvExecutionModeSpacingFractionalOdd = 3,
+    SpvExecutionModeVertexOrderCw = 4,
+    SpvExecutionModeVertexOrderCcw = 5,
+    SpvExecutionModePixelCenterInteger = 6,
+    SpvExecutionModeOriginUpperLeft = 7,
+    SpvExecutionModeOriginLowerLeft = 8,
+    SpvExecutionModeEarlyFragmentTests = 9,
+    SpvExecutionModePointMode = 10,
+    SpvExecutionModeXfb = 11,
+    SpvExecutionModeDepthReplacing = 12,
+    SpvExecutionModeDepthGreater = 14,
+    SpvExecutionModeDepthLess = 15,
+    SpvExecutionModeDepthUnchanged = 16,
+    SpvExecutionModeLocalSize = 17,
+    SpvExecutionModeLocalSizeHint = 18,
+    SpvExecutionModeInputPoints = 19,
+    SpvExecutionModeInputLines = 20,
+    SpvExecutionModeInputLinesAdjacency = 21,
+    SpvExecutionModeInputTriangles = 22,
+    SpvExecutionModeInputTrianglesAdjacency = 23,
+    SpvExecutionModeInputQuads = 24,
+    SpvExecutionModeInputIsolines = 25,
+    SpvExecutionModeOutputVertices = 26,
+    SpvExecutionModeOutputPoints = 27,
+    SpvExecutionModeOutputLineStrip = 28,
+    SpvExecutionModeOutputTriangleStrip = 29,
+    SpvExecutionModeVecTypeHint = 30,
+    SpvExecutionModeContractionOff = 31,
+    SpvExecutionModeIndependentForwardProgress = 32,
+} SpvExecutionMode;
+
+typedef enum SpvStorageClass_ {
+    SpvStorageClassUniformConstant = 0,
+    SpvStorageClassInput = 1,
+    SpvStorageClassUniform = 2,
+    SpvStorageClassOutput = 3,
+    SpvStorageClassWorkgroupLocal = 4,
+    SpvStorageClassWorkgroupGlobal = 5,
+    SpvStorageClassPrivateGlobal = 6,
+    SpvStorageClassFunction = 7,
+    SpvStorageClassGeneric = 8,
+    SpvStorageClassPushConstant = 9,
+    SpvStorageClassAtomicCounter = 10,
+    SpvStorageClassImage = 11,
+} SpvStorageClass;
+
+typedef enum SpvDim_ {
+    SpvDim1D = 0,
+    SpvDim2D = 1,
+    SpvDim3D = 2,
+    SpvDimCube = 3,
+    SpvDimRect = 4,
+    SpvDimBuffer = 5,
+    SpvDimInputTarget = 6,
+} SpvDim;
+
+typedef enum SpvSamplerAddressingMode_ {
+    SpvSamplerAddressingModeNone = 0,
+    SpvSamplerAddressingModeClampToEdge = 1,
+    SpvSamplerAddressingModeClamp = 2,
+    SpvSamplerAddressingModeRepeat = 3,
+    SpvSamplerAddressingModeRepeatMirrored = 4,
+} SpvSamplerAddressingMode;
+
+typedef enum SpvSamplerFilterMode_ {
+    SpvSamplerFilterModeNearest = 0,
+    SpvSamplerFilterModeLinear = 1,
+} SpvSamplerFilterMode;
+
+typedef enum SpvImageFormat_ {
+    SpvImageFormatUnknown = 0,
+    SpvImageFormatRgba32f = 1,
+    SpvImageFormatRgba16f = 2,
+    SpvImageFormatR32f = 3,
+    SpvImageFormatRgba8 = 4,
+    SpvImageFormatRgba8Snorm = 5,
+    SpvImageFormatRg32f = 6,
+    SpvImageFormatRg16f = 7,
+    SpvImageFormatR11fG11fB10f = 8,
+    SpvImageFormatR16f = 9,
+    SpvImageFormatRgba16 = 10,
+    SpvImageFormatRgb10A2 = 11,
+    SpvImageFormatRg16 = 12,
+    SpvImageFormatRg8 = 13,
+    SpvImageFormatR16 = 14,
+    SpvImageFormatR8 = 15,
+    SpvImageFormatRgba16Snorm = 16,
+    SpvImageFormatRg16Snorm = 17,
+    SpvImageFormatRg8Snorm = 18,
+    SpvImageFormatR16Snorm = 19,
+    SpvImageFormatR8Snorm = 20,
+    SpvImageFormatRgba32i = 21,
+    SpvImageFormatRgba16i = 22,
+    SpvImageFormatRgba8i = 23,
+    SpvImageFormatR32i = 24,
+    SpvImageFormatRg32i = 25,
+    SpvImageFormatRg16i = 26,
+    SpvImageFormatRg8i = 27,
+    SpvImageFormatR16i = 28,
+    SpvImageFormatR8i = 29,
+    SpvImageFormatRgba32ui = 30,
+    SpvImageFormatRgba16ui = 31,
+    SpvImageFormatRgba8ui = 32,
+    SpvImageFormatR32ui = 33,
+    SpvImageFormatRgb10a2ui = 34,
+    SpvImageFormatRg32ui = 35,
+    SpvImageFormatRg16ui = 36,
+    SpvImageFormatRg8ui = 37,
+    SpvImageFormatR16ui = 38,
+    SpvImageFormatR8ui = 39,
+} SpvImageFormat;
+
+typedef enum SpvImageChannelOrder_ {
+    SpvImageChannelOrderR = 0,
+    SpvImageChannelOrderA = 1,
+    SpvImageChannelOrderRG = 2,
+    SpvImageChannelOrderRA = 3,
+    SpvImageChannelOrderRGB = 4,
+    SpvImageChannelOrderRGBA = 5,
+    SpvImageChannelOrderBGRA = 6,
+    SpvImageChannelOrderARGB = 7,
+    SpvImageChannelOrderIntensity = 8,
+    SpvImageChannelOrderLuminance = 9,
+    SpvImageChannelOrderRx = 10,
+    SpvImageChannelOrderRGx = 11,
+    SpvImageChannelOrderRGBx = 12,
+    SpvImageChannelOrderDepth = 13,
+    SpvImageChannelOrderDepthStencil = 14,
+    SpvImageChannelOrdersRGB = 15,
+    SpvImageChannelOrdersRGBx = 16,
+    SpvImageChannelOrdersRGBA = 17,
+    SpvImageChannelOrdersBGRA = 18,
+} SpvImageChannelOrder;
+
+typedef enum SpvImageChannelDataType_ {
+    SpvImageChannelDataTypeSnormInt8 = 0,
+    SpvImageChannelDataTypeSnormInt16 = 1,
+    SpvImageChannelDataTypeUnormInt8 = 2,
+    SpvImageChannelDataTypeUnormInt16 = 3,
+    SpvImageChannelDataTypeUnormShort565 = 4,
+    SpvImageChannelDataTypeUnormShort555 = 5,
+    SpvImageChannelDataTypeUnormInt101010 = 6,
+    SpvImageChannelDataTypeSignedInt8 = 7,
+    SpvImageChannelDataTypeSignedInt16 = 8,
+    SpvImageChannelDataTypeSignedInt32 = 9,
+    SpvImageChannelDataTypeUnsignedInt8 = 10,
+    SpvImageChannelDataTypeUnsignedInt16 = 11,
+    SpvImageChannelDataTypeUnsignedInt32 = 12,
+    SpvImageChannelDataTypeHalfFloat = 13,
+    SpvImageChannelDataTypeFloat = 14,
+    SpvImageChannelDataTypeUnormInt24 = 15,
+} SpvImageChannelDataType;
+
+typedef enum SpvImageOperandsShift_ {
+    SpvImageOperandsBiasShift = 0,
+    SpvImageOperandsLodShift = 1,
+    SpvImageOperandsGradShift = 2,
+    SpvImageOperandsConstOffsetShift = 3,
+    SpvImageOperandsOffsetShift = 4,
+    SpvImageOperandsConstOffsetsShift = 5,
+    SpvImageOperandsSampleShift = 6,
+    SpvImageOperandsMinLodShift = 7,
+} SpvImageOperandsShift;
+
+typedef enum SpvImageOperandsMask_ {
+    SpvImageOperandsMaskNone = 0,
+    SpvImageOperandsBiasMask = 0x00000001,
+    SpvImageOperandsLodMask = 0x00000002,
+    SpvImageOperandsGradMask = 0x00000004,
+    SpvImageOperandsConstOffsetMask = 0x00000008,
+    SpvImageOperandsOffsetMask = 0x00000010,
+    SpvImageOperandsConstOffsetsMask = 0x00000020,
+    SpvImageOperandsSampleMask = 0x00000040,
+    SpvImageOperandsMinLodMask = 0x00000080,
+} SpvImageOperandsMask;
+
+typedef enum SpvFPFastMathModeShift_ {
+    SpvFPFastMathModeNotNaNShift = 0,
+    SpvFPFastMathModeNotInfShift = 1,
+    SpvFPFastMathModeNSZShift = 2,
+    SpvFPFastMathModeAllowRecipShift = 3,
+    SpvFPFastMathModeFastShift = 4,
+} SpvFPFastMathModeShift;
+
+typedef enum SpvFPFastMathModeMask_ {
+    SpvFPFastMathModeMaskNone = 0,
+    SpvFPFastMathModeNotNaNMask = 0x00000001,
+    SpvFPFastMathModeNotInfMask = 0x00000002,
+    SpvFPFastMathModeNSZMask = 0x00000004,
+    SpvFPFastMathModeAllowRecipMask = 0x00000008,
+    SpvFPFastMathModeFastMask = 0x00000010,
+} SpvFPFastMathModeMask;
+
+typedef enum SpvFPRoundingMode_ {
+    SpvFPRoundingModeRTE = 0,
+    SpvFPRoundingModeRTZ = 1,
+    SpvFPRoundingModeRTP = 2,
+    SpvFPRoundingModeRTN = 3,
+} SpvFPRoundingMode;
+
+typedef enum SpvLinkageType_ {
+    SpvLinkageTypeExport = 0,
+    SpvLinkageTypeImport = 1,
+} SpvLinkageType;
+
+typedef enum SpvAccessQualifier_ {
+    SpvAccessQualifierReadOnly = 0,
+    SpvAccessQualifierWriteOnly = 1,
+    SpvAccessQualifierReadWrite = 2,
+} SpvAccessQualifier;
+
+typedef enum SpvFunctionParameterAttribute_ {
+    SpvFunctionParameterAttributeZext = 0,
+    SpvFunctionParameterAttributeSext = 1,
+    SpvFunctionParameterAttributeByVal = 2,
+    SpvFunctionParameterAttributeSret = 3,
+    SpvFunctionParameterAttributeNoAlias = 4,
+    SpvFunctionParameterAttributeNoCapture = 5,
+    SpvFunctionParameterAttributeNoWrite = 6,
+    SpvFunctionParameterAttributeNoReadWrite = 7,
+} SpvFunctionParameterAttribute;
+
+typedef enum SpvDecoration_ {
+    SpvDecorationRelaxedPrecision = 0,
+    SpvDecorationSpecId = 1,
+    SpvDecorationBlock = 2,
+    SpvDecorationBufferBlock = 3,
+    SpvDecorationRowMajor = 4,
+    SpvDecorationColMajor = 5,
+    SpvDecorationArrayStride = 6,
+    SpvDecorationMatrixStride = 7,
+    SpvDecorationGLSLShared = 8,
+    SpvDecorationGLSLPacked = 9,
+    SpvDecorationCPacked = 10,
+    SpvDecorationBuiltIn = 11,
+    SpvDecorationSmooth = 12,
+    SpvDecorationNoPerspective = 13,
+    SpvDecorationFlat = 14,
+    SpvDecorationPatch = 15,
+    SpvDecorationCentroid = 16,
+    SpvDecorationSample = 17,
+    SpvDecorationInvariant = 18,
+    SpvDecorationRestrict = 19,
+    SpvDecorationAliased = 20,
+    SpvDecorationVolatile = 21,
+    SpvDecorationConstant = 22,
+    SpvDecorationCoherent = 23,
+    SpvDecorationNonWritable = 24,
+    SpvDecorationNonReadable = 25,
+    SpvDecorationUniform = 26,
+    SpvDecorationSaturatedConversion = 28,
+    SpvDecorationStream = 29,
+    SpvDecorationLocation = 30,
+    SpvDecorationComponent = 31,
+    SpvDecorationIndex = 32,
+    SpvDecorationBinding = 33,
+    SpvDecorationDescriptorSet = 34,
+    SpvDecorationOffset = 35,
+    SpvDecorationXfbBuffer = 36,
+    SpvDecorationXfbStride = 37,
+    SpvDecorationFuncParamAttr = 38,
+    SpvDecorationFPRoundingMode = 39,
+    SpvDecorationFPFastMathMode = 40,
+    SpvDecorationLinkageAttributes = 41,
+    SpvDecorationNoContraction = 42,
+    SpvDecorationInputTargetIndex = 43,
+    SpvDecorationAlignment = 44,
+} SpvDecoration;
+
+typedef enum SpvBuiltIn_ {
+    SpvBuiltInPosition = 0,
+    SpvBuiltInPointSize = 1,
+    SpvBuiltInClipDistance = 3,
+    SpvBuiltInCullDistance = 4,
+    SpvBuiltInVertexId = 5,
+    SpvBuiltInInstanceId = 6,
+    SpvBuiltInPrimitiveId = 7,
+    SpvBuiltInInvocationId = 8,
+    SpvBuiltInLayer = 9,
+    SpvBuiltInViewportIndex = 10,
+    SpvBuiltInTessLevelOuter = 11,
+    SpvBuiltInTessLevelInner = 12,
+    SpvBuiltInTessCoord = 13,
+    SpvBuiltInPatchVertices = 14,
+    SpvBuiltInFragCoord = 15,
+    SpvBuiltInPointCoord = 16,
+    SpvBuiltInFrontFacing = 17,
+    SpvBuiltInSampleId = 18,
+    SpvBuiltInSamplePosition = 19,
+    SpvBuiltInSampleMask = 20,
+    SpvBuiltInFragColor = 21,
+    SpvBuiltInFragDepth = 22,
+    SpvBuiltInHelperInvocation = 23,
+    SpvBuiltInNumWorkgroups = 24,
+    SpvBuiltInWorkgroupSize = 25,
+    SpvBuiltInWorkgroupId = 26,
+    SpvBuiltInLocalInvocationId = 27,
+    SpvBuiltInGlobalInvocationId = 28,
+    SpvBuiltInLocalInvocationIndex = 29,
+    SpvBuiltInWorkDim = 30,
+    SpvBuiltInGlobalSize = 31,
+    SpvBuiltInEnqueuedWorkgroupSize = 32,
+    SpvBuiltInGlobalOffset = 33,
+    SpvBuiltInGlobalLinearId = 34,
+    SpvBuiltInWorkgroupLinearId = 35,
+    SpvBuiltInSubgroupSize = 36,
+    SpvBuiltInSubgroupMaxSize = 37,
+    SpvBuiltInNumSubgroups = 38,
+    SpvBuiltInNumEnqueuedSubgroups = 39,
+    SpvBuiltInSubgroupId = 40,
+    SpvBuiltInSubgroupLocalInvocationId = 41,
+    SpvBuiltInVertexIndex = 42,
+    SpvBuiltInInstanceIndex = 43,
+} SpvBuiltIn;
+
+typedef enum SpvSelectionControlShift_ {
+    SpvSelectionControlFlattenShift = 0,
+    SpvSelectionControlDontFlattenShift = 1,
+} SpvSelectionControlShift;
+
+typedef enum SpvSelectionControlMask_ {
+    SpvSelectionControlMaskNone = 0,
+    SpvSelectionControlFlattenMask = 0x00000001,
+    SpvSelectionControlDontFlattenMask = 0x00000002,
+} SpvSelectionControlMask;
+
+typedef enum SpvLoopControlShift_ {
+    SpvLoopControlUnrollShift = 0,
+    SpvLoopControlDontUnrollShift = 1,
+} SpvLoopControlShift;
+
+typedef enum SpvLoopControlMask_ {
+    SpvLoopControlMaskNone = 0,
+    SpvLoopControlUnrollMask = 0x00000001,
+    SpvLoopControlDontUnrollMask = 0x00000002,
+} SpvLoopControlMask;
+
+typedef enum SpvFunctionControlShift_ {
+    SpvFunctionControlInlineShift = 0,
+    SpvFunctionControlDontInlineShift = 1,
+    SpvFunctionControlPureShift = 2,
+    SpvFunctionControlConstShift = 3,
+} SpvFunctionControlShift;
+
+typedef enum SpvFunctionControlMask_ {
+    SpvFunctionControlMaskNone = 0,
+    SpvFunctionControlInlineMask = 0x00000001,
+    SpvFunctionControlDontInlineMask = 0x00000002,
+    SpvFunctionControlPureMask = 0x00000004,
+    SpvFunctionControlConstMask = 0x00000008,
+} SpvFunctionControlMask;
+
+typedef enum SpvMemorySemanticsShift_ {
+    SpvMemorySemanticsAcquireShift = 1,
+    SpvMemorySemanticsReleaseShift = 2,
+    SpvMemorySemanticsAcquireReleaseShift = 3,
+    SpvMemorySemanticsSequentiallyConsistentShift = 4,
+    SpvMemorySemanticsUniformMemoryShift = 6,
+    SpvMemorySemanticsSubgroupMemoryShift = 7,
+    SpvMemorySemanticsWorkgroupLocalMemoryShift = 8,
+    SpvMemorySemanticsWorkgroupGlobalMemoryShift = 9,
+    SpvMemorySemanticsAtomicCounterMemoryShift = 10,
+    SpvMemorySemanticsImageMemoryShift = 11,
+} SpvMemorySemanticsShift;
+
+typedef enum SpvMemorySemanticsMask_ {
+    SpvMemorySemanticsMaskNone = 0,
+    SpvMemorySemanticsAcquireMask = 0x00000002,
+    SpvMemorySemanticsReleaseMask = 0x00000004,
+    SpvMemorySemanticsAcquireReleaseMask = 0x00000008,
+    SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010,
+    SpvMemorySemanticsUniformMemoryMask = 0x00000040,
+    SpvMemorySemanticsSubgroupMemoryMask = 0x00000080,
+    SpvMemorySemanticsWorkgroupLocalMemoryMask = 0x00000100,
+    SpvMemorySemanticsWorkgroupGlobalMemoryMask = 0x00000200,
+    SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400,
+    SpvMemorySemanticsImageMemoryMask = 0x00000800,
+} SpvMemorySemanticsMask;
+
+typedef enum SpvMemoryAccessShift_ {
+    SpvMemoryAccessVolatileShift = 0,
+    SpvMemoryAccessAlignedShift = 1,
+    SpvMemoryAccessNontemporalShift = 2,
+} SpvMemoryAccessShift;
+
+typedef enum SpvMemoryAccessMask_ {
+    SpvMemoryAccessMaskNone = 0,
+    SpvMemoryAccessVolatileMask = 0x00000001,
+    SpvMemoryAccessAlignedMask = 0x00000002,
+    SpvMemoryAccessNontemporalMask = 0x00000004,
+} SpvMemoryAccessMask;
+
+typedef enum SpvScope_ {
+    SpvScopeCrossDevice = 0,
+    SpvScopeDevice = 1,
+    SpvScopeWorkgroup = 2,
+    SpvScopeSubgroup = 3,
+    SpvScopeInvocation = 4,
+} SpvScope;
+
+typedef enum SpvGroupOperation_ {
+    SpvGroupOperationReduce = 0,
+    SpvGroupOperationInclusiveScan = 1,
+    SpvGroupOperationExclusiveScan = 2,
+} SpvGroupOperation;
+
+typedef enum SpvKernelEnqueueFlags_ {
+    SpvKernelEnqueueFlagsNoWait = 0,
+    SpvKernelEnqueueFlagsWaitKernel = 1,
+    SpvKernelEnqueueFlagsWaitWorkGroup = 2,
+} SpvKernelEnqueueFlags;
+
+typedef enum SpvKernelProfilingInfoShift_ {
+    SpvKernelProfilingInfoCmdExecTimeShift = 0,
+} SpvKernelProfilingInfoShift;
+
+typedef enum SpvKernelProfilingInfoMask_ {
+    SpvKernelProfilingInfoMaskNone = 0,
+    SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001,
+} SpvKernelProfilingInfoMask;
+
+typedef enum SpvCapability_ {
+    SpvCapabilityMatrix = 0,
+    SpvCapabilityShader = 1,
+    SpvCapabilityGeometry = 2,
+    SpvCapabilityTessellation = 3,
+    SpvCapabilityAddresses = 4,
+    SpvCapabilityLinkage = 5,
+    SpvCapabilityKernel = 6,
+    SpvCapabilityVector16 = 7,
+    SpvCapabilityFloat16Buffer = 8,
+    SpvCapabilityFloat16 = 9,
+    SpvCapabilityFloat64 = 10,
+    SpvCapabilityInt64 = 11,
+    SpvCapabilityInt64Atomics = 12,
+    SpvCapabilityImageBasic = 13,
+    SpvCapabilityImageReadWrite = 14,
+    SpvCapabilityImageMipmap = 15,
+    SpvCapabilityImageSRGBWrite = 16,
+    SpvCapabilityPipes = 17,
+    SpvCapabilityGroups = 18,
+    SpvCapabilityDeviceEnqueue = 19,
+    SpvCapabilityLiteralSampler = 20,
+    SpvCapabilityAtomicStorage = 21,
+    SpvCapabilityInt16 = 22,
+    SpvCapabilityTessellationPointSize = 23,
+    SpvCapabilityGeometryPointSize = 24,
+    SpvCapabilityImageGatherExtended = 25,
+    SpvCapabilityStorageImageExtendedFormats = 26,
+    SpvCapabilityStorageImageMultisample = 27,
+    SpvCapabilityUniformBufferArrayDynamicIndexing = 28,
+    SpvCapabilitySampledImageArrayDynamicIndexing = 29,
+    SpvCapabilityStorageBufferArrayDynamicIndexing = 30,
+    SpvCapabilityStorageImageArrayDynamicIndexing = 31,
+    SpvCapabilityClipDistance = 32,
+    SpvCapabilityCullDistance = 33,
+    SpvCapabilityImageCubeArray = 34,
+    SpvCapabilitySampleRateShading = 35,
+    SpvCapabilityImageRect = 36,
+    SpvCapabilitySampledRect = 37,
+    SpvCapabilityGenericPointer = 38,
+    SpvCapabilityInt8 = 39,
+    SpvCapabilityInputTarget = 40,
+    SpvCapabilitySparseResidency = 41,
+    SpvCapabilityMinLod = 42,
+    SpvCapabilitySampled1D = 43,
+    SpvCapabilityImage1D = 44,
+    SpvCapabilitySampledCubeArray = 45,
+    SpvCapabilitySampledBuffer = 46,
+    SpvCapabilityImageBuffer = 47,
+    SpvCapabilityImageMSArray = 48,
+    SpvCapabilityAdvancedFormats = 49,
+    SpvCapabilityImageQuery = 50,
+    SpvCapabilityDerivativeControl = 51,
+    SpvCapabilityInterpolationFunction = 52,
+    SpvCapabilityTransformFeedback = 53,
+} SpvCapability;
+
+typedef enum SpvOp_ {
+    SpvOpNop = 0,
+    SpvOpUndef = 1,
+    SpvOpSourceContinued = 2,
+    SpvOpSource = 3,
+    SpvOpSourceExtension = 4,
+    SpvOpName = 5,
+    SpvOpMemberName = 6,
+    SpvOpString = 7,
+    SpvOpLine = 8,
+    SpvOpExtension = 10,
+    SpvOpExtInstImport = 11,
+    SpvOpExtInst = 12,
+    SpvOpMemoryModel = 14,
+    SpvOpEntryPoint = 15,
+    SpvOpExecutionMode = 16,
+    SpvOpCapability = 17,
+    SpvOpTypeVoid = 19,
+    SpvOpTypeBool = 20,
+    SpvOpTypeInt = 21,
+    SpvOpTypeFloat = 22,
+    SpvOpTypeVector = 23,
+    SpvOpTypeMatrix = 24,
+    SpvOpTypeImage = 25,
+    SpvOpTypeSampler = 26,
+    SpvOpTypeSampledImage = 27,
+    SpvOpTypeArray = 28,
+    SpvOpTypeRuntimeArray = 29,
+    SpvOpTypeStruct = 30,
+    SpvOpTypeOpaque = 31,
+    SpvOpTypePointer = 32,
+    SpvOpTypeFunction = 33,
+    SpvOpTypeEvent = 34,
+    SpvOpTypeDeviceEvent = 35,
+    SpvOpTypeReserveId = 36,
+    SpvOpTypeQueue = 37,
+    SpvOpTypePipe = 38,
+    SpvOpTypeForwardPointer = 39,
+    SpvOpConstantTrue = 41,
+    SpvOpConstantFalse = 42,
+    SpvOpConstant = 43,
+    SpvOpConstantComposite = 44,
+    SpvOpConstantSampler = 45,
+    SpvOpConstantNull = 46,
+    SpvOpSpecConstantTrue = 48,
+    SpvOpSpecConstantFalse = 49,
+    SpvOpSpecConstant = 50,
+    SpvOpSpecConstantComposite = 51,
+    SpvOpSpecConstantOp = 52,
+    SpvOpFunction = 54,
+    SpvOpFunctionParameter = 55,
+    SpvOpFunctionEnd = 56,
+    SpvOpFunctionCall = 57,
+    SpvOpVariable = 59,
+    SpvOpImageTexelPointer = 60,
+    SpvOpLoad = 61,
+    SpvOpStore = 62,
+    SpvOpCopyMemory = 63,
+    SpvOpCopyMemorySized = 64,
+    SpvOpAccessChain = 65,
+    SpvOpInBoundsAccessChain = 66,
+    SpvOpPtrAccessChain = 67,
+    SpvOpArrayLength = 68,
+    SpvOpGenericPtrMemSemantics = 69,
+    SpvOpInBoundsPtrAccessChain = 70,
+    SpvOpDecorate = 71,
+    SpvOpMemberDecorate = 72,
+    SpvOpDecorationGroup = 73,
+    SpvOpGroupDecorate = 74,
+    SpvOpGroupMemberDecorate = 75,
+    SpvOpVectorExtractDynamic = 77,
+    SpvOpVectorInsertDynamic = 78,
+    SpvOpVectorShuffle = 79,
+    SpvOpCompositeConstruct = 80,
+    SpvOpCompositeExtract = 81,
+    SpvOpCompositeInsert = 82,
+    SpvOpCopyObject = 83,
+    SpvOpTranspose = 84,
+    SpvOpSampledImage = 86,
+    SpvOpImageSampleImplicitLod = 87,
+    SpvOpImageSampleExplicitLod = 88,
+    SpvOpImageSampleDrefImplicitLod = 89,
+    SpvOpImageSampleDrefExplicitLod = 90,
+    SpvOpImageSampleProjImplicitLod = 91,
+    SpvOpImageSampleProjExplicitLod = 92,
+    SpvOpImageSampleProjDrefImplicitLod = 93,
+    SpvOpImageSampleProjDrefExplicitLod = 94,
+    SpvOpImageFetch = 95,
+    SpvOpImageGather = 96,
+    SpvOpImageDrefGather = 97,
+    SpvOpImageRead = 98,
+    SpvOpImageWrite = 99,
+    SpvOpImageQueryFormat = 101,
+    SpvOpImageQueryOrder = 102,
+    SpvOpImageQuerySizeLod = 103,
+    SpvOpImageQuerySize = 104,
+    SpvOpImageQueryLod = 105,
+    SpvOpImageQueryLevels = 106,
+    SpvOpImageQuerySamples = 107,
+    SpvOpConvertFToU = 109,
+    SpvOpConvertFToS = 110,
+    SpvOpConvertSToF = 111,
+    SpvOpConvertUToF = 112,
+    SpvOpUConvert = 113,
+    SpvOpSConvert = 114,
+    SpvOpFConvert = 115,
+    SpvOpQuantizeToF16 = 116,
+    SpvOpConvertPtrToU = 117,
+    SpvOpSatConvertSToU = 118,
+    SpvOpSatConvertUToS = 119,
+    SpvOpConvertUToPtr = 120,
+    SpvOpPtrCastToGeneric = 121,
+    SpvOpGenericCastToPtr = 122,
+    SpvOpGenericCastToPtrExplicit = 123,
+    SpvOpBitcast = 124,
+    SpvOpSNegate = 126,
+    SpvOpFNegate = 127,
+    SpvOpIAdd = 128,
+    SpvOpFAdd = 129,
+    SpvOpISub = 130,
+    SpvOpFSub = 131,
+    SpvOpIMul = 132,
+    SpvOpFMul = 133,
+    SpvOpUDiv = 134,
+    SpvOpSDiv = 135,
+    SpvOpFDiv = 136,
+    SpvOpUMod = 137,
+    SpvOpSRem = 138,
+    SpvOpSMod = 139,
+    SpvOpFRem = 140,
+    SpvOpFMod = 141,
+    SpvOpVectorTimesScalar = 142,
+    SpvOpMatrixTimesScalar = 143,
+    SpvOpVectorTimesMatrix = 144,
+    SpvOpMatrixTimesVector = 145,
+    SpvOpMatrixTimesMatrix = 146,
+    SpvOpOuterProduct = 147,
+    SpvOpDot = 148,
+    SpvOpIAddCarry = 149,
+    SpvOpISubBorrow = 150,
+    SpvOpUMulExtended = 151,
+    SpvOpSMulExtended = 152,
+    SpvOpAny = 154,
+    SpvOpAll = 155,
+    SpvOpIsNan = 156,
+    SpvOpIsInf = 157,
+    SpvOpIsFinite = 158,
+    SpvOpIsNormal = 159,
+    SpvOpSignBitSet = 160,
+    SpvOpLessOrGreater = 161,
+    SpvOpOrdered = 162,
+    SpvOpUnordered = 163,
+    SpvOpLogicalEqual = 164,
+    SpvOpLogicalNotEqual = 165,
+    SpvOpLogicalOr = 166,
+    SpvOpLogicalAnd = 167,
+    SpvOpLogicalNot = 168,
+    SpvOpSelect = 169,
+    SpvOpIEqual = 170,
+    SpvOpINotEqual = 171,
+    SpvOpUGreaterThan = 172,
+    SpvOpSGreaterThan = 173,
+    SpvOpUGreaterThanEqual = 174,
+    SpvOpSGreaterThanEqual = 175,
+    SpvOpULessThan = 176,
+    SpvOpSLessThan = 177,
+    SpvOpULessThanEqual = 178,
+    SpvOpSLessThanEqual = 179,
+    SpvOpFOrdEqual = 180,
+    SpvOpFUnordEqual = 181,
+    SpvOpFOrdNotEqual = 182,
+    SpvOpFUnordNotEqual = 183,
+    SpvOpFOrdLessThan = 184,
+    SpvOpFUnordLessThan = 185,
+    SpvOpFOrdGreaterThan = 186,
+    SpvOpFUnordGreaterThan = 187,
+    SpvOpFOrdLessThanEqual = 188,
+    SpvOpFUnordLessThanEqual = 189,
+    SpvOpFOrdGreaterThanEqual = 190,
+    SpvOpFUnordGreaterThanEqual = 191,
+    SpvOpShiftRightLogical = 194,
+    SpvOpShiftRightArithmetic = 195,
+    SpvOpShiftLeftLogical = 196,
+    SpvOpBitwiseOr = 197,
+    SpvOpBitwiseXor = 198,
+    SpvOpBitwiseAnd = 199,
+    SpvOpNot = 200,
+    SpvOpBitFieldInsert = 201,
+    SpvOpBitFieldSExtract = 202,
+    SpvOpBitFieldUExtract = 203,
+    SpvOpBitReverse = 204,
+    SpvOpBitCount = 205,
+    SpvOpDPdx = 207,
+    SpvOpDPdy = 208,
+    SpvOpFwidth = 209,
+    SpvOpDPdxFine = 210,
+    SpvOpDPdyFine = 211,
+    SpvOpFwidthFine = 212,
+    SpvOpDPdxCoarse = 213,
+    SpvOpDPdyCoarse = 214,
+    SpvOpFwidthCoarse = 215,
+    SpvOpEmitVertex = 218,
+    SpvOpEndPrimitive = 219,
+    SpvOpEmitStreamVertex = 220,
+    SpvOpEndStreamPrimitive = 221,
+    SpvOpControlBarrier = 224,
+    SpvOpMemoryBarrier = 225,
+    SpvOpAtomicLoad = 227,
+    SpvOpAtomicStore = 228,
+    SpvOpAtomicExchange = 229,
+    SpvOpAtomicCompareExchange = 230,
+    SpvOpAtomicCompareExchangeWeak = 231,
+    SpvOpAtomicIIncrement = 232,
+    SpvOpAtomicIDecrement = 233,
+    SpvOpAtomicIAdd = 234,
+    SpvOpAtomicISub = 235,
+    SpvOpAtomicSMin = 236,
+    SpvOpAtomicUMin = 237,
+    SpvOpAtomicSMax = 238,
+    SpvOpAtomicUMax = 239,
+    SpvOpAtomicAnd = 240,
+    SpvOpAtomicOr = 241,
+    SpvOpAtomicXor = 242,
+    SpvOpPhi = 245,
+    SpvOpLoopMerge = 246,
+    SpvOpSelectionMerge = 247,
+    SpvOpLabel = 248,
+    SpvOpBranch = 249,
+    SpvOpBranchConditional = 250,
+    SpvOpSwitch = 251,
+    SpvOpKill = 252,
+    SpvOpReturn = 253,
+    SpvOpReturnValue = 254,
+    SpvOpUnreachable = 255,
+    SpvOpLifetimeStart = 256,
+    SpvOpLifetimeStop = 257,
+    SpvOpAsyncGroupCopy = 259,
+    SpvOpWaitGroupEvents = 260,
+    SpvOpGroupAll = 261,
+    SpvOpGroupAny = 262,
+    SpvOpGroupBroadcast = 263,
+    SpvOpGroupIAdd = 264,
+    SpvOpGroupFAdd = 265,
+    SpvOpGroupFMin = 266,
+    SpvOpGroupUMin = 267,
+    SpvOpGroupSMin = 268,
+    SpvOpGroupFMax = 269,
+    SpvOpGroupUMax = 270,
+    SpvOpGroupSMax = 271,
+    SpvOpReadPipe = 274,
+    SpvOpWritePipe = 275,
+    SpvOpReservedReadPipe = 276,
+    SpvOpReservedWritePipe = 277,
+    SpvOpReserveReadPipePackets = 278,
+    SpvOpReserveWritePipePackets = 279,
+    SpvOpCommitReadPipe = 280,
+    SpvOpCommitWritePipe = 281,
+    SpvOpIsValidReserveId = 282,
+    SpvOpGetNumPipePackets = 283,
+    SpvOpGetMaxPipePackets = 284,
+    SpvOpGroupReserveReadPipePackets = 285,
+    SpvOpGroupReserveWritePipePackets = 286,
+    SpvOpGroupCommitReadPipe = 287,
+    SpvOpGroupCommitWritePipe = 288,
+    SpvOpEnqueueMarker = 291,
+    SpvOpEnqueueKernel = 292,
+    SpvOpGetKernelNDrangeSubGroupCount = 293,
+    SpvOpGetKernelNDrangeMaxSubGroupSize = 294,
+    SpvOpGetKernelWorkGroupSize = 295,
+    SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296,
+    SpvOpRetainEvent = 297,
+    SpvOpReleaseEvent = 298,
+    SpvOpCreateUserEvent = 299,
+    SpvOpIsValidEvent = 300,
+    SpvOpSetUserEventStatus = 301,
+    SpvOpCaptureEventProfilingInfo = 302,
+    SpvOpGetDefaultQueue = 303,
+    SpvOpBuildNDRange = 304,
+    SpvOpImageSparseSampleImplicitLod = 305,
+    SpvOpImageSparseSampleExplicitLod = 306,
+    SpvOpImageSparseSampleDrefImplicitLod = 307,
+    SpvOpImageSparseSampleDrefExplicitLod = 308,
+    SpvOpImageSparseSampleProjImplicitLod = 309,
+    SpvOpImageSparseSampleProjExplicitLod = 310,
+    SpvOpImageSparseSampleProjDrefImplicitLod = 311,
+    SpvOpImageSparseSampleProjDrefExplicitLod = 312,
+    SpvOpImageSparseFetch = 313,
+    SpvOpImageSparseGather = 314,
+    SpvOpImageSparseDrefGather = 315,
+    SpvOpImageSparseTexelsResident = 316,
+    SpvOpNoLine = 317,
+    SpvOpAtomicFlagTestAndSet = 318,
+    SpvOpAtomicFlagClear = 319,
+} SpvOp;
+
+#endif  // #ifndef spirv_H
+
diff --git a/src/glsl/nir/spirv2nir.c b/src/glsl/nir/spirv2nir.c
new file mode 100644 (file)
index 0000000..e06e825
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Jason Ekstrand (jason@jlekstrand.net)
+ *
+ */
+
+/*
+ * A simple executable that opens a SPIR-V shader, converts it to NIR, and
+ * dumps out the result.  This should be useful for testing the
+ * spirv_to_nir code.
+ */
+
+#include "nir_spirv.h"
+
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int main(int argc, char **argv)
+{
+   int fd = open(argv[1], O_RDONLY);
+   off_t len = lseek(fd, 0, SEEK_END);
+
+   assert(len % 4 == 0);
+   size_t word_count = len / 4;
+
+   const void *map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
+   assert(map != NULL);
+
+   nir_shader *shader = spirv_to_nir(map, MESA_SHADER_FRAGMENT,
+                                     word_count, NULL);
+   nir_print_shader(shader, stderr);
+}
diff --git a/src/glsl/nir/spirv_glsl450.h b/src/glsl/nir/spirv_glsl450.h
new file mode 100644 (file)
index 0000000..d1c9b5c
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+** Copyright (c) 2014-2015 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a copy
+** of this software and/or associated documentation files (the "Materials"),
+** to deal in the Materials without restriction, including without limitation
+** the rights to use, copy, modify, merge, publish, distribute, sublicense,
+** and/or sell copies of the Materials, and to permit persons to whom the
+** Materials are 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 Materials.
+**
+** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
+** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
+** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ 
+**
+** THE MATERIALS ARE 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 MATERIALS OR THE USE OR OTHER DEALINGS
+** IN THE MATERIALS.
+*/
+
+#ifndef GLSLstd450_H
+#define GLSLstd450_H
+
+const int GLSLstd450Version = 99;
+const int GLSLstd450Revision = 3;
+
+enum GLSLstd450 {
+    GLSLstd450Bad = 0,              // Don't use
+
+    GLSLstd450Round = 1,
+    GLSLstd450RoundEven = 2,
+    GLSLstd450Trunc = 3,
+    GLSLstd450FAbs = 4,
+    GLSLstd450SAbs = 5,
+    GLSLstd450FSign = 6,
+    GLSLstd450SSign = 7,
+    GLSLstd450Floor = 8,
+    GLSLstd450Ceil = 9,
+    GLSLstd450Fract = 10,
+
+    GLSLstd450Radians = 11,
+    GLSLstd450Degrees = 12,
+    GLSLstd450Sin = 13,
+    GLSLstd450Cos = 14,
+    GLSLstd450Tan = 15,
+    GLSLstd450Asin = 16,
+    GLSLstd450Acos = 17,
+    GLSLstd450Atan = 18,
+    GLSLstd450Sinh = 19,
+    GLSLstd450Cosh = 20,
+    GLSLstd450Tanh = 21,
+    GLSLstd450Asinh = 22,
+    GLSLstd450Acosh = 23,
+    GLSLstd450Atanh = 24,
+    GLSLstd450Atan2 = 25,
+
+    GLSLstd450Pow = 26,
+    GLSLstd450Exp = 27,
+    GLSLstd450Log = 28,
+    GLSLstd450Exp2 = 29,
+    GLSLstd450Log2 = 30,
+    GLSLstd450Sqrt = 31,
+    GLSLstd450InverseSqrt = 32,
+
+    GLSLstd450Determinant = 33,
+    GLSLstd450MatrixInverse = 34,
+
+    GLSLstd450Modf = 35,            // second operand needs an OpVariable to write to
+    GLSLstd450ModfStruct = 36,      // no OpVariable operand
+    GLSLstd450FMin = 37,
+    GLSLstd450UMin = 38,
+    GLSLstd450SMin = 39,
+    GLSLstd450FMax = 40,
+    GLSLstd450UMax = 41,
+    GLSLstd450SMax = 42,
+    GLSLstd450FClamp = 43,
+    GLSLstd450UClamp = 44,
+    GLSLstd450SClamp = 45,
+    GLSLstd450FMix = 46,
+    GLSLstd450IMix = 47,
+    GLSLstd450Step = 48,
+    GLSLstd450SmoothStep = 49,
+
+    GLSLstd450Fma = 50,
+    GLSLstd450Frexp = 51,            // second operand needs an OpVariable to write to
+    GLSLstd450FrexpStruct = 52,      // no OpVariable operand
+    GLSLstd450Ldexp = 53,
+
+    GLSLstd450PackSnorm4x8 = 54,
+    GLSLstd450PackUnorm4x8 = 55,
+    GLSLstd450PackSnorm2x16 = 56,
+    GLSLstd450PackUnorm2x16 = 57,
+    GLSLstd450PackHalf2x16 = 58,
+    GLSLstd450PackDouble2x32 = 59,
+    GLSLstd450UnpackSnorm2x16 = 60,
+    GLSLstd450UnpackUnorm2x16 = 61,
+    GLSLstd450UnpackHalf2x16 = 62,
+    GLSLstd450UnpackSnorm4x8 = 63,
+    GLSLstd450UnpackUnorm4x8 = 64,
+    GLSLstd450UnpackDouble2x32 = 65,
+
+    GLSLstd450Length = 66,
+    GLSLstd450Distance = 67,
+    GLSLstd450Cross = 68,
+    GLSLstd450Normalize = 69,
+    GLSLstd450FaceForward = 70,
+    GLSLstd450Reflect = 71,
+    GLSLstd450Refract = 72,
+
+    GLSLstd450FindILsb = 73,
+    GLSLstd450FindSMsb = 74,
+    GLSLstd450FindUMsb = 75,
+
+    GLSLstd450InterpolateAtCentroid = 76,
+    GLSLstd450InterpolateAtSample = 77,
+    GLSLstd450InterpolateAtOffset = 78,
+
+    GLSLstd450Count
+};
+
+#endif  // #ifndef GLSLstd450_H
diff --git a/src/glsl/nir/spirv_glsl450_to_nir.c b/src/glsl/nir/spirv_glsl450_to_nir.c
new file mode 100644 (file)
index 0000000..1056c0f
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Jason Ekstrand (jason@jlekstrand.net)
+ *
+ */
+
+#include "spirv_to_nir_private.h"
+#include "spirv_glsl450.h"
+
+static nir_ssa_def*
+build_length(nir_builder *b, nir_ssa_def *vec)
+{
+   switch (vec->num_components) {
+   case 1: return nir_fsqrt(b, nir_fmul(b, vec, vec));
+   case 2: return nir_fsqrt(b, nir_fdot2(b, vec, vec));
+   case 3: return nir_fsqrt(b, nir_fdot3(b, vec, vec));
+   case 4: return nir_fsqrt(b, nir_fdot4(b, vec, vec));
+   default:
+      unreachable("Invalid number of components");
+   }
+}
+
+static void
+handle_glsl450_alu(struct vtn_builder *b, enum GLSLstd450 entrypoint,
+                   const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+   val->ssa = rzalloc(b, struct vtn_ssa_value);
+   val->ssa->type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
+
+   /* Collect the various SSA sources */
+   unsigned num_inputs = count - 5;
+   nir_ssa_def *src[3];
+   for (unsigned i = 0; i < num_inputs; i++)
+      src[i] = vtn_ssa_value(b, w[i + 5])->def;
+
+   nir_op op;
+   switch (entrypoint) {
+   case GLSLstd450Round:       op = nir_op_fround_even;   break; /* TODO */
+   case GLSLstd450RoundEven:   op = nir_op_fround_even;   break;
+   case GLSLstd450Trunc:       op = nir_op_ftrunc;        break;
+   case GLSLstd450FAbs:        op = nir_op_fabs;          break;
+   case GLSLstd450FSign:       op = nir_op_fsign;         break;
+   case GLSLstd450Floor:       op = nir_op_ffloor;        break;
+   case GLSLstd450Ceil:        op = nir_op_fceil;         break;
+   case GLSLstd450Fract:       op = nir_op_ffract;        break;
+   case GLSLstd450Radians:
+      val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 0.01745329251));
+      return;
+   case GLSLstd450Degrees:
+      val->ssa->def = nir_fmul(&b->nb, src[0], nir_imm_float(&b->nb, 57.2957795131));
+      return;
+   case GLSLstd450Sin:         op = nir_op_fsin;       break;
+   case GLSLstd450Cos:         op = nir_op_fcos;       break;
+   case GLSLstd450Tan:
+      val->ssa->def = nir_fdiv(&b->nb, nir_fsin(&b->nb, src[0]),
+                               nir_fcos(&b->nb, src[0]));
+      return;
+   case GLSLstd450Pow:         op = nir_op_fpow;       break;
+   case GLSLstd450Exp2:        op = nir_op_fexp2;      break;
+   case GLSLstd450Log2:        op = nir_op_flog2;      break;
+   case GLSLstd450Sqrt:        op = nir_op_fsqrt;      break;
+   case GLSLstd450InverseSqrt: op = nir_op_frsq;       break;
+
+   case GLSLstd450Modf:        op = nir_op_fmod;       break;
+   case GLSLstd450FMin:        op = nir_op_fmin;       break;
+   case GLSLstd450FMax:        op = nir_op_fmax;       break;
+   case GLSLstd450FMix:        op = nir_op_flrp;       break;
+   case GLSLstd450Step:
+      val->ssa->def = nir_sge(&b->nb, src[1], src[0]);
+      return;
+
+   case GLSLstd450Fma:         op = nir_op_ffma;       break;
+   case GLSLstd450Ldexp:       op = nir_op_ldexp;      break;
+
+   /* Packing/Unpacking functions */
+   case GLSLstd450PackSnorm4x8:      op = nir_op_pack_snorm_4x8;      break;
+   case GLSLstd450PackUnorm4x8:      op = nir_op_pack_unorm_4x8;      break;
+   case GLSLstd450PackSnorm2x16:     op = nir_op_pack_snorm_2x16;     break;
+   case GLSLstd450PackUnorm2x16:     op = nir_op_pack_unorm_2x16;     break;
+   case GLSLstd450PackHalf2x16:      op = nir_op_pack_half_2x16;      break;
+   case GLSLstd450UnpackSnorm4x8:    op = nir_op_unpack_snorm_4x8;    break;
+   case GLSLstd450UnpackUnorm4x8:    op = nir_op_unpack_unorm_4x8;    break;
+   case GLSLstd450UnpackSnorm2x16:   op = nir_op_unpack_snorm_2x16;   break;
+   case GLSLstd450UnpackUnorm2x16:   op = nir_op_unpack_unorm_2x16;   break;
+   case GLSLstd450UnpackHalf2x16:    op = nir_op_unpack_half_2x16;    break;
+
+   case GLSLstd450Length:
+      val->ssa->def = build_length(&b->nb, src[0]);
+      return;
+   case GLSLstd450Distance:
+      val->ssa->def = build_length(&b->nb, nir_fsub(&b->nb, src[0], src[1]));
+      return;
+   case GLSLstd450Normalize:
+      val->ssa->def = nir_fdiv(&b->nb, src[0], build_length(&b->nb, src[0]));
+      return;
+
+   case GLSLstd450Exp:
+   case GLSLstd450Log:
+   case GLSLstd450FClamp:
+   case GLSLstd450UClamp:
+   case GLSLstd450SClamp:
+   case GLSLstd450Asin:
+   case GLSLstd450Acos:
+   case GLSLstd450Atan:
+   case GLSLstd450Atan2:
+   case GLSLstd450Sinh:
+   case GLSLstd450Cosh:
+   case GLSLstd450Tanh:
+   case GLSLstd450Asinh:
+   case GLSLstd450Acosh:
+   case GLSLstd450Atanh:
+   case GLSLstd450SmoothStep:
+   case GLSLstd450Frexp:
+   case GLSLstd450PackDouble2x32:
+   case GLSLstd450UnpackDouble2x32:
+   case GLSLstd450Cross:
+   case GLSLstd450FaceForward:
+   case GLSLstd450Reflect:
+   case GLSLstd450Refract:
+   case GLSLstd450IMix:
+   default:
+      unreachable("Unhandled opcode");
+   }
+
+   nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
+   nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
+                     glsl_get_vector_elements(val->ssa->type), val->name);
+   instr->dest.write_mask = (1 << instr->dest.dest.ssa.num_components) - 1;
+   val->ssa->def = &instr->dest.dest.ssa;
+
+   for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
+      instr->src[i].src = nir_src_for_ssa(src[i]);
+
+   nir_builder_instr_insert(&b->nb, &instr->instr);
+}
+
+bool
+vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
+                               const uint32_t *words, unsigned count)
+{
+   switch ((enum GLSLstd450)ext_opcode) {
+   case GLSLstd450Determinant:
+   case GLSLstd450MatrixInverse:
+   case GLSLstd450InterpolateAtCentroid:
+   case GLSLstd450InterpolateAtSample:
+   case GLSLstd450InterpolateAtOffset:
+      unreachable("Unhandled opcode");
+
+   default:
+      handle_glsl450_alu(b, (enum GLSLstd450)ext_opcode, words, count);
+   }
+
+   return true;
+}
diff --git a/src/glsl/nir/spirv_to_nir.c b/src/glsl/nir/spirv_to_nir.c
new file mode 100644 (file)
index 0000000..740479f
--- /dev/null
@@ -0,0 +1,3726 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Jason Ekstrand (jason@jlekstrand.net)
+ *
+ */
+
+#include "spirv_to_nir_private.h"
+#include "nir_vla.h"
+#include "nir_control_flow.h"
+
+static struct vtn_ssa_value *
+vtn_const_ssa_value(struct vtn_builder *b, nir_constant *constant,
+                    const struct glsl_type *type)
+{
+   struct hash_entry *entry = _mesa_hash_table_search(b->const_table, constant);
+
+   if (entry)
+      return entry->data;
+
+   struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
+   val->type = type;
+
+   switch (glsl_get_base_type(type)) {
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_BOOL:
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_DOUBLE:
+      if (glsl_type_is_vector_or_scalar(type)) {
+         unsigned num_components = glsl_get_vector_elements(val->type);
+         nir_load_const_instr *load =
+            nir_load_const_instr_create(b->shader, num_components);
+
+         for (unsigned i = 0; i < num_components; i++)
+            load->value.u[i] = constant->value.u[i];
+
+         nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
+         val->def = &load->def;
+      } else {
+         assert(glsl_type_is_matrix(type));
+         unsigned rows = glsl_get_vector_elements(val->type);
+         unsigned columns = glsl_get_matrix_columns(val->type);
+         val->elems = ralloc_array(b, struct vtn_ssa_value *, columns);
+
+         for (unsigned i = 0; i < columns; i++) {
+            struct vtn_ssa_value *col_val = rzalloc(b, struct vtn_ssa_value);
+            col_val->type = glsl_get_column_type(val->type);
+            nir_load_const_instr *load =
+               nir_load_const_instr_create(b->shader, rows);
+
+            for (unsigned j = 0; j < rows; j++)
+               load->value.u[j] = constant->value.u[rows * i + j];
+
+            nir_instr_insert_before_cf_list(&b->impl->body, &load->instr);
+            col_val->def = &load->def;
+
+            val->elems[i] = col_val;
+         }
+      }
+      break;
+
+   case GLSL_TYPE_ARRAY: {
+      unsigned elems = glsl_get_length(val->type);
+      val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+      const struct glsl_type *elem_type = glsl_get_array_element(val->type);
+      for (unsigned i = 0; i < elems; i++)
+         val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
+                                             elem_type);
+      break;
+   }
+
+   case GLSL_TYPE_STRUCT: {
+      unsigned elems = glsl_get_length(val->type);
+      val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+      for (unsigned i = 0; i < elems; i++) {
+         const struct glsl_type *elem_type =
+            glsl_get_struct_field(val->type, i);
+         val->elems[i] = vtn_const_ssa_value(b, constant->elements[i],
+                                             elem_type);
+      }
+      break;
+   }
+
+   default:
+      unreachable("bad constant type");
+   }
+
+   return val;
+}
+
+struct vtn_ssa_value *
+vtn_ssa_value(struct vtn_builder *b, uint32_t value_id)
+{
+   struct vtn_value *val = vtn_untyped_value(b, value_id);
+   switch (val->value_type) {
+   case vtn_value_type_constant:
+      return vtn_const_ssa_value(b, val->constant, val->const_type);
+
+   case vtn_value_type_ssa:
+      return val->ssa;
+   default:
+      unreachable("Invalid type for an SSA value");
+   }
+}
+
+static char *
+vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
+                   unsigned word_count)
+{
+   return ralloc_strndup(b, (char *)words, word_count * sizeof(*words));
+}
+
+static const uint32_t *
+vtn_foreach_instruction(struct vtn_builder *b, const uint32_t *start,
+                        const uint32_t *end, vtn_instruction_handler handler)
+{
+   const uint32_t *w = start;
+   while (w < end) {
+      SpvOp opcode = w[0] & SpvOpCodeMask;
+      unsigned count = w[0] >> SpvWordCountShift;
+      assert(count >= 1 && w + count <= end);
+
+      if (!handler(b, opcode, w, count))
+         return w;
+
+      w += count;
+   }
+   assert(w == end);
+   return w;
+}
+
+static void
+vtn_handle_extension(struct vtn_builder *b, SpvOp opcode,
+                     const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpExtInstImport: {
+      struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_extension);
+      if (strcmp((const char *)&w[2], "GLSL.std.450") == 0) {
+         val->ext_handler = vtn_handle_glsl450_instruction;
+      } else {
+         assert(!"Unsupported extension");
+      }
+      break;
+   }
+
+   case SpvOpExtInst: {
+      struct vtn_value *val = vtn_value(b, w[3], vtn_value_type_extension);
+      bool handled = val->ext_handler(b, w[4], w, count);
+      (void)handled;
+      assert(handled);
+      break;
+   }
+
+   default:
+      unreachable("Unhandled opcode");
+   }
+}
+
+static void
+_foreach_decoration_helper(struct vtn_builder *b,
+                           struct vtn_value *base_value,
+                           int member,
+                           struct vtn_value *value,
+                           vtn_decoration_foreach_cb cb, void *data)
+{
+   int new_member = member;
+
+   for (struct vtn_decoration *dec = value->decoration; dec; dec = dec->next) {
+      if (dec->member >= 0) {
+         assert(member == -1);
+         new_member = dec->member;
+      }
+
+      if (dec->group) {
+         assert(dec->group->value_type == vtn_value_type_decoration_group);
+         _foreach_decoration_helper(b, base_value, new_member, dec->group,
+                                    cb, data);
+      } else {
+         cb(b, base_value, new_member, dec, data);
+      }
+   }
+}
+
+/** Iterates (recursively if needed) over all of the decorations on a value
+ *
+ * This function iterates over all of the decorations applied to a given
+ * value.  If it encounters a decoration group, it recurses into the group
+ * and iterates over all of those decorations as well.
+ */
+void
+vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
+                       vtn_decoration_foreach_cb cb, void *data)
+{
+   _foreach_decoration_helper(b, value, -1, value, cb, data);
+}
+
+static void
+vtn_handle_decoration(struct vtn_builder *b, SpvOp opcode,
+                      const uint32_t *w, unsigned count)
+{
+   const uint32_t *w_end = w + count;
+   const uint32_t target = w[1];
+   w += 2;
+
+   int member = -1;
+   switch (opcode) {
+   case SpvOpDecorationGroup:
+      vtn_push_value(b, target, vtn_value_type_undef);
+      break;
+
+   case SpvOpMemberDecorate:
+      member = *(w++);
+      /* fallthrough */
+   case SpvOpDecorate: {
+      struct vtn_value *val = &b->values[target];
+
+      struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
+      dec->member = member;
+      dec->decoration = *(w++);
+      dec->literals = w;
+
+      /* Link into the list */
+      dec->next = val->decoration;
+      val->decoration = dec;
+      break;
+   }
+
+   case SpvOpGroupMemberDecorate:
+      member = *(w++);
+      /* fallthrough */
+   case SpvOpGroupDecorate: {
+      struct vtn_value *group = &b->values[target];
+      assert(group->value_type == vtn_value_type_decoration_group);
+
+      for (; w < w_end; w++) {
+         struct vtn_value *val = &b->values[*w];
+         struct vtn_decoration *dec = rzalloc(b, struct vtn_decoration);
+         dec->member = member;
+         dec->group = group;
+
+         /* Link into the list */
+         dec->next = val->decoration;
+         val->decoration = dec;
+      }
+      break;
+   }
+
+   default:
+      unreachable("Unhandled opcode");
+   }
+}
+
+struct member_decoration_ctx {
+   struct glsl_struct_field *fields;
+   struct vtn_type *type;
+};
+
+/* does a shallow copy of a vtn_type */
+
+static struct vtn_type *
+vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
+{
+   struct vtn_type *dest = ralloc(b, struct vtn_type);
+   dest->type = src->type;
+   dest->is_builtin = src->is_builtin;
+   if (src->is_builtin)
+      dest->builtin = src->builtin;
+
+   if (!glsl_type_is_vector_or_scalar(src->type)) {
+      switch (glsl_get_base_type(src->type)) {
+      case GLSL_TYPE_ARRAY:
+         dest->array_element = src->array_element;
+         dest->stride = src->stride;
+         break;
+
+      case GLSL_TYPE_INT:
+      case GLSL_TYPE_UINT:
+      case GLSL_TYPE_BOOL:
+      case GLSL_TYPE_FLOAT:
+      case GLSL_TYPE_DOUBLE:
+         /* matrices */
+         dest->row_major = src->row_major;
+         dest->stride = src->stride;
+         break;
+
+      case GLSL_TYPE_STRUCT: {
+         unsigned elems = glsl_get_length(src->type);
+
+         dest->members = ralloc_array(b, struct vtn_type *, elems);
+         memcpy(dest->members, src->members, elems * sizeof(struct vtn_type *));
+
+         dest->offsets = ralloc_array(b, unsigned, elems);
+         memcpy(dest->offsets, src->offsets, elems * sizeof(unsigned));
+         break;
+      }
+
+      default:
+         unreachable("unhandled type");
+      }
+   }
+
+   return dest;
+}
+
+static void
+struct_member_decoration_cb(struct vtn_builder *b,
+                            struct vtn_value *val, int member,
+                            const struct vtn_decoration *dec, void *void_ctx)
+{
+   struct member_decoration_ctx *ctx = void_ctx;
+
+   if (member < 0)
+      return;
+
+   switch (dec->decoration) {
+   case SpvDecorationRelaxedPrecision:
+      break; /* FIXME: Do nothing with this for now. */
+   case SpvDecorationSmooth:
+      ctx->fields[member].interpolation = INTERP_QUALIFIER_SMOOTH;
+      break;
+   case SpvDecorationNoPerspective:
+      ctx->fields[member].interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
+      break;
+   case SpvDecorationFlat:
+      ctx->fields[member].interpolation = INTERP_QUALIFIER_FLAT;
+      break;
+   case SpvDecorationCentroid:
+      ctx->fields[member].centroid = true;
+      break;
+   case SpvDecorationSample:
+      ctx->fields[member].sample = true;
+      break;
+   case SpvDecorationLocation:
+      ctx->fields[member].location = dec->literals[0];
+      break;
+   case SpvDecorationBuiltIn:
+      ctx->type->members[member] = vtn_type_copy(b,
+                                                 ctx->type->members[member]);
+      ctx->type->members[member]->is_builtin = true;
+      ctx->type->members[member]->builtin = dec->literals[0];
+      ctx->type->builtin_block = true;
+      break;
+   case SpvDecorationOffset:
+      ctx->type->offsets[member] = dec->literals[0];
+      break;
+   case SpvDecorationMatrixStride:
+      ctx->type->members[member]->stride = dec->literals[0];
+      break;
+   case SpvDecorationColMajor:
+      break; /* Nothing to do here.  Column-major is the default. */
+   default:
+      unreachable("Unhandled member decoration");
+   }
+}
+
+static void
+type_decoration_cb(struct vtn_builder *b,
+                   struct vtn_value *val, int member,
+                    const struct vtn_decoration *dec, void *ctx)
+{
+   struct vtn_type *type = val->type;
+
+   if (member != -1)
+      return;
+
+   switch (dec->decoration) {
+   case SpvDecorationArrayStride:
+      type->stride = dec->literals[0];
+      break;
+   case SpvDecorationBlock:
+      type->block = true;
+      break;
+   case SpvDecorationBufferBlock:
+      type->buffer_block = true;
+      break;
+   case SpvDecorationGLSLShared:
+   case SpvDecorationGLSLPacked:
+      /* Ignore these, since we get explicit offsets anyways */
+      break;
+
+   case SpvDecorationStream:
+      assert(dec->literals[0] == 0);
+      break;
+
+   default:
+      unreachable("Unhandled type decoration");
+   }
+}
+
+static unsigned
+translate_image_format(SpvImageFormat format)
+{
+   switch (format) {
+   case SpvImageFormatUnknown:      return 0;      /* GL_NONE */
+   case SpvImageFormatRgba32f:      return 0x8814; /* GL_RGBA32F */
+   case SpvImageFormatRgba16f:      return 0x881A; /* GL_RGBA16F */
+   case SpvImageFormatR32f:         return 0x822E; /* GL_R32F */
+   case SpvImageFormatRgba8:        return 0x8058; /* GL_RGBA8 */
+   case SpvImageFormatRgba8Snorm:   return 0x8F97; /* GL_RGBA8_SNORM */
+   case SpvImageFormatRg32f:        return 0x8230; /* GL_RG32F */
+   case SpvImageFormatRg16f:        return 0x822F; /* GL_RG16F */
+   case SpvImageFormatR11fG11fB10f: return 0x8C3A; /* GL_R11F_G11F_B10F */
+   case SpvImageFormatR16f:         return 0x822D; /* GL_R16F */
+   case SpvImageFormatRgba16:       return 0x805B; /* GL_RGBA16 */
+   case SpvImageFormatRgb10A2:      return 0x8059; /* GL_RGB10_A2 */
+   case SpvImageFormatRg16:         return 0x822C; /* GL_RG16 */
+   case SpvImageFormatRg8:          return 0x822B; /* GL_RG8 */
+   case SpvImageFormatR16:          return 0x822A; /* GL_R16 */
+   case SpvImageFormatR8:           return 0x8229; /* GL_R8 */
+   case SpvImageFormatRgba16Snorm:  return 0x8F9B; /* GL_RGBA16_SNORM */
+   case SpvImageFormatRg16Snorm:    return 0x8F99; /* GL_RG16_SNORM */
+   case SpvImageFormatRg8Snorm:     return 0x8F95; /* GL_RG8_SNORM */
+   case SpvImageFormatR16Snorm:     return 0x8F98; /* GL_R16_SNORM */
+   case SpvImageFormatR8Snorm:      return 0x8F94; /* GL_R8_SNORM */
+   case SpvImageFormatRgba32i:      return 0x8D82; /* GL_RGBA32I */
+   case SpvImageFormatRgba16i:      return 0x8D88; /* GL_RGBA16I */
+   case SpvImageFormatRgba8i:       return 0x8D8E; /* GL_RGBA8I */
+   case SpvImageFormatR32i:         return 0x8235; /* GL_R32I */
+   case SpvImageFormatRg32i:        return 0x823B; /* GL_RG32I */
+   case SpvImageFormatRg16i:        return 0x8239; /* GL_RG16I */
+   case SpvImageFormatRg8i:         return 0x8237; /* GL_RG8I */
+   case SpvImageFormatR16i:         return 0x8233; /* GL_R16I */
+   case SpvImageFormatR8i:          return 0x8231; /* GL_R8I */
+   case SpvImageFormatRgba32ui:     return 0x8D70; /* GL_RGBA32UI */
+   case SpvImageFormatRgba16ui:     return 0x8D76; /* GL_RGBA16UI */
+   case SpvImageFormatRgba8ui:      return 0x8D7C; /* GL_RGBA8UI */
+   case SpvImageFormatR32ui:        return 0x8236; /* GL_R32UI */
+   case SpvImageFormatRgb10a2ui:    return 0x906F; /* GL_RGB10_A2UI */
+   case SpvImageFormatRg32ui:       return 0x823C; /* GL_RG32UI */
+   case SpvImageFormatRg16ui:       return 0x823A; /* GL_RG16UI */
+   case SpvImageFormatRg8ui:        return 0x8238; /* GL_RG8UI */
+   case SpvImageFormatR16ui:        return 0x823A; /* GL_RG16UI */
+   case SpvImageFormatR8ui:         return 0x8232; /* GL_R8UI */
+   default:
+      assert(!"Invalid image format");
+      return 0;
+   }
+}
+
+static void
+vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
+                const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_type);
+
+   val->type = rzalloc(b, struct vtn_type);
+   val->type->is_builtin = false;
+
+   switch (opcode) {
+   case SpvOpTypeVoid:
+      val->type->type = glsl_void_type();
+      break;
+   case SpvOpTypeBool:
+      val->type->type = glsl_bool_type();
+      break;
+   case SpvOpTypeInt:
+      val->type->type = glsl_int_type();
+      break;
+   case SpvOpTypeFloat:
+      val->type->type = glsl_float_type();
+      break;
+
+   case SpvOpTypeVector: {
+      const struct glsl_type *base =
+         vtn_value(b, w[2], vtn_value_type_type)->type->type;
+      unsigned elems = w[3];
+
+      assert(glsl_type_is_scalar(base));
+      val->type->type = glsl_vector_type(glsl_get_base_type(base), elems);
+      break;
+   }
+
+   case SpvOpTypeMatrix: {
+      struct vtn_type *base =
+         vtn_value(b, w[2], vtn_value_type_type)->type;
+      unsigned columns = w[3];
+
+      assert(glsl_type_is_vector(base->type));
+      val->type->type = glsl_matrix_type(glsl_get_base_type(base->type),
+                                         glsl_get_vector_elements(base->type),
+                                         columns);
+      val->type->array_element = base;
+      val->type->row_major = false;
+      val->type->stride = 0;
+      break;
+   }
+
+   case SpvOpTypeArray: {
+      struct vtn_type *array_element =
+         vtn_value(b, w[2], vtn_value_type_type)->type;
+      val->type->type = glsl_array_type(array_element->type, w[3]);
+      val->type->array_element = array_element;
+      val->type->stride = 0;
+      break;
+   }
+
+   case SpvOpTypeStruct: {
+      unsigned num_fields = count - 2;
+      val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
+      val->type->offsets = ralloc_array(b, unsigned, num_fields);
+
+      NIR_VLA(struct glsl_struct_field, fields, count);
+      for (unsigned i = 0; i < num_fields; i++) {
+         /* TODO: Handle decorators */
+         val->type->members[i] =
+            vtn_value(b, w[i + 2], vtn_value_type_type)->type;
+         fields[i].type = val->type->members[i]->type;
+         fields[i].name = ralloc_asprintf(b, "field%d", i);
+         fields[i].location = -1;
+         fields[i].interpolation = 0;
+         fields[i].centroid = 0;
+         fields[i].sample = 0;
+         fields[i].matrix_layout = 2;
+      }
+
+      struct member_decoration_ctx ctx = {
+         .fields = fields,
+         .type = val->type
+      };
+
+      vtn_foreach_decoration(b, val, struct_member_decoration_cb, &ctx);
+
+      const char *name = val->name ? val->name : "struct";
+
+      val->type->type = glsl_struct_type(fields, num_fields, name);
+      break;
+   }
+
+   case SpvOpTypeFunction: {
+      const struct glsl_type *return_type =
+         vtn_value(b, w[2], vtn_value_type_type)->type->type;
+      NIR_VLA(struct glsl_function_param, params, count - 3);
+      for (unsigned i = 0; i < count - 3; i++) {
+         params[i].type = vtn_value(b, w[i + 3], vtn_value_type_type)->type->type;
+
+         /* FIXME: */
+         params[i].in = true;
+         params[i].out = true;
+      }
+      val->type->type = glsl_function_type(return_type, params, count - 3);
+      break;
+   }
+
+   case SpvOpTypePointer:
+      /* FIXME:  For now, we'll just do the really lame thing and return
+       * the same type.  The validator should ensure that the proper number
+       * of dereferences happen
+       */
+      val->type = vtn_value(b, w[3], vtn_value_type_type)->type;
+      break;
+
+   case SpvOpTypeImage: {
+      const struct glsl_type *sampled_type =
+         vtn_value(b, w[2], vtn_value_type_type)->type->type;
+
+      assert(glsl_type_is_vector_or_scalar(sampled_type));
+
+      enum glsl_sampler_dim dim;
+      switch ((SpvDim)w[3]) {
+      case SpvDim1D:       dim = GLSL_SAMPLER_DIM_1D;    break;
+      case SpvDim2D:       dim = GLSL_SAMPLER_DIM_2D;    break;
+      case SpvDim3D:       dim = GLSL_SAMPLER_DIM_3D;    break;
+      case SpvDimCube:     dim = GLSL_SAMPLER_DIM_CUBE;  break;
+      case SpvDimRect:     dim = GLSL_SAMPLER_DIM_RECT;  break;
+      case SpvDimBuffer:   dim = GLSL_SAMPLER_DIM_BUF;   break;
+      default:
+         unreachable("Invalid SPIR-V Sampler dimension");
+      }
+
+      bool is_shadow = w[4];
+      bool is_array = w[5];
+      bool multisampled = w[6];
+      unsigned sampled = w[7];
+      SpvImageFormat format = w[8];
+
+      assert(!multisampled && "FIXME: Handl multi-sampled textures");
+
+      val->type->image_format = translate_image_format(format);
+
+      if (sampled == 1) {
+         val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
+                                             glsl_get_base_type(sampled_type));
+      } else if (sampled == 2) {
+         assert(format);
+         assert(!is_shadow);
+         val->type->type = glsl_image_type(dim, is_array,
+                                           glsl_get_base_type(sampled_type));
+      } else {
+         assert(!"We need to know if the image will be sampled");
+      }
+      break;
+   }
+
+   case SpvOpTypeSampledImage:
+      val->type = vtn_value(b, w[2], vtn_value_type_type)->type;
+      break;
+
+   case SpvOpTypeRuntimeArray:
+   case SpvOpTypeOpaque:
+   case SpvOpTypeEvent:
+   case SpvOpTypeDeviceEvent:
+   case SpvOpTypeReserveId:
+   case SpvOpTypeQueue:
+   case SpvOpTypePipe:
+   default:
+      unreachable("Unhandled opcode");
+   }
+
+   vtn_foreach_decoration(b, val, type_decoration_cb, NULL);
+}
+
+static void
+vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
+                    const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_constant);
+   val->const_type = vtn_value(b, w[1], vtn_value_type_type)->type->type;
+   val->constant = ralloc(b, nir_constant);
+   switch (opcode) {
+   case SpvOpConstantTrue:
+      assert(val->const_type == glsl_bool_type());
+      val->constant->value.u[0] = NIR_TRUE;
+      break;
+   case SpvOpConstantFalse:
+      assert(val->const_type == glsl_bool_type());
+      val->constant->value.u[0] = NIR_FALSE;
+      break;
+   case SpvOpConstant:
+      assert(glsl_type_is_scalar(val->const_type));
+      val->constant->value.u[0] = w[3];
+      break;
+   case SpvOpConstantComposite: {
+      unsigned elem_count = count - 3;
+      nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
+      for (unsigned i = 0; i < elem_count; i++)
+         elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
+
+      switch (glsl_get_base_type(val->const_type)) {
+      case GLSL_TYPE_UINT:
+      case GLSL_TYPE_INT:
+      case GLSL_TYPE_FLOAT:
+      case GLSL_TYPE_BOOL:
+         if (glsl_type_is_matrix(val->const_type)) {
+            unsigned rows = glsl_get_vector_elements(val->const_type);
+            assert(glsl_get_matrix_columns(val->const_type) == elem_count);
+            for (unsigned i = 0; i < elem_count; i++)
+               for (unsigned j = 0; j < rows; j++)
+                  val->constant->value.u[rows * i + j] = elems[i]->value.u[j];
+         } else {
+            assert(glsl_type_is_vector(val->const_type));
+            assert(glsl_get_vector_elements(val->const_type) == elem_count);
+            for (unsigned i = 0; i < elem_count; i++)
+               val->constant->value.u[i] = elems[i]->value.u[0];
+         }
+         ralloc_free(elems);
+         break;
+
+      case GLSL_TYPE_STRUCT:
+      case GLSL_TYPE_ARRAY:
+         ralloc_steal(val->constant, elems);
+         val->constant->elements = elems;
+         break;
+
+      default:
+         unreachable("Unsupported type for constants");
+      }
+      break;
+   }
+
+   default:
+      unreachable("Unhandled opcode");
+   }
+}
+
+static void
+set_mode_system_value(nir_variable_mode *mode)
+{
+   assert(*mode == nir_var_system_value || *mode == nir_var_shader_in);
+   *mode = nir_var_system_value;
+}
+
+static void
+validate_per_vertex_mode(struct vtn_builder *b, nir_variable_mode mode)
+{
+   switch (b->shader->stage) {
+   case MESA_SHADER_VERTEX:
+      assert(mode == nir_var_shader_out);
+      break;
+   case MESA_SHADER_GEOMETRY:
+      assert(mode == nir_var_shader_out || mode == nir_var_shader_in);
+      break;
+   default:
+      assert(!"Invalid shader stage");
+   }
+}
+
+static void
+vtn_get_builtin_location(struct vtn_builder *b,
+                         SpvBuiltIn builtin, int *location,
+                         nir_variable_mode *mode)
+{
+   switch (builtin) {
+   case SpvBuiltInPosition:
+      *location = VARYING_SLOT_POS;
+      validate_per_vertex_mode(b, *mode);
+      break;
+   case SpvBuiltInPointSize:
+      *location = VARYING_SLOT_PSIZ;
+      validate_per_vertex_mode(b, *mode);
+      break;
+   case SpvBuiltInClipDistance:
+      *location = VARYING_SLOT_CLIP_DIST0; /* XXX CLIP_DIST1? */
+      validate_per_vertex_mode(b, *mode);
+      break;
+   case SpvBuiltInCullDistance:
+      /* XXX figure this out */
+      unreachable("unhandled builtin");
+   case SpvBuiltInVertexId:
+      /* Vulkan defines VertexID to be zero-based and reserves the new
+       * builtin keyword VertexIndex to indicate the non-zero-based value.
+       */
+      *location = SYSTEM_VALUE_VERTEX_ID_ZERO_BASE;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInInstanceId:
+      *location = SYSTEM_VALUE_INSTANCE_ID;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInPrimitiveId:
+      *location = VARYING_SLOT_PRIMITIVE_ID;
+      *mode = nir_var_shader_out;
+      break;
+   case SpvBuiltInInvocationId:
+      *location = SYSTEM_VALUE_INVOCATION_ID;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInLayer:
+      *location = VARYING_SLOT_LAYER;
+      *mode = nir_var_shader_out;
+      break;
+   case SpvBuiltInTessLevelOuter:
+   case SpvBuiltInTessLevelInner:
+   case SpvBuiltInTessCoord:
+   case SpvBuiltInPatchVertices:
+      unreachable("no tessellation support");
+   case SpvBuiltInFragCoord:
+      *location = VARYING_SLOT_POS;
+      assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+      assert(*mode == nir_var_shader_in);
+      break;
+   case SpvBuiltInPointCoord:
+      *location = VARYING_SLOT_PNTC;
+      assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+      assert(*mode == nir_var_shader_in);
+      break;
+   case SpvBuiltInFrontFacing:
+      *location = VARYING_SLOT_FACE;
+      assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+      assert(*mode == nir_var_shader_in);
+      break;
+   case SpvBuiltInSampleId:
+      *location = SYSTEM_VALUE_SAMPLE_ID;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInSamplePosition:
+      *location = SYSTEM_VALUE_SAMPLE_POS;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInSampleMask:
+      *location = SYSTEM_VALUE_SAMPLE_MASK_IN; /* XXX out? */
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInFragColor:
+      *location = FRAG_RESULT_COLOR;
+      assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+      assert(*mode == nir_var_shader_out);
+      break;
+   case SpvBuiltInFragDepth:
+      *location = FRAG_RESULT_DEPTH;
+      assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+      assert(*mode == nir_var_shader_out);
+      break;
+   case SpvBuiltInNumWorkgroups:
+   case SpvBuiltInWorkgroupSize:
+      /* these are constants, need to be handled specially */
+      unreachable("unsupported builtin");
+      break;
+   case SpvBuiltInGlobalInvocationId:
+   case SpvBuiltInLocalInvocationIndex:
+      /* these are computed values, need to be handled specially */
+      unreachable("unsupported builtin");
+   case SpvBuiltInWorkgroupId:
+      *location = SYSTEM_VALUE_WORK_GROUP_ID;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInLocalInvocationId:
+      *location = SYSTEM_VALUE_LOCAL_INVOCATION_ID;
+      set_mode_system_value(mode);
+      break;
+   case SpvBuiltInHelperInvocation:
+   default:
+      unreachable("unsupported builtin");
+   }
+}
+
+static void
+var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member,
+                  const struct vtn_decoration *dec, void *void_var)
+{
+   assert(val->value_type == vtn_value_type_deref);
+   assert(val->deref->deref.child == NULL);
+   assert(val->deref->var == void_var);
+
+   nir_variable *var = void_var;
+   switch (dec->decoration) {
+   case SpvDecorationRelaxedPrecision:
+      break; /* FIXME: Do nothing with this for now. */
+   case SpvDecorationSmooth:
+      var->data.interpolation = INTERP_QUALIFIER_SMOOTH;
+      break;
+   case SpvDecorationNoPerspective:
+      var->data.interpolation = INTERP_QUALIFIER_NOPERSPECTIVE;
+      break;
+   case SpvDecorationFlat:
+      var->data.interpolation = INTERP_QUALIFIER_FLAT;
+      break;
+   case SpvDecorationCentroid:
+      var->data.centroid = true;
+      break;
+   case SpvDecorationSample:
+      var->data.sample = true;
+      break;
+   case SpvDecorationInvariant:
+      var->data.invariant = true;
+      break;
+   case SpvDecorationConstant:
+      assert(var->constant_initializer != NULL);
+      var->data.read_only = true;
+      break;
+   case SpvDecorationNonWritable:
+      var->data.read_only = true;
+      break;
+   case SpvDecorationLocation:
+      var->data.location = dec->literals[0];
+      break;
+   case SpvDecorationComponent:
+      var->data.location_frac = dec->literals[0];
+      break;
+   case SpvDecorationIndex:
+      var->data.explicit_index = true;
+      var->data.index = dec->literals[0];
+      break;
+   case SpvDecorationBinding:
+      var->data.explicit_binding = true;
+      var->data.binding = dec->literals[0];
+      break;
+   case SpvDecorationDescriptorSet:
+      var->data.descriptor_set = dec->literals[0];
+      break;
+   case SpvDecorationBuiltIn: {
+      SpvBuiltIn builtin = dec->literals[0];
+
+      nir_variable_mode mode = var->data.mode;
+      vtn_get_builtin_location(b, builtin, &var->data.location, &mode);
+      var->data.explicit_location = true;
+      var->data.mode = mode;
+      if (mode == nir_var_shader_in || mode == nir_var_system_value)
+         var->data.read_only = true;
+
+      if (builtin == SpvBuiltInFragCoord || builtin == SpvBuiltInSamplePosition)
+         var->data.origin_upper_left = b->origin_upper_left;
+
+      if (mode == nir_var_shader_out)
+         b->builtins[dec->literals[0]].out = var;
+      else
+         b->builtins[dec->literals[0]].in = var;
+      break;
+   }
+   case SpvDecorationRowMajor:
+   case SpvDecorationColMajor:
+   case SpvDecorationGLSLShared:
+   case SpvDecorationPatch:
+   case SpvDecorationRestrict:
+   case SpvDecorationAliased:
+   case SpvDecorationVolatile:
+   case SpvDecorationCoherent:
+   case SpvDecorationNonReadable:
+   case SpvDecorationUniform:
+      /* This is really nice but we have no use for it right now. */
+   case SpvDecorationCPacked:
+   case SpvDecorationSaturatedConversion:
+   case SpvDecorationStream:
+   case SpvDecorationOffset:
+   case SpvDecorationXfbBuffer:
+   case SpvDecorationFuncParamAttr:
+   case SpvDecorationFPRoundingMode:
+   case SpvDecorationFPFastMathMode:
+   case SpvDecorationLinkageAttributes:
+   case SpvDecorationSpecId:
+      break;
+   default:
+      unreachable("Unhandled variable decoration");
+   }
+}
+
+static nir_variable *
+get_builtin_variable(struct vtn_builder *b,
+                     nir_variable_mode mode,
+                     const struct glsl_type *type,
+                     SpvBuiltIn builtin)
+{
+   nir_variable *var;
+   if (mode == nir_var_shader_out)
+      var = b->builtins[builtin].out;
+   else
+      var = b->builtins[builtin].in;
+
+   if (!var) {
+      int location;
+      vtn_get_builtin_location(b, builtin, &location, &mode);
+
+      var = nir_variable_create(b->shader, mode, type, "builtin");
+
+      var->data.location = location;
+      var->data.explicit_location = true;
+
+      if (builtin == SpvBuiltInFragCoord || builtin == SpvBuiltInSamplePosition)
+         var->data.origin_upper_left = b->origin_upper_left;
+
+      if (mode == nir_var_shader_out)
+         b->builtins[builtin].out = var;
+      else
+         b->builtins[builtin].in = var;
+   }
+
+   return var;
+}
+
+static struct vtn_ssa_value *
+_vtn_variable_load(struct vtn_builder *b,
+                   nir_deref_var *src_deref, nir_deref *src_deref_tail)
+{
+   struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
+   val->type = src_deref_tail->type;
+
+   /* The deref tail may contain a deref to select a component of a vector (in
+    * other words, it might not be an actual tail) so we have to save it away
+    * here since we overwrite it later.
+    */
+   nir_deref *old_child = src_deref_tail->child;
+
+   if (glsl_type_is_vector_or_scalar(val->type)) {
+      /* Terminate the deref chain in case there is one more link to pick
+       * off a component of the vector.
+       */
+      src_deref_tail->child = NULL;
+
+      nir_intrinsic_instr *load =
+         nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_var);
+      load->variables[0] =
+         nir_deref_as_var(nir_copy_deref(load, &src_deref->deref));
+      load->num_components = glsl_get_vector_elements(val->type);
+      nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, NULL);
+
+      nir_builder_instr_insert(&b->nb, &load->instr);
+
+      if (src_deref->var->data.mode == nir_var_uniform &&
+          glsl_get_base_type(val->type) == GLSL_TYPE_BOOL) {
+         /* Uniform boolean loads need to be fixed up since they're defined
+          * to be zero/nonzero rather than NIR_FALSE/NIR_TRUE.
+          */
+         val->def = nir_ine(&b->nb, &load->dest.ssa, nir_imm_int(&b->nb, 0));
+      } else {
+         val->def = &load->dest.ssa;
+      }
+   } else if (glsl_get_base_type(val->type) == GLSL_TYPE_ARRAY ||
+              glsl_type_is_matrix(val->type)) {
+      unsigned elems = glsl_get_length(val->type);
+      val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+
+      nir_deref_array *deref = nir_deref_array_create(b);
+      deref->deref_array_type = nir_deref_array_type_direct;
+      deref->deref.type = glsl_get_array_element(val->type);
+      src_deref_tail->child = &deref->deref;
+      for (unsigned i = 0; i < elems; i++) {
+         deref->base_offset = i;
+         val->elems[i] = _vtn_variable_load(b, src_deref, &deref->deref);
+      }
+   } else {
+      assert(glsl_get_base_type(val->type) == GLSL_TYPE_STRUCT);
+      unsigned elems = glsl_get_length(val->type);
+      val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+
+      nir_deref_struct *deref = nir_deref_struct_create(b, 0);
+      src_deref_tail->child = &deref->deref;
+      for (unsigned i = 0; i < elems; i++) {
+         deref->index = i;
+         deref->deref.type = glsl_get_struct_field(val->type, i);
+         val->elems[i] = _vtn_variable_load(b, src_deref, &deref->deref);
+      }
+   }
+
+   src_deref_tail->child = old_child;
+
+   return val;
+}
+
+static void
+_vtn_variable_store(struct vtn_builder *b,
+                    nir_deref_var *dest_deref, nir_deref *dest_deref_tail,
+                    struct vtn_ssa_value *src)
+{
+   nir_deref *old_child = dest_deref_tail->child;
+
+   if (glsl_type_is_vector_or_scalar(src->type)) {
+      /* Terminate the deref chain in case there is one more link to pick
+       * off a component of the vector.
+       */
+      dest_deref_tail->child = NULL;
+
+      nir_intrinsic_instr *store =
+         nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_var);
+      store->variables[0] =
+         nir_deref_as_var(nir_copy_deref(store, &dest_deref->deref));
+      store->num_components = glsl_get_vector_elements(src->type);
+      store->src[0] = nir_src_for_ssa(src->def);
+
+      nir_builder_instr_insert(&b->nb, &store->instr);
+   } else if (glsl_get_base_type(src->type) == GLSL_TYPE_ARRAY ||
+              glsl_type_is_matrix(src->type)) {
+      unsigned elems = glsl_get_length(src->type);
+
+      nir_deref_array *deref = nir_deref_array_create(b);
+      deref->deref_array_type = nir_deref_array_type_direct;
+      deref->deref.type = glsl_get_array_element(src->type);
+      dest_deref_tail->child = &deref->deref;
+      for (unsigned i = 0; i < elems; i++) {
+         deref->base_offset = i;
+         _vtn_variable_store(b, dest_deref, &deref->deref, src->elems[i]);
+      }
+   } else {
+      assert(glsl_get_base_type(src->type) == GLSL_TYPE_STRUCT);
+      unsigned elems = glsl_get_length(src->type);
+
+      nir_deref_struct *deref = nir_deref_struct_create(b, 0);
+      dest_deref_tail->child = &deref->deref;
+      for (unsigned i = 0; i < elems; i++) {
+         deref->index = i;
+         deref->deref.type = glsl_get_struct_field(src->type, i);
+         _vtn_variable_store(b, dest_deref, &deref->deref, src->elems[i]);
+      }
+   }
+
+   dest_deref_tail->child = old_child;
+}
+
+static nir_ssa_def *
+nir_vulkan_resource_index(nir_builder *b, unsigned set, unsigned binding,
+                          nir_variable_mode mode, nir_ssa_def *array_index)
+{
+   if (array_index == NULL)
+      array_index = nir_imm_int(b, 0);
+
+   nir_intrinsic_instr *instr =
+      nir_intrinsic_instr_create(b->shader,
+                                 nir_intrinsic_vulkan_resource_index);
+   instr->src[0] = nir_src_for_ssa(array_index);
+   instr->const_index[0] = set;
+   instr->const_index[1] = binding;
+   instr->const_index[2] = mode;
+
+   nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL);
+   nir_builder_instr_insert(b, &instr->instr);
+
+   return &instr->dest.ssa;
+}
+
+static struct vtn_ssa_value *
+_vtn_block_load(struct vtn_builder *b, nir_intrinsic_op op,
+                unsigned set, unsigned binding, nir_variable_mode mode,
+                nir_ssa_def *index, unsigned offset, nir_ssa_def *indirect,
+                struct vtn_type *type)
+{
+   struct vtn_ssa_value *val = ralloc(b, struct vtn_ssa_value);
+   val->type = type->type;
+   val->transposed = NULL;
+   if (glsl_type_is_vector_or_scalar(type->type)) {
+      nir_intrinsic_instr *load = nir_intrinsic_instr_create(b->shader, op);
+      load->num_components = glsl_get_vector_elements(type->type);
+      load->const_index[0] = offset;
+
+      switch (op) {
+      case nir_intrinsic_load_ubo_indirect:
+      case nir_intrinsic_load_ssbo_indirect:
+         load->src[1] = nir_src_for_ssa(indirect);
+         /* fall through */
+      case nir_intrinsic_load_ubo:
+      case nir_intrinsic_load_ssbo: {
+         nir_ssa_def *res_index = nir_vulkan_resource_index(&b->nb,
+                                                            set, binding,
+                                                            mode, index);
+         load->src[0] = nir_src_for_ssa(res_index);
+         break;
+      }
+
+      case nir_intrinsic_load_push_constant:
+         break; /* Nothing to do */
+      case nir_intrinsic_load_push_constant_indirect:
+         load->src[0] = nir_src_for_ssa(indirect);
+         break;
+
+      default:
+         unreachable("Invalid block load intrinsic");
+      }
+
+      nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, NULL);
+      nir_builder_instr_insert(&b->nb, &load->instr);
+      val->def = &load->dest.ssa;
+   } else {
+      unsigned elems = glsl_get_length(type->type);
+      val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+      if (glsl_type_is_struct(type->type)) {
+         for (unsigned i = 0; i < elems; i++) {
+            val->elems[i] = _vtn_block_load(b, op, set, binding, mode, index,
+                                            offset + type->offsets[i],
+                                            indirect, type->members[i]);
+         }
+      } else {
+         for (unsigned i = 0; i < elems; i++) {
+            val->elems[i] = _vtn_block_load(b, op, set, binding, mode, index,
+                                            offset + i * type->stride,
+                                            indirect, type->array_element);
+         }
+      }
+   }
+
+   return val;
+}
+
+static void
+vtn_block_get_offset(struct vtn_builder *b, nir_deref_var *src,
+                     struct vtn_type **type, nir_deref *src_tail,
+                     nir_ssa_def **index,
+                     unsigned *offset, nir_ssa_def **indirect)
+{
+   nir_deref *deref = &src->deref;
+
+   if (deref->child->deref_type == nir_deref_type_array) {
+      deref = deref->child;
+      *type = (*type)->array_element;
+      nir_deref_array *deref_array = nir_deref_as_array(deref);
+      *index = nir_imm_int(&b->nb, deref_array->base_offset);
+
+      if (deref_array->deref_array_type == nir_deref_array_type_indirect)
+         *index = nir_iadd(&b->nb, *index, deref_array->indirect.ssa);
+   } else {
+      *index = nir_imm_int(&b->nb, 0);
+   }
+
+   *offset = 0;
+   *indirect = NULL;
+   while (deref != src_tail) {
+      deref = deref->child;
+      switch (deref->deref_type) {
+      case nir_deref_type_array: {
+         nir_deref_array *deref_array = nir_deref_as_array(deref);
+         if (deref_array->deref_array_type == nir_deref_array_type_direct) {
+            *offset += (*type)->stride * deref_array->base_offset;
+         } else {
+            nir_ssa_def *off = nir_imul(&b->nb, deref_array->indirect.ssa,
+                                        nir_imm_int(&b->nb, (*type)->stride));
+            *indirect = *indirect ? nir_iadd(&b->nb, *indirect, off) : off;
+         }
+         *type = (*type)->array_element;
+         break;
+      }
+
+      case nir_deref_type_struct: {
+         nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
+         *offset += (*type)->offsets[deref_struct->index];
+         *type = (*type)->members[deref_struct->index];
+         break;
+      }
+
+      default:
+         unreachable("unknown deref type");
+      }
+   }
+}
+
+static struct vtn_ssa_value *
+vtn_block_load(struct vtn_builder *b, nir_deref_var *src,
+               struct vtn_type *type, nir_deref *src_tail)
+{
+   nir_ssa_def *index;
+   unsigned offset;
+   nir_ssa_def *indirect;
+   vtn_block_get_offset(b, src, &type, src_tail, &index, &offset, &indirect);
+
+   nir_intrinsic_op op;
+   if (src->var->data.mode == nir_var_uniform) {
+      if (src->var->data.descriptor_set >= 0) {
+         /* UBO load */
+         assert(src->var->data.binding >= 0);
+
+         op = indirect ? nir_intrinsic_load_ubo_indirect
+                       : nir_intrinsic_load_ubo;
+      } else {
+         /* Push constant load */
+         assert(src->var->data.descriptor_set == -1 &&
+                src->var->data.binding == -1);
+
+         op = indirect ? nir_intrinsic_load_push_constant_indirect
+                       : nir_intrinsic_load_push_constant;
+      }
+   } else {
+      assert(src->var->data.mode == nir_var_shader_storage);
+      op = indirect ? nir_intrinsic_load_ssbo_indirect
+                    : nir_intrinsic_load_ssbo;
+   }
+
+   return _vtn_block_load(b, op, src->var->data.descriptor_set,
+                          src->var->data.binding, src->var->data.mode,
+                          index, offset, indirect, type);
+}
+
+/*
+ * Gets the NIR-level deref tail, which may have as a child an array deref
+ * selecting which component due to OpAccessChain supporting per-component
+ * indexing in SPIR-V.
+ */
+
+static nir_deref *
+get_deref_tail(nir_deref_var *deref)
+{
+   nir_deref *cur = &deref->deref;
+   while (!glsl_type_is_vector_or_scalar(cur->type) && cur->child)
+      cur = cur->child;
+
+   return cur;
+}
+
+static nir_ssa_def *vtn_vector_extract(struct vtn_builder *b,
+                                       nir_ssa_def *src, unsigned index);
+
+static nir_ssa_def *vtn_vector_extract_dynamic(struct vtn_builder *b,
+                                               nir_ssa_def *src,
+                                               nir_ssa_def *index);
+
+static bool
+variable_is_external_block(nir_variable *var)
+{
+   return var->interface_type &&
+          glsl_type_is_struct(var->interface_type) &&
+          (var->data.mode == nir_var_uniform ||
+           var->data.mode == nir_var_shader_storage);
+}
+
+static struct vtn_ssa_value *
+vtn_variable_load(struct vtn_builder *b, nir_deref_var *src,
+                  struct vtn_type *src_type)
+{
+   nir_deref *src_tail = get_deref_tail(src);
+
+   struct vtn_ssa_value *val;
+   if (variable_is_external_block(src->var))
+      val = vtn_block_load(b, src, src_type, src_tail);
+   else
+      val = _vtn_variable_load(b, src, src_tail);
+
+   if (src_tail->child) {
+      nir_deref_array *vec_deref = nir_deref_as_array(src_tail->child);
+      assert(vec_deref->deref.child == NULL);
+      val->type = vec_deref->deref.type;
+      if (vec_deref->deref_array_type == nir_deref_array_type_direct)
+         val->def = vtn_vector_extract(b, val->def, vec_deref->base_offset);
+      else
+         val->def = vtn_vector_extract_dynamic(b, val->def,
+                                               vec_deref->indirect.ssa);
+   }
+
+   return val;
+}
+
+static void
+_vtn_block_store(struct vtn_builder *b, nir_intrinsic_op op,
+                 struct vtn_ssa_value *src, unsigned set, unsigned binding,
+                 nir_variable_mode mode, nir_ssa_def *index, unsigned offset,
+                 nir_ssa_def *indirect, struct vtn_type *type)
+{
+   assert(src->type == type->type);
+   if (glsl_type_is_vector_or_scalar(type->type)) {
+      nir_intrinsic_instr *store = nir_intrinsic_instr_create(b->shader, op);
+      store->num_components = glsl_get_vector_elements(type->type);
+      store->const_index[0] = offset;
+      store->const_index[1] = (1 << store->num_components) - 1;
+      store->src[0] = nir_src_for_ssa(src->def);
+
+      nir_ssa_def *res_index = nir_vulkan_resource_index(&b->nb,
+                                                         set, binding,
+                                                         mode, index);
+      store->src[1] = nir_src_for_ssa(res_index);
+
+      if (op == nir_intrinsic_store_ssbo_indirect)
+         store->src[2] = nir_src_for_ssa(indirect);
+
+      nir_builder_instr_insert(&b->nb, &store->instr);
+   } else {
+      unsigned elems = glsl_get_length(type->type);
+      if (glsl_type_is_struct(type->type)) {
+         for (unsigned i = 0; i < elems; i++) {
+            _vtn_block_store(b, op, src->elems[i], set, binding, mode,
+                             index, offset + type->offsets[i], indirect,
+                             type->members[i]);
+         }
+      } else {
+         for (unsigned i = 0; i < elems; i++) {
+            _vtn_block_store(b, op, src->elems[i], set, binding, mode,
+                             index, offset + i * type->stride, indirect,
+                             type->array_element);
+         }
+      }
+   }
+}
+
+static void
+vtn_block_store(struct vtn_builder *b, struct vtn_ssa_value *src,
+                nir_deref_var *dest, struct vtn_type *type,
+                nir_deref *dest_tail)
+{
+   nir_ssa_def *index;
+   unsigned offset;
+   nir_ssa_def *indirect;
+   vtn_block_get_offset(b, dest, &type, dest_tail, &index, &offset, &indirect);
+
+   nir_intrinsic_op op = indirect ? nir_intrinsic_store_ssbo_indirect
+                                  : nir_intrinsic_store_ssbo;
+
+   return _vtn_block_store(b, op, src, dest->var->data.descriptor_set,
+                           dest->var->data.binding, dest->var->data.mode,
+                           index, offset, indirect, type);
+}
+
+static nir_ssa_def * vtn_vector_insert(struct vtn_builder *b,
+                                       nir_ssa_def *src, nir_ssa_def *insert,
+                                       unsigned index);
+
+static nir_ssa_def * vtn_vector_insert_dynamic(struct vtn_builder *b,
+                                               nir_ssa_def *src,
+                                               nir_ssa_def *insert,
+                                               nir_ssa_def *index);
+static void
+vtn_variable_store(struct vtn_builder *b, struct vtn_ssa_value *src,
+                   nir_deref_var *dest, struct vtn_type *dest_type)
+{
+   nir_deref *dest_tail = get_deref_tail(dest);
+   if (variable_is_external_block(dest->var)) {
+      assert(dest->var->data.mode == nir_var_shader_storage);
+      vtn_block_store(b, src, dest, dest_type, dest_tail);
+   } else {
+      if (dest_tail->child) {
+         struct vtn_ssa_value *val = _vtn_variable_load(b, dest, dest_tail);
+         nir_deref_array *deref = nir_deref_as_array(dest_tail->child);
+         assert(deref->deref.child == NULL);
+         if (deref->deref_array_type == nir_deref_array_type_direct)
+            val->def = vtn_vector_insert(b, val->def, src->def,
+                                         deref->base_offset);
+         else
+            val->def = vtn_vector_insert_dynamic(b, val->def, src->def,
+                                                 deref->indirect.ssa);
+         _vtn_variable_store(b, dest, dest_tail, val);
+      } else {
+         _vtn_variable_store(b, dest, dest_tail, src);
+      }
+   }
+}
+
+static void
+vtn_variable_copy(struct vtn_builder *b, nir_deref_var *src,
+                  nir_deref_var *dest, struct vtn_type *type)
+{
+   nir_deref *src_tail = get_deref_tail(src);
+
+   if (src_tail->child || src->var->interface_type) {
+      assert(get_deref_tail(dest)->child);
+      struct vtn_ssa_value *val = vtn_variable_load(b, src, type);
+      vtn_variable_store(b, val, dest, type);
+   } else {
+      nir_intrinsic_instr *copy =
+         nir_intrinsic_instr_create(b->shader, nir_intrinsic_copy_var);
+      copy->variables[0] = nir_deref_as_var(nir_copy_deref(copy, &dest->deref));
+      copy->variables[1] = nir_deref_as_var(nir_copy_deref(copy, &src->deref));
+
+      nir_builder_instr_insert(&b->nb, &copy->instr);
+   }
+}
+
+/* Tries to compute the size of an interface block based on the strides and
+ * offsets that are provided to us in the SPIR-V source.
+ */
+static unsigned
+vtn_type_block_size(struct vtn_type *type)
+{
+   enum glsl_base_type base_type = glsl_get_base_type(type->type);
+   switch (base_type) {
+   case GLSL_TYPE_UINT:
+   case GLSL_TYPE_INT:
+   case GLSL_TYPE_FLOAT:
+   case GLSL_TYPE_BOOL:
+   case GLSL_TYPE_DOUBLE: {
+      unsigned cols = type->row_major ? glsl_get_vector_elements(type->type) :
+                                        glsl_get_matrix_columns(type->type);
+      if (cols > 1) {
+         assert(type->stride > 0);
+         return type->stride * cols;
+      } else if (base_type == GLSL_TYPE_DOUBLE) {
+         return glsl_get_vector_elements(type->type) * 8;
+      } else {
+         return glsl_get_vector_elements(type->type) * 4;
+      }
+   }
+
+   case GLSL_TYPE_STRUCT:
+   case GLSL_TYPE_INTERFACE: {
+      unsigned size = 0;
+      unsigned num_fields = glsl_get_length(type->type);
+      for (unsigned f = 0; f < num_fields; f++) {
+         unsigned field_end = type->offsets[f] +
+                              vtn_type_block_size(type->members[f]);
+         size = MAX2(size, field_end);
+      }
+      return size;
+   }
+
+   case GLSL_TYPE_ARRAY:
+      assert(type->stride > 0);
+      assert(glsl_get_length(type->type) > 0);
+      return type->stride * glsl_get_length(type->type);
+
+   default:
+      assert(!"Invalid block type");
+      return 0;
+   }
+}
+
+static bool
+is_interface_type(struct vtn_type *type)
+{
+   return type->block || type->buffer_block ||
+          glsl_type_is_sampler(type->type) ||
+          glsl_type_is_image(type->type);
+}
+
+static void
+vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
+                     const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpVariable: {
+      struct vtn_type *type =
+         vtn_value(b, w[1], vtn_value_type_type)->type;
+      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
+
+      nir_variable *var = rzalloc(b->shader, nir_variable);
+
+      var->type = type->type;
+      var->name = ralloc_strdup(var, val->name);
+
+      struct vtn_type *interface_type;
+      if (is_interface_type(type)) {
+         interface_type = type;
+      } else if (glsl_type_is_array(type->type) &&
+                 is_interface_type(type->array_element)) {
+         interface_type = type->array_element;
+      } else {
+         interface_type = NULL;
+      }
+
+      if (interface_type)
+         var->interface_type = interface_type->type;
+
+      switch ((SpvStorageClass)w[3]) {
+      case SpvStorageClassUniform:
+      case SpvStorageClassUniformConstant:
+         if (interface_type && interface_type->buffer_block) {
+            var->data.mode = nir_var_shader_storage;
+            b->shader->info.num_ssbos++;
+         } else {
+            /* UBO's and samplers */
+            var->data.mode = nir_var_uniform;
+            var->data.read_only = true;
+            if (interface_type) {
+               if (glsl_type_is_image(interface_type->type)) {
+                  b->shader->info.num_images++;
+                  var->data.image.format = interface_type->image_format;
+               } else if (glsl_type_is_sampler(interface_type->type)) {
+                  b->shader->info.num_textures++;
+               } else {
+                  assert(glsl_type_is_struct(interface_type->type));
+                  b->shader->info.num_ubos++;
+               }
+            }
+         }
+         break;
+      case SpvStorageClassPushConstant:
+         assert(interface_type && interface_type->block);
+         var->data.mode = nir_var_uniform;
+         var->data.read_only = true;
+         var->data.descriptor_set = -1;
+         var->data.binding = -1;
+
+         /* We have exactly one push constant block */
+         assert(b->shader->num_uniforms == 0);
+         b->shader->num_uniforms = vtn_type_block_size(type);
+         break;
+      case SpvStorageClassInput:
+         var->data.mode = nir_var_shader_in;
+         var->data.read_only = true;
+         break;
+      case SpvStorageClassOutput:
+         var->data.mode = nir_var_shader_out;
+         break;
+      case SpvStorageClassPrivateGlobal:
+         var->data.mode = nir_var_global;
+         break;
+      case SpvStorageClassFunction:
+         var->data.mode = nir_var_local;
+         break;
+      case SpvStorageClassWorkgroupLocal:
+      case SpvStorageClassWorkgroupGlobal:
+      case SpvStorageClassGeneric:
+      case SpvStorageClassAtomicCounter:
+      default:
+         unreachable("Unhandled variable storage class");
+      }
+
+      if (count > 4) {
+         assert(count == 5);
+         var->constant_initializer =
+            vtn_value(b, w[4], vtn_value_type_constant)->constant;
+      }
+
+      val->deref = nir_deref_var_create(b, var);
+      val->deref_type = type;
+
+      /* We handle decorations first because decorations might give us
+       * location information.  We use the data.explicit_location field to
+       * note that the location provided is the "final" location.  If
+       * data.explicit_location == false, this means that it's relative to
+       * whatever the base location is.
+       */
+      vtn_foreach_decoration(b, val, var_decoration_cb, var);
+
+      if (!var->data.explicit_location) {
+         if (b->execution_model == SpvExecutionModelFragment &&
+             var->data.mode == nir_var_shader_out) {
+            var->data.location += FRAG_RESULT_DATA0;
+         } else if (b->execution_model == SpvExecutionModelVertex &&
+                    var->data.mode == nir_var_shader_in) {
+            var->data.location += VERT_ATTRIB_GENERIC0;
+         } else if (var->data.mode == nir_var_shader_in ||
+                    var->data.mode == nir_var_shader_out) {
+            var->data.location += VARYING_SLOT_VAR0;
+         }
+      }
+
+      /* Interface block variables aren't actually going to be referenced
+       * by the generated NIR, so we don't put them in the list
+       */
+      if (interface_type && glsl_type_is_struct(interface_type->type))
+         break;
+
+      if (var->data.mode == nir_var_local) {
+         nir_function_impl_add_variable(b->impl, var);
+      } else {
+         nir_shader_add_variable(b->shader, var);
+      }
+
+      break;
+   }
+
+   case SpvOpAccessChain:
+   case SpvOpInBoundsAccessChain: {
+      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_deref);
+      nir_deref_var *base = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+      val->deref = nir_deref_as_var(nir_copy_deref(b, &base->deref));
+      struct vtn_type *deref_type = vtn_value(b, w[3], vtn_value_type_deref)->deref_type;
+
+      nir_deref *tail = &val->deref->deref;
+      while (tail->child)
+         tail = tail->child;
+
+      for (unsigned i = 0; i < count - 4; i++) {
+         assert(w[i + 4] < b->value_id_bound);
+         struct vtn_value *idx_val = &b->values[w[i + 4]];
+
+         enum glsl_base_type base_type = glsl_get_base_type(tail->type);
+         switch (base_type) {
+         case GLSL_TYPE_UINT:
+         case GLSL_TYPE_INT:
+         case GLSL_TYPE_FLOAT:
+         case GLSL_TYPE_DOUBLE:
+         case GLSL_TYPE_BOOL:
+         case GLSL_TYPE_ARRAY: {
+            nir_deref_array *deref_arr = nir_deref_array_create(b);
+            if (base_type == GLSL_TYPE_ARRAY ||
+                glsl_type_is_matrix(tail->type)) {
+               deref_type = deref_type->array_element;
+            } else {
+               assert(glsl_type_is_vector(tail->type));
+               deref_type = ralloc(b, struct vtn_type);
+               deref_type->type = glsl_scalar_type(base_type);
+            }
+
+            deref_arr->deref.type = deref_type->type;
+
+            if (idx_val->value_type == vtn_value_type_constant) {
+               unsigned idx = idx_val->constant->value.u[0];
+               deref_arr->deref_array_type = nir_deref_array_type_direct;
+               deref_arr->base_offset = idx;
+            } else {
+               assert(idx_val->value_type == vtn_value_type_ssa);
+               assert(glsl_type_is_scalar(idx_val->ssa->type));
+               deref_arr->deref_array_type = nir_deref_array_type_indirect;
+               deref_arr->base_offset = 0;
+               deref_arr->indirect = nir_src_for_ssa(idx_val->ssa->def);
+            }
+            tail->child = &deref_arr->deref;
+            break;
+         }
+
+         case GLSL_TYPE_STRUCT: {
+            assert(idx_val->value_type == vtn_value_type_constant);
+            unsigned idx = idx_val->constant->value.u[0];
+            deref_type = deref_type->members[idx];
+            nir_deref_struct *deref_struct = nir_deref_struct_create(b, idx);
+            deref_struct->deref.type = deref_type->type;
+            tail->child = &deref_struct->deref;
+            break;
+         }
+         default:
+            unreachable("Invalid type for deref");
+         }
+
+         if (deref_type->is_builtin) {
+            /* If we encounter a builtin, we throw away the ress of the
+             * access chain, jump to the builtin, and keep building.
+             */
+            const struct glsl_type *builtin_type = deref_type->type;
+
+            nir_deref_array *per_vertex_deref = NULL;
+            if (glsl_type_is_array(base->var->type)) {
+               /* This builtin is a per-vertex builtin */
+               assert(b->shader->stage == MESA_SHADER_GEOMETRY);
+               assert(base->var->data.mode == nir_var_shader_in);
+               builtin_type = glsl_array_type(builtin_type,
+                                              b->shader->info.gs.vertices_in);
+
+               /* The first non-var deref should be an array deref. */
+               assert(val->deref->deref.child->deref_type ==
+                      nir_deref_type_array);
+               per_vertex_deref = nir_deref_as_array(val->deref->deref.child);
+            }
+
+            nir_variable *builtin = get_builtin_variable(b,
+                                                         base->var->data.mode,
+                                                         builtin_type,
+                                                         deref_type->builtin);
+            val->deref = nir_deref_var_create(b, builtin);
+
+            if (per_vertex_deref) {
+               /* Since deref chains start at the variable, we can just
+                * steal that link and use it.
+                */
+               val->deref->deref.child = &per_vertex_deref->deref;
+               per_vertex_deref->deref.child = NULL;
+               per_vertex_deref->deref.type =
+                  glsl_get_array_element(builtin_type);
+
+               tail = &per_vertex_deref->deref;
+            } else {
+               tail = &val->deref->deref;
+            }
+         } else {
+            tail = tail->child;
+         }
+      }
+
+      /* For uniform blocks, we don't resolve the access chain until we
+       * actually access the variable, so we need to keep around the original
+       * type of the variable.
+       */
+
+      if (variable_is_external_block(base->var))
+         val->deref_type = vtn_value(b, w[3], vtn_value_type_deref)->deref_type;
+      else
+         val->deref_type = deref_type;
+
+
+      break;
+   }
+
+   case SpvOpCopyMemory: {
+      nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
+      nir_deref_var *src = vtn_value(b, w[2], vtn_value_type_deref)->deref;
+      struct vtn_type *type =
+         vtn_value(b, w[1], vtn_value_type_deref)->deref_type;
+
+      vtn_variable_copy(b, src, dest, type);
+      break;
+   }
+
+   case SpvOpLoad: {
+      nir_deref_var *src = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+      struct vtn_type *src_type =
+         vtn_value(b, w[3], vtn_value_type_deref)->deref_type;
+
+      if (src->var->interface_type &&
+          (glsl_type_is_sampler(src->var->interface_type) ||
+           glsl_type_is_image(src->var->interface_type))) {
+         vtn_push_value(b, w[2], vtn_value_type_deref)->deref = src;
+         return;
+      }
+
+      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+      val->ssa = vtn_variable_load(b, src, src_type);
+      break;
+   }
+
+   case SpvOpStore: {
+      nir_deref_var *dest = vtn_value(b, w[1], vtn_value_type_deref)->deref;
+      struct vtn_type *dest_type =
+         vtn_value(b, w[1], vtn_value_type_deref)->deref_type;
+      struct vtn_ssa_value *src = vtn_ssa_value(b, w[2]);
+      vtn_variable_store(b, src, dest, dest_type);
+      break;
+   }
+
+   case SpvOpCopyMemorySized:
+   case SpvOpArrayLength:
+   default:
+      unreachable("Unhandled opcode");
+   }
+}
+
+static void
+vtn_handle_function_call(struct vtn_builder *b, SpvOp opcode,
+                         const uint32_t *w, unsigned count)
+{
+   unreachable("Unhandled opcode");
+}
+
+static struct vtn_ssa_value *
+vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type)
+{
+   struct vtn_ssa_value *val = rzalloc(b, struct vtn_ssa_value);
+   val->type = type;
+
+   if (!glsl_type_is_vector_or_scalar(type)) {
+      unsigned elems = glsl_get_length(type);
+      val->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+      for (unsigned i = 0; i < elems; i++) {
+         const struct glsl_type *child_type;
+
+         switch (glsl_get_base_type(type)) {
+         case GLSL_TYPE_INT:
+         case GLSL_TYPE_UINT:
+         case GLSL_TYPE_BOOL:
+         case GLSL_TYPE_FLOAT:
+         case GLSL_TYPE_DOUBLE:
+            child_type = glsl_get_column_type(type);
+            break;
+         case GLSL_TYPE_ARRAY:
+            child_type = glsl_get_array_element(type);
+            break;
+         case GLSL_TYPE_STRUCT:
+            child_type = glsl_get_struct_field(type, i);
+            break;
+         default:
+            unreachable("unkown base type");
+         }
+
+         val->elems[i] = vtn_create_ssa_value(b, child_type);
+      }
+   }
+
+   return val;
+}
+
+static nir_tex_src
+vtn_tex_src(struct vtn_builder *b, unsigned index, nir_tex_src_type type)
+{
+   nir_tex_src src;
+   src.src = nir_src_for_ssa(vtn_ssa_value(b, index)->def);
+   src.src_type = type;
+   return src;
+}
+
+static void
+vtn_handle_texture(struct vtn_builder *b, SpvOp opcode,
+                   const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+   nir_deref_var *sampler = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+
+   nir_tex_src srcs[8]; /* 8 should be enough */
+   nir_tex_src *p = srcs;
+
+   unsigned idx = 4;
+
+   unsigned coord_components = 0;
+   switch (opcode) {
+   case SpvOpImageSampleImplicitLod:
+   case SpvOpImageSampleExplicitLod:
+   case SpvOpImageSampleDrefImplicitLod:
+   case SpvOpImageSampleDrefExplicitLod:
+   case SpvOpImageSampleProjImplicitLod:
+   case SpvOpImageSampleProjExplicitLod:
+   case SpvOpImageSampleProjDrefImplicitLod:
+   case SpvOpImageSampleProjDrefExplicitLod:
+   case SpvOpImageFetch:
+   case SpvOpImageGather:
+   case SpvOpImageDrefGather:
+   case SpvOpImageQueryLod: {
+      /* All these types have the coordinate as their first real argument */
+      struct vtn_ssa_value *coord = vtn_ssa_value(b, w[idx++]);
+      coord_components = glsl_get_vector_elements(coord->type);
+      p->src = nir_src_for_ssa(coord->def);
+      p->src_type = nir_tex_src_coord;
+      p++;
+      break;
+   }
+
+   default:
+      break;
+   }
+
+   /* These all have an explicit depth value as their next source */
+   switch (opcode) {
+   case SpvOpImageSampleDrefImplicitLod:
+   case SpvOpImageSampleDrefExplicitLod:
+   case SpvOpImageSampleProjDrefImplicitLod:
+   case SpvOpImageSampleProjDrefExplicitLod:
+      (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_comparitor);
+      break;
+   default:
+      break;
+   }
+
+   /* Figure out the base texture operation */
+   nir_texop texop;
+   switch (opcode) {
+   case SpvOpImageSampleImplicitLod:
+   case SpvOpImageSampleDrefImplicitLod:
+   case SpvOpImageSampleProjImplicitLod:
+   case SpvOpImageSampleProjDrefImplicitLod:
+      texop = nir_texop_tex;
+      break;
+
+   case SpvOpImageSampleExplicitLod:
+   case SpvOpImageSampleDrefExplicitLod:
+   case SpvOpImageSampleProjExplicitLod:
+   case SpvOpImageSampleProjDrefExplicitLod:
+      texop = nir_texop_txl;
+      break;
+
+   case SpvOpImageFetch:
+      texop = nir_texop_txf;
+      break;
+
+   case SpvOpImageGather:
+   case SpvOpImageDrefGather:
+      texop = nir_texop_tg4;
+      break;
+
+   case SpvOpImageQuerySizeLod:
+   case SpvOpImageQuerySize:
+      texop = nir_texop_txs;
+      break;
+
+   case SpvOpImageQueryLod:
+      texop = nir_texop_lod;
+      break;
+
+   case SpvOpImageQueryLevels:
+      texop = nir_texop_query_levels;
+      break;
+
+   case SpvOpImageQuerySamples:
+   default:
+      unreachable("Unhandled opcode");
+   }
+
+   /* Now we need to handle some number of optional arguments */
+   if (idx < count) {
+      uint32_t operands = w[idx++];
+
+      if (operands & SpvImageOperandsBiasMask) {
+         assert(texop == nir_texop_tex);
+         texop = nir_texop_txb;
+         (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_bias);
+      }
+
+      if (operands & SpvImageOperandsLodMask) {
+         assert(texop == nir_texop_txl || texop == nir_texop_txf ||
+                texop == nir_texop_txs);
+         (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_lod);
+      }
+
+      if (operands & SpvImageOperandsGradMask) {
+         assert(texop == nir_texop_tex);
+         texop = nir_texop_txd;
+         (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddx);
+         (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ddy);
+      }
+
+      if (operands & SpvImageOperandsOffsetMask ||
+          operands & SpvImageOperandsConstOffsetMask)
+         (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_offset);
+
+      if (operands & SpvImageOperandsConstOffsetsMask)
+         assert(!"Constant offsets to texture gather not yet implemented");
+
+      if (operands & SpvImageOperandsSampleMask) {
+         assert(texop == nir_texop_txf);
+         texop = nir_texop_txf_ms;
+         (*p++) = vtn_tex_src(b, w[idx++], nir_tex_src_ms_index);
+      }
+   }
+   /* We should have now consumed exactly all of the arguments */
+   assert(idx == count);
+
+   nir_tex_instr *instr = nir_tex_instr_create(b->shader, p - srcs);
+
+   const struct glsl_type *sampler_type = nir_deref_tail(&sampler->deref)->type;
+   instr->sampler_dim = glsl_get_sampler_dim(sampler_type);
+
+   switch (glsl_get_sampler_result_type(sampler_type)) {
+   case GLSL_TYPE_FLOAT:   instr->dest_type = nir_type_float;     break;
+   case GLSL_TYPE_INT:     instr->dest_type = nir_type_int;       break;
+   case GLSL_TYPE_UINT:    instr->dest_type = nir_type_unsigned;  break;
+   case GLSL_TYPE_BOOL:    instr->dest_type = nir_type_bool;      break;
+   default:
+      unreachable("Invalid base type for sampler result");
+   }
+
+   instr->op = texop;
+   memcpy(instr->src, srcs, instr->num_srcs * sizeof(*instr->src));
+   instr->coord_components = coord_components;
+   instr->is_array = glsl_sampler_type_is_array(sampler_type);
+   instr->is_shadow = glsl_sampler_type_is_shadow(sampler_type);
+
+   instr->sampler = nir_deref_as_var(nir_copy_deref(instr, &sampler->deref));
+
+   nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
+   val->ssa = vtn_create_ssa_value(b, glsl_vector_type(GLSL_TYPE_FLOAT, 4));
+   val->ssa->def = &instr->dest.ssa;
+
+   nir_builder_instr_insert(&b->nb, &instr->instr);
+}
+
+static nir_ssa_def *
+get_image_coord(struct vtn_builder *b, uint32_t value)
+{
+   struct vtn_ssa_value *coord = vtn_ssa_value(b, value);
+
+   /* The image_load_store intrinsics assume a 4-dim coordinate */
+   unsigned dim = glsl_get_vector_elements(coord->type);
+   unsigned swizzle[4];
+   for (unsigned i = 0; i < 4; i++)
+      swizzle[i] = MIN2(i, dim - 1);
+
+   return nir_swizzle(&b->nb, coord->def, swizzle, 4, false);
+}
+
+static void
+vtn_handle_image(struct vtn_builder *b, SpvOp opcode,
+                 const uint32_t *w, unsigned count)
+{
+   /* Just get this one out of the way */
+   if (opcode == SpvOpImageTexelPointer) {
+      struct vtn_value *val =
+         vtn_push_value(b, w[2], vtn_value_type_image_pointer);
+      val->image = ralloc(b, struct vtn_image_pointer);
+
+      val->image->deref = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+      val->image->coord = get_image_coord(b, w[4]);
+      val->image->sample = vtn_ssa_value(b, w[5])->def;
+      return;
+   }
+
+   struct vtn_image_pointer image;
+
+   switch (opcode) {
+   case SpvOpAtomicExchange:
+   case SpvOpAtomicCompareExchange:
+   case SpvOpAtomicCompareExchangeWeak:
+   case SpvOpAtomicIIncrement:
+   case SpvOpAtomicIDecrement:
+   case SpvOpAtomicIAdd:
+   case SpvOpAtomicISub:
+   case SpvOpAtomicSMin:
+   case SpvOpAtomicUMin:
+   case SpvOpAtomicSMax:
+   case SpvOpAtomicUMax:
+   case SpvOpAtomicAnd:
+   case SpvOpAtomicOr:
+   case SpvOpAtomicXor:
+      image = *vtn_value(b, w[3], vtn_value_type_image_pointer)->image;
+      break;
+
+   case SpvOpImageRead:
+      image.deref = vtn_value(b, w[3], vtn_value_type_deref)->deref;
+      image.coord = get_image_coord(b, w[4]);
+
+      if (count > 5 && (w[5] & SpvImageOperandsSampleMask)) {
+         assert(w[5] == SpvImageOperandsSampleMask);
+         image.sample = vtn_ssa_value(b, w[6])->def;
+      } else {
+         image.sample = nir_ssa_undef(&b->nb, 1);
+      }
+      break;
+
+   case SpvOpImageWrite:
+      image.deref = vtn_value(b, w[1], vtn_value_type_deref)->deref;
+      image.coord = get_image_coord(b, w[2]);
+
+      /* texel = w[3] */
+
+      if (count > 4 && (w[4] & SpvImageOperandsSampleMask)) {
+         assert(w[4] == SpvImageOperandsSampleMask);
+         image.sample = vtn_ssa_value(b, w[5])->def;
+      } else {
+         image.sample = nir_ssa_undef(&b->nb, 1);
+      }
+
+   default:
+      unreachable("Invalid image opcode");
+   }
+
+   nir_intrinsic_op op;
+   switch (opcode) {
+#define OP(S, N) case SpvOp##S: op = nir_intrinsic_image_##N; break;
+   OP(ImageRead,              load)
+   OP(ImageWrite,             store)
+   OP(AtomicExchange,         atomic_exchange)
+   OP(AtomicCompareExchange,  atomic_comp_swap)
+   OP(AtomicIIncrement,       atomic_add)
+   OP(AtomicIDecrement,       atomic_add)
+   OP(AtomicIAdd,             atomic_add)
+   OP(AtomicISub,             atomic_add)
+   OP(AtomicSMin,             atomic_min)
+   OP(AtomicUMin,             atomic_min)
+   OP(AtomicSMax,             atomic_max)
+   OP(AtomicUMax,             atomic_max)
+   OP(AtomicAnd,              atomic_and)
+   OP(AtomicOr,               atomic_or)
+   OP(AtomicXor,              atomic_xor)
+#undef OP
+   default:
+      unreachable("Invalid image opcode");
+   }
+
+   nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(b->shader, op);
+   intrin->variables[0] =
+      nir_deref_as_var(nir_copy_deref(&intrin->instr, &image.deref->deref));
+   intrin->src[0] = nir_src_for_ssa(image.coord);
+   intrin->src[1] = nir_src_for_ssa(image.sample);
+
+   switch (opcode) {
+   case SpvOpImageRead:
+      break;
+   case SpvOpImageWrite:
+      intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
+      break;
+   case SpvOpAtomicIIncrement:
+      intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, 1));
+      break;
+   case SpvOpAtomicIDecrement:
+      intrin->src[2] = nir_src_for_ssa(nir_imm_int(&b->nb, -1));
+      break;
+
+   case SpvOpAtomicExchange:
+   case SpvOpAtomicIAdd:
+   case SpvOpAtomicSMin:
+   case SpvOpAtomicUMin:
+   case SpvOpAtomicSMax:
+   case SpvOpAtomicUMax:
+   case SpvOpAtomicAnd:
+   case SpvOpAtomicOr:
+   case SpvOpAtomicXor:
+      intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
+      break;
+
+   case SpvOpAtomicCompareExchange:
+      intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[7])->def);
+      intrin->src[3] = nir_src_for_ssa(vtn_ssa_value(b, w[6])->def);
+      break;
+
+   case SpvOpAtomicISub:
+      intrin->src[2] = nir_src_for_ssa(nir_ineg(&b->nb, vtn_ssa_value(b, w[6])->def));
+      break;
+
+   default:
+      unreachable("Invalid image opcode");
+   }
+
+   if (opcode != SpvOpImageWrite) {
+      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+      struct vtn_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
+      nir_ssa_dest_init(&intrin->instr, &intrin->dest,
+                        glsl_get_vector_elements(type->type), NULL);
+      val->ssa = vtn_create_ssa_value(b, type->type);
+      val->ssa->def = &intrin->dest.ssa;
+   }
+
+   nir_builder_instr_insert(&b->nb, &intrin->instr);
+}
+
+static nir_alu_instr *
+create_vec(void *mem_ctx, unsigned num_components)
+{
+   nir_op op;
+   switch (num_components) {
+   case 1: op = nir_op_fmov; break;
+   case 2: op = nir_op_vec2; break;
+   case 3: op = nir_op_vec3; break;
+   case 4: op = nir_op_vec4; break;
+   default: unreachable("bad vector size");
+   }
+
+   nir_alu_instr *vec = nir_alu_instr_create(mem_ctx, op);
+   nir_ssa_dest_init(&vec->instr, &vec->dest.dest, num_components, NULL);
+   vec->dest.write_mask = (1 << num_components) - 1;
+
+   return vec;
+}
+
+static struct vtn_ssa_value *
+vtn_transpose(struct vtn_builder *b, struct vtn_ssa_value *src)
+{
+   if (src->transposed)
+      return src->transposed;
+
+   struct vtn_ssa_value *dest =
+      vtn_create_ssa_value(b, glsl_transposed_type(src->type));
+
+   for (unsigned i = 0; i < glsl_get_matrix_columns(dest->type); i++) {
+      nir_alu_instr *vec = create_vec(b, glsl_get_matrix_columns(src->type));
+      if (glsl_type_is_vector_or_scalar(src->type)) {
+          vec->src[0].src = nir_src_for_ssa(src->def);
+          vec->src[0].swizzle[0] = i;
+      } else {
+         for (unsigned j = 0; j < glsl_get_matrix_columns(src->type); j++) {
+            vec->src[j].src = nir_src_for_ssa(src->elems[j]->def);
+            vec->src[j].swizzle[0] = i;
+         }
+      }
+      nir_builder_instr_insert(&b->nb, &vec->instr);
+      dest->elems[i]->def = &vec->dest.dest.ssa;
+   }
+
+   dest->transposed = src;
+
+   return dest;
+}
+
+/*
+ * Normally, column vectors in SPIR-V correspond to a single NIR SSA
+ * definition. But for matrix multiplies, we want to do one routine for
+ * multiplying a matrix by a matrix and then pretend that vectors are matrices
+ * with one column. So we "wrap" these things, and unwrap the result before we
+ * send it off.
+ */
+
+static struct vtn_ssa_value *
+vtn_wrap_matrix(struct vtn_builder *b, struct vtn_ssa_value *val)
+{
+   if (val == NULL)
+      return NULL;
+
+   if (glsl_type_is_matrix(val->type))
+      return val;
+
+   struct vtn_ssa_value *dest = rzalloc(b, struct vtn_ssa_value);
+   dest->type = val->type;
+   dest->elems = ralloc_array(b, struct vtn_ssa_value *, 1);
+   dest->elems[0] = val;
+
+   return dest;
+}
+
+static struct vtn_ssa_value *
+vtn_unwrap_matrix(struct vtn_ssa_value *val)
+{
+   if (glsl_type_is_matrix(val->type))
+         return val;
+
+   return val->elems[0];
+}
+
+static struct vtn_ssa_value *
+vtn_matrix_multiply(struct vtn_builder *b,
+                    struct vtn_ssa_value *_src0, struct vtn_ssa_value *_src1)
+{
+
+   struct vtn_ssa_value *src0 = vtn_wrap_matrix(b, _src0);
+   struct vtn_ssa_value *src1 = vtn_wrap_matrix(b, _src1);
+   struct vtn_ssa_value *src0_transpose = vtn_wrap_matrix(b, _src0->transposed);
+   struct vtn_ssa_value *src1_transpose = vtn_wrap_matrix(b, _src1->transposed);
+
+   unsigned src0_rows = glsl_get_vector_elements(src0->type);
+   unsigned src0_columns = glsl_get_matrix_columns(src0->type);
+   unsigned src1_columns = glsl_get_matrix_columns(src1->type);
+
+   struct vtn_ssa_value *dest =
+      vtn_create_ssa_value(b, glsl_matrix_type(glsl_get_base_type(src0->type),
+                                               src0_rows, src1_columns));
+
+   dest = vtn_wrap_matrix(b, dest);
+
+   bool transpose_result = false;
+   if (src0_transpose && src1_transpose) {
+      /* transpose(A) * transpose(B) = transpose(B * A) */
+      src1 = src0_transpose;
+      src0 = src1_transpose;
+      src0_transpose = NULL;
+      src1_transpose = NULL;
+      transpose_result = true;
+   }
+
+   if (src0_transpose && !src1_transpose &&
+       glsl_get_base_type(src0->type) == GLSL_TYPE_FLOAT) {
+      /* We already have the rows of src0 and the columns of src1 available,
+       * so we can just take the dot product of each row with each column to
+       * get the result.
+       */
+
+      for (unsigned i = 0; i < src1_columns; i++) {
+         nir_alu_instr *vec = create_vec(b, src0_rows);
+         for (unsigned j = 0; j < src0_rows; j++) {
+            vec->src[j].src =
+               nir_src_for_ssa(nir_fdot(&b->nb, src0_transpose->elems[j]->def,
+                                        src1->elems[i]->def));
+         }
+
+         nir_builder_instr_insert(&b->nb, &vec->instr);
+         dest->elems[i]->def = &vec->dest.dest.ssa;
+      }
+   } else {
+      /* We don't handle the case where src1 is transposed but not src0, since
+       * the general case only uses individual components of src1 so the
+       * optimizer should chew through the transpose we emitted for src1.
+       */
+
+      for (unsigned i = 0; i < src1_columns; i++) {
+         /* dest[i] = sum(src0[j] * src1[i][j] for all j) */
+         dest->elems[i]->def =
+            nir_fmul(&b->nb, src0->elems[0]->def,
+                     vtn_vector_extract(b, src1->elems[i]->def, 0));
+         for (unsigned j = 1; j < src0_columns; j++) {
+            dest->elems[i]->def =
+               nir_fadd(&b->nb, dest->elems[i]->def,
+                        nir_fmul(&b->nb, src0->elems[j]->def,
+                                 vtn_vector_extract(b,
+                                                    src1->elems[i]->def, j)));
+         }
+      }
+   }
+
+   dest = vtn_unwrap_matrix(dest);
+
+   if (transpose_result)
+      dest = vtn_transpose(b, dest);
+
+   return dest;
+}
+
+static struct vtn_ssa_value *
+vtn_mat_times_scalar(struct vtn_builder *b,
+                     struct vtn_ssa_value *mat,
+                     nir_ssa_def *scalar)
+{
+   struct vtn_ssa_value *dest = vtn_create_ssa_value(b, mat->type);
+   for (unsigned i = 0; i < glsl_get_matrix_columns(mat->type); i++) {
+      if (glsl_get_base_type(mat->type) == GLSL_TYPE_FLOAT)
+         dest->elems[i]->def = nir_fmul(&b->nb, mat->elems[i]->def, scalar);
+      else
+         dest->elems[i]->def = nir_imul(&b->nb, mat->elems[i]->def, scalar);
+   }
+
+   return dest;
+}
+
+static void
+vtn_handle_matrix_alu(struct vtn_builder *b, SpvOp opcode,
+                      const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+
+   switch (opcode) {
+   case SpvOpTranspose: {
+      struct vtn_ssa_value *src = vtn_ssa_value(b, w[3]);
+      val->ssa = vtn_transpose(b, src);
+      break;
+   }
+
+   case SpvOpOuterProduct: {
+      struct vtn_ssa_value *src0 = vtn_ssa_value(b, w[3]);
+      struct vtn_ssa_value *src1 = vtn_ssa_value(b, w[4]);
+
+      val->ssa = vtn_matrix_multiply(b, src0, vtn_transpose(b, src1));
+      break;
+   }
+
+   case SpvOpMatrixTimesScalar: {
+      struct vtn_ssa_value *mat = vtn_ssa_value(b, w[3]);
+      struct vtn_ssa_value *scalar = vtn_ssa_value(b, w[4]);
+
+      if (mat->transposed) {
+         val->ssa = vtn_transpose(b, vtn_mat_times_scalar(b, mat->transposed,
+                                                          scalar->def));
+      } else {
+         val->ssa = vtn_mat_times_scalar(b, mat, scalar->def);
+      }
+      break;
+   }
+
+   case SpvOpVectorTimesMatrix:
+   case SpvOpMatrixTimesVector:
+   case SpvOpMatrixTimesMatrix: {
+      struct vtn_ssa_value *src0 = vtn_ssa_value(b, w[3]);
+      struct vtn_ssa_value *src1 = vtn_ssa_value(b, w[4]);
+
+      val->ssa = vtn_matrix_multiply(b, src0, src1);
+      break;
+   }
+
+   default: unreachable("unknown matrix opcode");
+   }
+}
+
+static void
+vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
+               const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+   const struct glsl_type *type =
+      vtn_value(b, w[1], vtn_value_type_type)->type->type;
+   val->ssa = vtn_create_ssa_value(b, type);
+
+   /* Collect the various SSA sources */
+   unsigned num_inputs = count - 3;
+   nir_ssa_def *src[4];
+   for (unsigned i = 0; i < num_inputs; i++)
+      src[i] = vtn_ssa_value(b, w[i + 3])->def;
+
+   /* Indicates that the first two arguments should be swapped.  This is
+    * used for implementing greater-than and less-than-or-equal.
+    */
+   bool swap = false;
+
+   nir_op op;
+   switch (opcode) {
+   /* Basic ALU operations */
+   case SpvOpSNegate:               op = nir_op_ineg;    break;
+   case SpvOpFNegate:               op = nir_op_fneg;    break;
+   case SpvOpNot:                   op = nir_op_inot;    break;
+
+   case SpvOpAny:
+      switch (src[0]->num_components) {
+      case 1:  op = nir_op_imov;    break;
+      case 2:  op = nir_op_bany2;   break;
+      case 3:  op = nir_op_bany3;   break;
+      case 4:  op = nir_op_bany4;   break;
+      }
+      break;
+
+   case SpvOpAll:
+      switch (src[0]->num_components) {
+      case 1:  op = nir_op_imov;    break;
+      case 2:  op = nir_op_ball2;   break;
+      case 3:  op = nir_op_ball3;   break;
+      case 4:  op = nir_op_ball4;   break;
+      }
+      break;
+
+   case SpvOpIAdd:                  op = nir_op_iadd;    break;
+   case SpvOpFAdd:                  op = nir_op_fadd;    break;
+   case SpvOpISub:                  op = nir_op_isub;    break;
+   case SpvOpFSub:                  op = nir_op_fsub;    break;
+   case SpvOpIMul:                  op = nir_op_imul;    break;
+   case SpvOpFMul:                  op = nir_op_fmul;    break;
+   case SpvOpUDiv:                  op = nir_op_udiv;    break;
+   case SpvOpSDiv:                  op = nir_op_idiv;    break;
+   case SpvOpFDiv:                  op = nir_op_fdiv;    break;
+   case SpvOpUMod:                  op = nir_op_umod;    break;
+   case SpvOpSMod:                  op = nir_op_umod;    break; /* FIXME? */
+   case SpvOpFMod:                  op = nir_op_fmod;    break;
+
+   case SpvOpDot:
+      assert(src[0]->num_components == src[1]->num_components);
+      switch (src[0]->num_components) {
+      case 1:  op = nir_op_fmul;    break;
+      case 2:  op = nir_op_fdot2;   break;
+      case 3:  op = nir_op_fdot3;   break;
+      case 4:  op = nir_op_fdot4;   break;
+      }
+      break;
+
+   case SpvOpShiftRightLogical:     op = nir_op_ushr;    break;
+   case SpvOpShiftRightArithmetic:  op = nir_op_ishr;    break;
+   case SpvOpShiftLeftLogical:      op = nir_op_ishl;    break;
+   case SpvOpLogicalOr:             op = nir_op_ior;     break;
+   case SpvOpLogicalEqual:          op = nir_op_ieq;     break;
+   case SpvOpLogicalNotEqual:       op = nir_op_ine;     break;
+   case SpvOpLogicalAnd:            op = nir_op_iand;    break;
+   case SpvOpBitwiseOr:             op = nir_op_ior;     break;
+   case SpvOpBitwiseXor:            op = nir_op_ixor;    break;
+   case SpvOpBitwiseAnd:            op = nir_op_iand;    break;
+   case SpvOpSelect:                op = nir_op_bcsel;   break;
+   case SpvOpIEqual:                op = nir_op_ieq;     break;
+
+   /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
+   case SpvOpFOrdEqual:             op = nir_op_feq;     break;
+   case SpvOpFUnordEqual:           op = nir_op_feq;     break;
+   case SpvOpINotEqual:             op = nir_op_ine;     break;
+   case SpvOpFOrdNotEqual:          op = nir_op_fne;     break;
+   case SpvOpFUnordNotEqual:        op = nir_op_fne;     break;
+   case SpvOpULessThan:             op = nir_op_ult;     break;
+   case SpvOpSLessThan:             op = nir_op_ilt;     break;
+   case SpvOpFOrdLessThan:          op = nir_op_flt;     break;
+   case SpvOpFUnordLessThan:        op = nir_op_flt;     break;
+   case SpvOpUGreaterThan:          op = nir_op_ult;  swap = true;   break;
+   case SpvOpSGreaterThan:          op = nir_op_ilt;  swap = true;   break;
+   case SpvOpFOrdGreaterThan:       op = nir_op_flt;  swap = true;   break;
+   case SpvOpFUnordGreaterThan:     op = nir_op_flt;  swap = true;   break;
+   case SpvOpULessThanEqual:        op = nir_op_uge;  swap = true;   break;
+   case SpvOpSLessThanEqual:        op = nir_op_ige;  swap = true;   break;
+   case SpvOpFOrdLessThanEqual:     op = nir_op_fge;  swap = true;   break;
+   case SpvOpFUnordLessThanEqual:   op = nir_op_fge;  swap = true;   break;
+   case SpvOpUGreaterThanEqual:     op = nir_op_uge;     break;
+   case SpvOpSGreaterThanEqual:     op = nir_op_ige;     break;
+   case SpvOpFOrdGreaterThanEqual:  op = nir_op_fge;     break;
+   case SpvOpFUnordGreaterThanEqual:op = nir_op_fge;     break;
+
+   /* Conversions: */
+   case SpvOpConvertFToU:           op = nir_op_f2u;     break;
+   case SpvOpConvertFToS:           op = nir_op_f2i;     break;
+   case SpvOpConvertSToF:           op = nir_op_i2f;     break;
+   case SpvOpConvertUToF:           op = nir_op_u2f;     break;
+   case SpvOpBitcast:               op = nir_op_imov;    break;
+   case SpvOpUConvert:
+   case SpvOpSConvert:
+      op = nir_op_imov; /* TODO: NIR is 32-bit only; these are no-ops. */
+      break;
+   case SpvOpFConvert:
+      op = nir_op_fmov;
+      break;
+
+   /* Derivatives: */
+   case SpvOpDPdx:         op = nir_op_fddx;          break;
+   case SpvOpDPdy:         op = nir_op_fddy;          break;
+   case SpvOpDPdxFine:     op = nir_op_fddx_fine;     break;
+   case SpvOpDPdyFine:     op = nir_op_fddy_fine;     break;
+   case SpvOpDPdxCoarse:   op = nir_op_fddx_coarse;   break;
+   case SpvOpDPdyCoarse:   op = nir_op_fddy_coarse;   break;
+   case SpvOpFwidth:
+      val->ssa->def = nir_fadd(&b->nb,
+                               nir_fabs(&b->nb, nir_fddx(&b->nb, src[0])),
+                               nir_fabs(&b->nb, nir_fddx(&b->nb, src[1])));
+      return;
+   case SpvOpFwidthFine:
+      val->ssa->def = nir_fadd(&b->nb,
+                               nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[0])),
+                               nir_fabs(&b->nb, nir_fddx_fine(&b->nb, src[1])));
+      return;
+   case SpvOpFwidthCoarse:
+      val->ssa->def = nir_fadd(&b->nb,
+                               nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[0])),
+                               nir_fabs(&b->nb, nir_fddx_coarse(&b->nb, src[1])));
+      return;
+
+   case SpvOpVectorTimesScalar:
+      /* The builder will take care of splatting for us. */
+      val->ssa->def = nir_fmul(&b->nb, src[0], src[1]);
+      return;
+
+   case SpvOpSRem:
+   case SpvOpFRem:
+      unreachable("No NIR equivalent");
+
+   case SpvOpIsNan:
+   case SpvOpIsInf:
+   case SpvOpIsFinite:
+   case SpvOpIsNormal:
+   case SpvOpSignBitSet:
+   case SpvOpLessOrGreater:
+   case SpvOpOrdered:
+   case SpvOpUnordered:
+   default:
+      unreachable("Unhandled opcode");
+   }
+
+   if (swap) {
+      nir_ssa_def *tmp = src[0];
+      src[0] = src[1];
+      src[1] = tmp;
+   }
+
+   nir_alu_instr *instr = nir_alu_instr_create(b->shader, op);
+   nir_ssa_dest_init(&instr->instr, &instr->dest.dest,
+                     glsl_get_vector_elements(type), val->name);
+   instr->dest.write_mask = (1 << glsl_get_vector_elements(type)) - 1;
+   val->ssa->def = &instr->dest.dest.ssa;
+
+   for (unsigned i = 0; i < nir_op_infos[op].num_inputs; i++)
+      instr->src[i].src = nir_src_for_ssa(src[i]);
+
+   nir_builder_instr_insert(&b->nb, &instr->instr);
+}
+
+static nir_ssa_def *
+vtn_vector_extract(struct vtn_builder *b, nir_ssa_def *src, unsigned index)
+{
+   unsigned swiz[4] = { index };
+   return nir_swizzle(&b->nb, src, swiz, 1, true);
+}
+
+
+static nir_ssa_def *
+vtn_vector_insert(struct vtn_builder *b, nir_ssa_def *src, nir_ssa_def *insert,
+                  unsigned index)
+{
+   nir_alu_instr *vec = create_vec(b->shader, src->num_components);
+
+   for (unsigned i = 0; i < src->num_components; i++) {
+      if (i == index) {
+         vec->src[i].src = nir_src_for_ssa(insert);
+      } else {
+         vec->src[i].src = nir_src_for_ssa(src);
+         vec->src[i].swizzle[0] = i;
+      }
+   }
+
+   nir_builder_instr_insert(&b->nb, &vec->instr);
+
+   return &vec->dest.dest.ssa;
+}
+
+static nir_ssa_def *
+vtn_vector_extract_dynamic(struct vtn_builder *b, nir_ssa_def *src,
+                           nir_ssa_def *index)
+{
+   nir_ssa_def *dest = vtn_vector_extract(b, src, 0);
+   for (unsigned i = 1; i < src->num_components; i++)
+      dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
+                       vtn_vector_extract(b, src, i), dest);
+
+   return dest;
+}
+
+static nir_ssa_def *
+vtn_vector_insert_dynamic(struct vtn_builder *b, nir_ssa_def *src,
+                          nir_ssa_def *insert, nir_ssa_def *index)
+{
+   nir_ssa_def *dest = vtn_vector_insert(b, src, insert, 0);
+   for (unsigned i = 1; i < src->num_components; i++)
+      dest = nir_bcsel(&b->nb, nir_ieq(&b->nb, index, nir_imm_int(&b->nb, i)),
+                       vtn_vector_insert(b, src, insert, i), dest);
+
+   return dest;
+}
+
+static nir_ssa_def *
+vtn_vector_shuffle(struct vtn_builder *b, unsigned num_components,
+                   nir_ssa_def *src0, nir_ssa_def *src1,
+                   const uint32_t *indices)
+{
+   nir_alu_instr *vec = create_vec(b->shader, num_components);
+
+   nir_ssa_undef_instr *undef = nir_ssa_undef_instr_create(b->shader, 1);
+   nir_builder_instr_insert(&b->nb, &undef->instr);
+
+   for (unsigned i = 0; i < num_components; i++) {
+      uint32_t index = indices[i];
+      if (index == 0xffffffff) {
+         vec->src[i].src = nir_src_for_ssa(&undef->def);
+      } else if (index < src0->num_components) {
+         vec->src[i].src = nir_src_for_ssa(src0);
+         vec->src[i].swizzle[0] = index;
+      } else {
+         vec->src[i].src = nir_src_for_ssa(src1);
+         vec->src[i].swizzle[0] = index - src0->num_components;
+      }
+   }
+
+   nir_builder_instr_insert(&b->nb, &vec->instr);
+
+   return &vec->dest.dest.ssa;
+}
+
+/*
+ * Concatentates a number of vectors/scalars together to produce a vector
+ */
+static nir_ssa_def *
+vtn_vector_construct(struct vtn_builder *b, unsigned num_components,
+                     unsigned num_srcs, nir_ssa_def **srcs)
+{
+   nir_alu_instr *vec = create_vec(b->shader, num_components);
+
+   unsigned dest_idx = 0;
+   for (unsigned i = 0; i < num_srcs; i++) {
+      nir_ssa_def *src = srcs[i];
+      for (unsigned j = 0; j < src->num_components; j++) {
+         vec->src[dest_idx].src = nir_src_for_ssa(src);
+         vec->src[dest_idx].swizzle[0] = j;
+         dest_idx++;
+      }
+   }
+
+   nir_builder_instr_insert(&b->nb, &vec->instr);
+
+   return &vec->dest.dest.ssa;
+}
+
+static struct vtn_ssa_value *
+vtn_composite_copy(void *mem_ctx, struct vtn_ssa_value *src)
+{
+   struct vtn_ssa_value *dest = rzalloc(mem_ctx, struct vtn_ssa_value);
+   dest->type = src->type;
+
+   if (glsl_type_is_vector_or_scalar(src->type)) {
+      dest->def = src->def;
+   } else {
+      unsigned elems = glsl_get_length(src->type);
+
+      dest->elems = ralloc_array(mem_ctx, struct vtn_ssa_value *, elems);
+      for (unsigned i = 0; i < elems; i++)
+         dest->elems[i] = vtn_composite_copy(mem_ctx, src->elems[i]);
+   }
+
+   return dest;
+}
+
+static struct vtn_ssa_value *
+vtn_composite_insert(struct vtn_builder *b, struct vtn_ssa_value *src,
+                     struct vtn_ssa_value *insert, const uint32_t *indices,
+                     unsigned num_indices)
+{
+   struct vtn_ssa_value *dest = vtn_composite_copy(b, src);
+
+   struct vtn_ssa_value *cur = dest;
+   unsigned i;
+   for (i = 0; i < num_indices - 1; i++) {
+      cur = cur->elems[indices[i]];
+   }
+
+   if (glsl_type_is_vector_or_scalar(cur->type)) {
+      /* According to the SPIR-V spec, OpCompositeInsert may work down to
+       * the component granularity. In that case, the last index will be
+       * the index to insert the scalar into the vector.
+       */
+
+      cur->def = vtn_vector_insert(b, cur->def, insert->def, indices[i]);
+   } else {
+      cur->elems[indices[i]] = insert;
+   }
+
+   return dest;
+}
+
+static struct vtn_ssa_value *
+vtn_composite_extract(struct vtn_builder *b, struct vtn_ssa_value *src,
+                      const uint32_t *indices, unsigned num_indices)
+{
+   struct vtn_ssa_value *cur = src;
+   for (unsigned i = 0; i < num_indices; i++) {
+      if (glsl_type_is_vector_or_scalar(cur->type)) {
+         assert(i == num_indices - 1);
+         /* According to the SPIR-V spec, OpCompositeExtract may work down to
+          * the component granularity. The last index will be the index of the
+          * vector to extract.
+          */
+
+         struct vtn_ssa_value *ret = rzalloc(b, struct vtn_ssa_value);
+         ret->type = glsl_scalar_type(glsl_get_base_type(cur->type));
+         ret->def = vtn_vector_extract(b, cur->def, indices[i]);
+         return ret;
+      }
+   }
+
+   return cur;
+}
+
+static void
+vtn_handle_composite(struct vtn_builder *b, SpvOp opcode,
+                     const uint32_t *w, unsigned count)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+   const struct glsl_type *type =
+      vtn_value(b, w[1], vtn_value_type_type)->type->type;
+   val->ssa = vtn_create_ssa_value(b, type);
+
+   switch (opcode) {
+   case SpvOpVectorExtractDynamic:
+      val->ssa->def = vtn_vector_extract_dynamic(b, vtn_ssa_value(b, w[3])->def,
+                                                 vtn_ssa_value(b, w[4])->def);
+      break;
+
+   case SpvOpVectorInsertDynamic:
+      val->ssa->def = vtn_vector_insert_dynamic(b, vtn_ssa_value(b, w[3])->def,
+                                                vtn_ssa_value(b, w[4])->def,
+                                                vtn_ssa_value(b, w[5])->def);
+      break;
+
+   case SpvOpVectorShuffle:
+      val->ssa->def = vtn_vector_shuffle(b, glsl_get_vector_elements(type),
+                                         vtn_ssa_value(b, w[3])->def,
+                                         vtn_ssa_value(b, w[4])->def,
+                                         w + 5);
+      break;
+
+   case SpvOpCompositeConstruct: {
+      unsigned elems = count - 3;
+      if (glsl_type_is_vector_or_scalar(type)) {
+         nir_ssa_def *srcs[4];
+         for (unsigned i = 0; i < elems; i++)
+            srcs[i] = vtn_ssa_value(b, w[3 + i])->def;
+         val->ssa->def =
+            vtn_vector_construct(b, glsl_get_vector_elements(type),
+                                 elems, srcs);
+      } else {
+         val->ssa->elems = ralloc_array(b, struct vtn_ssa_value *, elems);
+         for (unsigned i = 0; i < elems; i++)
+            val->ssa->elems[i] = vtn_ssa_value(b, w[3 + i]);
+      }
+      break;
+   }
+   case SpvOpCompositeExtract:
+      val->ssa = vtn_composite_extract(b, vtn_ssa_value(b, w[3]),
+                                       w + 4, count - 4);
+      break;
+
+   case SpvOpCompositeInsert:
+      val->ssa = vtn_composite_insert(b, vtn_ssa_value(b, w[4]),
+                                      vtn_ssa_value(b, w[3]),
+                                      w + 5, count - 5);
+      break;
+
+   case SpvOpCopyObject:
+      val->ssa = vtn_composite_copy(b, vtn_ssa_value(b, w[3]));
+      break;
+
+   default:
+      unreachable("unknown composite operation");
+   }
+}
+
+static void
+vtn_handle_barrier(struct vtn_builder *b, SpvOp opcode,
+                   const uint32_t *w, unsigned count)
+{
+   nir_intrinsic_op intrinsic_op;
+   switch (opcode) {
+   case SpvOpEmitVertex:
+   case SpvOpEmitStreamVertex:
+      intrinsic_op = nir_intrinsic_emit_vertex;
+      break;
+   case SpvOpEndPrimitive:
+   case SpvOpEndStreamPrimitive:
+      intrinsic_op = nir_intrinsic_end_primitive;
+      break;
+   case SpvOpMemoryBarrier:
+      intrinsic_op = nir_intrinsic_memory_barrier;
+      break;
+   case SpvOpControlBarrier:
+   default:
+      unreachable("unknown barrier instruction");
+   }
+
+   nir_intrinsic_instr *intrin =
+      nir_intrinsic_instr_create(b->shader, intrinsic_op);
+
+   if (opcode == SpvOpEmitStreamVertex || opcode == SpvOpEndStreamPrimitive)
+      intrin->const_index[0] = w[1];
+
+   nir_builder_instr_insert(&b->nb, &intrin->instr);
+}
+
+static void
+vtn_phi_node_init(struct vtn_builder *b, struct vtn_ssa_value *val)
+{
+   if (glsl_type_is_vector_or_scalar(val->type)) {
+      nir_phi_instr *phi = nir_phi_instr_create(b->shader);
+      nir_ssa_dest_init(&phi->instr, &phi->dest,
+                        glsl_get_vector_elements(val->type), NULL);
+      exec_list_make_empty(&phi->srcs);
+      nir_builder_instr_insert(&b->nb, &phi->instr);
+      val->def = &phi->dest.ssa;
+   } else {
+      unsigned elems = glsl_get_length(val->type);
+      for (unsigned i = 0; i < elems; i++)
+         vtn_phi_node_init(b, val->elems[i]);
+   }
+}
+
+static struct vtn_ssa_value *
+vtn_phi_node_create(struct vtn_builder *b, const struct glsl_type *type)
+{
+   struct vtn_ssa_value *val = vtn_create_ssa_value(b, type);
+   vtn_phi_node_init(b, val);
+   return val;
+}
+
+static void
+vtn_handle_phi_first_pass(struct vtn_builder *b, const uint32_t *w)
+{
+   struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa);
+   const struct glsl_type *type =
+      vtn_value(b, w[1], vtn_value_type_type)->type->type;
+   val->ssa = vtn_phi_node_create(b, type);
+}
+
+static void
+vtn_phi_node_add_src(struct vtn_ssa_value *phi, const nir_block *pred,
+                     struct vtn_ssa_value *val)
+{
+   assert(phi->type == val->type);
+   if (glsl_type_is_vector_or_scalar(phi->type)) {
+      nir_phi_instr *phi_instr = nir_instr_as_phi(phi->def->parent_instr);
+      nir_phi_src *src = ralloc(phi_instr, nir_phi_src);
+      src->pred = (nir_block *) pred;
+      src->src = nir_src_for_ssa(val->def);
+      exec_list_push_tail(&phi_instr->srcs, &src->node);
+   } else {
+      unsigned elems = glsl_get_length(phi->type);
+      for (unsigned i = 0; i < elems; i++)
+         vtn_phi_node_add_src(phi->elems[i], pred, val->elems[i]);
+   }
+}
+
+static struct vtn_ssa_value *
+vtn_get_phi_node_src(struct vtn_builder *b, nir_block *block,
+                     const struct glsl_type *type, const uint32_t *w,
+                     unsigned count)
+{
+   struct hash_entry *entry = _mesa_hash_table_search(b->block_table, block);
+   if (entry) {
+      struct vtn_block *spv_block = entry->data;
+      for (unsigned off = 4; off < count; off += 2) {
+         if (spv_block == vtn_value(b, w[off], vtn_value_type_block)->block) {
+            return vtn_ssa_value(b, w[off - 1]);
+         }
+      }
+   }
+
+   b->nb.cursor = nir_before_block(block);
+   struct vtn_ssa_value *phi = vtn_phi_node_create(b, type);
+
+   struct set_entry *entry2;
+   set_foreach(block->predecessors, entry2) {
+      nir_block *pred = (nir_block *) entry2->key;
+      struct vtn_ssa_value *val = vtn_get_phi_node_src(b, pred, type, w,
+                                                       count);
+      vtn_phi_node_add_src(phi, pred, val);
+   }
+
+   return phi;
+}
+
+static bool
+vtn_handle_phi_second_pass(struct vtn_builder *b, SpvOp opcode,
+                           const uint32_t *w, unsigned count)
+{
+   if (opcode == SpvOpLabel) {
+      b->block = vtn_value(b, w[1], vtn_value_type_block)->block;
+      return true;
+   }
+
+   if (opcode != SpvOpPhi)
+      return true;
+
+   struct vtn_ssa_value *phi = vtn_value(b, w[2], vtn_value_type_ssa)->ssa;
+
+   struct set_entry *entry;
+   set_foreach(b->block->block->predecessors, entry) {
+      nir_block *pred = (nir_block *) entry->key;
+
+      struct vtn_ssa_value *val = vtn_get_phi_node_src(b, pred, phi->type, w,
+                                                       count);
+      vtn_phi_node_add_src(phi, pred, val);
+   }
+
+   return true;
+}
+
+static unsigned
+gl_primitive_from_spv_execution_mode(SpvExecutionMode mode)
+{
+   switch (mode) {
+   case SpvExecutionModeInputPoints:
+   case SpvExecutionModeOutputPoints:
+      return 0; /* GL_POINTS */
+   case SpvExecutionModeInputLines:
+      return 1; /* GL_LINES */
+   case SpvExecutionModeInputLinesAdjacency:
+      return 0x000A; /* GL_LINE_STRIP_ADJACENCY_ARB */
+   case SpvExecutionModeInputTriangles:
+      return 4; /* GL_TRIANGLES */
+   case SpvExecutionModeInputTrianglesAdjacency:
+      return 0x000C; /* GL_TRIANGLES_ADJACENCY_ARB */
+   case SpvExecutionModeInputQuads:
+      return 7; /* GL_QUADS */
+   case SpvExecutionModeInputIsolines:
+      return 0x8E7A; /* GL_ISOLINES */
+   case SpvExecutionModeOutputLineStrip:
+      return 3; /* GL_LINE_STRIP */
+   case SpvExecutionModeOutputTriangleStrip:
+      return 5; /* GL_TRIANGLE_STRIP */
+   default:
+      assert(!"Invalid primitive type");
+      return 4;
+   }
+}
+
+static unsigned
+vertices_in_from_spv_execution_mode(SpvExecutionMode mode)
+{
+   switch (mode) {
+   case SpvExecutionModeInputPoints:
+      return 1;
+   case SpvExecutionModeInputLines:
+      return 2;
+   case SpvExecutionModeInputLinesAdjacency:
+      return 4;
+   case SpvExecutionModeInputTriangles:
+      return 3;
+   case SpvExecutionModeInputTrianglesAdjacency:
+      return 6;
+   default:
+      assert(!"Invalid GS input mode");
+      return 0;
+   }
+}
+
+static bool
+vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
+                                const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpSource:
+   case SpvOpSourceExtension:
+   case SpvOpExtension:
+      /* Unhandled, but these are for debug so that's ok. */
+      break;
+
+   case SpvOpCapability:
+      switch ((SpvCapability)w[1]) {
+      case SpvCapabilityMatrix:
+      case SpvCapabilityShader:
+         /* All shaders support these */
+         break;
+      case SpvCapabilityGeometry:
+         assert(b->shader->stage == MESA_SHADER_GEOMETRY);
+         break;
+      default:
+         assert(!"Unsupported capability");
+      }
+      break;
+
+   case SpvOpExtInstImport:
+      vtn_handle_extension(b, opcode, w, count);
+      break;
+
+   case SpvOpMemoryModel:
+      assert(w[1] == SpvAddressingModelLogical);
+      assert(w[2] == SpvMemoryModelGLSL450);
+      break;
+
+   case SpvOpEntryPoint:
+      assert(b->entry_point == NULL);
+      b->entry_point = &b->values[w[2]];
+      b->execution_model = w[1];
+      break;
+
+   case SpvOpExecutionMode:
+      assert(b->entry_point == &b->values[w[1]]);
+
+      SpvExecutionMode mode = w[2];
+      switch(mode) {
+      case SpvExecutionModeOriginUpperLeft:
+      case SpvExecutionModeOriginLowerLeft:
+         b->origin_upper_left = (mode == SpvExecutionModeOriginUpperLeft);
+         break;
+
+      case SpvExecutionModeEarlyFragmentTests:
+         assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+         b->shader->info.fs.early_fragment_tests = true;
+         break;
+
+      case SpvExecutionModeInvocations:
+         assert(b->shader->stage == MESA_SHADER_GEOMETRY);
+         b->shader->info.gs.invocations = w[3];
+         break;
+
+      case SpvExecutionModeDepthReplacing:
+         assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+         b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_ANY;
+         break;
+      case SpvExecutionModeDepthGreater:
+         assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+         b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_GREATER;
+         break;
+      case SpvExecutionModeDepthLess:
+         assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+         b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_LESS;
+         break;
+      case SpvExecutionModeDepthUnchanged:
+         assert(b->shader->stage == MESA_SHADER_FRAGMENT);
+         b->shader->info.fs.depth_layout = FRAG_DEPTH_LAYOUT_UNCHANGED;
+         break;
+
+      case SpvExecutionModeLocalSize:
+         assert(b->shader->stage == MESA_SHADER_COMPUTE);
+         b->shader->info.cs.local_size[0] = w[3];
+         b->shader->info.cs.local_size[1] = w[4];
+         b->shader->info.cs.local_size[2] = w[5];
+         break;
+      case SpvExecutionModeLocalSizeHint:
+         break; /* Nothing do do with this */
+
+      case SpvExecutionModeOutputVertices:
+         assert(b->shader->stage == MESA_SHADER_GEOMETRY);
+         b->shader->info.gs.vertices_out = w[3];
+         break;
+
+      case SpvExecutionModeInputPoints:
+      case SpvExecutionModeInputLines:
+      case SpvExecutionModeInputLinesAdjacency:
+      case SpvExecutionModeInputTriangles:
+      case SpvExecutionModeInputTrianglesAdjacency:
+      case SpvExecutionModeInputQuads:
+      case SpvExecutionModeInputIsolines:
+         if (b->shader->stage == MESA_SHADER_GEOMETRY) {
+            b->shader->info.gs.vertices_in =
+               vertices_in_from_spv_execution_mode(mode);
+         } else {
+            assert(!"Tesselation shaders not yet supported");
+         }
+         break;
+
+      case SpvExecutionModeOutputPoints:
+      case SpvExecutionModeOutputLineStrip:
+      case SpvExecutionModeOutputTriangleStrip:
+         assert(b->shader->stage == MESA_SHADER_GEOMETRY);
+         b->shader->info.gs.output_primitive =
+            gl_primitive_from_spv_execution_mode(mode);
+         break;
+
+      case SpvExecutionModeSpacingEqual:
+      case SpvExecutionModeSpacingFractionalEven:
+      case SpvExecutionModeSpacingFractionalOdd:
+      case SpvExecutionModeVertexOrderCw:
+      case SpvExecutionModeVertexOrderCcw:
+      case SpvExecutionModePointMode:
+         assert(!"TODO: Add tessellation metadata");
+         break;
+
+      case SpvExecutionModePixelCenterInteger:
+      case SpvExecutionModeXfb:
+         assert(!"Unhandled execution mode");
+         break;
+
+      case SpvExecutionModeVecTypeHint:
+      case SpvExecutionModeContractionOff:
+      case SpvExecutionModeIndependentForwardProgress:
+         break; /* OpenCL */
+      }
+      break;
+
+   case SpvOpString:
+      vtn_push_value(b, w[1], vtn_value_type_string)->str =
+         vtn_string_literal(b, &w[2], count - 2);
+      break;
+
+   case SpvOpName:
+      b->values[w[1]].name = vtn_string_literal(b, &w[2], count - 2);
+      break;
+
+   case SpvOpMemberName:
+      /* TODO */
+      break;
+
+   case SpvOpLine:
+      break; /* Ignored for now */
+
+   case SpvOpDecorationGroup:
+   case SpvOpDecorate:
+   case SpvOpMemberDecorate:
+   case SpvOpGroupDecorate:
+   case SpvOpGroupMemberDecorate:
+      vtn_handle_decoration(b, opcode, w, count);
+      break;
+
+   case SpvOpTypeVoid:
+   case SpvOpTypeBool:
+   case SpvOpTypeInt:
+   case SpvOpTypeFloat:
+   case SpvOpTypeVector:
+   case SpvOpTypeMatrix:
+   case SpvOpTypeImage:
+   case SpvOpTypeSampler:
+   case SpvOpTypeSampledImage:
+   case SpvOpTypeArray:
+   case SpvOpTypeRuntimeArray:
+   case SpvOpTypeStruct:
+   case SpvOpTypeOpaque:
+   case SpvOpTypePointer:
+   case SpvOpTypeFunction:
+   case SpvOpTypeEvent:
+   case SpvOpTypeDeviceEvent:
+   case SpvOpTypeReserveId:
+   case SpvOpTypeQueue:
+   case SpvOpTypePipe:
+      vtn_handle_type(b, opcode, w, count);
+      break;
+
+   case SpvOpConstantTrue:
+   case SpvOpConstantFalse:
+   case SpvOpConstant:
+   case SpvOpConstantComposite:
+   case SpvOpConstantSampler:
+   case SpvOpSpecConstantTrue:
+   case SpvOpSpecConstantFalse:
+   case SpvOpSpecConstant:
+   case SpvOpSpecConstantComposite:
+      vtn_handle_constant(b, opcode, w, count);
+      break;
+
+   case SpvOpVariable:
+      vtn_handle_variables(b, opcode, w, count);
+      break;
+
+   default:
+      return false; /* End of preamble */
+   }
+
+   return true;
+}
+
+static bool
+vtn_handle_first_cfg_pass_instruction(struct vtn_builder *b, SpvOp opcode,
+                                      const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpFunction: {
+      assert(b->func == NULL);
+      b->func = rzalloc(b, struct vtn_function);
+
+      const struct glsl_type *result_type =
+         vtn_value(b, w[1], vtn_value_type_type)->type->type;
+      struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_function);
+      const struct glsl_type *func_type =
+         vtn_value(b, w[4], vtn_value_type_type)->type->type;
+
+      assert(glsl_get_function_return_type(func_type) == result_type);
+
+      nir_function *func =
+         nir_function_create(b->shader, ralloc_strdup(b->shader, val->name));
+
+      nir_function_overload *overload = nir_function_overload_create(func);
+      overload->num_params = glsl_get_length(func_type);
+      overload->params = ralloc_array(overload, nir_parameter,
+                                      overload->num_params);
+      for (unsigned i = 0; i < overload->num_params; i++) {
+         const struct glsl_function_param *param =
+            glsl_get_function_param(func_type, i);
+         overload->params[i].type = param->type;
+         if (param->in) {
+            if (param->out) {
+               overload->params[i].param_type = nir_parameter_inout;
+            } else {
+               overload->params[i].param_type = nir_parameter_in;
+            }
+         } else {
+            if (param->out) {
+               overload->params[i].param_type = nir_parameter_out;
+            } else {
+               assert(!"Parameter is neither in nor out");
+            }
+         }
+      }
+      b->func->overload = overload;
+      break;
+   }
+
+   case SpvOpFunctionEnd:
+      b->func->end = w;
+      b->func = NULL;
+      break;
+
+   case SpvOpFunctionParameter:
+      break; /* Does nothing */
+
+   case SpvOpLabel: {
+      assert(b->block == NULL);
+      b->block = rzalloc(b, struct vtn_block);
+      b->block->label = w;
+      vtn_push_value(b, w[1], vtn_value_type_block)->block = b->block;
+
+      if (b->func->start_block == NULL) {
+         /* This is the first block encountered for this function.  In this
+          * case, we set the start block and add it to the list of
+          * implemented functions that we'll walk later.
+          */
+         b->func->start_block = b->block;
+         exec_list_push_tail(&b->functions, &b->func->node);
+      }
+      break;
+   }
+
+   case SpvOpBranch:
+   case SpvOpBranchConditional:
+   case SpvOpSwitch:
+   case SpvOpKill:
+   case SpvOpReturn:
+   case SpvOpReturnValue:
+   case SpvOpUnreachable:
+      assert(b->block);
+      b->block->branch = w;
+      b->block = NULL;
+      break;
+
+   case SpvOpSelectionMerge:
+   case SpvOpLoopMerge:
+      assert(b->block && b->block->merge_op == SpvOpNop);
+      b->block->merge_op = opcode;
+      b->block->merge_block_id = w[1];
+      break;
+
+   default:
+      /* Continue on as per normal */
+      return true;
+   }
+
+   return true;
+}
+
+static bool
+vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
+                            const uint32_t *w, unsigned count)
+{
+   switch (opcode) {
+   case SpvOpLabel: {
+      struct vtn_block *block = vtn_value(b, w[1], vtn_value_type_block)->block;
+      assert(block->block == NULL);
+
+      block->block = nir_cursor_current_block(b->nb.cursor);
+      break;
+   }
+
+   case SpvOpLoopMerge:
+   case SpvOpSelectionMerge:
+      /* This is handled by cfg pre-pass and walk_blocks */
+      break;
+
+   case SpvOpUndef:
+      vtn_push_value(b, w[2], vtn_value_type_undef);
+      break;
+
+   case SpvOpExtInst:
+      vtn_handle_extension(b, opcode, w, count);
+      break;
+
+   case SpvOpVariable:
+   case SpvOpLoad:
+   case SpvOpStore:
+   case SpvOpCopyMemory:
+   case SpvOpCopyMemorySized:
+   case SpvOpAccessChain:
+   case SpvOpInBoundsAccessChain:
+   case SpvOpArrayLength:
+      vtn_handle_variables(b, opcode, w, count);
+      break;
+
+   case SpvOpFunctionCall:
+      vtn_handle_function_call(b, opcode, w, count);
+      break;
+
+   case SpvOpImageSampleImplicitLod:
+   case SpvOpImageSampleExplicitLod:
+   case SpvOpImageSampleDrefImplicitLod:
+   case SpvOpImageSampleDrefExplicitLod:
+   case SpvOpImageSampleProjImplicitLod:
+   case SpvOpImageSampleProjExplicitLod:
+   case SpvOpImageSampleProjDrefImplicitLod:
+   case SpvOpImageSampleProjDrefExplicitLod:
+   case SpvOpImageFetch:
+   case SpvOpImageGather:
+   case SpvOpImageDrefGather:
+   case SpvOpImageQuerySizeLod:
+   case SpvOpImageQuerySize:
+   case SpvOpImageQueryLod:
+   case SpvOpImageQueryLevels:
+   case SpvOpImageQuerySamples:
+      vtn_handle_texture(b, opcode, w, count);
+      break;
+
+   case SpvOpImageRead:
+   case SpvOpImageWrite:
+   case SpvOpImageTexelPointer:
+      vtn_handle_image(b, opcode, w, count);
+      break;
+
+   case SpvOpAtomicExchange:
+   case SpvOpAtomicCompareExchange:
+   case SpvOpAtomicCompareExchangeWeak:
+   case SpvOpAtomicIIncrement:
+   case SpvOpAtomicIDecrement:
+   case SpvOpAtomicIAdd:
+   case SpvOpAtomicISub:
+   case SpvOpAtomicSMin:
+   case SpvOpAtomicUMin:
+   case SpvOpAtomicSMax:
+   case SpvOpAtomicUMax:
+   case SpvOpAtomicAnd:
+   case SpvOpAtomicOr:
+   case SpvOpAtomicXor: {
+      struct vtn_value *pointer = vtn_untyped_value(b, w[3]);
+      if (pointer->value_type == vtn_value_type_image_pointer) {
+         vtn_handle_image(b, opcode, w, count);
+      } else {
+         assert(!"Atomic buffers not yet implemented");
+      }
+   }
+
+   case SpvOpSNegate:
+   case SpvOpFNegate:
+   case SpvOpNot:
+   case SpvOpAny:
+   case SpvOpAll:
+   case SpvOpConvertFToU:
+   case SpvOpConvertFToS:
+   case SpvOpConvertSToF:
+   case SpvOpConvertUToF:
+   case SpvOpUConvert:
+   case SpvOpSConvert:
+   case SpvOpFConvert:
+   case SpvOpConvertPtrToU:
+   case SpvOpConvertUToPtr:
+   case SpvOpPtrCastToGeneric:
+   case SpvOpGenericCastToPtr:
+   case SpvOpBitcast:
+   case SpvOpIsNan:
+   case SpvOpIsInf:
+   case SpvOpIsFinite:
+   case SpvOpIsNormal:
+   case SpvOpSignBitSet:
+   case SpvOpLessOrGreater:
+   case SpvOpOrdered:
+   case SpvOpUnordered:
+   case SpvOpIAdd:
+   case SpvOpFAdd:
+   case SpvOpISub:
+   case SpvOpFSub:
+   case SpvOpIMul:
+   case SpvOpFMul:
+   case SpvOpUDiv:
+   case SpvOpSDiv:
+   case SpvOpFDiv:
+   case SpvOpUMod:
+   case SpvOpSRem:
+   case SpvOpSMod:
+   case SpvOpFRem:
+   case SpvOpFMod:
+   case SpvOpVectorTimesScalar:
+   case SpvOpDot:
+   case SpvOpShiftRightLogical:
+   case SpvOpShiftRightArithmetic:
+   case SpvOpShiftLeftLogical:
+   case SpvOpLogicalOr:
+   case SpvOpLogicalEqual:
+   case SpvOpLogicalNotEqual:
+   case SpvOpLogicalAnd:
+   case SpvOpBitwiseOr:
+   case SpvOpBitwiseXor:
+   case SpvOpBitwiseAnd:
+   case SpvOpSelect:
+   case SpvOpIEqual:
+   case SpvOpFOrdEqual:
+   case SpvOpFUnordEqual:
+   case SpvOpINotEqual:
+   case SpvOpFOrdNotEqual:
+   case SpvOpFUnordNotEqual:
+   case SpvOpULessThan:
+   case SpvOpSLessThan:
+   case SpvOpFOrdLessThan:
+   case SpvOpFUnordLessThan:
+   case SpvOpUGreaterThan:
+   case SpvOpSGreaterThan:
+   case SpvOpFOrdGreaterThan:
+   case SpvOpFUnordGreaterThan:
+   case SpvOpULessThanEqual:
+   case SpvOpSLessThanEqual:
+   case SpvOpFOrdLessThanEqual:
+   case SpvOpFUnordLessThanEqual:
+   case SpvOpUGreaterThanEqual:
+   case SpvOpSGreaterThanEqual:
+   case SpvOpFOrdGreaterThanEqual:
+   case SpvOpFUnordGreaterThanEqual:
+   case SpvOpDPdx:
+   case SpvOpDPdy:
+   case SpvOpFwidth:
+   case SpvOpDPdxFine:
+   case SpvOpDPdyFine:
+   case SpvOpFwidthFine:
+   case SpvOpDPdxCoarse:
+   case SpvOpDPdyCoarse:
+   case SpvOpFwidthCoarse:
+      vtn_handle_alu(b, opcode, w, count);
+      break;
+
+   case SpvOpTranspose:
+   case SpvOpOuterProduct:
+   case SpvOpMatrixTimesScalar:
+   case SpvOpVectorTimesMatrix:
+   case SpvOpMatrixTimesVector:
+   case SpvOpMatrixTimesMatrix:
+      vtn_handle_matrix_alu(b, opcode, w, count);
+      break;
+
+   case SpvOpVectorExtractDynamic:
+   case SpvOpVectorInsertDynamic:
+   case SpvOpVectorShuffle:
+   case SpvOpCompositeConstruct:
+   case SpvOpCompositeExtract:
+   case SpvOpCompositeInsert:
+   case SpvOpCopyObject:
+      vtn_handle_composite(b, opcode, w, count);
+      break;
+
+   case SpvOpPhi:
+      vtn_handle_phi_first_pass(b, w);
+      break;
+
+   case SpvOpEmitVertex:
+   case SpvOpEndPrimitive:
+   case SpvOpEmitStreamVertex:
+   case SpvOpEndStreamPrimitive:
+   case SpvOpControlBarrier:
+   case SpvOpMemoryBarrier:
+      vtn_handle_barrier(b, opcode, w, count);
+      break;
+
+   default:
+      unreachable("Unhandled opcode");
+   }
+
+   return true;
+}
+
+static void
+vtn_walk_blocks(struct vtn_builder *b, struct vtn_block *start,
+                struct vtn_block *break_block, struct vtn_block *cont_block,
+                struct vtn_block *end_block)
+{
+   struct vtn_block *block = start;
+   while (block != end_block) {
+      if (block->merge_op == SpvOpLoopMerge) {
+         /* This is the jump into a loop. */
+         struct vtn_block *new_cont_block = block;
+         struct vtn_block *new_break_block =
+            vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
+
+         nir_loop *loop = nir_loop_create(b->shader);
+         nir_cf_node_insert(b->nb.cursor, &loop->cf_node);
+
+         /* Reset the merge_op to prerevent infinite recursion */
+         block->merge_op = SpvOpNop;
+
+         b->nb.cursor = nir_after_cf_list(&loop->body);
+         vtn_walk_blocks(b, block, new_break_block, new_cont_block, NULL);
+
+         b->nb.cursor = nir_after_cf_node(&loop->cf_node);
+         block = new_break_block;
+         continue;
+      }
+
+      const uint32_t *w = block->branch;
+      SpvOp branch_op = w[0] & SpvOpCodeMask;
+
+      b->block = block;
+      vtn_foreach_instruction(b, block->label, block->branch,
+                              vtn_handle_body_instruction);
+
+      nir_block *cur_block = nir_cursor_current_block(b->nb.cursor);
+      assert(cur_block == block->block);
+      _mesa_hash_table_insert(b->block_table, cur_block, block);
+
+      switch (branch_op) {
+      case SpvOpBranch: {
+         struct vtn_block *branch_block =
+            vtn_value(b, w[1], vtn_value_type_block)->block;
+
+         if (branch_block == break_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_break);
+            nir_builder_instr_insert(&b->nb, &jump->instr);
+
+            return;
+         } else if (branch_block == cont_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_continue);
+            nir_builder_instr_insert(&b->nb, &jump->instr);
+
+            return;
+         } else if (branch_block == end_block) {
+            /* We're branching to the merge block of an if, since for loops
+             * and functions end_block == NULL, so we're done here.
+             */
+            return;
+         } else {
+            /* We're branching to another block, and according to the rules,
+             * we can only branch to another block with one predecessor (so
+             * we're the only one jumping to it) so we can just process it
+             * next.
+             */
+            block = branch_block;
+            continue;
+         }
+      }
+
+      case SpvOpBranchConditional: {
+         /* Gather up the branch blocks */
+         struct vtn_block *then_block =
+            vtn_value(b, w[2], vtn_value_type_block)->block;
+         struct vtn_block *else_block =
+            vtn_value(b, w[3], vtn_value_type_block)->block;
+
+         nir_if *if_stmt = nir_if_create(b->shader);
+         if_stmt->condition = nir_src_for_ssa(vtn_ssa_value(b, w[1])->def);
+         nir_cf_node_insert(b->nb.cursor, &if_stmt->cf_node);
+
+         if (then_block == break_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_break);
+            nir_instr_insert_after_cf_list(&if_stmt->then_list,
+                                           &jump->instr);
+            block = else_block;
+         } else if (else_block == break_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_break);
+            nir_instr_insert_after_cf_list(&if_stmt->else_list,
+                                           &jump->instr);
+            block = then_block;
+         } else if (then_block == cont_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_continue);
+            nir_instr_insert_after_cf_list(&if_stmt->then_list,
+                                           &jump->instr);
+            block = else_block;
+         } else if (else_block == cont_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_continue);
+            nir_instr_insert_after_cf_list(&if_stmt->else_list,
+                                           &jump->instr);
+            block = then_block;
+         } else {
+            /* According to the rules we're branching to two blocks that don't
+             * have any other predecessors, so we can handle this as a
+             * conventional if.
+             */
+            assert(block->merge_op == SpvOpSelectionMerge);
+            struct vtn_block *merge_block =
+               vtn_value(b, block->merge_block_id, vtn_value_type_block)->block;
+
+            b->nb.cursor = nir_after_cf_list(&if_stmt->then_list);
+            vtn_walk_blocks(b, then_block, break_block, cont_block, merge_block);
+
+            b->nb.cursor = nir_after_cf_list(&if_stmt->else_list);
+            vtn_walk_blocks(b, else_block, break_block, cont_block, merge_block);
+
+            b->nb.cursor = nir_after_cf_node(&if_stmt->cf_node);
+            block = merge_block;
+            continue;
+         }
+
+         /* If we got here then we inserted a predicated break or continue
+          * above and we need to handle the other case.  We already set
+          * `block` above to indicate what block to visit after the
+          * predicated break.
+          */
+
+         /* It's possible that the other branch is also a break/continue.
+          * If it is, we handle that here.
+          */
+         if (block == break_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_break);
+            nir_builder_instr_insert(&b->nb, &jump->instr);
+
+            return;
+         } else if (block == cont_block) {
+            nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                         nir_jump_continue);
+            nir_builder_instr_insert(&b->nb, &jump->instr);
+
+            return;
+         }
+
+         /* If we got here then there was a predicated break/continue but
+          * the other half of the if has stuff in it.  `block` was already
+          * set above so there is nothing left for us to do.
+          */
+         continue;
+      }
+
+      case SpvOpReturn: {
+         nir_jump_instr *jump = nir_jump_instr_create(b->shader,
+                                                      nir_jump_return);
+         nir_builder_instr_insert(&b->nb, &jump->instr);
+         return;
+      }
+
+      case SpvOpKill: {
+         nir_intrinsic_instr *discard =
+            nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
+         nir_builder_instr_insert(&b->nb, &discard->instr);
+         return;
+      }
+
+      case SpvOpSwitch:
+      case SpvOpReturnValue:
+      case SpvOpUnreachable:
+      default:
+         unreachable("Unhandled opcode");
+      }
+   }
+}
+
+nir_shader *
+spirv_to_nir(const uint32_t *words, size_t word_count,
+             gl_shader_stage stage,
+             const nir_shader_compiler_options *options)
+{
+   const uint32_t *word_end = words + word_count;
+
+   /* Handle the SPIR-V header (first 4 dwords)  */
+   assert(word_count > 5);
+
+   assert(words[0] == SpvMagicNumber);
+   assert(words[1] == 99);
+   /* words[2] == generator magic */
+   unsigned value_id_bound = words[3];
+   assert(words[4] == 0);
+
+   words+= 5;
+
+   nir_shader *shader = nir_shader_create(NULL, stage, options);
+
+   /* Initialize the stn_builder object */
+   struct vtn_builder *b = rzalloc(NULL, struct vtn_builder);
+   b->shader = shader;
+   b->value_id_bound = value_id_bound;
+   b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
+   exec_list_make_empty(&b->functions);
+
+   /* XXX: We shouldn't need these defaults */
+   if (b->shader->stage == MESA_SHADER_GEOMETRY) {
+      b->shader->info.gs.vertices_in = 3;
+      b->shader->info.gs.output_primitive = 4; /* GL_TRIANGLES */
+   }
+
+   /* Handle all the preamble instructions */
+   words = vtn_foreach_instruction(b, words, word_end,
+                                   vtn_handle_preamble_instruction);
+
+   /* Do a very quick CFG analysis pass */
+   vtn_foreach_instruction(b, words, word_end,
+                           vtn_handle_first_cfg_pass_instruction);
+
+   foreach_list_typed(struct vtn_function, func, node, &b->functions) {
+      b->impl = nir_function_impl_create(func->overload);
+      b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
+                                               _mesa_key_pointer_equal);
+      b->block_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
+                                               _mesa_key_pointer_equal);
+      nir_builder_init(&b->nb, b->impl);
+      b->nb.cursor = nir_after_cf_list(&b->impl->body);
+      vtn_walk_blocks(b, func->start_block, NULL, NULL, NULL);
+      vtn_foreach_instruction(b, func->start_block->label, func->end,
+                              vtn_handle_phi_second_pass);
+   }
+
+   /* Because we can still have output reads in NIR, we need to lower
+    * outputs to temporaries before we are truely finished.
+    */
+   nir_lower_outputs_to_temporaries(shader);
+
+   ralloc_free(b);
+
+   return shader;
+}
diff --git a/src/glsl/nir/spirv_to_nir_private.h b/src/glsl/nir/spirv_to_nir_private.h
new file mode 100644 (file)
index 0000000..f7be166
--- /dev/null
@@ -0,0 +1,242 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Jason Ekstrand (jason@jlekstrand.net)
+ *
+ */
+
+#include "nir.h"
+#include "nir_spirv.h"
+#include "nir_builder.h"
+#include "spirv.h"
+
+struct vtn_builder;
+struct vtn_decoration;
+
+enum vtn_value_type {
+   vtn_value_type_invalid = 0,
+   vtn_value_type_undef,
+   vtn_value_type_string,
+   vtn_value_type_decoration_group,
+   vtn_value_type_type,
+   vtn_value_type_constant,
+   vtn_value_type_deref,
+   vtn_value_type_function,
+   vtn_value_type_block,
+   vtn_value_type_ssa,
+   vtn_value_type_extension,
+   vtn_value_type_image_pointer,
+};
+
+struct vtn_block {
+   /* Merge opcode if this block contains a merge; SpvOpNop otherwise. */
+   SpvOp merge_op;
+   uint32_t merge_block_id;
+   const uint32_t *label;
+   const uint32_t *branch;
+   nir_block *block;
+};
+
+struct vtn_function {
+   struct exec_node node;
+
+   nir_function_overload *overload;
+   struct vtn_block *start_block;
+
+   const uint32_t *end;
+};
+
+typedef bool (*vtn_instruction_handler)(struct vtn_builder *, uint32_t,
+                                        const uint32_t *, unsigned);
+
+struct vtn_ssa_value {
+   union {
+      nir_ssa_def *def;
+      struct vtn_ssa_value **elems;
+   };
+
+   /* For matrices, a transposed version of the value, or NULL if it hasn't
+    * been computed
+    */
+   struct vtn_ssa_value *transposed;
+
+   const struct glsl_type *type;
+};
+
+struct vtn_type {
+   const struct glsl_type *type;
+
+   /* for matrices, whether the matrix is stored row-major */
+   bool row_major;
+
+   /* for structs, the offset of each member */
+   unsigned *offsets;
+
+   /* for structs, whether it was decorated as a "non-SSBO-like" block */
+   bool block;
+
+   /* for structs, whether it was decorated as an "SSBO-like" block */
+   bool buffer_block;
+
+   /* for structs with block == true, whether this is a builtin block (i.e. a
+    * block that contains only builtins).
+    */
+   bool builtin_block;
+
+   /* Image format for image_load_store type images */
+   unsigned image_format;
+
+   /* for arrays and matrices, the array stride */
+   unsigned stride;
+
+   /* for arrays, the vtn_type for the elements of the array */
+   struct vtn_type *array_element;
+
+   /* for structures, the vtn_type for each member */
+   struct vtn_type **members;
+
+   /* Whether this type, or a parent type, has been decorated as a builtin */
+   bool is_builtin;
+
+   SpvBuiltIn builtin;
+};
+
+struct vtn_image_pointer {
+   nir_deref_var *deref;
+   nir_ssa_def *coord;
+   nir_ssa_def *sample;
+};
+
+struct vtn_value {
+   enum vtn_value_type value_type;
+   const char *name;
+   struct vtn_decoration *decoration;
+   union {
+      void *ptr;
+      char *str;
+      struct vtn_type *type;
+      struct {
+         nir_constant *constant;
+         const struct glsl_type *const_type;
+      };
+      struct {
+         nir_deref_var *deref;
+         struct vtn_type *deref_type;
+      };
+      struct vtn_image_pointer *image;
+      struct vtn_function *func;
+      struct vtn_block *block;
+      struct vtn_ssa_value *ssa;
+      vtn_instruction_handler ext_handler;
+   };
+};
+
+struct vtn_decoration {
+   struct vtn_decoration *next;
+   int member; /* -1 if not a member decoration */
+   const uint32_t *literals;
+   struct vtn_value *group;
+   SpvDecoration decoration;
+};
+
+struct vtn_builder {
+   nir_builder nb;
+
+   nir_shader *shader;
+   nir_function_impl *impl;
+   struct vtn_block *block;
+
+   /*
+    * In SPIR-V, constants are global, whereas in NIR, the load_const
+    * instruction we use is per-function. So while we parse each function, we
+    * keep a hash table of constants we've resolved to nir_ssa_value's so
+    * far, and we lazily resolve them when we see them used in a function.
+    */
+   struct hash_table *const_table;
+
+   /*
+    * Map from nir_block to the vtn_block which ends with it -- used for
+    * handling phi nodes.
+    */
+   struct hash_table *block_table;
+
+   /*
+    * NIR variable for each SPIR-V builtin.
+    */
+   struct {
+      nir_variable *in;
+      nir_variable *out;
+   } builtins[42]; /* XXX need symbolic constant from SPIR-V header */
+
+   unsigned value_id_bound;
+   struct vtn_value *values;
+
+   SpvExecutionModel execution_model;
+   bool origin_upper_left;
+   struct vtn_value *entry_point;
+
+   struct vtn_function *func;
+   struct exec_list functions;
+};
+
+static inline struct vtn_value *
+vtn_push_value(struct vtn_builder *b, uint32_t value_id,
+               enum vtn_value_type value_type)
+{
+   assert(value_id < b->value_id_bound);
+   assert(b->values[value_id].value_type == vtn_value_type_invalid);
+
+   b->values[value_id].value_type = value_type;
+
+   return &b->values[value_id];
+}
+
+static inline struct vtn_value *
+vtn_untyped_value(struct vtn_builder *b, uint32_t value_id)
+{
+   assert(value_id < b->value_id_bound);
+   return &b->values[value_id];
+}
+
+static inline struct vtn_value *
+vtn_value(struct vtn_builder *b, uint32_t value_id,
+          enum vtn_value_type value_type)
+{
+   struct vtn_value *val = vtn_untyped_value(b, value_id);
+   assert(val->value_type == value_type);
+   return val;
+}
+
+struct vtn_ssa_value *vtn_ssa_value(struct vtn_builder *b, uint32_t value_id);
+
+typedef void (*vtn_decoration_foreach_cb)(struct vtn_builder *,
+                                          struct vtn_value *,
+                                          int member,
+                                          const struct vtn_decoration *,
+                                          void *);
+
+void vtn_foreach_decoration(struct vtn_builder *b, struct vtn_value *value,
+                            vtn_decoration_foreach_cb cb, void *data);
+
+bool vtn_handle_glsl450_instruction(struct vtn_builder *b, uint32_t ext_opcode,
+                                    const uint32_t *words, unsigned count);
index f3e34c6ff050b70a7807d1a4fbf8948cf3911497..7d59c787aed2a63fd0fc3e27105b3c0d4e18cfbe 100644 (file)
 #include "util/ralloc.h"
 #include "util/strtod.h"
 
+extern "C" void
+_mesa_error_no_memory(const char *caller)
+{
+   fprintf(stderr, "Mesa error: out of memory in %s", caller);
+}
+
 void
 _mesa_warning(struct gl_context *ctx, const char *fmt, ...)
 {
index 5a88d66a31b8270424049c696fe7b797ec2e38c9..595903dd572e807b4fbfc245f071a9e04eec2b72 100644 (file)
@@ -56,6 +56,7 @@ i965_compiler_FILES = \
        brw_shader.cpp \
        brw_shader.h \
        brw_surface_formats.c \
+       brw_surface_formats.h \
        brw_util.c \
        brw_util.h \
        brw_vec4_builder.h \
index e3a26d6a353ffa0a02db719a91f06dbce6d7c716..cd78af0dce40b05d6486ec8e765bf4a50b292776 100644 (file)
@@ -94,6 +94,9 @@ struct brw_compiler {
    struct gl_shader_compiler_options glsl_compiler_options[MESA_SHADER_STAGES];
 };
 
+struct brw_compiler *
+brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo);
+
 
 /**
  * Program key structures.
index 6484484ed3469a8019d1f5be3b9db7f17db3ec4f..3ad90da8b2fed2dd0fc4ff9c99a45388b1503fe9 100644 (file)
@@ -57,6 +57,7 @@
 # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL (0 << 8)
 # define GEN7_3DPRIM_VERTEXBUFFER_ACCESS_RANDOM     (1 << 8)
 
+#ifndef _3DPRIM_POINTLIST /* FIXME: Avoid clashing with defines from bdw_pack.h */
 #define _3DPRIM_POINTLIST         0x01
 #define _3DPRIM_LINELIST          0x02
 #define _3DPRIM_LINESTRIP         0x03
@@ -80,6 +81,7 @@
 #define _3DPRIM_TRIFAN_NOSTIPPLE  0x16
 #define _3DPRIM_PATCHLIST(n) ({ assert(n > 0 && n <= 32); 0x20 + (n - 1); })
 
+#endif /* bdw_pack.h */
 
 /* We use this offset to be able to pass native primitive types in struct
  * _mesa_prim::mode.  Native primitive types are BRW_PRIM_OFFSET +
index 45505507be73fc89488d962538b9ed33fedc2ba4..541c7958d5e74653a42fe92b5c59d69bd07f2e07 100644 (file)
@@ -387,3 +387,15 @@ brw_get_device_info(int devid)
 
    return devinfo;
 }
+
+const char *
+brw_get_device_name(int devid)
+{
+   switch (devid) {
+#undef CHIPSET
+#define CHIPSET(id, family, name) case id: return name;
+#include "pci_ids/i965_pci_ids.h"
+   default:
+      return NULL;
+   }
+}
index 4911c233deaf5e2f1eed010ee4c85769f566d05a..6f4a250e874bd4583b4db12de24669e97a94d680 100644 (file)
@@ -87,3 +87,4 @@ struct brw_device_info
 };
 
 const struct brw_device_info *brw_get_device_info(int devid);
+const char *brw_get_device_name(int devid);
index bff484f09d802be5411db67937a02301886fa89b..a2eaf8fb1e02feaaacb68cde24ece115f4385417 100644 (file)
 
 #define FILE_DEBUG_FLAG DEBUG_PRIMS
 
-static const GLuint prim_to_hw_prim[GL_TRIANGLE_STRIP_ADJACENCY+1] = {
-   [GL_POINTS] =_3DPRIM_POINTLIST,
-   [GL_LINES] = _3DPRIM_LINELIST,
-   [GL_LINE_LOOP] = _3DPRIM_LINELOOP,
-   [GL_LINE_STRIP] = _3DPRIM_LINESTRIP,
-   [GL_TRIANGLES] = _3DPRIM_TRILIST,
-   [GL_TRIANGLE_STRIP] = _3DPRIM_TRISTRIP,
-   [GL_TRIANGLE_FAN] = _3DPRIM_TRIFAN,
-   [GL_QUADS] = _3DPRIM_QUADLIST,
-   [GL_QUAD_STRIP] = _3DPRIM_QUADSTRIP,
-   [GL_POLYGON] = _3DPRIM_POLYGON,
-   [GL_LINES_ADJACENCY] = _3DPRIM_LINELIST_ADJ,
-   [GL_LINE_STRIP_ADJACENCY] = _3DPRIM_LINESTRIP_ADJ,
-   [GL_TRIANGLES_ADJACENCY] = _3DPRIM_TRILIST_ADJ,
-   [GL_TRIANGLE_STRIP_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ,
-};
-
 
 static const GLenum reduced_prim[GL_POLYGON+1] = {
    [GL_POINTS] = GL_POINTS,
@@ -86,18 +69,6 @@ static const GLenum reduced_prim[GL_POLYGON+1] = {
    [GL_POLYGON] = GL_TRIANGLES
 };
 
-uint32_t
-get_hw_prim_for_gl_prim(int mode)
-{
-   if (mode >= BRW_PRIM_OFFSET)
-      return mode - BRW_PRIM_OFFSET;
-   else {
-      assert(mode < ARRAY_SIZE(prim_to_hw_prim));
-      return prim_to_hw_prim[mode];
-   }
-}
-
-
 /* When the primitive changes, set a state bit and re-validate.  Not
  * the nicest and would rather deal with this by having all the
  * programs be immune to the active primitive (ie. cope with all
index 80b8c8e120754877e6e15070ccd63efe60788622..3bec7285ef557f6c06f2f21144a67b0f20ae6967 100644 (file)
@@ -505,6 +505,7 @@ type_size_scalar(const struct glsl_type *type)
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
    case GLSL_TYPE_DOUBLE:
+   case GLSL_TYPE_FUNCTION:
       unreachable("not reached");
    }
 
@@ -2762,10 +2763,23 @@ fs_visitor::emit_repclear_shader()
    brw_wm_prog_key *key = (brw_wm_prog_key*) this->key;
    int base_mrf = 1;
    int color_mrf = base_mrf + 2;
+   fs_inst *mov;
 
-   fs_inst *mov = bld.exec_all().group(4, 0)
-                     .MOV(brw_message_reg(color_mrf),
-                          fs_reg(UNIFORM, 0, BRW_REGISTER_TYPE_F));
+   if (uniforms == 1) {
+      mov = bld.exec_all().group(4, 0)
+               .MOV(brw_message_reg(color_mrf),
+                    fs_reg(UNIFORM, 0, BRW_REGISTER_TYPE_F));
+   } else {
+      struct brw_reg reg =
+         brw_reg(BRW_GENERAL_REGISTER_FILE,
+                 2, 3, 0, 0, BRW_REGISTER_TYPE_F,
+                 BRW_VERTICAL_STRIDE_8,
+                 BRW_WIDTH_2,
+                 BRW_HORIZONTAL_STRIDE_4, BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+
+      mov = bld.exec_all().group(4, 0)
+               .MOV(vec4(brw_message_reg(color_mrf)), fs_reg(reg));
+   }
 
    fs_inst *write;
    if (key->nr_color_regions == 1) {
@@ -2794,8 +2808,10 @@ fs_visitor::emit_repclear_shader()
    assign_curb_setup();
 
    /* Now that we have the uniform assigned, go ahead and force it to a vec4. */
-   assert(mov->src[0].file == FIXED_GRF);
-   mov->src[0] = brw_vec4_grf(mov->src[0].nr, 0);
+   if (uniforms == 1) {
+      assert(mov->src[0].file == FIXED_GRF);
+      mov->src[0] = brw_vec4_grf(mov->src[0].nr, 0);
+   }
 }
 
 /**
index c282f835cae8f31fd9df256f178110298d6b1718..a47b6ce50cc4a703972c023bd35b2a20194ae6be 100644 (file)
@@ -2686,6 +2686,12 @@ fs_visitor::nir_emit_jump(const fs_builder &bld, nir_jump_instr *instr)
       bld.emit(BRW_OPCODE_CONTINUE);
       break;
    case nir_jump_return:
+      /* This has to be the last block in the shader.  We don't handle
+       * early returns.
+       */
+      assert(nir_cf_node_next(&instr->instr.block->cf_node) == NULL &&
+             instr->instr.block->cf_node.parent->type == nir_cf_node_function);
+      break;
    default:
       unreachable("unknown jump");
    }
index fe5cad4e435aab9a69a71606dae4f35fa33765a2..58754adc88774fec509bc1cbd5821beba06e8191 100644 (file)
@@ -224,10 +224,6 @@ brw_create_nir(struct brw_context *brw,
    const struct brw_device_info *devinfo = brw->intelScreen->devinfo;
    const nir_shader_compiler_options *options =
       ctx->Const.ShaderCompilerOptions[stage].NirOptions;
-   static const nir_lower_tex_options tex_options = {
-      .lower_txp = ~0,
-   };
-   bool debug_enabled = INTEL_DEBUG & intel_debug_flag_for_shader_stage(stage);
    nir_shader *nir;
 
    /* First, lower the GLSL IR or Mesa IR to NIR */
@@ -239,7 +235,39 @@ brw_create_nir(struct brw_context *brw,
    }
    nir_validate_shader(nir);
 
-   if (stage == MESA_SHADER_GEOMETRY) {
+   brw_preprocess_nir(nir, brw->intelScreen->devinfo, is_scalar);
+
+   if (shader_prog) {
+      nir_lower_samplers(nir, shader_prog);
+      nir_validate_shader(nir);
+
+      nir_lower_atomics(nir, shader_prog);
+      nir_validate_shader(nir);
+   }
+
+   brw_postprocess_nir(nir, brw->intelScreen->devinfo, is_scalar);
+
+   static GLuint msg_id = 0;
+   _mesa_gl_debug(&brw->ctx, &msg_id,
+                  MESA_DEBUG_SOURCE_SHADER_COMPILER,
+                  MESA_DEBUG_TYPE_OTHER,
+                  MESA_DEBUG_SEVERITY_NOTIFICATION,
+                  "%s NIR shader:\n",
+                  _mesa_shader_stage_to_abbrev(nir->stage));
+
+   return nir;
+}
+
+void
+brw_preprocess_nir(nir_shader *nir,
+                   const struct brw_device_info *devinfo,
+                   bool is_scalar)
+{
+   static const nir_lower_tex_options tex_options = {
+      .lower_txp = ~0,
+   };
+
+   if (nir->stage == MESA_SHADER_GEOMETRY) {
       nir_lower_gs_intrinsics(nir);
       nir_validate_shader(nir);
    }
@@ -264,6 +292,15 @@ brw_create_nir(struct brw_context *brw,
 
    /* Get rid of split copies */
    nir_optimize(nir, is_scalar);
+}
+
+void
+brw_postprocess_nir(nir_shader *nir,
+                    const struct brw_device_info *devinfo,
+                    bool is_scalar)
+{
+   bool debug_enabled =
+      (INTEL_DEBUG & intel_debug_flag_for_shader_stage(nir->stage));
 
    brw_nir_lower_inputs(devinfo, nir, is_scalar);
    brw_nir_lower_outputs(nir, is_scalar);
@@ -276,22 +313,12 @@ brw_create_nir(struct brw_context *brw,
    nir_remove_dead_variables(nir);
    nir_validate_shader(nir);
 
-   if (shader_prog) {
-      nir_lower_samplers(nir, shader_prog);
-      nir_validate_shader(nir);
-   }
-
    nir_lower_system_values(nir);
    nir_validate_shader(nir);
 
-   if (shader_prog) {
-      nir_lower_atomics(nir, shader_prog);
-      nir_validate_shader(nir);
-   }
-
    nir_optimize(nir, is_scalar);
 
-   if (brw->gen >= 6) {
+   if (devinfo->gen >= 6) {
       /* Try and fuse multiply-adds */
       brw_nir_opt_peephole_ffma(nir);
       nir_validate_shader(nir);
@@ -318,7 +345,7 @@ brw_create_nir(struct brw_context *brw,
       }
 
       fprintf(stderr, "NIR (SSA form) for %s shader:\n",
-              _mesa_shader_stage_to_string(stage));
+              _mesa_shader_stage_to_string(nir->stage));
       nir_print_shader(nir, stderr);
    }
 
@@ -338,18 +365,16 @@ brw_create_nir(struct brw_context *brw,
     * run it last because it stashes data in instr->pass_flags and we don't
     * want that to be squashed by other NIR passes.
     */
-   if (brw->gen <= 5)
+   if (devinfo->gen <= 5)
       brw_nir_analyze_boolean_resolves(nir);
 
    nir_sweep(nir);
 
    if (unlikely(debug_enabled)) {
       fprintf(stderr, "NIR (final form) for %s shader:\n",
-              _mesa_shader_stage_to_string(stage));
+              _mesa_shader_stage_to_string(nir->stage));
       nir_print_shader(nir, stderr);
    }
-
-   return nir;
 }
 
 enum brw_reg_type
index e7c93684fb3f07339439ddd94021c1376364bc80..d259777e1c932136d8a64ab522ed28da47913a01 100644 (file)
@@ -85,6 +85,15 @@ enum brw_reg_type brw_type_for_nir_type(nir_alu_type type);
 
 enum glsl_base_type brw_glsl_base_type_for_nir_type(nir_alu_type type);
 
+void
+brw_preprocess_nir(nir_shader *nir,
+                   const struct brw_device_info *devinfo,
+                   bool is_scalar);
+void
+brw_postprocess_nir(nir_shader *nir,
+                    const struct brw_device_info *devinfo,
+                    bool is_scalar);
+
 void brw_nir_setup_glsl_uniforms(nir_shader *shader,
                                  struct gl_shader_program *shader_prog,
                                  const struct gl_program *prog,
index 1ccfa1b6a1d9c02d60f76b8772a7148ac0a69975..6433dec9041a12040639bd53c934c155cfeb3d36 100644 (file)
@@ -258,7 +258,7 @@ brw_get_scratch_bo(struct brw_context *brw,
 
 void brwInitFragProgFuncs( struct dd_function_table *functions )
 {
-   assert(functions->ProgramStringNotify == _tnl_program_string);
+   /* assert(functions->ProgramStringNotify == _tnl_program_string); */
 
    functions->NewProgram = brwNewProgram;
    functions->DeleteProgram = brwDeleteProgram;
index a438e1881d523b9b8b3ed2307d30f22e365dbbc5..1f3ae7ab5e67f46501a584f02178a27336dfac61 100644 (file)
@@ -115,6 +115,8 @@ brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo)
     */
    nir_options->lower_ffma = true;
    nir_options->lower_sub = true;
+   nir_options->lower_fdiv = true;
+
    /* In the vec4 backend, our dpN instruction replicates its result to all
     * the components of a vec4.  We would like NIR to give us replicated fdot
     * instructions because it can optimize better for us.
@@ -209,6 +211,7 @@ brw_type_for_base_type(const struct glsl_type *type)
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
    case GLSL_TYPE_DOUBLE:
+   case GLSL_TYPE_FUNCTION:
       unreachable("not reached");
    }
 
index c851941021de031c4bf9548d8a4305f486c74b6f..c4a37187ce23a8a314c3bc2781fb52e1c8bbabae 100644 (file)
@@ -227,9 +227,6 @@ struct brw_gs_compile
    unsigned control_data_header_size_bits;
 };
 
-struct brw_compiler *
-brw_compiler_create(void *mem_ctx, const struct brw_device_info *devinfo);
-
 void
 brw_assign_common_binding_table_offsets(gl_shader_stage stage,
                                         const struct brw_device_info *devinfo,
index 97fff60f3e523338941d6cf94e98da735eb4cc30..0d49ab7b43159670011267ebc14c038dffb40c16 100644 (file)
 #include "brw_state.h"
 #include "brw_defines.h"
 #include "brw_wm.h"
-
-struct surface_format_info {
-   bool exists;
-   int sampling;
-   int filtering;
-   int shadow_compare;
-   int chroma_key;
-   int render_target;
-   int alpha_blend;
-   int input_vb;
-   int streamed_output_vb;
-   int color_processing;
-   const char *name;
-};
+#include "brw_surface_formats.h"
 
 /* This macro allows us to write the table almost as it appears in the PRM,
  * while restructuring it to turn it into the C code we want.
@@ -85,7 +72,7 @@ struct surface_format_info {
  * - VOL4_Part1 section 2.12.2.1.2 Sampler Output Channel Mapping.
  * - VOL4_Part1 section 3.9.11 Render Target Write.
  */
-const struct surface_format_info surface_formats[] = {
+const struct brw_surface_format_info surface_formats[] = {
 /* smpl filt shad CK  RT  AB  VB  SO  color */
    SF( Y, 50,  x,  x,  Y,  Y,  Y,  Y,  x, R32G32B32A32_FLOAT)
    SF( Y,  x,  x,  x,  Y,  x,  Y,  Y,  x, R32G32B32A32_SINT)
@@ -616,7 +603,7 @@ brw_init_surface_formats(struct brw_context *brw)
 
    for (format = MESA_FORMAT_NONE + 1; format < MESA_FORMAT_COUNT; format++) {
       uint32_t texture, render;
-      const struct surface_format_info *rinfo, *tinfo;
+      const struct brw_surface_format_info *rinfo, *tinfo;
       bool is_integer = _mesa_is_format_integer_color(format);
 
       render = texture = brw_format_for_mesa_format(format);
diff --git a/src/mesa/drivers/dri/i965/brw_surface_formats.h b/src/mesa/drivers/dri/i965/brw_surface_formats.h
new file mode 100644 (file)
index 0000000..5c7b60e
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+
+struct brw_surface_format_info {
+   bool exists;
+   int sampling;
+   int filtering;
+   int shadow_compare;
+   int chroma_key;
+   int render_target;
+   int alpha_blend;
+   int input_vb;
+   int streamed_output_vb;
+   int color_processing;
+   const char *name;
+};
+
+extern const struct brw_surface_format_info surface_formats[];
index f801dc06628995906e2dfc7ee956f2c830cc876e..e4533f34f1f77503bc7c260052fba7a95a9d03eb 100644 (file)
@@ -102,3 +102,31 @@ GLuint brw_translate_blend_factor( GLenum factor )
       unreachable("not reached");
    }
 }
+
+static const GLuint prim_to_hw_prim[GL_TRIANGLE_STRIP_ADJACENCY+1] = {
+   [GL_POINTS] =_3DPRIM_POINTLIST,
+   [GL_LINES] = _3DPRIM_LINELIST,
+   [GL_LINE_LOOP] = _3DPRIM_LINELOOP,
+   [GL_LINE_STRIP] = _3DPRIM_LINESTRIP,
+   [GL_TRIANGLES] = _3DPRIM_TRILIST,
+   [GL_TRIANGLE_STRIP] = _3DPRIM_TRISTRIP,
+   [GL_TRIANGLE_FAN] = _3DPRIM_TRIFAN,
+   [GL_QUADS] = _3DPRIM_QUADLIST,
+   [GL_QUAD_STRIP] = _3DPRIM_QUADSTRIP,
+   [GL_POLYGON] = _3DPRIM_POLYGON,
+   [GL_LINES_ADJACENCY] = _3DPRIM_LINELIST_ADJ,
+   [GL_LINE_STRIP_ADJACENCY] = _3DPRIM_LINESTRIP_ADJ,
+   [GL_TRIANGLES_ADJACENCY] = _3DPRIM_TRILIST_ADJ,
+   [GL_TRIANGLE_STRIP_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ,
+};
+
+uint32_t
+get_hw_prim_for_gl_prim(int mode)
+{
+   if (mode >= BRW_PRIM_OFFSET)
+      return mode - BRW_PRIM_OFFSET;
+   else {
+      assert(mode < ARRAY_SIZE(prim_to_hw_prim));
+      return prim_to_hw_prim[mode];
+   }
+}
index 27933d7d61c8621d2a9a0bc670b4fb4338b16498..258dd4f654891403172fd219a20095b648f05f28 100644 (file)
@@ -1522,7 +1522,13 @@ vec4_visitor::nir_emit_jump(nir_jump_instr *instr)
       break;
 
    case nir_jump_return:
-      /* fall through */
+      /* This has to be the last block in the shader.  We don't handle
+       * early returns.
+       */
+      assert(nir_cf_node_next(&instr->instr.block->cf_node) == NULL &&
+             instr->instr.block->cf_node.parent->type == nir_cf_node_function);
+      break;
+
    default:
       unreachable("unknown jump");
    }
index fda3d7c4427f4854bd17ec3eb319aa03bcb9706a..70a1ea4f9d4c09ce6439a6909795e85a628e93ee 100644 (file)
@@ -622,6 +622,7 @@ type_size_vec4(const struct glsl_type *type)
    case GLSL_TYPE_DOUBLE:
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
+   case GLSL_TYPE_FUNCTION:
       unreachable("not reached");
    }
 
index 4efdf1ee8c11849dc2598d3efe6099bfcdcdebcd..95cbba4ed57e81459336353642685181cbebabeb 100644 (file)
@@ -2478,6 +2478,11 @@ struct gl_uniform_block
     */
    GLuint Binding;
 
+   /**
+    * Vulkan descriptor set qualifier for this block.
+    */
+   GLuint Set;
+
    /**
     * Minimum size (in bytes) of a buffer object to back this uniform buffer
     * (GL_UNIFORM_BLOCK_DATA_SIZE).
index 61a5064d07497c25580da4b297c8b4855f08d32e..1099d79d834b07c160d459eddd8f5b0507213028 100644 (file)
@@ -541,6 +541,7 @@ type_size(const struct glsl_type *type)
    case GLSL_TYPE_VOID:
    case GLSL_TYPE_ERROR:
    case GLSL_TYPE_INTERFACE:
+   case GLSL_TYPE_FUNCTION:
       assert(!"Invalid type in type_size");
       break;
    }
@@ -2466,6 +2467,7 @@ _mesa_associate_uniform_storage(struct gl_context *ctx,
          case GLSL_TYPE_STRUCT:
          case GLSL_TYPE_ERROR:
          case GLSL_TYPE_INTERFACE:
+         case GLSL_TYPE_FUNCTION:
            assert(!"Should not get here.");
            break;
         }
index 066f9b8dfe50bb5852e9b31d781e602cb6b55ce4..f0dec5da60874c7cf9e6028589e9d1f03697816b 100644 (file)
@@ -116,6 +116,28 @@ static inline unsigned list_length(struct list_head *list)
    return length;
 }
 
+static inline void list_splice(struct list_head *src, struct list_head *dst)
+{
+   if (list_empty(src))
+      return;
+
+   src->next->prev = dst;
+   src->prev->next = dst->next;
+   dst->next->prev = src->prev;
+   dst->next = src->next;
+}
+
+static inline void list_splicetail(struct list_head *src, struct list_head *dst)
+{
+   if (list_empty(src))
+      return;
+
+   src->prev->next = dst;
+   src->next->prev = dst->prev;
+   dst->prev->next = src->next;
+   dst->prev = src->prev;
+}
+
 static inline void list_validate(struct list_head *list)
 {
    struct list_head *node;
diff --git a/src/vulkan/.gitignore b/src/vulkan/.gitignore
new file mode 100644 (file)
index 0000000..316d24a
--- /dev/null
@@ -0,0 +1,8 @@
+# Generated source files
+/*_spirv_autogen.h
+/anv_entrypoints.c
+/anv_entrypoints.h
+/wayland-drm-protocol.c
+/wayland-drm-client-protocol.h
+/anv_icd.json
+/isl_format_layout.c
diff --git a/src/vulkan/Makefile.am b/src/vulkan/Makefile.am
new file mode 100644 (file)
index 0000000..6e4de53
--- /dev/null
@@ -0,0 +1,145 @@
+# Copyright © 2015 Intel Corporation
+#
+# 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 (including the next
+# paragraph) 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.
+
+SUBDIRS = . tests
+
+vulkan_includedir = $(includedir)/vulkan
+
+vulkan_include_HEADERS =                               \
+       $(top_srcdir)/include/vulkan/vk_platform.h      \
+       $(top_srcdir)/include/vulkan/vulkan.h           \
+       $(top_srcdir)/include/vulkan/vulkan_intel.h     \
+       $(top_srcdir)/include/vulkan/vk_ext_khr_swapchain.h     \
+       $(top_srcdir)/include/vulkan/vk_ext_khr_device_swapchain.h
+
+lib_LTLIBRARIES = libvulkan.la
+
+check_LTLIBRARIES = libvulkan-test.la
+
+# The gallium includes are for the util/u_math.h include from main/macros.h
+
+AM_CPPFLAGS = \
+       $(INTEL_CFLAGS) \
+       $(VALGRIND_CFLAGS) \
+       $(DEFINES) \
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/glsl/nir \
+       -I$(top_srcdir)/src/mapi \
+       -I$(top_srcdir)/src/mesa \
+       -I$(top_srcdir)/src/mesa/drivers/dri/common \
+       -I$(top_srcdir)/src/mesa/drivers/dri/i965 \
+       -I$(top_srcdir)/src/gallium/auxiliary \
+       -I$(top_srcdir)/src/gallium/include \
+       -I$(top_builddir)/src/vulkan
+
+libvulkan_la_CFLAGS =                                                  \
+       -Wall -Wno-unused-parameter -fvisibility=hidden -O0 -g          \
+       -Wstrict-prototypes -Wmissing-prototypes -Wno-override-init
+
+VULKAN_SOURCES =                                        \
+       anv_allocator.c                                 \
+       anv_cmd_buffer.c                                \
+       anv_batch_chain.c                               \
+       anv_device.c                                    \
+        anv_dump.c                                      \
+       anv_entrypoints.c                               \
+       anv_entrypoints.h                               \
+       anv_formats.c                                   \
+       anv_image.c                                     \
+       anv_intel.c                                     \
+       anv_meta.c                                      \
+       anv_meta_clear.c                                \
+       anv_nir_apply_dynamic_offsets.c                 \
+       anv_nir_apply_pipeline_layout.c                 \
+       anv_nir_lower_push_constants.c                  \
+       anv_pass.c                                      \
+       anv_pipeline.c                                  \
+       anv_private.h                                   \
+       anv_query.c                                     \
+       anv_util.c                                      \
+       anv_wsi.c                                       \
+       anv_wsi_x11.c                                   \
+       gen8_state.c                                    \
+       gen8_cmd_buffer.c                               \
+       gen8_pipeline.c                                 \
+       gen7_state.c                                    \
+       gen7_cmd_buffer.c                               \
+       gen7_pipeline.c                                 \
+       isl.c                                           \
+       isl_format_layout.c
+
+BUILT_SOURCES =                                         \
+       anv_entrypoints.h                               \
+       anv_entrypoints.c                               \
+       isl_format_layout.c
+
+if HAVE_EGL_PLATFORM_WAYLAND
+BUILT_SOURCES += \
+       wayland-drm-protocol.c \
+       wayland-drm-client-protocol.h
+
+%-protocol.c : $(top_srcdir)/src/egl/wayland/wayland-drm/%.xml
+       $(AM_V_GEN)$(WAYLAND_SCANNER) code < $< > $@
+
+%-client-protocol.h : $(top_srcdir)/src/egl/wayland/wayland-drm/%.xml
+       $(AM_V_GEN)$(WAYLAND_SCANNER) client-header < $< > $@
+
+AM_CPPFLAGS += -I$(top_srcdir)/src/egl/wayland/wayland-drm
+VULKAN_SOURCES += \
+       wayland-drm-protocol.c \
+       anv_wsi_wayland.c
+libvulkan_la_CFLAGS += -DHAVE_WAYLAND_PLATFORM
+endif
+
+libvulkan_la_SOURCES =                                  \
+       $(VULKAN_SOURCES)                               \
+       anv_gem.c
+
+anv_entrypoints.h : anv_entrypoints_gen.py $(vulkan_include_HEADERS)
+       $(AM_V_GEN)cat $(vulkan_include_HEADERS) | $(PYTHON2) $< header > $@
+
+anv_entrypoints.c : anv_entrypoints_gen.py $(vulkan_include_HEADERS)
+       $(AM_V_GEN)cat $(vulkan_include_HEADERS) | $(PYTHON2) $< code > $@
+
+isl_format_layout.c: isl_format_layout_gen.bash \
+                     isl_format_layout.csv
+       $(AM_V_GEN)$(srcdir)/isl_format_layout_gen.bash \
+           <$(srcdir)/isl_format_layout.csv >$@
+
+CLEANFILES = $(BUILT_SOURCES)
+
+libvulkan_la_LIBADD = $(WAYLAND_LIBS) -lxcb -lxcb-dri3 \
+       $(top_builddir)/src/mesa/drivers/dri/i965/libi965_compiler.la \
+       ../mesa/libmesa.la \
+       ../mesa/drivers/dri/common/libdri_test_stubs.la \
+       -lpthread -ldl -lstdc++
+
+# Libvulkan with dummy gem. Used for unit tests.
+
+libvulkan_test_la_SOURCES =                             \
+       $(VULKAN_SOURCES)                               \
+       anv_gem_stubs.c
+
+libvulkan_test_la_CFLAGS = $(libvulkan_la_CFLAGS)
+libvulkan_test_la_LIBADD = $(libvulkan_la_LIBADD)
+
+include $(top_srcdir)/install-lib-links.mk
diff --git a/src/vulkan/anv_allocator.c b/src/vulkan/anv_allocator.c
new file mode 100644 (file)
index 0000000..db04a2c
--- /dev/null
@@ -0,0 +1,837 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#define _DEFAULT_SOURCE
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <values.h>
+#include <assert.h>
+#include <linux/futex.h>
+#include <linux/memfd.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+#include "anv_private.h"
+
+#ifdef HAVE_VALGRIND
+#define VG_NOACCESS_READ(__ptr) ({                       \
+   VALGRIND_MAKE_MEM_DEFINED((__ptr), sizeof(*(__ptr))); \
+   __typeof(*(__ptr)) __val = *(__ptr);                  \
+   VALGRIND_MAKE_MEM_NOACCESS((__ptr), sizeof(*(__ptr)));\
+   __val;                                                \
+})
+#define VG_NOACCESS_WRITE(__ptr, __val) ({                  \
+   VALGRIND_MAKE_MEM_UNDEFINED((__ptr), sizeof(*(__ptr)));  \
+   *(__ptr) = (__val);                                      \
+   VALGRIND_MAKE_MEM_NOACCESS((__ptr), sizeof(*(__ptr)));   \
+})
+#else
+#define VG_NOACCESS_READ(__ptr) (*(__ptr))
+#define VG_NOACCESS_WRITE(__ptr, __val) (*(__ptr) = (__val))
+#endif
+
+/* Design goals:
+ *
+ *  - Lock free (except when resizing underlying bos)
+ *
+ *  - Constant time allocation with typically only one atomic
+ *
+ *  - Multiple allocation sizes without fragmentation
+ *
+ *  - Can grow while keeping addresses and offset of contents stable
+ *
+ *  - All allocations within one bo so we can point one of the
+ *    STATE_BASE_ADDRESS pointers at it.
+ *
+ * The overall design is a two-level allocator: top level is a fixed size, big
+ * block (8k) allocator, which operates out of a bo.  Allocation is done by
+ * either pulling a block from the free list or growing the used range of the
+ * bo.  Growing the range may run out of space in the bo which we then need to
+ * grow.  Growing the bo is tricky in a multi-threaded, lockless environment:
+ * we need to keep all pointers and contents in the old map valid.  GEM bos in
+ * general can't grow, but we use a trick: we create a memfd and use ftruncate
+ * to grow it as necessary.  We mmap the new size and then create a gem bo for
+ * it using the new gem userptr ioctl.  Without heavy-handed locking around
+ * our allocation fast-path, there isn't really a way to munmap the old mmap,
+ * so we just keep it around until garbage collection time.  While the block
+ * allocator is lockless for normal operations, we block other threads trying
+ * to allocate while we're growing the map.  It sholdn't happen often, and
+ * growing is fast anyway.
+ *
+ * At the next level we can use various sub-allocators.  The state pool is a
+ * pool of smaller, fixed size objects, which operates much like the block
+ * pool.  It uses a free list for freeing objects, but when it runs out of
+ * space it just allocates a new block from the block pool.  This allocator is
+ * intended for longer lived state objects such as SURFACE_STATE and most
+ * other persistent state objects in the API.  We may need to track more info
+ * with these object and a pointer back to the CPU object (eg VkImage).  In
+ * those cases we just allocate a slightly bigger object and put the extra
+ * state after the GPU state object.
+ *
+ * The state stream allocator works similar to how the i965 DRI driver streams
+ * all its state.  Even with Vulkan, we need to emit transient state (whether
+ * surface state base or dynamic state base), and for that we can just get a
+ * block and fill it up.  These cases are local to a command buffer and the
+ * sub-allocator need not be thread safe.  The streaming allocator gets a new
+ * block when it runs out of space and chains them together so they can be
+ * easily freed.
+ */
+
+/* Allocations are always at least 64 byte aligned, so 1 is an invalid value.
+ * We use it to indicate the free list is empty. */
+#define EMPTY 1
+
+struct anv_mmap_cleanup {
+   void *map;
+   size_t size;
+   uint32_t gem_handle;
+};
+
+#define ANV_MMAP_CLEANUP_INIT ((struct anv_mmap_cleanup){0})
+
+static inline long
+sys_futex(void *addr1, int op, int val1,
+          struct timespec *timeout, void *addr2, int val3)
+{
+   return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
+}
+
+static inline int
+futex_wake(uint32_t *addr, int count)
+{
+   return sys_futex(addr, FUTEX_WAKE, count, NULL, NULL, 0);
+}
+
+static inline int
+futex_wait(uint32_t *addr, int32_t value)
+{
+   return sys_futex(addr, FUTEX_WAIT, value, NULL, NULL, 0);
+}
+
+static inline int
+memfd_create(const char *name, unsigned int flags)
+{
+   return syscall(SYS_memfd_create, name, flags);
+}
+
+static inline uint32_t
+ilog2_round_up(uint32_t value)
+{
+   assert(value != 0);
+   return 32 - __builtin_clz(value - 1);
+}
+
+static inline uint32_t
+round_to_power_of_two(uint32_t value)
+{
+   return 1 << ilog2_round_up(value);
+}
+
+static bool
+anv_free_list_pop(union anv_free_list *list, void **map, int32_t *offset)
+{
+   union anv_free_list current, new, old;
+
+   current.u64 = list->u64;
+   while (current.offset != EMPTY) {
+      /* We have to add a memory barrier here so that the list head (and
+       * offset) gets read before we read the map pointer.  This way we
+       * know that the map pointer is valid for the given offset at the
+       * point where we read it.
+       */
+      __sync_synchronize();
+
+      int32_t *next_ptr = *map + current.offset;
+      new.offset = VG_NOACCESS_READ(next_ptr);
+      new.count = current.count + 1;
+      old.u64 = __sync_val_compare_and_swap(&list->u64, current.u64, new.u64);
+      if (old.u64 == current.u64) {
+         *offset = current.offset;
+         return true;
+      }
+      current = old;
+   }
+
+   return false;
+}
+
+static void
+anv_free_list_push(union anv_free_list *list, void *map, int32_t offset)
+{
+   union anv_free_list current, old, new;
+   int32_t *next_ptr = map + offset;
+
+   old = *list;
+   do {
+      current = old;
+      VG_NOACCESS_WRITE(next_ptr, current.offset);
+      new.offset = offset;
+      new.count = current.count + 1;
+      old.u64 = __sync_val_compare_and_swap(&list->u64, current.u64, new.u64);
+   } while (old.u64 != current.u64);
+}
+
+/* All pointers in the ptr_free_list are assumed to be page-aligned.  This
+ * means that the bottom 12 bits should all be zero.
+ */
+#define PFL_COUNT(x) ((uintptr_t)(x) & 0xfff)
+#define PFL_PTR(x) ((void *)((uintptr_t)(x) & ~0xfff))
+#define PFL_PACK(ptr, count) ({           \
+   assert(((uintptr_t)(ptr) & 0xfff) == 0); \
+   (void *)((uintptr_t)(ptr) | (uintptr_t)((count) & 0xfff)); \
+})
+
+static bool
+anv_ptr_free_list_pop(void **list, void **elem)
+{
+   void *current = *list;
+   while (PFL_PTR(current) != NULL) {
+      void **next_ptr = PFL_PTR(current);
+      void *new_ptr = VG_NOACCESS_READ(next_ptr);
+      unsigned new_count = PFL_COUNT(current) + 1;
+      void *new = PFL_PACK(new_ptr, new_count);
+      void *old = __sync_val_compare_and_swap(list, current, new);
+      if (old == current) {
+         *elem = PFL_PTR(current);
+         return true;
+      }
+      current = old;
+   }
+
+   return false;
+}
+
+static void
+anv_ptr_free_list_push(void **list, void *elem)
+{
+   void *old, *current;
+   void **next_ptr = elem;
+
+   old = *list;
+   do {
+      current = old;
+      VG_NOACCESS_WRITE(next_ptr, PFL_PTR(current));
+      unsigned new_count = PFL_COUNT(current) + 1;
+      void *new = PFL_PACK(elem, new_count);
+      old = __sync_val_compare_and_swap(list, current, new);
+   } while (old != current);
+}
+
+static uint32_t
+anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state);
+
+void
+anv_block_pool_init(struct anv_block_pool *pool,
+                    struct anv_device *device, uint32_t block_size)
+{
+   assert(util_is_power_of_two(block_size));
+
+   pool->device = device;
+   pool->bo.gem_handle = 0;
+   pool->bo.offset = 0;
+   pool->bo.size = 0;
+   pool->block_size = block_size;
+   pool->free_list = ANV_FREE_LIST_EMPTY;
+   pool->back_free_list = ANV_FREE_LIST_EMPTY;
+
+   pool->fd = memfd_create("block pool", MFD_CLOEXEC);
+   if (pool->fd == -1)
+      return;
+
+   /* Just make it 2GB up-front.  The Linux kernel won't actually back it
+    * with pages until we either map and fault on one of them or we use
+    * userptr and send a chunk of it off to the GPU.
+    */
+   if (ftruncate(pool->fd, BLOCK_POOL_MEMFD_SIZE) == -1)
+      return;
+
+   anv_vector_init(&pool->mmap_cleanups,
+                   round_to_power_of_two(sizeof(struct anv_mmap_cleanup)), 128);
+
+   pool->state.next = 0;
+   pool->state.end = 0;
+   pool->back_state.next = 0;
+   pool->back_state.end = 0;
+
+   /* Immediately grow the pool so we'll have a backing bo. */
+   pool->state.end = anv_block_pool_grow(pool, &pool->state);
+}
+
+void
+anv_block_pool_finish(struct anv_block_pool *pool)
+{
+   struct anv_mmap_cleanup *cleanup;
+
+   anv_vector_foreach(cleanup, &pool->mmap_cleanups) {
+      if (cleanup->map)
+         munmap(cleanup->map, cleanup->size);
+      if (cleanup->gem_handle)
+         anv_gem_close(pool->device, cleanup->gem_handle);
+   }
+
+   anv_vector_finish(&pool->mmap_cleanups);
+
+   close(pool->fd);
+}
+
+#define PAGE_SIZE 4096
+
+/** Grows and re-centers the block pool.
+ *
+ * We grow the block pool in one or both directions in such a way that the
+ * following conditions are met:
+ *
+ *  1) The size of the entire pool is always a power of two.
+ *
+ *  2) The pool only grows on both ends.  Neither end can get
+ *     shortened.
+ *
+ *  3) At the end of the allocation, we have about twice as much space
+ *     allocated for each end as we have used.  This way the pool doesn't
+ *     grow too far in one direction or the other.
+ *
+ *  4) If the _alloc_back() has never been called, then the back portion of
+ *     the pool retains a size of zero.  (This makes it easier for users of
+ *     the block pool that only want a one-sided pool.)
+ *
+ *  5) We have enough space allocated for at least one more block in
+ *     whichever side `state` points to.
+ *
+ *  6) The center of the pool is always aligned to both the block_size of
+ *     the pool and a 4K CPU page.
+ */
+static uint32_t
+anv_block_pool_grow(struct anv_block_pool *pool, struct anv_block_state *state)
+{
+   size_t size;
+   void *map;
+   int gem_handle;
+   struct anv_mmap_cleanup *cleanup;
+
+   pthread_mutex_lock(&pool->device->mutex);
+
+   assert(state == &pool->state || state == &pool->back_state);
+
+   /* Gather a little usage information on the pool.  Since we may have
+    * threadsd waiting in queue to get some storage while we resize, it's
+    * actually possible that total_used will be larger than old_size.  In
+    * particular, block_pool_alloc() increments state->next prior to
+    * calling block_pool_grow, so this ensures that we get enough space for
+    * which ever side tries to grow the pool.
+    *
+    * We align to a page size because it makes it easier to do our
+    * calculations later in such a way that we state page-aigned.
+    */
+   uint32_t back_used = align_u32(pool->back_state.next, PAGE_SIZE);
+   uint32_t front_used = align_u32(pool->state.next, PAGE_SIZE);
+   uint32_t total_used = front_used + back_used;
+
+   assert(state == &pool->state || back_used > 0);
+
+   size_t old_size = pool->bo.size;
+
+   if (old_size != 0 &&
+       back_used * 2 <= pool->center_bo_offset &&
+       front_used * 2 <= (old_size - pool->center_bo_offset)) {
+      /* If we're in this case then this isn't the firsta allocation and we
+       * already have enough space on both sides to hold double what we
+       * have allocated.  There's nothing for us to do.
+       */
+      goto done;
+   }
+
+   if (old_size == 0) {
+      /* This is the first allocation */
+      size = MAX2(32 * pool->block_size, PAGE_SIZE);
+   } else {
+      size = old_size * 2;
+   }
+
+   /* We can't have a block pool bigger than 1GB because we use signed
+    * 32-bit offsets in the free list and we don't want overflow.  We
+    * should never need a block pool bigger than 1GB anyway.
+    */
+   assert(size <= (1u << 31));
+
+   /* We compute a new center_bo_offset such that, when we double the size
+    * of the pool, we maintain the ratio of how much is used by each side.
+    * This way things should remain more-or-less balanced.
+    */
+   uint32_t center_bo_offset;
+   if (back_used == 0) {
+      /* If we're in this case then we have never called alloc_back().  In
+       * this case, we want keep the offset at 0 to make things as simple
+       * as possible for users that don't care about back allocations.
+       */
+      center_bo_offset = 0;
+   } else {
+      /* Try to "center" the allocation based on how much is currently in
+       * use on each side of the center line.
+       */
+      center_bo_offset = ((uint64_t)size * back_used) / total_used;
+
+      /* Align down to a multiple of both the block size and page size */
+      uint32_t granularity = MAX2(pool->block_size, PAGE_SIZE);
+      assert(util_is_power_of_two(granularity));
+      center_bo_offset &= ~(granularity - 1);
+
+      assert(center_bo_offset >= back_used);
+
+      /* Make sure we don't shrink the back end of the pool */
+      if (center_bo_offset < pool->back_state.end)
+         center_bo_offset = pool->back_state.end;
+
+      /* Make sure that we don't shrink the front end of the pool */
+      if (size - center_bo_offset < pool->state.end)
+         center_bo_offset = size - pool->state.end;
+   }
+
+   assert(center_bo_offset % pool->block_size == 0);
+   assert(center_bo_offset % PAGE_SIZE == 0);
+
+   /* Assert that we only ever grow the pool */
+   assert(center_bo_offset >= pool->back_state.end);
+   assert(size - center_bo_offset >= pool->state.end);
+
+   cleanup = anv_vector_add(&pool->mmap_cleanups);
+   if (!cleanup)
+      goto fail;
+   *cleanup = ANV_MMAP_CLEANUP_INIT;
+
+   /* Just leak the old map until we destroy the pool.  We can't munmap it
+    * without races or imposing locking on the block allocate fast path. On
+    * the whole the leaked maps adds up to less than the size of the
+    * current map.  MAP_POPULATE seems like the right thing to do, but we
+    * should try to get some numbers.
+    */
+   map = mmap(NULL, size, PROT_READ | PROT_WRITE,
+              MAP_SHARED | MAP_POPULATE, pool->fd,
+              BLOCK_POOL_MEMFD_CENTER - center_bo_offset);
+   cleanup->map = map;
+   cleanup->size = size;
+
+   if (map == MAP_FAILED)
+      goto fail;
+
+   gem_handle = anv_gem_userptr(pool->device, map, size);
+   if (gem_handle == 0)
+      goto fail;
+   cleanup->gem_handle = gem_handle;
+
+   /* Now that we successfull allocated everything, we can write the new
+    * values back into pool. */
+   pool->map = map + center_bo_offset;
+   pool->center_bo_offset = center_bo_offset;
+   pool->bo.gem_handle = gem_handle;
+   pool->bo.size = size;
+   pool->bo.map = map;
+   pool->bo.index = 0;
+
+done:
+   pthread_mutex_unlock(&pool->device->mutex);
+
+   /* Return the appropreate new size.  This function never actually
+    * updates state->next.  Instead, we let the caller do that because it
+    * needs to do so in order to maintain its concurrency model.
+    */
+   if (state == &pool->state) {
+      return pool->bo.size - pool->center_bo_offset;
+   } else {
+      assert(pool->center_bo_offset > 0);
+      return pool->center_bo_offset;
+   }
+
+fail:
+   pthread_mutex_unlock(&pool->device->mutex);
+
+   return 0;
+}
+
+static uint32_t
+anv_block_pool_alloc_new(struct anv_block_pool *pool,
+                         struct anv_block_state *pool_state)
+{
+   struct anv_block_state state, old, new;
+
+   while (1) {
+      state.u64 = __sync_fetch_and_add(&pool_state->u64, pool->block_size);
+      if (state.next < state.end) {
+         assert(pool->map);
+         return state.next;
+      } else if (state.next == state.end) {
+         /* We allocated the first block outside the pool, we have to grow it.
+          * pool_state->next acts a mutex: threads who try to allocate now will
+          * get block indexes above the current limit and hit futex_wait
+          * below. */
+         new.next = state.next + pool->block_size;
+         new.end = anv_block_pool_grow(pool, pool_state);
+         assert(new.end >= new.next && new.end % pool->block_size == 0);
+         old.u64 = __sync_lock_test_and_set(&pool_state->u64, new.u64);
+         if (old.next != state.next)
+            futex_wake(&pool_state->end, INT_MAX);
+         return state.next;
+      } else {
+         futex_wait(&pool_state->end, state.end);
+         continue;
+      }
+   }
+}
+
+int32_t
+anv_block_pool_alloc(struct anv_block_pool *pool)
+{
+   int32_t offset;
+
+   /* Try free list first. */
+   if (anv_free_list_pop(&pool->free_list, &pool->map, &offset)) {
+      assert(offset >= 0);
+      assert(pool->map);
+      return offset;
+   }
+
+   return anv_block_pool_alloc_new(pool, &pool->state);
+}
+
+/* Allocates a block out of the back of the block pool.
+ *
+ * This will allocated a block earlier than the "start" of the block pool.
+ * The offsets returned from this function will be negative but will still
+ * be correct relative to the block pool's map pointer.
+ *
+ * If you ever use anv_block_pool_alloc_back, then you will have to do
+ * gymnastics with the block pool's BO when doing relocations.
+ */
+int32_t
+anv_block_pool_alloc_back(struct anv_block_pool *pool)
+{
+   int32_t offset;
+
+   /* Try free list first. */
+   if (anv_free_list_pop(&pool->back_free_list, &pool->map, &offset)) {
+      assert(offset < 0);
+      assert(pool->map);
+      return offset;
+   }
+
+   offset = anv_block_pool_alloc_new(pool, &pool->back_state);
+
+   /* The offset we get out of anv_block_pool_alloc_new() is actually the
+    * number of bytes downwards from the middle to the end of the block.
+    * We need to turn it into a (negative) offset from the middle to the
+    * start of the block.
+    */
+   assert(offset >= 0);
+   return -(offset + pool->block_size);
+}
+
+void
+anv_block_pool_free(struct anv_block_pool *pool, int32_t offset)
+{
+   if (offset < 0) {
+      anv_free_list_push(&pool->back_free_list, pool->map, offset);
+   } else {
+      anv_free_list_push(&pool->free_list, pool->map, offset);
+   }
+}
+
+static void
+anv_fixed_size_state_pool_init(struct anv_fixed_size_state_pool *pool,
+                               size_t state_size)
+{
+   /* At least a cache line and must divide the block size. */
+   assert(state_size >= 64 && util_is_power_of_two(state_size));
+
+   pool->state_size = state_size;
+   pool->free_list = ANV_FREE_LIST_EMPTY;
+   pool->block.next = 0;
+   pool->block.end = 0;
+}
+
+static uint32_t
+anv_fixed_size_state_pool_alloc(struct anv_fixed_size_state_pool *pool,
+                                struct anv_block_pool *block_pool)
+{
+   int32_t offset;
+   struct anv_block_state block, old, new;
+
+   /* Try free list first. */
+   if (anv_free_list_pop(&pool->free_list, &block_pool->map, &offset)) {
+      assert(offset >= 0);
+      return offset;
+   }
+
+   /* If free list was empty (or somebody raced us and took the items) we
+    * allocate a new item from the end of the block */
+ restart:
+   block.u64 = __sync_fetch_and_add(&pool->block.u64, pool->state_size);
+
+   if (block.next < block.end) {
+      return block.next;
+   } else if (block.next == block.end) {
+      offset = anv_block_pool_alloc(block_pool);
+      new.next = offset + pool->state_size;
+      new.end = offset + block_pool->block_size;
+      old.u64 = __sync_lock_test_and_set(&pool->block.u64, new.u64);
+      if (old.next != block.next)
+         futex_wake(&pool->block.end, INT_MAX);
+      return offset;
+   } else {
+      futex_wait(&pool->block.end, block.end);
+      goto restart;
+   }
+}
+
+static void
+anv_fixed_size_state_pool_free(struct anv_fixed_size_state_pool *pool,
+                               struct anv_block_pool *block_pool,
+                               uint32_t offset)
+{
+   anv_free_list_push(&pool->free_list, block_pool->map, offset);
+}
+
+void
+anv_state_pool_init(struct anv_state_pool *pool,
+                    struct anv_block_pool *block_pool)
+{
+   pool->block_pool = block_pool;
+   for (unsigned i = 0; i < ANV_STATE_BUCKETS; i++) {
+      size_t size = 1 << (ANV_MIN_STATE_SIZE_LOG2 + i);
+      anv_fixed_size_state_pool_init(&pool->buckets[i], size);
+   }
+   VG(VALGRIND_CREATE_MEMPOOL(pool, 0, false));
+}
+
+void
+anv_state_pool_finish(struct anv_state_pool *pool)
+{
+   VG(VALGRIND_DESTROY_MEMPOOL(pool));
+}
+
+struct anv_state
+anv_state_pool_alloc(struct anv_state_pool *pool, size_t size, size_t align)
+{
+   unsigned size_log2 = ilog2_round_up(size < align ? align : size);
+   assert(size_log2 <= ANV_MAX_STATE_SIZE_LOG2);
+   if (size_log2 < ANV_MIN_STATE_SIZE_LOG2)
+      size_log2 = ANV_MIN_STATE_SIZE_LOG2;
+   unsigned bucket = size_log2 - ANV_MIN_STATE_SIZE_LOG2;
+
+   struct anv_state state;
+   state.alloc_size = 1 << size_log2;
+   state.offset = anv_fixed_size_state_pool_alloc(&pool->buckets[bucket],
+                                                  pool->block_pool);
+   state.map = pool->block_pool->map + state.offset;
+   VG(VALGRIND_MEMPOOL_ALLOC(pool, state.map, size));
+   return state;
+}
+
+void
+anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state)
+{
+   assert(util_is_power_of_two(state.alloc_size));
+   unsigned size_log2 = ilog2_round_up(state.alloc_size);
+   assert(size_log2 >= ANV_MIN_STATE_SIZE_LOG2 &&
+          size_log2 <= ANV_MAX_STATE_SIZE_LOG2);
+   unsigned bucket = size_log2 - ANV_MIN_STATE_SIZE_LOG2;
+
+   VG(VALGRIND_MEMPOOL_FREE(pool, state.map));
+   anv_fixed_size_state_pool_free(&pool->buckets[bucket],
+                                  pool->block_pool, state.offset);
+}
+
+#define NULL_BLOCK 1
+struct stream_block {
+   uint32_t next;
+
+   /* The map for the BO at the time the block was givne to us */
+   void *current_map;
+
+#ifdef HAVE_VALGRIND
+   void *_vg_ptr;
+#endif
+};
+
+/* The state stream allocator is a one-shot, single threaded allocator for
+ * variable sized blocks.  We use it for allocating dynamic state.
+ */
+void
+anv_state_stream_init(struct anv_state_stream *stream,
+                      struct anv_block_pool *block_pool)
+{
+   stream->block_pool = block_pool;
+   stream->next = 0;
+   stream->end = 0;
+   stream->current_block = NULL_BLOCK;
+
+   VG(VALGRIND_CREATE_MEMPOOL(stream, 0, false));
+}
+
+void
+anv_state_stream_finish(struct anv_state_stream *stream)
+{
+   struct stream_block *sb;
+   uint32_t block, next_block;
+
+   block = stream->current_block;
+   while (block != NULL_BLOCK) {
+      assert(block % stream->block_pool->block_size == 0);
+      sb = stream->block_pool->map + block;
+      next_block = VG_NOACCESS_READ(&sb->next);
+      VG(VALGRIND_MEMPOOL_FREE(stream, VG_NOACCESS_READ(&sb->_vg_ptr)));
+      anv_block_pool_free(stream->block_pool, block);
+      block = next_block;
+   }
+
+   VG(VALGRIND_DESTROY_MEMPOOL(stream));
+}
+
+struct anv_state
+anv_state_stream_alloc(struct anv_state_stream *stream,
+                       uint32_t size, uint32_t alignment)
+{
+   struct stream_block *sb;
+   struct anv_state state;
+   uint32_t block;
+
+   state.offset = align_u32(stream->next, alignment);
+   if (state.offset + size > stream->end) {
+      block = anv_block_pool_alloc(stream->block_pool);
+      void *current_map = stream->block_pool->map;
+      sb = current_map + block;
+      VG_NOACCESS_WRITE(&sb->current_map, current_map);
+      VG_NOACCESS_WRITE(&sb->next, stream->current_block);
+      VG(VG_NOACCESS_WRITE(&sb->_vg_ptr, 0));
+      stream->current_block = block;
+      stream->next = block + sizeof(*sb);
+      stream->end = block + stream->block_pool->block_size;
+      state.offset = align_u32(stream->next, alignment);
+      assert(state.offset + size <= stream->end);
+   }
+
+   sb = stream->block_pool->map + stream->current_block;
+   void *current_map = VG_NOACCESS_READ(&sb->current_map);
+
+   state.map = current_map + state.offset;
+   state.alloc_size = size;
+
+#ifdef HAVE_VALGRIND
+   void *vg_ptr = VG_NOACCESS_READ(&sb->_vg_ptr);
+   if (vg_ptr == NULL) {
+      vg_ptr = state.map;
+      VG_NOACCESS_WRITE(&sb->_vg_ptr, vg_ptr);
+      VALGRIND_MEMPOOL_ALLOC(stream, vg_ptr, size);
+   } else {
+      ptrdiff_t vg_offset = vg_ptr - current_map;
+      assert(vg_offset >= stream->current_block &&
+             vg_offset < stream->end);
+      VALGRIND_MEMPOOL_CHANGE(stream, vg_ptr, vg_ptr,
+                              (state.offset + size) - vg_offset);
+   }
+#endif
+
+   stream->next = state.offset + size;
+
+   return state;
+}
+
+struct bo_pool_bo_link {
+   struct bo_pool_bo_link *next;
+   struct anv_bo bo;
+};
+
+void
+anv_bo_pool_init(struct anv_bo_pool *pool,
+                 struct anv_device *device, uint32_t bo_size)
+{
+   pool->device = device;
+   pool->bo_size = bo_size;
+   pool->free_list = NULL;
+
+   VG(VALGRIND_CREATE_MEMPOOL(pool, 0, false));
+}
+
+void
+anv_bo_pool_finish(struct anv_bo_pool *pool)
+{
+   struct bo_pool_bo_link *link = PFL_PTR(pool->free_list);
+   while (link != NULL) {
+      struct bo_pool_bo_link link_copy = VG_NOACCESS_READ(link);
+
+      anv_gem_munmap(link_copy.bo.map, pool->bo_size);
+      anv_gem_close(pool->device, link_copy.bo.gem_handle);
+      link = link_copy.next;
+   }
+
+   VG(VALGRIND_DESTROY_MEMPOOL(pool));
+}
+
+VkResult
+anv_bo_pool_alloc(struct anv_bo_pool *pool, struct anv_bo *bo)
+{
+   VkResult result;
+
+   void *next_free_void;
+   if (anv_ptr_free_list_pop(&pool->free_list, &next_free_void)) {
+      struct bo_pool_bo_link *next_free = next_free_void;
+      *bo = VG_NOACCESS_READ(&next_free->bo);
+      assert(bo->map == next_free);
+      assert(bo->size == pool->bo_size);
+
+      VG(VALGRIND_MEMPOOL_ALLOC(pool, bo->map, pool->bo_size));
+
+      return VK_SUCCESS;
+   }
+
+   struct anv_bo new_bo;
+
+   result = anv_bo_init_new(&new_bo, pool->device, pool->bo_size);
+   if (result != VK_SUCCESS)
+      return result;
+
+   assert(new_bo.size == pool->bo_size);
+
+   new_bo.map = anv_gem_mmap(pool->device, new_bo.gem_handle, 0, pool->bo_size);
+   if (new_bo.map == NULL) {
+      anv_gem_close(pool->device, new_bo.gem_handle);
+      return vk_error(VK_ERROR_MEMORY_MAP_FAILED);
+   }
+
+   *bo = new_bo;
+
+   VG(VALGRIND_MEMPOOL_ALLOC(pool, bo->map, pool->bo_size));
+
+   return VK_SUCCESS;
+}
+
+void
+anv_bo_pool_free(struct anv_bo_pool *pool, const struct anv_bo *bo)
+{
+   struct bo_pool_bo_link *link = bo->map;
+   link->bo = *bo;
+
+   VG(VALGRIND_MEMPOOL_FREE(pool, bo->map));
+   anv_ptr_free_list_push(&pool->free_list, link);
+}
diff --git a/src/vulkan/anv_aub.h b/src/vulkan/anv_aub.h
new file mode 100644 (file)
index 0000000..7a67712
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Authors:
+ *    Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file intel_aub.h
+ *
+ * The AUB file is a file format used by Intel's internal simulation
+ * and other validation tools.  It can be used at various levels by a
+ * driver to input state to the simulated hardware or a replaying
+ * debugger.
+ *
+ * We choose to dump AUB files using the trace block format for ease
+ * of implementation -- dump out the blocks of memory as plain blobs
+ * and insert ring commands to execute the batchbuffer blob.
+ */
+
+#ifndef _INTEL_AUB_H
+#define _INTEL_AUB_H
+
+#define AUB_MI_NOOP                    (0)
+#define AUB_MI_BATCH_BUFFER_START      (0x31 << 23)
+#define AUB_PIPE_CONTROL               (0x7a000002)
+
+/* DW0: instruction type. */
+
+#define CMD_AUB                        (7 << 29)
+
+#define CMD_AUB_HEADER         (CMD_AUB | (1 << 23) | (0x05 << 16))
+/* DW1 */
+# define AUB_HEADER_MAJOR_SHIFT                24
+# define AUB_HEADER_MINOR_SHIFT                16
+
+#define CMD_AUB_TRACE_HEADER_BLOCK (CMD_AUB | (1 << 23) | (0x41 << 16))
+#define CMD_AUB_DUMP_BMP           (CMD_AUB | (1 << 23) | (0x9e << 16))
+
+/* DW1 */
+#define AUB_TRACE_OPERATION_MASK       0x000000ff
+#define AUB_TRACE_OP_COMMENT           0x00000000
+#define AUB_TRACE_OP_DATA_WRITE                0x00000001
+#define AUB_TRACE_OP_COMMAND_WRITE     0x00000002
+#define AUB_TRACE_OP_MMIO_WRITE                0x00000003
+// operation = TRACE_DATA_WRITE, Type
+#define AUB_TRACE_TYPE_MASK            0x0000ff00
+#define AUB_TRACE_TYPE_NOTYPE          (0 << 8)
+#define AUB_TRACE_TYPE_BATCH           (1 << 8)
+#define AUB_TRACE_TYPE_VERTEX_BUFFER   (5 << 8)
+#define AUB_TRACE_TYPE_2D_MAP          (6 << 8)
+#define AUB_TRACE_TYPE_CUBE_MAP                (7 << 8)
+#define AUB_TRACE_TYPE_VOLUME_MAP      (9 << 8)
+#define AUB_TRACE_TYPE_1D_MAP          (10 << 8)
+#define AUB_TRACE_TYPE_CONSTANT_BUFFER (11 << 8)
+#define AUB_TRACE_TYPE_CONSTANT_URB    (12 << 8)
+#define AUB_TRACE_TYPE_INDEX_BUFFER    (13 << 8)
+#define AUB_TRACE_TYPE_GENERAL         (14 << 8)
+#define AUB_TRACE_TYPE_SURFACE         (15 << 8)
+
+
+// operation = TRACE_COMMAND_WRITE, Type =
+#define AUB_TRACE_TYPE_RING_HWB                (1 << 8)
+#define AUB_TRACE_TYPE_RING_PRB0       (2 << 8)
+#define AUB_TRACE_TYPE_RING_PRB1       (3 << 8)
+#define AUB_TRACE_TYPE_RING_PRB2       (4 << 8)
+
+// Address space
+#define AUB_TRACE_ADDRESS_SPACE_MASK   0x00ff0000
+#define AUB_TRACE_MEMTYPE_GTT          (0 << 16)
+#define AUB_TRACE_MEMTYPE_LOCAL                (1 << 16)
+#define AUB_TRACE_MEMTYPE_NONLOCAL     (2 << 16)
+#define AUB_TRACE_MEMTYPE_PCI          (3 << 16)
+#define AUB_TRACE_MEMTYPE_GTT_ENTRY     (4 << 16)
+
+/* DW2 */
+
+/**
+ * aub_state_struct_type enum values are encoded with the top 16 bits
+ * representing the type to be delivered to the .aub file, and the bottom 16
+ * bits representing the subtype.  This macro performs the encoding.
+ */
+#define ENCODE_SS_TYPE(type, subtype) (((type) << 16) | (subtype))
+
+enum aub_state_struct_type {
+   AUB_TRACE_VS_STATE =                        ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 1),
+   AUB_TRACE_GS_STATE =                        ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 2),
+   AUB_TRACE_CLIP_STATE =              ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 3),
+   AUB_TRACE_SF_STATE =                        ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 4),
+   AUB_TRACE_WM_STATE =                        ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 5),
+   AUB_TRACE_CC_STATE =                        ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 6),
+   AUB_TRACE_CLIP_VP_STATE =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 7),
+   AUB_TRACE_SF_VP_STATE =             ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 8),
+   AUB_TRACE_CC_VP_STATE =             ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0x9),
+   AUB_TRACE_SAMPLER_STATE =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0xa),
+   AUB_TRACE_KERNEL_INSTRUCTIONS =     ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0xb),
+   AUB_TRACE_SCRATCH_SPACE =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0xc),
+   AUB_TRACE_SAMPLER_DEFAULT_COLOR =   ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0xd),
+
+   AUB_TRACE_SCISSOR_STATE =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0x15),
+   AUB_TRACE_BLEND_STATE =             ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0x16),
+   AUB_TRACE_DEPTH_STENCIL_STATE =     ENCODE_SS_TYPE(AUB_TRACE_TYPE_GENERAL, 0x17),
+
+   AUB_TRACE_VERTEX_BUFFER =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_VERTEX_BUFFER, 0),
+   AUB_TRACE_BINDING_TABLE =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_SURFACE, 0x100),
+   AUB_TRACE_SURFACE_STATE =           ENCODE_SS_TYPE(AUB_TRACE_TYPE_SURFACE, 0x200),
+   AUB_TRACE_VS_CONSTANTS =            ENCODE_SS_TYPE(AUB_TRACE_TYPE_CONSTANT_BUFFER, 0),
+   AUB_TRACE_WM_CONSTANTS =            ENCODE_SS_TYPE(AUB_TRACE_TYPE_CONSTANT_BUFFER, 1),
+};
+
+#undef ENCODE_SS_TYPE
+
+/**
+ * Decode a aub_state_struct_type value to determine the type that should be
+ * stored in the .aub file.
+ */
+static inline uint32_t AUB_TRACE_TYPE(enum aub_state_struct_type ss_type)
+{
+   return (ss_type & 0xFFFF0000) >> 16;
+}
+
+/**
+ * Decode a state_struct_type value to determine the subtype that should be
+ * stored in the .aub file.
+ */
+static inline uint32_t AUB_TRACE_SUBTYPE(enum aub_state_struct_type ss_type)
+{
+   return ss_type & 0xFFFF;
+}
+
+/* DW3: address */
+/* DW4: len */
+
+#endif /* _INTEL_AUB_H */
diff --git a/src/vulkan/anv_batch_chain.c b/src/vulkan/anv_batch_chain.c
new file mode 100644 (file)
index 0000000..2391497
--- /dev/null
@@ -0,0 +1,1005 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+/** \file anv_batch_chain.c
+ *
+ * This file contains functions related to anv_cmd_buffer as a data
+ * structure.  This involves everything required to create and destroy
+ * the actual batch buffers as well as link them together and handle
+ * relocations and surface state.  It specifically does *not* contain any
+ * handling of actual vkCmd calls beyond vkCmdExecuteCommands.
+ */
+
+/*-----------------------------------------------------------------------*
+ * Functions related to anv_reloc_list
+ *-----------------------------------------------------------------------*/
+
+static VkResult
+anv_reloc_list_init_clone(struct anv_reloc_list *list,
+                          struct anv_device *device,
+                          const struct anv_reloc_list *other_list)
+{
+   if (other_list) {
+      list->num_relocs = other_list->num_relocs;
+      list->array_length = other_list->array_length;
+   } else {
+      list->num_relocs = 0;
+      list->array_length = 256;
+   }
+
+   list->relocs =
+      anv_device_alloc(device, list->array_length * sizeof(*list->relocs), 8,
+                       VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+
+   if (list->relocs == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   list->reloc_bos =
+      anv_device_alloc(device, list->array_length * sizeof(*list->reloc_bos), 8,
+                       VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+
+   if (list->reloc_bos == NULL) {
+      anv_device_free(device, list->relocs);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+
+   if (other_list) {
+      memcpy(list->relocs, other_list->relocs,
+             list->array_length * sizeof(*list->relocs));
+      memcpy(list->reloc_bos, other_list->reloc_bos,
+             list->array_length * sizeof(*list->reloc_bos));
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_reloc_list_init(struct anv_reloc_list *list, struct anv_device *device)
+{
+   return anv_reloc_list_init_clone(list, device, NULL);
+}
+
+void
+anv_reloc_list_finish(struct anv_reloc_list *list, struct anv_device *device)
+{
+   anv_device_free(device, list->relocs);
+   anv_device_free(device, list->reloc_bos);
+}
+
+static VkResult
+anv_reloc_list_grow(struct anv_reloc_list *list, struct anv_device *device,
+                    size_t num_additional_relocs)
+{
+   if (list->num_relocs + num_additional_relocs <= list->array_length)
+      return VK_SUCCESS;
+
+   size_t new_length = list->array_length * 2;
+   while (new_length < list->num_relocs + num_additional_relocs)
+      new_length *= 2;
+
+   struct drm_i915_gem_relocation_entry *new_relocs =
+      anv_device_alloc(device, new_length * sizeof(*list->relocs), 8,
+                       VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (new_relocs == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct anv_bo **new_reloc_bos =
+      anv_device_alloc(device, new_length * sizeof(*list->reloc_bos), 8,
+                       VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (new_relocs == NULL) {
+      anv_device_free(device, new_relocs);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+
+   memcpy(new_relocs, list->relocs, list->num_relocs * sizeof(*list->relocs));
+   memcpy(new_reloc_bos, list->reloc_bos,
+          list->num_relocs * sizeof(*list->reloc_bos));
+
+   anv_device_free(device, list->relocs);
+   anv_device_free(device, list->reloc_bos);
+
+   list->array_length = new_length;
+   list->relocs = new_relocs;
+   list->reloc_bos = new_reloc_bos;
+
+   return VK_SUCCESS;
+}
+
+uint64_t
+anv_reloc_list_add(struct anv_reloc_list *list, struct anv_device *device,
+                   uint32_t offset, struct anv_bo *target_bo, uint32_t delta)
+{
+   struct drm_i915_gem_relocation_entry *entry;
+   int index;
+
+   anv_reloc_list_grow(list, device, 1);
+   /* TODO: Handle failure */
+
+   /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
+   index = list->num_relocs++;
+   list->reloc_bos[index] = target_bo;
+   entry = &list->relocs[index];
+   entry->target_handle = target_bo->gem_handle;
+   entry->delta = delta;
+   entry->offset = offset;
+   entry->presumed_offset = target_bo->offset;
+   entry->read_domains = 0;
+   entry->write_domain = 0;
+
+   return target_bo->offset + delta;
+}
+
+static void
+anv_reloc_list_append(struct anv_reloc_list *list, struct anv_device *device,
+                      struct anv_reloc_list *other, uint32_t offset)
+{
+   anv_reloc_list_grow(list, device, other->num_relocs);
+   /* TODO: Handle failure */
+
+   memcpy(&list->relocs[list->num_relocs], &other->relocs[0],
+          other->num_relocs * sizeof(other->relocs[0]));
+   memcpy(&list->reloc_bos[list->num_relocs], &other->reloc_bos[0],
+          other->num_relocs * sizeof(other->reloc_bos[0]));
+
+   for (uint32_t i = 0; i < other->num_relocs; i++)
+      list->relocs[i + list->num_relocs].offset += offset;
+
+   list->num_relocs += other->num_relocs;
+}
+
+/*-----------------------------------------------------------------------*
+ * Functions related to anv_batch
+ *-----------------------------------------------------------------------*/
+
+void *
+anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
+{
+   if (batch->next + num_dwords * 4 > batch->end)
+      batch->extend_cb(batch, batch->user_data);
+
+   void *p = batch->next;
+
+   batch->next += num_dwords * 4;
+   assert(batch->next <= batch->end);
+
+   return p;
+}
+
+uint64_t
+anv_batch_emit_reloc(struct anv_batch *batch,
+                     void *location, struct anv_bo *bo, uint32_t delta)
+{
+   return anv_reloc_list_add(batch->relocs, batch->device,
+                             location - batch->start, bo, delta);
+}
+
+void
+anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other)
+{
+   uint32_t size, offset;
+
+   size = other->next - other->start;
+   assert(size % 4 == 0);
+
+   if (batch->next + size > batch->end)
+      batch->extend_cb(batch, batch->user_data);
+
+   assert(batch->next + size <= batch->end);
+
+   VG(VALGRIND_CHECK_MEM_IS_DEFINED(other->start, size));
+   memcpy(batch->next, other->start, size);
+
+   offset = batch->next - batch->start;
+   anv_reloc_list_append(batch->relocs, batch->device,
+                         other->relocs, offset);
+
+   batch->next += size;
+}
+
+/*-----------------------------------------------------------------------*
+ * Functions related to anv_batch_bo
+ *-----------------------------------------------------------------------*/
+
+static VkResult
+anv_batch_bo_create(struct anv_device *device, struct anv_batch_bo **bbo_out)
+{
+   VkResult result;
+
+   struct anv_batch_bo *bbo =
+      anv_device_alloc(device, sizeof(*bbo), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (bbo == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   result = anv_bo_pool_alloc(&device->batch_bo_pool, &bbo->bo);
+   if (result != VK_SUCCESS)
+      goto fail_alloc;
+
+   result = anv_reloc_list_init(&bbo->relocs, device);
+   if (result != VK_SUCCESS)
+      goto fail_bo_alloc;
+
+   *bbo_out = bbo;
+
+   return VK_SUCCESS;
+
+ fail_bo_alloc:
+   anv_bo_pool_free(&device->batch_bo_pool, &bbo->bo);
+ fail_alloc:
+   anv_device_free(device, bbo);
+
+   return result;
+}
+
+static VkResult
+anv_batch_bo_clone(struct anv_device *device,
+                   const struct anv_batch_bo *other_bbo,
+                   struct anv_batch_bo **bbo_out)
+{
+   VkResult result;
+
+   struct anv_batch_bo *bbo =
+      anv_device_alloc(device, sizeof(*bbo), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (bbo == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   result = anv_bo_pool_alloc(&device->batch_bo_pool, &bbo->bo);
+   if (result != VK_SUCCESS)
+      goto fail_alloc;
+
+   result = anv_reloc_list_init_clone(&bbo->relocs, device, &other_bbo->relocs);
+   if (result != VK_SUCCESS)
+      goto fail_bo_alloc;
+
+   bbo->length = other_bbo->length;
+   memcpy(bbo->bo.map, other_bbo->bo.map, other_bbo->length);
+
+   bbo->last_ss_pool_bo_offset = other_bbo->last_ss_pool_bo_offset;
+
+   *bbo_out = bbo;
+
+   return VK_SUCCESS;
+
+ fail_bo_alloc:
+   anv_bo_pool_free(&device->batch_bo_pool, &bbo->bo);
+ fail_alloc:
+   anv_device_free(device, bbo);
+
+   return result;
+}
+
+static void
+anv_batch_bo_start(struct anv_batch_bo *bbo, struct anv_batch *batch,
+                   size_t batch_padding)
+{
+   batch->next = batch->start = bbo->bo.map;
+   batch->end = bbo->bo.map + bbo->bo.size - batch_padding;
+   batch->relocs = &bbo->relocs;
+   bbo->last_ss_pool_bo_offset = 0;
+   bbo->relocs.num_relocs = 0;
+}
+
+static void
+anv_batch_bo_continue(struct anv_batch_bo *bbo, struct anv_batch *batch,
+                      size_t batch_padding)
+{
+   batch->start = bbo->bo.map;
+   batch->next = bbo->bo.map + bbo->length;
+   batch->end = bbo->bo.map + bbo->bo.size - batch_padding;
+   batch->relocs = &bbo->relocs;
+}
+
+static void
+anv_batch_bo_finish(struct anv_batch_bo *bbo, struct anv_batch *batch)
+{
+   assert(batch->start == bbo->bo.map);
+   bbo->length = batch->next - batch->start;
+   VG(VALGRIND_CHECK_MEM_IS_DEFINED(batch->start, bbo->length));
+}
+
+static void
+anv_batch_bo_destroy(struct anv_batch_bo *bbo, struct anv_device *device)
+{
+   anv_reloc_list_finish(&bbo->relocs, device);
+   anv_bo_pool_free(&device->batch_bo_pool, &bbo->bo);
+   anv_device_free(device, bbo);
+}
+
+static VkResult
+anv_batch_bo_list_clone(const struct list_head *list, struct anv_device *device,
+                        struct list_head *new_list)
+{
+   VkResult result = VK_SUCCESS;
+
+   list_inithead(new_list);
+
+   struct anv_batch_bo *prev_bbo = NULL;
+   list_for_each_entry(struct anv_batch_bo, bbo, list, link) {
+      struct anv_batch_bo *new_bbo;
+      result = anv_batch_bo_clone(device, bbo, &new_bbo);
+      if (result != VK_SUCCESS)
+         break;
+      list_addtail(&new_bbo->link, new_list);
+
+      if (prev_bbo) {
+         /* As we clone this list of batch_bo's, they chain one to the
+          * other using MI_BATCH_BUFFER_START commands.  We need to fix up
+          * those relocations as we go.  Fortunately, this is pretty easy
+          * as it will always be the last relocation in the list.
+          */
+         uint32_t last_idx = prev_bbo->relocs.num_relocs - 1;
+         assert(prev_bbo->relocs.reloc_bos[last_idx] == &bbo->bo);
+         prev_bbo->relocs.reloc_bos[last_idx] = &new_bbo->bo;
+      }
+
+      prev_bbo = new_bbo;
+   }
+
+   if (result != VK_SUCCESS) {
+      list_for_each_entry_safe(struct anv_batch_bo, bbo, new_list, link)
+         anv_batch_bo_destroy(bbo, device);
+   }
+
+   return result;
+}
+
+/*-----------------------------------------------------------------------*
+ * Functions related to anv_batch_bo
+ *-----------------------------------------------------------------------*/
+
+static inline struct anv_batch_bo *
+anv_cmd_buffer_current_batch_bo(struct anv_cmd_buffer *cmd_buffer)
+{
+   return LIST_ENTRY(struct anv_batch_bo, cmd_buffer->batch_bos.prev, link);
+}
+
+struct anv_address
+anv_cmd_buffer_surface_base_address(struct anv_cmd_buffer *cmd_buffer)
+{
+   return (struct anv_address) {
+      .bo = &cmd_buffer->device->surface_state_block_pool.bo,
+      .offset = *(int32_t *)anv_vector_head(&cmd_buffer->bt_blocks),
+   };
+}
+
+static void
+emit_batch_buffer_start(struct anv_batch *batch, struct anv_bo *bo, uint32_t offset)
+{
+   /* In gen8+ the address field grew to two dwords to accomodate 48 bit
+    * offsets. The high 16 bits are in the last dword, so we can use the gen8
+    * version in either case, as long as we set the instruction length in the
+    * header accordingly.  This means that we always emit three dwords here
+    * and all the padding and adjustment we do in this file works for all
+    * gens.
+    */
+
+   const uint32_t gen7_length =
+      GEN7_MI_BATCH_BUFFER_START_length - GEN7_MI_BATCH_BUFFER_START_length_bias;
+   const uint32_t gen8_length =
+      GEN8_MI_BATCH_BUFFER_START_length - GEN8_MI_BATCH_BUFFER_START_length_bias;
+
+   anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_START,
+      .DwordLength = batch->device->info.gen < 8 ? gen7_length : gen8_length,
+      ._2ndLevelBatchBuffer = _1stlevelbatch,
+      .AddressSpaceIndicator = ASI_PPGTT,
+      .BatchBufferStartAddress = { bo, offset });
+}
+
+static void
+cmd_buffer_chain_to_batch_bo(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_batch_bo *bbo)
+{
+   struct anv_batch *batch = &cmd_buffer->batch;
+   struct anv_batch_bo *current_bbo =
+      anv_cmd_buffer_current_batch_bo(cmd_buffer);
+
+   /* We set the end of the batch a little short so we would be sure we
+    * have room for the chaining command.  Since we're about to emit the
+    * chaining command, let's set it back where it should go.
+    */
+   batch->end += GEN8_MI_BATCH_BUFFER_START_length * 4;
+   assert(batch->end == current_bbo->bo.map + current_bbo->bo.size);
+
+   emit_batch_buffer_start(batch, &bbo->bo, 0);
+
+   anv_batch_bo_finish(current_bbo, batch);
+}
+
+static VkResult
+anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
+{
+   struct anv_cmd_buffer *cmd_buffer = _data;
+   struct anv_batch_bo *new_bbo;
+
+   VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
+   if (result != VK_SUCCESS)
+      return result;
+
+   struct anv_batch_bo **seen_bbo = anv_vector_add(&cmd_buffer->seen_bbos);
+   if (seen_bbo == NULL) {
+      anv_batch_bo_destroy(new_bbo, cmd_buffer->device);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+   *seen_bbo = new_bbo;
+
+   cmd_buffer_chain_to_batch_bo(cmd_buffer, new_bbo);
+
+   list_addtail(&new_bbo->link, &cmd_buffer->batch_bos);
+
+   anv_batch_bo_start(new_bbo, batch, GEN8_MI_BATCH_BUFFER_START_length * 4);
+
+   return VK_SUCCESS;
+}
+
+struct anv_state
+anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer,
+                                   uint32_t entries, uint32_t *state_offset)
+{
+   struct anv_block_pool *block_pool =
+       &cmd_buffer->device->surface_state_block_pool;
+   int32_t *bt_block = anv_vector_head(&cmd_buffer->bt_blocks);
+   struct anv_state state;
+
+   state.alloc_size = align_u32(entries * 4, 32);
+
+   if (cmd_buffer->bt_next + state.alloc_size > block_pool->block_size)
+      return (struct anv_state) { 0 };
+
+   state.offset = cmd_buffer->bt_next;
+   state.map = block_pool->map + *bt_block + state.offset;
+
+   cmd_buffer->bt_next += state.alloc_size;
+
+   assert(*bt_block < 0);
+   *state_offset = -(*bt_block);
+
+   return state;
+}
+
+struct anv_state
+anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   return anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
+}
+
+struct anv_state
+anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
+                                   uint32_t size, uint32_t alignment)
+{
+   return anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
+                                 size, alignment);
+}
+
+VkResult
+anv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_block_pool *block_pool =
+       &cmd_buffer->device->surface_state_block_pool;
+
+   int32_t *offset = anv_vector_add(&cmd_buffer->bt_blocks);
+   if (offset == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   *offset = anv_block_pool_alloc_back(block_pool);
+   cmd_buffer->bt_next = 0;
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_batch_bo *batch_bo;
+   struct anv_device *device = cmd_buffer->device;
+   VkResult result;
+
+   list_inithead(&cmd_buffer->batch_bos);
+
+   result = anv_batch_bo_create(device, &batch_bo);
+   if (result != VK_SUCCESS)
+      return result;
+
+   list_addtail(&batch_bo->link, &cmd_buffer->batch_bos);
+
+   cmd_buffer->batch.device = device;
+   cmd_buffer->batch.extend_cb = anv_cmd_buffer_chain_batch;
+   cmd_buffer->batch.user_data = cmd_buffer;
+
+   anv_batch_bo_start(batch_bo, &cmd_buffer->batch,
+                      GEN8_MI_BATCH_BUFFER_START_length * 4);
+
+   int success = anv_vector_init(&cmd_buffer->seen_bbos,
+                                 sizeof(struct anv_bo *),
+                                 8 * sizeof(struct anv_bo *));
+   if (!success)
+      goto fail_batch_bo;
+
+   *(struct anv_batch_bo **)anv_vector_add(&cmd_buffer->seen_bbos) = batch_bo;
+
+   success = anv_vector_init(&cmd_buffer->bt_blocks, sizeof(int32_t),
+                             8 * sizeof(int32_t));
+   if (!success)
+      goto fail_seen_bbos;
+
+   result = anv_reloc_list_init(&cmd_buffer->surface_relocs,
+                                cmd_buffer->device);
+   if (result != VK_SUCCESS)
+      goto fail_bt_blocks;
+
+   anv_cmd_buffer_new_binding_table_block(cmd_buffer);
+
+   cmd_buffer->execbuf2.objects = NULL;
+   cmd_buffer->execbuf2.bos = NULL;
+   cmd_buffer->execbuf2.array_length = 0;
+
+   return VK_SUCCESS;
+
+ fail_bt_blocks:
+   anv_vector_finish(&cmd_buffer->bt_blocks);
+ fail_seen_bbos:
+   anv_vector_finish(&cmd_buffer->seen_bbos);
+ fail_batch_bo:
+   anv_batch_bo_destroy(batch_bo, device);
+
+   return result;
+}
+
+void
+anv_cmd_buffer_fini_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+
+   int32_t *bt_block;
+   anv_vector_foreach(bt_block, &cmd_buffer->bt_blocks) {
+      anv_block_pool_free(&cmd_buffer->device->surface_state_block_pool,
+                          *bt_block);
+   }
+   anv_vector_finish(&cmd_buffer->bt_blocks);
+
+   anv_reloc_list_finish(&cmd_buffer->surface_relocs, cmd_buffer->device);
+
+   anv_vector_finish(&cmd_buffer->seen_bbos);
+
+   /* Destroy all of the batch buffers */
+   list_for_each_entry_safe(struct anv_batch_bo, bbo,
+                            &cmd_buffer->batch_bos, link) {
+      anv_batch_bo_destroy(bbo, device);
+   }
+
+   anv_device_free(device, cmd_buffer->execbuf2.objects);
+   anv_device_free(device, cmd_buffer->execbuf2.bos);
+}
+
+void
+anv_cmd_buffer_reset_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+
+   /* Delete all but the first batch bo */
+   assert(!list_empty(&cmd_buffer->batch_bos));
+   while (cmd_buffer->batch_bos.next != cmd_buffer->batch_bos.prev) {
+      struct anv_batch_bo *bbo = anv_cmd_buffer_current_batch_bo(cmd_buffer);
+      list_del(&bbo->link);
+      anv_batch_bo_destroy(bbo, device);
+   }
+   assert(!list_empty(&cmd_buffer->batch_bos));
+
+   anv_batch_bo_start(anv_cmd_buffer_current_batch_bo(cmd_buffer),
+                      &cmd_buffer->batch,
+                      GEN8_MI_BATCH_BUFFER_START_length * 4);
+
+   while (anv_vector_length(&cmd_buffer->bt_blocks) > 1) {
+      int32_t *bt_block = anv_vector_remove(&cmd_buffer->bt_blocks);
+      anv_block_pool_free(&cmd_buffer->device->surface_state_block_pool,
+                          *bt_block);
+   }
+   assert(anv_vector_length(&cmd_buffer->bt_blocks) == 1);
+   cmd_buffer->bt_next = 0;
+
+   cmd_buffer->surface_relocs.num_relocs = 0;
+
+   /* Reset the list of seen buffers */
+   cmd_buffer->seen_bbos.head = 0;
+   cmd_buffer->seen_bbos.tail = 0;
+
+   *(struct anv_batch_bo **)anv_vector_add(&cmd_buffer->seen_bbos) =
+      anv_cmd_buffer_current_batch_bo(cmd_buffer);
+}
+
+void
+anv_cmd_buffer_end_batch_buffer(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_batch_bo *batch_bo = anv_cmd_buffer_current_batch_bo(cmd_buffer);
+
+   if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_MI_BATCH_BUFFER_END);
+
+      /* Round batch up to an even number of dwords. */
+      if ((cmd_buffer->batch.next - cmd_buffer->batch.start) & 4)
+         anv_batch_emit(&cmd_buffer->batch, GEN7_MI_NOOP);
+
+      cmd_buffer->exec_mode = ANV_CMD_BUFFER_EXEC_MODE_PRIMARY;
+   }
+
+   anv_batch_bo_finish(batch_bo, &cmd_buffer->batch);
+
+   if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_SECONDARY) {
+      /* If this is a secondary command buffer, we need to determine the
+       * mode in which it will be executed with vkExecuteCommands.  We
+       * determine this statically here so that this stays in sync with the
+       * actual ExecuteCommands implementation.
+       */
+      if ((cmd_buffer->batch_bos.next == cmd_buffer->batch_bos.prev) &&
+          (anv_cmd_buffer_current_batch_bo(cmd_buffer)->length <
+           ANV_CMD_BUFFER_BATCH_SIZE / 2)) {
+         /* If the secondary has exactly one batch buffer in its list *and*
+          * that batch buffer is less than half of the maximum size, we're
+          * probably better of simply copying it into our batch.
+          */
+         cmd_buffer->exec_mode = ANV_CMD_BUFFER_EXEC_MODE_EMIT;
+      } else if (cmd_buffer->opt_flags &
+                 VK_CMD_BUFFER_OPTIMIZE_NO_SIMULTANEOUS_USE_BIT) {
+         cmd_buffer->exec_mode = ANV_CMD_BUFFER_EXEC_MODE_CHAIN;
+
+         /* When we chain, we need to add an MI_BATCH_BUFFER_START command
+          * with its relocation.  In order to handle this we'll increment here
+          * so we can unconditionally decrement right before adding the
+          * MI_BATCH_BUFFER_START command.
+          */
+         anv_cmd_buffer_current_batch_bo(cmd_buffer)->relocs.num_relocs++;
+         cmd_buffer->batch.next += GEN8_MI_BATCH_BUFFER_START_length * 4;
+      } else {
+         cmd_buffer->exec_mode = ANV_CMD_BUFFER_EXEC_MODE_COPY_AND_CHAIN;
+      }
+   }
+}
+
+static inline VkResult
+anv_cmd_buffer_add_seen_bbos(struct anv_cmd_buffer *cmd_buffer,
+                             struct list_head *list)
+{
+   list_for_each_entry(struct anv_batch_bo, bbo, list, link) {
+      struct anv_batch_bo **bbo_ptr = anv_vector_add(&cmd_buffer->seen_bbos);
+      if (bbo_ptr == NULL)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+      *bbo_ptr = bbo;
+   }
+
+   return VK_SUCCESS;
+}
+
+void
+anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
+                             struct anv_cmd_buffer *secondary)
+{
+   switch (secondary->exec_mode) {
+   case ANV_CMD_BUFFER_EXEC_MODE_EMIT:
+      anv_batch_emit_batch(&primary->batch, &secondary->batch);
+      break;
+   case ANV_CMD_BUFFER_EXEC_MODE_CHAIN: {
+      struct anv_batch_bo *first_bbo =
+         list_first_entry(&secondary->batch_bos, struct anv_batch_bo, link);
+      struct anv_batch_bo *last_bbo =
+         list_last_entry(&secondary->batch_bos, struct anv_batch_bo, link);
+
+      emit_batch_buffer_start(&primary->batch, &first_bbo->bo, 0);
+
+      struct anv_batch_bo *this_bbo = anv_cmd_buffer_current_batch_bo(primary);
+      assert(primary->batch.start == this_bbo->bo.map);
+      uint32_t offset = primary->batch.next - primary->batch.start;
+
+      /* Roll back the previous MI_BATCH_BUFFER_START and its relocation so we
+       * can emit a new command and relocation for the current splice.  In
+       * order to handle the initial-use case, we incremented next and
+       * num_relocs in end_batch_buffer() so we can alyways just subtract
+       * here.
+       */
+      last_bbo->relocs.num_relocs--;
+      secondary->batch.next -= GEN8_MI_BATCH_BUFFER_START_length * 4;
+      emit_batch_buffer_start(&secondary->batch, &this_bbo->bo, offset);
+      anv_cmd_buffer_add_seen_bbos(primary, &secondary->batch_bos);
+      break;
+   }
+   case ANV_CMD_BUFFER_EXEC_MODE_COPY_AND_CHAIN: {
+      struct list_head copy_list;
+      VkResult result = anv_batch_bo_list_clone(&secondary->batch_bos,
+                                                secondary->device,
+                                                &copy_list);
+      if (result != VK_SUCCESS)
+         return; /* FIXME */
+
+      anv_cmd_buffer_add_seen_bbos(primary, &copy_list);
+
+      struct anv_batch_bo *first_bbo =
+         list_first_entry(&copy_list, struct anv_batch_bo, link);
+      struct anv_batch_bo *last_bbo =
+         list_last_entry(&copy_list, struct anv_batch_bo, link);
+
+      cmd_buffer_chain_to_batch_bo(primary, first_bbo);
+
+      list_splicetail(&copy_list, &primary->batch_bos);
+
+      anv_batch_bo_continue(last_bbo, &primary->batch,
+                            GEN8_MI_BATCH_BUFFER_START_length * 4);
+
+      anv_cmd_buffer_emit_state_base_address(primary);
+      break;
+   }
+   default:
+      assert(!"Invalid execution mode");
+   }
+
+   anv_reloc_list_append(&primary->surface_relocs, primary->device,
+                         &secondary->surface_relocs, 0);
+}
+
+static VkResult
+anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
+                      struct anv_bo *bo,
+                      struct anv_reloc_list *relocs)
+{
+   struct drm_i915_gem_exec_object2 *obj = NULL;
+
+   if (bo->index < cmd_buffer->execbuf2.bo_count &&
+       cmd_buffer->execbuf2.bos[bo->index] == bo)
+      obj = &cmd_buffer->execbuf2.objects[bo->index];
+
+   if (obj == NULL) {
+      /* We've never seen this one before.  Add it to the list and assign
+       * an id that we can use later.
+       */
+      if (cmd_buffer->execbuf2.bo_count >= cmd_buffer->execbuf2.array_length) {
+         uint32_t new_len = cmd_buffer->execbuf2.objects ?
+                            cmd_buffer->execbuf2.array_length * 2 : 64;
+
+         struct drm_i915_gem_exec_object2 *new_objects =
+            anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_objects),
+                             8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+         if (new_objects == NULL)
+            return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+         struct anv_bo **new_bos =
+            anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_bos),
+                             8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+         if (new_objects == NULL) {
+            anv_device_free(cmd_buffer->device, new_objects);
+            return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+         }
+
+         if (cmd_buffer->execbuf2.objects) {
+            memcpy(new_objects, cmd_buffer->execbuf2.objects,
+                   cmd_buffer->execbuf2.bo_count * sizeof(*new_objects));
+            memcpy(new_bos, cmd_buffer->execbuf2.bos,
+                   cmd_buffer->execbuf2.bo_count * sizeof(*new_bos));
+         }
+
+         cmd_buffer->execbuf2.objects = new_objects;
+         cmd_buffer->execbuf2.bos = new_bos;
+         cmd_buffer->execbuf2.array_length = new_len;
+      }
+
+      assert(cmd_buffer->execbuf2.bo_count < cmd_buffer->execbuf2.array_length);
+
+      bo->index = cmd_buffer->execbuf2.bo_count++;
+      obj = &cmd_buffer->execbuf2.objects[bo->index];
+      cmd_buffer->execbuf2.bos[bo->index] = bo;
+
+      obj->handle = bo->gem_handle;
+      obj->relocation_count = 0;
+      obj->relocs_ptr = 0;
+      obj->alignment = 0;
+      obj->offset = bo->offset;
+      obj->flags = 0;
+      obj->rsvd1 = 0;
+      obj->rsvd2 = 0;
+   }
+
+   if (relocs != NULL && obj->relocation_count == 0) {
+      /* This is the first time we've ever seen a list of relocations for
+       * this BO.  Go ahead and set the relocations and then walk the list
+       * of relocations and add them all.
+       */
+      obj->relocation_count = relocs->num_relocs;
+      obj->relocs_ptr = (uintptr_t) relocs->relocs;
+
+      for (size_t i = 0; i < relocs->num_relocs; i++) {
+         /* A quick sanity check on relocations */
+         assert(relocs->relocs[i].offset < bo->size);
+         anv_cmd_buffer_add_bo(cmd_buffer, relocs->reloc_bos[i], NULL);
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+static void
+anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
+                              struct anv_reloc_list *list)
+{
+   struct anv_bo *bo;
+
+   /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
+    * struct drm_i915_gem_exec_object2 against the bos current offset and if
+    * all bos haven't moved it will skip relocation processing alltogether.
+    * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
+    * value of offset so we can set it either way.  For that to work we need
+    * to make sure all relocs use the same presumed offset.
+    */
+
+   for (size_t i = 0; i < list->num_relocs; i++) {
+      bo = list->reloc_bos[i];
+      if (bo->offset != list->relocs[i].presumed_offset)
+         cmd_buffer->execbuf2.need_reloc = true;
+
+      list->relocs[i].target_handle = bo->index;
+   }
+}
+
+static void
+adjust_relocations_from_block_pool(struct anv_block_pool *pool,
+                                   struct anv_reloc_list *relocs)
+{
+   for (size_t i = 0; i < relocs->num_relocs; i++) {
+      /* In general, we don't know how stale the relocated value is.  It
+       * may have been used last time or it may not.  Since we don't want
+       * to stomp it while the GPU may be accessing it, we haven't updated
+       * it anywhere else in the code.  Instead, we just set the presumed
+       * offset to what it is now based on the delta and the data in the
+       * block pool.  Then the kernel will update it for us if needed.
+       */
+      assert(relocs->relocs[i].offset < pool->state.end);
+      uint32_t *reloc_data = pool->map + relocs->relocs[i].offset;
+      relocs->relocs[i].presumed_offset = *reloc_data - relocs->relocs[i].delta;
+
+      /* All of the relocations from this block pool to other BO's should
+       * have been emitted relative to the surface block pool center.  We
+       * need to add the center offset to make them relative to the
+       * beginning of the actual GEM bo.
+       */
+      relocs->relocs[i].offset += pool->center_bo_offset;
+   }
+}
+
+static void
+adjust_relocations_to_block_pool(struct anv_block_pool *pool,
+                                 struct anv_bo *from_bo,
+                                 struct anv_reloc_list *relocs,
+                                 uint32_t *last_pool_center_bo_offset)
+{
+   assert(*last_pool_center_bo_offset <= pool->center_bo_offset);
+   uint32_t delta = pool->center_bo_offset - *last_pool_center_bo_offset;
+
+   /* When we initially emit relocations into a block pool, we don't
+    * actually know what the final center_bo_offset will be so we just emit
+    * it as if center_bo_offset == 0.  Now that we know what the center
+    * offset is, we need to walk the list of relocations and adjust any
+    * relocations that point to the pool bo with the correct offset.
+    */
+   for (size_t i = 0; i < relocs->num_relocs; i++) {
+      if (relocs->reloc_bos[i] == &pool->bo) {
+         /* Adjust the delta value in the relocation to correctly
+          * correspond to the new delta.  Initially, this value may have
+          * been negative (if treated as unsigned), but we trust in
+          * uint32_t roll-over to fix that for us at this point.
+          */
+         relocs->relocs[i].delta += delta;
+
+         /* Since the delta has changed, we need to update the actual
+          * relocated value with the new presumed value.  This function
+          * should only be called on batch buffers, so we know it isn't in
+          * use by the GPU at the moment.
+          */
+         assert(relocs->relocs[i].offset < from_bo->size);
+         uint32_t *reloc_data = from_bo->map + relocs->relocs[i].offset;
+         *reloc_data = relocs->relocs[i].presumed_offset +
+                       relocs->relocs[i].delta;
+      }
+   }
+
+   *last_pool_center_bo_offset = pool->center_bo_offset;
+}
+
+void
+anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_batch *batch = &cmd_buffer->batch;
+   struct anv_block_pool *ss_pool =
+      &cmd_buffer->device->surface_state_block_pool;
+
+   cmd_buffer->execbuf2.bo_count = 0;
+   cmd_buffer->execbuf2.need_reloc = false;
+
+   adjust_relocations_from_block_pool(ss_pool, &cmd_buffer->surface_relocs);
+   anv_cmd_buffer_add_bo(cmd_buffer, &ss_pool->bo, &cmd_buffer->surface_relocs);
+
+   /* First, we walk over all of the bos we've seen and add them and their
+    * relocations to the validate list.
+    */
+   struct anv_batch_bo **bbo;
+   anv_vector_foreach(bbo, &cmd_buffer->seen_bbos) {
+      adjust_relocations_to_block_pool(ss_pool, &(*bbo)->bo, &(*bbo)->relocs,
+                                       &(*bbo)->last_ss_pool_bo_offset);
+
+      anv_cmd_buffer_add_bo(cmd_buffer, &(*bbo)->bo, &(*bbo)->relocs);
+   }
+
+   struct anv_batch_bo *first_batch_bo =
+      list_first_entry(&cmd_buffer->batch_bos, struct anv_batch_bo, link);
+
+   /* The kernel requires that the last entry in the validation list be the
+    * batch buffer to execute.  We can simply swap the element
+    * corresponding to the first batch_bo in the chain with the last
+    * element in the list.
+    */
+   if (first_batch_bo->bo.index != cmd_buffer->execbuf2.bo_count - 1) {
+      uint32_t idx = first_batch_bo->bo.index;
+      uint32_t last_idx = cmd_buffer->execbuf2.bo_count - 1;
+
+      struct drm_i915_gem_exec_object2 tmp_obj =
+         cmd_buffer->execbuf2.objects[idx];
+      assert(cmd_buffer->execbuf2.bos[idx] == &first_batch_bo->bo);
+
+      cmd_buffer->execbuf2.objects[idx] = cmd_buffer->execbuf2.objects[last_idx];
+      cmd_buffer->execbuf2.bos[idx] = cmd_buffer->execbuf2.bos[last_idx];
+      cmd_buffer->execbuf2.bos[idx]->index = idx;
+
+      cmd_buffer->execbuf2.objects[last_idx] = tmp_obj;
+      cmd_buffer->execbuf2.bos[last_idx] = &first_batch_bo->bo;
+      first_batch_bo->bo.index = last_idx;
+   }
+
+   /* Now we go through and fixup all of the relocation lists to point to
+    * the correct indices in the object array.  We have to do this after we
+    * reorder the list above as some of the indices may have changed.
+    */
+   anv_vector_foreach(bbo, &cmd_buffer->seen_bbos)
+      anv_cmd_buffer_process_relocs(cmd_buffer, &(*bbo)->relocs);
+
+   anv_cmd_buffer_process_relocs(cmd_buffer, &cmd_buffer->surface_relocs);
+
+   cmd_buffer->execbuf2.execbuf = (struct drm_i915_gem_execbuffer2) {
+      .buffers_ptr = (uintptr_t) cmd_buffer->execbuf2.objects,
+      .buffer_count = cmd_buffer->execbuf2.bo_count,
+      .batch_start_offset = 0,
+      .batch_len = batch->next - batch->start,
+      .cliprects_ptr = 0,
+      .num_cliprects = 0,
+      .DR1 = 0,
+      .DR4 = 0,
+      .flags = I915_EXEC_HANDLE_LUT | I915_EXEC_RENDER |
+               I915_EXEC_CONSTANTS_REL_GENERAL,
+      .rsvd1 = cmd_buffer->device->context_id,
+      .rsvd2 = 0,
+   };
+
+   if (!cmd_buffer->execbuf2.need_reloc)
+      cmd_buffer->execbuf2.execbuf.flags |= I915_EXEC_NO_RELOC;
+}
diff --git a/src/vulkan/anv_cmd_buffer.c b/src/vulkan/anv_cmd_buffer.c
new file mode 100644 (file)
index 0000000..6763278
--- /dev/null
@@ -0,0 +1,1178 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+/** \file anv_cmd_buffer.c
+ *
+ * This file contains all of the stuff for emitting commands into a command
+ * buffer.  This includes implementations of most of the vkCmd*
+ * entrypoints.  This file is concerned entirely with state emission and
+ * not with the command buffer data structure itself.  As far as this file
+ * is concerned, most of anv_cmd_buffer is magic.
+ */
+
+/* TODO: These are taken from GLES.  We should check the Vulkan spec */
+const struct anv_dynamic_state default_dynamic_state = {
+   .viewport = {
+      .count = 0,
+   },
+   .scissor = {
+      .count = 0,
+   },
+   .line_width = 1.0f,
+   .depth_bias = {
+      .bias = 0.0f,
+      .clamp = 0.0f,
+      .slope_scaled = 0.0f,
+   },
+   .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
+   .depth_bounds = {
+      .min = 0.0f,
+      .max = 1.0f,
+   },
+   .stencil_compare_mask = {
+      .front = ~0u,
+      .back = ~0u,
+   },
+   .stencil_write_mask = {
+      .front = ~0u,
+      .back = ~0u,
+   },
+   .stencil_reference = {
+      .front = 0u,
+      .back = 0u,
+   },
+};
+
+void
+anv_dynamic_state_copy(struct anv_dynamic_state *dest,
+                       const struct anv_dynamic_state *src,
+                       uint32_t copy_mask)
+{
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) {
+      dest->viewport.count = src->viewport.count;
+      typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
+                   src->viewport.count);
+   }
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) {
+      dest->scissor.count = src->scissor.count;
+      typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
+                   src->scissor.count);
+   }
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH))
+      dest->line_width = src->line_width;
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS))
+      dest->depth_bias = src->depth_bias;
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS))
+      typed_memcpy(dest->blend_constants, src->blend_constants, 4);
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS))
+      dest->depth_bounds = src->depth_bounds;
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))
+      dest->stencil_compare_mask = src->stencil_compare_mask;
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))
+      dest->stencil_write_mask = src->stencil_write_mask;
+
+   if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))
+      dest->stencil_reference = src->stencil_reference;
+}
+
+static void
+anv_cmd_state_init(struct anv_cmd_state *state)
+{
+   memset(&state->state_vf, 0, sizeof(state->state_vf));
+   memset(&state->descriptors, 0, sizeof(state->descriptors));
+   memset(&state->push_constants, 0, sizeof(state->push_constants));
+
+   state->dirty = ~0;
+   state->vb_dirty = 0;
+   state->descriptors_dirty = 0;
+   state->push_constants_dirty = 0;
+   state->pipeline = NULL;
+   state->dynamic = default_dynamic_state;
+
+   state->gen7.index_buffer = NULL;
+}
+
+static VkResult
+anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
+                                          VkShaderStage stage, uint32_t size)
+{
+   struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage];
+
+   if (*ptr == NULL) {
+      *ptr = anv_device_alloc(cmd_buffer->device, size, 8,
+                              VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+      if (*ptr == NULL)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+      (*ptr)->size = size;
+   } else if ((*ptr)->size < size) {
+      void *new_data = anv_device_alloc(cmd_buffer->device, size, 8,
+                                        VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+      if (new_data == NULL)
+         return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+      memcpy(new_data, *ptr, (*ptr)->size);
+      anv_device_free(cmd_buffer->device, *ptr);
+
+      *ptr = new_data;
+      (*ptr)->size = size;
+   }
+
+   return VK_SUCCESS;
+}
+
+#define anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, field) \
+   anv_cmd_buffer_ensure_push_constants_size(cmd_buffer, stage, \
+      (offsetof(struct anv_push_constants, field) + \
+       sizeof(cmd_buffer->state.push_constants[0]->field)))
+
+VkResult anv_CreateCommandBuffer(
+    VkDevice                                    _device,
+    const VkCmdBufferCreateInfo*                pCreateInfo,
+    VkCmdBuffer*                                pCmdBuffer)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_cmd_pool, pool, pCreateInfo->cmdPool);
+   struct anv_cmd_buffer *cmd_buffer;
+   VkResult result;
+
+   cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
+                                 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (cmd_buffer == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
+   cmd_buffer->device = device;
+
+   result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
+   if (result != VK_SUCCESS)
+      goto fail;
+
+   anv_state_stream_init(&cmd_buffer->surface_state_stream,
+                         &device->surface_state_block_pool);
+   anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
+                         &device->dynamic_state_block_pool);
+
+   cmd_buffer->level = pCreateInfo->level;
+   cmd_buffer->opt_flags = 0;
+
+   anv_cmd_state_init(&cmd_buffer->state);
+
+   if (pool) {
+      list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
+   } else {
+      /* Init the pool_link so we can safefly call list_del when we destroy
+       * the command buffer
+       */
+      list_inithead(&cmd_buffer->pool_link);
+   }
+
+   *pCmdBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
+
+   return VK_SUCCESS;
+
+ fail: anv_device_free(device, cmd_buffer);
+
+   return result;
+}
+
+void anv_DestroyCommandBuffer(
+    VkDevice                                    _device,
+    VkCmdBuffer                                 _cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, _cmd_buffer);
+
+   list_del(&cmd_buffer->pool_link);
+
+   anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
+
+   anv_state_stream_finish(&cmd_buffer->surface_state_stream);
+   anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
+   anv_device_free(device, cmd_buffer);
+}
+
+VkResult anv_ResetCommandBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkCmdBufferResetFlags                       flags)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
+
+   anv_cmd_state_init(&cmd_buffer->state);
+
+   return VK_SUCCESS;
+}
+
+void
+anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
+{
+   switch (cmd_buffer->device->info.gen) {
+   case 7:
+      return gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
+   case 8:
+      return gen8_cmd_buffer_emit_state_base_address(cmd_buffer);
+   default:
+      unreachable("unsupported gen\n");
+   }
+}
+
+VkResult anv_BeginCommandBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    const VkCmdBufferBeginInfo*                 pBeginInfo)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
+
+   cmd_buffer->opt_flags = pBeginInfo->flags;
+
+   if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_SECONDARY) {
+      cmd_buffer->state.framebuffer =
+         anv_framebuffer_from_handle(pBeginInfo->framebuffer);
+      cmd_buffer->state.pass =
+         anv_render_pass_from_handle(pBeginInfo->renderPass);
+
+      struct anv_subpass *subpass =
+         &cmd_buffer->state.pass->subpasses[pBeginInfo->subpass];
+
+      anv_cmd_buffer_begin_subpass(cmd_buffer, subpass);
+   }
+
+   anv_cmd_buffer_emit_state_base_address(cmd_buffer);
+   cmd_buffer->state.current_pipeline = UINT32_MAX;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_EndCommandBuffer(
+    VkCmdBuffer                                 cmdBuffer)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_device *device = cmd_buffer->device;
+
+   anv_cmd_buffer_end_batch_buffer(cmd_buffer);
+
+   if (cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY) {
+      /* The algorithm used to compute the validate list is not threadsafe as
+       * it uses the bo->index field.  We have to lock the device around it.
+       * Fortunately, the chances for contention here are probably very low.
+       */
+      pthread_mutex_lock(&device->mutex);
+      anv_cmd_buffer_prepare_execbuf(cmd_buffer);
+      pthread_mutex_unlock(&device->mutex);
+   }
+
+   return VK_SUCCESS;
+}
+
+void anv_CmdBindPipeline(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineBindPoint                         pipelineBindPoint,
+    VkPipeline                                  _pipeline)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
+
+   switch (pipelineBindPoint) {
+   case VK_PIPELINE_BIND_POINT_COMPUTE:
+      cmd_buffer->state.compute_pipeline = pipeline;
+      cmd_buffer->state.compute_dirty |= ANV_CMD_DIRTY_PIPELINE;
+      cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
+      break;
+
+   case VK_PIPELINE_BIND_POINT_GRAPHICS:
+      cmd_buffer->state.pipeline = pipeline;
+      cmd_buffer->state.vb_dirty |= pipeline->vb_used;
+      cmd_buffer->state.dirty |= ANV_CMD_DIRTY_PIPELINE;
+      cmd_buffer->state.push_constants_dirty |= pipeline->active_stages;
+
+      /* Apply the dynamic state from the pipeline */
+      cmd_buffer->state.dirty |= pipeline->dynamic_state_mask;
+      anv_dynamic_state_copy(&cmd_buffer->state.dynamic,
+                             &pipeline->dynamic_state,
+                             pipeline->dynamic_state_mask);
+      break;
+
+   default:
+      assert(!"invalid bind point");
+      break;
+   }
+}
+
+void anv_CmdSetViewport(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    viewportCount,
+    const VkViewport*                           pViewports)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   cmd_buffer->state.dynamic.viewport.count = viewportCount;
+   memcpy(cmd_buffer->state.dynamic.viewport.viewports,
+          pViewports, viewportCount * sizeof(*pViewports));
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
+}
+
+void anv_CmdSetScissor(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    scissorCount,
+    const VkRect2D*                             pScissors)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   cmd_buffer->state.dynamic.scissor.count = scissorCount;
+   memcpy(cmd_buffer->state.dynamic.scissor.scissors,
+          pScissors, scissorCount * sizeof(*pScissors));
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
+}
+
+void anv_CmdSetLineWidth(
+    VkCmdBuffer                                 cmdBuffer,
+    float                                       lineWidth)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   cmd_buffer->state.dynamic.line_width = lineWidth;
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
+}
+
+void anv_CmdSetDepthBias(
+    VkCmdBuffer                                 cmdBuffer,
+    float                                       depthBias,
+    float                                       depthBiasClamp,
+    float                                       slopeScaledDepthBias)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   cmd_buffer->state.dynamic.depth_bias.bias = depthBias;
+   cmd_buffer->state.dynamic.depth_bias.clamp = depthBiasClamp;
+   cmd_buffer->state.dynamic.depth_bias.slope_scaled = slopeScaledDepthBias;
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
+}
+
+void anv_CmdSetBlendConstants(
+    VkCmdBuffer                                 cmdBuffer,
+    const float                                 blendConst[4])
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   memcpy(cmd_buffer->state.dynamic.blend_constants,
+          blendConst, sizeof(float) * 4);
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
+}
+
+void anv_CmdSetDepthBounds(
+    VkCmdBuffer                                 cmdBuffer,
+    float                                       minDepthBounds,
+    float                                       maxDepthBounds)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   cmd_buffer->state.dynamic.depth_bounds.min = minDepthBounds;
+   cmd_buffer->state.dynamic.depth_bounds.max = maxDepthBounds;
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
+}
+
+void anv_CmdSetStencilCompareMask(
+    VkCmdBuffer                                 cmdBuffer,
+    VkStencilFaceFlags                          faceMask,
+    uint32_t                                    stencilCompareMask)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
+      cmd_buffer->state.dynamic.stencil_compare_mask.front = stencilCompareMask;
+   if (faceMask & VK_STENCIL_FACE_BACK_BIT)
+      cmd_buffer->state.dynamic.stencil_compare_mask.back = stencilCompareMask;
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
+}
+
+void anv_CmdSetStencilWriteMask(
+    VkCmdBuffer                                 cmdBuffer,
+    VkStencilFaceFlags                          faceMask,
+    uint32_t                                    stencilWriteMask)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
+      cmd_buffer->state.dynamic.stencil_write_mask.front = stencilWriteMask;
+   if (faceMask & VK_STENCIL_FACE_BACK_BIT)
+      cmd_buffer->state.dynamic.stencil_write_mask.back = stencilWriteMask;
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
+}
+
+void anv_CmdSetStencilReference(
+    VkCmdBuffer                                 cmdBuffer,
+    VkStencilFaceFlags                          faceMask,
+    uint32_t                                    stencilReference)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
+      cmd_buffer->state.dynamic.stencil_reference.front = stencilReference;
+   if (faceMask & VK_STENCIL_FACE_BACK_BIT)
+      cmd_buffer->state.dynamic.stencil_reference.back = stencilReference;
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
+}
+
+void anv_CmdBindDescriptorSets(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineBindPoint                         pipelineBindPoint,
+    VkPipelineLayout                            _layout,
+    uint32_t                                    firstSet,
+    uint32_t                                    setCount,
+    const VkDescriptorSet*                      pDescriptorSets,
+    uint32_t                                    dynamicOffsetCount,
+    const uint32_t*                             pDynamicOffsets)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
+   struct anv_descriptor_set_layout *set_layout;
+
+   assert(firstSet + setCount < MAX_SETS);
+
+   uint32_t dynamic_slot = 0;
+   for (uint32_t i = 0; i < setCount; i++) {
+      ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
+      set_layout = layout->set[firstSet + i].layout;
+
+      if (cmd_buffer->state.descriptors[firstSet + i] != set) {
+         cmd_buffer->state.descriptors[firstSet + i] = set;
+         cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
+      }
+
+      if (set_layout->dynamic_offset_count > 0) {
+         VkShaderStage s;
+         for_each_bit(s, set_layout->shader_stages) {
+            anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, s, dynamic);
+
+            struct anv_push_constants *push =
+               cmd_buffer->state.push_constants[s];
+
+            unsigned d = layout->set[firstSet + i].dynamic_offset_start;
+            const uint32_t *offsets = pDynamicOffsets + dynamic_slot;
+            struct anv_descriptor *desc = set->descriptors;
+
+            for (unsigned b = 0; b < set_layout->binding_count; b++) {
+               if (set_layout->binding[b].dynamic_offset_index < 0)
+                  continue;
+
+               unsigned array_size = set_layout->binding[b].array_size;
+               for (unsigned j = 0; j < array_size; j++) {
+                  push->dynamic[d].offset = *(offsets++);
+                  push->dynamic[d].range = (desc++)->range;
+                  d++;
+               }
+            }
+         }
+         cmd_buffer->state.push_constants_dirty |= set_layout->shader_stages;
+      }
+   }
+}
+
+void anv_CmdBindVertexBuffers(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    startBinding,
+    uint32_t                                    bindingCount,
+    const VkBuffer*                             pBuffers,
+    const VkDeviceSize*                         pOffsets)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
+
+   /* We have to defer setting up vertex buffer since we need the buffer
+    * stride from the pipeline. */
+
+   assert(startBinding + bindingCount < MAX_VBS);
+   for (uint32_t i = 0; i < bindingCount; i++) {
+      vb[startBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
+      vb[startBinding + i].offset = pOffsets[i];
+      cmd_buffer->state.vb_dirty |= 1 << (startBinding + i);
+   }
+}
+
+static void
+add_surface_state_reloc(struct anv_cmd_buffer *cmd_buffer,
+                        struct anv_state state, struct anv_bo *bo, uint32_t offset)
+{
+   /* The address goes in SURFACE_STATE dword 1 for gens < 8 and dwords 8 and
+    * 9 for gen8+.  We only write the first dword for gen8+ here and rely on
+    * the initial state to set the high bits to 0. */
+
+   const uint32_t dword = cmd_buffer->device->info.gen < 8 ? 1 : 8;
+
+   anv_reloc_list_add(&cmd_buffer->surface_relocs, cmd_buffer->device,
+                      state.offset + dword * 4, bo, offset);
+}
+
+static void
+fill_descriptor_buffer_surface_state(struct anv_device *device, void *state,
+                                     VkShaderStage stage, VkDescriptorType type,
+                                     uint32_t offset, uint32_t range)
+{
+   VkFormat format;
+   uint32_t stride;
+
+   switch (type) {
+   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      if (anv_is_scalar_shader_stage(device->instance->physicalDevice.compiler,
+                                     stage)) {
+         stride = 4;
+      } else {
+         stride = 16;
+      }
+      format = VK_FORMAT_R32G32B32A32_SFLOAT;
+      break;
+
+   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+      stride = 1;
+      format = VK_FORMAT_UNDEFINED;
+      break;
+
+   default:
+      unreachable("Invalid descriptor type");
+   }
+
+   anv_fill_buffer_surface_state(device, state,
+                                 anv_format_for_vk_format(format),
+                                 offset, range, stride);
+}
+
+VkResult
+anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
+                                  VkShaderStage stage, struct anv_state *bt_state)
+{
+   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   struct anv_subpass *subpass = cmd_buffer->state.subpass;
+   struct anv_pipeline_layout *layout;
+   uint32_t color_count, bias, state_offset;
+
+   if (stage == VK_SHADER_STAGE_COMPUTE)
+      layout = cmd_buffer->state.compute_pipeline->layout;
+   else
+      layout = cmd_buffer->state.pipeline->layout;
+
+   if (stage == VK_SHADER_STAGE_FRAGMENT) {
+      bias = MAX_RTS;
+      color_count = subpass->color_count;
+   } else {
+      bias = 0;
+      color_count = 0;
+   }
+
+   /* This is a little awkward: layout can be NULL but we still have to
+    * allocate and set a binding table for the PS stage for render
+    * targets. */
+   uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
+
+   if (color_count + surface_count == 0)
+      return VK_SUCCESS;
+
+   *bt_state = anv_cmd_buffer_alloc_binding_table(cmd_buffer,
+                                                  bias + surface_count,
+                                                  &state_offset);
+   uint32_t *bt_map = bt_state->map;
+
+   if (bt_state->map == NULL)
+      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+
+   for (uint32_t a = 0; a < color_count; a++) {
+      const struct anv_image_view *iview =
+         fb->attachments[subpass->color_attachments[a]];
+
+      bt_map[a] = iview->color_rt_surface_state.offset + state_offset;
+      add_surface_state_reloc(cmd_buffer, iview->color_rt_surface_state,
+                              iview->bo, iview->offset);
+   }
+
+   if (layout == NULL)
+      return VK_SUCCESS;
+
+   for (uint32_t s = 0; s < layout->stage[stage].surface_count; s++) {
+      struct anv_pipeline_binding *binding =
+         &layout->stage[stage].surface_to_descriptor[s];
+      struct anv_descriptor_set *set =
+         cmd_buffer->state.descriptors[binding->set];
+      struct anv_descriptor *desc = &set->descriptors[binding->offset];
+
+      struct anv_state surface_state;
+      struct anv_bo *bo;
+      uint32_t bo_offset;
+
+      switch (desc->type) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+         /* Nothing for us to do here */
+         continue;
+
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: {
+         bo = desc->buffer->bo;
+         bo_offset = desc->buffer->offset + desc->offset;
+
+         surface_state =
+            anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+
+         fill_descriptor_buffer_surface_state(cmd_buffer->device,
+                                              surface_state.map,
+                                              stage, desc->type,
+                                              bo_offset, desc->range);
+         break;
+      }
+
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+         surface_state = desc->image_view->nonrt_surface_state;
+         bo = desc->image_view->bo;
+         bo_offset = desc->image_view->offset;
+         break;
+
+      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+         assert(!"Unsupported descriptor type");
+         break;
+      }
+
+      bt_map[bias + s] = surface_state.offset + state_offset;
+      add_surface_state_reloc(cmd_buffer, surface_state, bo, bo_offset);
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
+                             VkShaderStage stage, struct anv_state *state)
+{
+   struct anv_pipeline_layout *layout;
+   uint32_t sampler_count;
+
+   if (stage == VK_SHADER_STAGE_COMPUTE)
+      layout = cmd_buffer->state.compute_pipeline->layout;
+   else
+      layout = cmd_buffer->state.pipeline->layout;
+
+   sampler_count = layout ? layout->stage[stage].sampler_count : 0;
+   if (sampler_count == 0)
+      return VK_SUCCESS;
+
+   uint32_t size = sampler_count * 16;
+   *state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 32);
+
+   if (state->map == NULL)
+      return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+
+   for (uint32_t s = 0; s < layout->stage[stage].sampler_count; s++) {
+      struct anv_pipeline_binding *binding =
+         &layout->stage[stage].sampler_to_descriptor[s];
+      struct anv_descriptor_set *set =
+         cmd_buffer->state.descriptors[binding->set];
+      struct anv_descriptor *desc = &set->descriptors[binding->offset];
+
+      if (desc->type != VK_DESCRIPTOR_TYPE_SAMPLER &&
+          desc->type != VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
+         continue;
+
+      struct anv_sampler *sampler = desc->sampler;
+
+      /* This can happen if we have an unfilled slot since TYPE_SAMPLER
+       * happens to be zero.
+       */
+      if (sampler == NULL)
+         continue;
+
+      memcpy(state->map + (s * 16),
+             sampler->state, sizeof(sampler->state));
+   }
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, VkShaderStage stage)
+{
+   struct anv_state surfaces = { 0, }, samplers = { 0, };
+   VkResult result;
+
+   result = anv_cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
+   if (result != VK_SUCCESS)
+      return result;
+   result = anv_cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
+   if (result != VK_SUCCESS)
+      return result;
+
+   static const uint32_t sampler_state_opcodes[] = {
+      [VK_SHADER_STAGE_VERTEX]                  = 43,
+      [VK_SHADER_STAGE_TESS_CONTROL]            = 44, /* HS */
+      [VK_SHADER_STAGE_TESS_EVALUATION]         = 45, /* DS */
+      [VK_SHADER_STAGE_GEOMETRY]                = 46,
+      [VK_SHADER_STAGE_FRAGMENT]                = 47,
+      [VK_SHADER_STAGE_COMPUTE]                 = 0,
+   };
+
+   static const uint32_t binding_table_opcodes[] = {
+      [VK_SHADER_STAGE_VERTEX]                  = 38,
+      [VK_SHADER_STAGE_TESS_CONTROL]            = 39,
+      [VK_SHADER_STAGE_TESS_EVALUATION]         = 40,
+      [VK_SHADER_STAGE_GEOMETRY]                = 41,
+      [VK_SHADER_STAGE_FRAGMENT]                = 42,
+      [VK_SHADER_STAGE_COMPUTE]                 = 0,
+   };
+
+   if (samplers.alloc_size > 0) {
+      anv_batch_emit(&cmd_buffer->batch,
+                     GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS,
+                     ._3DCommandSubOpcode  = sampler_state_opcodes[stage],
+                     .PointertoVSSamplerState = samplers.offset);
+   }
+
+   if (surfaces.alloc_size > 0) {
+      anv_batch_emit(&cmd_buffer->batch,
+                     GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS,
+                     ._3DCommandSubOpcode  = binding_table_opcodes[stage],
+                     .PointertoVSBindingTable = surfaces.offset);
+   }
+
+   return VK_SUCCESS;
+}
+
+void
+anv_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
+{
+   VkShaderStage s;
+   VkShaderStageFlags dirty = cmd_buffer->state.descriptors_dirty &
+                              cmd_buffer->state.pipeline->active_stages;
+
+   VkResult result = VK_SUCCESS;
+   for_each_bit(s, dirty) {
+      result = flush_descriptor_set(cmd_buffer, s);
+      if (result != VK_SUCCESS)
+         break;
+   }
+
+   if (result != VK_SUCCESS) {
+      assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
+
+      result = anv_cmd_buffer_new_binding_table_block(cmd_buffer);
+      assert(result == VK_SUCCESS);
+
+      /* Re-emit state base addresses so we get the new surface state base
+       * address before we start emitting binding tables etc.
+       */
+      anv_cmd_buffer_emit_state_base_address(cmd_buffer);
+
+      /* Re-emit all active binding tables */
+      for_each_bit(s, cmd_buffer->state.pipeline->active_stages) {
+         result = flush_descriptor_set(cmd_buffer, s);
+
+         /* It had better succeed this time */
+         assert(result == VK_SUCCESS);
+      }
+   }
+
+   cmd_buffer->state.descriptors_dirty &= ~cmd_buffer->state.pipeline->active_stages;
+}
+
+struct anv_state
+anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
+                             uint32_t *a, uint32_t dwords, uint32_t alignment)
+{
+   struct anv_state state;
+
+   state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+                                              dwords * 4, alignment);
+   memcpy(state.map, a, dwords * 4);
+
+   VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
+
+   return state;
+}
+
+struct anv_state
+anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
+                             uint32_t *a, uint32_t *b,
+                             uint32_t dwords, uint32_t alignment)
+{
+   struct anv_state state;
+   uint32_t *p;
+
+   state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+                                              dwords * 4, alignment);
+   p = state.map;
+   for (uint32_t i = 0; i < dwords; i++)
+      p[i] = a[i] | b[i];
+
+   VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
+
+   return state;
+}
+
+void
+anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_subpass *subpass)
+{
+   switch (cmd_buffer->device->info.gen) {
+   case 7:
+      gen7_cmd_buffer_begin_subpass(cmd_buffer, subpass);
+      break;
+   case 8:
+      gen8_cmd_buffer_begin_subpass(cmd_buffer, subpass);
+      break;
+   default:
+      unreachable("unsupported gen\n");
+   }
+}
+
+static void
+emit_viewport_state(struct anv_cmd_buffer *cmd_buffer,
+                    uint32_t count, const VkViewport *viewports)
+{
+   struct anv_state sf_clip_state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 64, 64);
+   struct anv_state cc_state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 8, 32);
+
+   for (uint32_t i = 0; i < count; i++) {
+      const VkViewport *vp = &viewports[i];
+
+      /* The gen7 state struct has just the matrix and guardband fields, the
+       * gen8 struct adds the min/max viewport fields. */
+      struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
+         .ViewportMatrixElementm00 = vp->width / 2,
+         .ViewportMatrixElementm11 = vp->height / 2,
+         .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
+         .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
+         .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
+         .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
+         .XMinClipGuardband = -1.0f,
+         .XMaxClipGuardband = 1.0f,
+         .YMinClipGuardband = -1.0f,
+         .YMaxClipGuardband = 1.0f,
+         .XMinViewPort = vp->originX,
+         .XMaxViewPort = vp->originX + vp->width - 1,
+         .YMinViewPort = vp->originY,
+         .YMaxViewPort = vp->originY + vp->height - 1,
+      };
+
+      struct GEN7_CC_VIEWPORT cc_viewport = {
+         .MinimumDepth = vp->minDepth,
+         .MaximumDepth = vp->maxDepth
+      };
+
+      GEN8_SF_CLIP_VIEWPORT_pack(NULL, sf_clip_state.map + i * 64,
+                                 &sf_clip_viewport);
+      GEN7_CC_VIEWPORT_pack(NULL, cc_state.map + i * 32, &cc_viewport);
+   }
+
+   anv_batch_emit(&cmd_buffer->batch,
+                  GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
+                  .CCViewportPointer = cc_state.offset);
+   anv_batch_emit(&cmd_buffer->batch,
+                  GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
+                  .SFClipViewportPointer = sf_clip_state.offset);
+}
+
+void
+anv_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
+{
+   if (cmd_buffer->state.dynamic.viewport.count > 0) {
+      emit_viewport_state(cmd_buffer, cmd_buffer->state.dynamic.viewport.count,
+                          cmd_buffer->state.dynamic.viewport.viewports);
+   } else {
+      /* If viewport count is 0, this is taken to mean "use the default" */
+      emit_viewport_state(cmd_buffer, 1,
+                          &(VkViewport) {
+                             .originX = 0.0f,
+                             .originY = 0.0f,
+                             .width = cmd_buffer->state.framebuffer->width,
+                             .height = cmd_buffer->state.framebuffer->height,
+                             .minDepth = 0.0f,
+                             .maxDepth = 1.0f,
+                          });
+   }
+}
+
+static inline int64_t
+clamp_int64(int64_t x, int64_t min, int64_t max)
+{
+   if (x < min)
+      return min;
+   else if (x < max)
+      return x;
+   else
+      return max;
+}
+
+static void
+emit_scissor_state(struct anv_cmd_buffer *cmd_buffer,
+                   uint32_t count, const VkRect2D *scissors)
+{
+   struct anv_state scissor_state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 32, 32);
+
+   for (uint32_t i = 0; i < count; i++) {
+      const VkRect2D *s = &scissors[i];
+
+      /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
+       * ymax < ymin for empty clips.  In case clip x, y, width height are all
+       * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
+       * what we want. Just special case empty clips and produce a canonical
+       * empty clip. */
+      static const struct GEN7_SCISSOR_RECT empty_scissor = {
+         .ScissorRectangleYMin = 1,
+         .ScissorRectangleXMin = 1,
+         .ScissorRectangleYMax = 0,
+         .ScissorRectangleXMax = 0
+      };
+
+      const int max = 0xffff;
+      struct GEN7_SCISSOR_RECT scissor = {
+         /* Do this math using int64_t so overflow gets clamped correctly. */
+         .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
+         .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
+         .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
+         .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
+      };
+
+      if (s->extent.width <= 0 || s->extent.height <= 0) {
+         GEN7_SCISSOR_RECT_pack(NULL, scissor_state.map + i * 32,
+                                &empty_scissor);
+      } else {
+         GEN7_SCISSOR_RECT_pack(NULL, scissor_state.map + i * 32, &scissor);
+      }
+   }
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
+                  .ScissorRectPointer = scissor_state.offset);
+}
+
+void
+anv_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer)
+{
+   if (cmd_buffer->state.dynamic.scissor.count > 0) {
+      emit_scissor_state(cmd_buffer, cmd_buffer->state.dynamic.scissor.count,
+                         cmd_buffer->state.dynamic.scissor.scissors);
+   } else {
+      /* Emit a default scissor based on the currently bound framebuffer */
+      emit_scissor_state(cmd_buffer, 1,
+                         &(VkRect2D) {
+                            .offset = { .x = 0, .y = 0, },
+                            .extent = {
+                               .width = cmd_buffer->state.framebuffer->width,
+                               .height = cmd_buffer->state.framebuffer->height,
+                            },
+                         });
+   }
+}
+
+void anv_CmdSetEvent(
+    VkCmdBuffer                                 cmdBuffer,
+    VkEvent                                     event,
+    VkPipelineStageFlags                        stageMask)
+{
+   stub();
+}
+
+void anv_CmdResetEvent(
+    VkCmdBuffer                                 cmdBuffer,
+    VkEvent                                     event,
+    VkPipelineStageFlags                        stageMask)
+{
+   stub();
+}
+
+void anv_CmdWaitEvents(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    eventCount,
+    const VkEvent*                              pEvents,
+    VkPipelineStageFlags                        srcStageMask,
+    VkPipelineStageFlags                        destStageMask,
+    uint32_t                                    memBarrierCount,
+    const void* const*                          ppMemBarriers)
+{
+   stub();
+}
+
+struct anv_state
+anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
+                              VkShaderStage stage)
+{
+   struct anv_push_constants *data =
+      cmd_buffer->state.push_constants[stage];
+   struct brw_stage_prog_data *prog_data =
+      cmd_buffer->state.pipeline->prog_data[stage];
+
+   /* If we don't actually have any push constants, bail. */
+   if (data == NULL || prog_data->nr_params == 0)
+      return (struct anv_state) { .offset = 0 };
+
+   struct anv_state state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+                                         prog_data->nr_params * sizeof(float),
+                                         32 /* bottom 5 bits MBZ */);
+
+   /* Walk through the param array and fill the buffer with data */
+   uint32_t *u32_map = state.map;
+   for (unsigned i = 0; i < prog_data->nr_params; i++) {
+      uint32_t offset = (uintptr_t)prog_data->param[i];
+      u32_map[i] = *(uint32_t *)((uint8_t *)data + offset);
+   }
+
+   return state;
+}
+
+void anv_CmdPushConstants(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineLayout                            layout,
+    VkShaderStageFlags                          stageFlags,
+    uint32_t                                    start,
+    uint32_t                                    length,
+    const void*                                 values)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   VkShaderStage stage;
+
+   for_each_bit(stage, stageFlags) {
+      anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, client_data);
+
+      memcpy(cmd_buffer->state.push_constants[stage]->client_data + start,
+             values, length);
+   }
+
+   cmd_buffer->state.push_constants_dirty |= stageFlags;
+}
+
+void anv_CmdExecuteCommands(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    cmdBuffersCount,
+    const VkCmdBuffer*                          pCmdBuffers)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, primary, cmdBuffer);
+
+   assert(primary->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+
+   anv_assert(primary->state.subpass == &primary->state.pass->subpasses[0]);
+
+   for (uint32_t i = 0; i < cmdBuffersCount; i++) {
+      ANV_FROM_HANDLE(anv_cmd_buffer, secondary, pCmdBuffers[i]);
+
+      assert(secondary->level == VK_CMD_BUFFER_LEVEL_SECONDARY);
+
+      anv_cmd_buffer_add_secondary(primary, secondary);
+   }
+}
+
+VkResult anv_CreateCommandPool(
+    VkDevice                                    _device,
+    const VkCmdPoolCreateInfo*                  pCreateInfo,
+    VkCmdPool*                                  pCmdPool)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_cmd_pool *pool;
+
+   pool = anv_device_alloc(device, sizeof(*pool), 8,
+                           VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pool == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   list_inithead(&pool->cmd_buffers);
+
+   *pCmdPool = anv_cmd_pool_to_handle(pool);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyCommandPool(
+    VkDevice                                    _device,
+    VkCmdPool                                   cmdPool)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
+
+   anv_ResetCommandPool(_device, cmdPool, 0);
+
+   anv_device_free(device, pool);
+}
+
+VkResult anv_ResetCommandPool(
+    VkDevice                                    device,
+    VkCmdPool                                   cmdPool,
+    VkCmdPoolResetFlags                         flags)
+{
+   ANV_FROM_HANDLE(anv_cmd_pool, pool, cmdPool);
+
+   list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
+                            &pool->cmd_buffers, pool_link) {
+      anv_DestroyCommandBuffer(device, anv_cmd_buffer_to_handle(cmd_buffer));
+   }
+
+   return VK_SUCCESS;
+}
+
+/**
+ * Return NULL if the current subpass has no depthstencil attachment.
+ */
+const struct anv_image_view *
+anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
+{
+   const struct anv_subpass *subpass = cmd_buffer->state.subpass;
+   const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+
+   if (subpass->depth_stencil_attachment == VK_ATTACHMENT_UNUSED)
+      return NULL;
+
+   const struct anv_image_view *iview =
+      fb->attachments[subpass->depth_stencil_attachment];
+
+   assert(anv_format_is_depth_or_stencil(iview->format));
+
+   return iview;
+}
diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c
new file mode 100644 (file)
index 0000000..fb60859
--- /dev/null
@@ -0,0 +1,1883 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+#include "mesa/main/git_sha1.h"
+#include "util/strtod.h"
+
+struct anv_dispatch_table dtable;
+
+static void
+compiler_debug_log(void *data, const char *fmt, ...)
+{ }
+
+static void
+compiler_perf_log(void *data, const char *fmt, ...)
+{
+   va_list args;
+   va_start(args, fmt);
+
+   if (unlikely(INTEL_DEBUG & DEBUG_PERF))
+      vfprintf(stderr, fmt, args);
+
+   va_end(args);
+}
+
+static VkResult
+anv_physical_device_init(struct anv_physical_device *device,
+                         struct anv_instance *instance,
+                         const char *path)
+{
+   VkResult result;
+   int fd;
+
+   fd = open(path, O_RDWR | O_CLOEXEC);
+   if (fd < 0)
+      return vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                       "failed to open %s: %m", path);
+
+   device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
+   device->instance = instance;
+   device->path = path;
+
+   device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID);
+   if (!device->chipset_id) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "failed to get chipset id: %m");
+      goto fail;
+   }
+
+   device->name = brw_get_device_name(device->chipset_id);
+   device->info = brw_get_device_info(device->chipset_id);
+   if (!device->info) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "failed to get device info");
+      goto fail;
+   }
+
+   if (device->info->gen == 7 &&
+       !device->info->is_haswell && !device->info->is_baytrail) {
+      fprintf(stderr, "WARNING: Ivy Bridge Vulkan support is incomplete\n");
+   } else if (device->info->gen == 8 && !device->info->is_cherryview) {
+      /* Briadwell is as fully supported as anything */
+   } else {
+      result = vk_errorf(VK_UNSUPPORTED,
+                         "Vulkan not yet supported on %s", device->name);
+      goto fail;
+   }
+
+   if (anv_gem_get_aperture(fd, &device->aperture_size) == -1) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "failed to get aperture size: %m");
+      goto fail;
+   }
+
+   if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "kernel missing gem wait");
+      goto fail;
+   }
+
+   if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2)) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "kernel missing execbuf2");
+      goto fail;
+   }
+
+   if (!anv_gem_get_param(fd, I915_PARAM_HAS_LLC)) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "non-llc gpu");
+      goto fail;
+   }
+
+   close(fd);
+
+   brw_process_intel_debug_variable();
+
+   device->compiler = brw_compiler_create(NULL, device->info);
+   if (device->compiler == NULL) {
+      result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto fail;
+   }
+   device->compiler->shader_debug_log = compiler_debug_log;
+   device->compiler->shader_perf_log = compiler_perf_log;
+
+   isl_device_init(&device->isl_dev, device->info);
+
+   return VK_SUCCESS;
+
+fail:
+   close(fd);
+   return result;
+}
+
+static void
+anv_physical_device_finish(struct anv_physical_device *device)
+{
+   ralloc_free(device->compiler);
+}
+
+static void *default_alloc(
+    void*                                       pUserData,
+    size_t                                      size,
+    size_t                                      alignment,
+    VkSystemAllocType                           allocType)
+{
+   return malloc(size);
+}
+
+static void default_free(
+    void*                                       pUserData,
+    void*                                       pMem)
+{
+   free(pMem);
+}
+
+static const VkAllocCallbacks default_alloc_callbacks = {
+   .pUserData = NULL,
+   .pfnAlloc = default_alloc,
+   .pfnFree = default_free
+};
+
+static const VkExtensionProperties global_extensions[] = {
+   {
+      .extName = VK_EXT_KHR_SWAPCHAIN_EXTENSION_NAME,
+      .specVersion = 17,
+   },
+};
+
+static const VkExtensionProperties device_extensions[] = {
+   {
+      .extName = VK_EXT_KHR_DEVICE_SWAPCHAIN_EXTENSION_NAME,
+      .specVersion = 53,
+   },
+};
+
+VkResult anv_CreateInstance(
+    const VkInstanceCreateInfo*                 pCreateInfo,
+    VkInstance*                                 pInstance)
+{
+   struct anv_instance *instance;
+   const VkAllocCallbacks *alloc_callbacks = &default_alloc_callbacks;
+   void *user_data = NULL;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
+
+   if (pCreateInfo->pAppInfo->apiVersion != VK_MAKE_VERSION(0, 170, 2))
+      return vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
+
+   for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
+      bool found = false;
+      for (uint32_t j = 0; j < ARRAY_SIZE(global_extensions); j++) {
+         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
+                    global_extensions[j].extName) == 0) {
+            found = true;
+            break;
+         }
+      }
+      if (!found)
+         return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
+   }
+
+   if (pCreateInfo->pAllocCb) {
+      alloc_callbacks = pCreateInfo->pAllocCb;
+      user_data = pCreateInfo->pAllocCb->pUserData;
+   }
+   instance = alloc_callbacks->pfnAlloc(user_data, sizeof(*instance), 8,
+                                        VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!instance)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   instance->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
+   instance->pAllocUserData = alloc_callbacks->pUserData;
+   instance->pfnAlloc = alloc_callbacks->pfnAlloc;
+   instance->pfnFree = alloc_callbacks->pfnFree;
+   instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
+   instance->physicalDeviceCount = -1;
+
+   _mesa_locale_init();
+
+   VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
+
+   anv_init_wsi(instance);
+
+   *pInstance = anv_instance_to_handle(instance);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyInstance(
+    VkInstance                                  _instance)
+{
+   ANV_FROM_HANDLE(anv_instance, instance, _instance);
+
+   if (instance->physicalDeviceCount > 0) {
+      /* We support at most one physical device. */
+      assert(instance->physicalDeviceCount == 1);
+      anv_physical_device_finish(&instance->physicalDevice);
+   }
+
+   anv_finish_wsi(instance);
+
+   VG(VALGRIND_DESTROY_MEMPOOL(instance));
+
+   _mesa_locale_fini();
+
+   instance->pfnFree(instance->pAllocUserData, instance);
+}
+
+void *
+anv_instance_alloc(struct anv_instance *instance, size_t size,
+                   size_t alignment, VkSystemAllocType allocType)
+{
+   void *mem = instance->pfnAlloc(instance->pAllocUserData,
+                                  size, alignment, allocType);
+   if (mem) {
+      VG(VALGRIND_MEMPOOL_ALLOC(instance, mem, size));
+      VG(VALGRIND_MAKE_MEM_UNDEFINED(mem, size));
+   }
+   return mem;
+}
+
+void
+anv_instance_free(struct anv_instance *instance, void *mem)
+{
+   if (mem == NULL)
+      return;
+
+   VG(VALGRIND_MEMPOOL_FREE(instance, mem));
+
+   instance->pfnFree(instance->pAllocUserData, mem);
+}
+
+VkResult anv_EnumeratePhysicalDevices(
+    VkInstance                                  _instance,
+    uint32_t*                                   pPhysicalDeviceCount,
+    VkPhysicalDevice*                           pPhysicalDevices)
+{
+   ANV_FROM_HANDLE(anv_instance, instance, _instance);
+   VkResult result;
+
+   if (instance->physicalDeviceCount < 0) {
+      result = anv_physical_device_init(&instance->physicalDevice,
+                                        instance, "/dev/dri/renderD128");
+      if (result == VK_UNSUPPORTED) {
+         instance->physicalDeviceCount = 0;
+      } else if (result == VK_SUCCESS) {
+         instance->physicalDeviceCount = 1;
+      } else {
+         return result;
+      }
+   }
+
+   /* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
+    * otherwise it's an inout parameter.
+    *
+    * The Vulkan spec (git aaed022) says:
+    *
+    *    pPhysicalDeviceCount is a pointer to an unsigned integer variable
+    *    that is initialized with the number of devices the application is
+    *    prepared to receive handles to. pname:pPhysicalDevices is pointer to
+    *    an array of at least this many VkPhysicalDevice handles [...].
+    *
+    *    Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
+    *    overwrites the contents of the variable pointed to by
+    *    pPhysicalDeviceCount with the number of physical devices in in the
+    *    instance; otherwise, vkEnumeratePhysicalDevices overwrites
+    *    pPhysicalDeviceCount with the number of physical handles written to
+    *    pPhysicalDevices.
+    */
+   if (!pPhysicalDevices) {
+      *pPhysicalDeviceCount = instance->physicalDeviceCount;
+   } else if (*pPhysicalDeviceCount >= 1) {
+      pPhysicalDevices[0] = anv_physical_device_to_handle(&instance->physicalDevice);
+      *pPhysicalDeviceCount = 1;
+   } else {
+      *pPhysicalDeviceCount = 0;
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceFeatures(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceFeatures*                   pFeatures)
+{
+   anv_finishme("Get correct values for PhysicalDeviceFeatures");
+
+   *pFeatures = (VkPhysicalDeviceFeatures) {
+      .robustBufferAccess                       = false,
+      .fullDrawIndexUint32                      = false,
+      .imageCubeArray                           = false,
+      .independentBlend                         = false,
+      .geometryShader                           = true,
+      .tessellationShader                       = false,
+      .sampleRateShading                        = false,
+      .dualSourceBlend                          = true,
+      .logicOp                                  = true,
+      .multiDrawIndirect                        = true,
+      .depthClip                                = false,
+      .depthBiasClamp                           = false,
+      .fillModeNonSolid                         = true,
+      .depthBounds                              = false,
+      .wideLines                                = true,
+      .largePoints                              = true,
+      .textureCompressionETC2                   = true,
+      .textureCompressionASTC_LDR               = true,
+      .textureCompressionBC                     = true,
+      .occlusionQueryNonConservative            = false, /* FINISHME */
+      .pipelineStatisticsQuery                  = true,
+      .vertexSideEffects                        = false,
+      .tessellationSideEffects                  = false,
+      .geometrySideEffects                      = false,
+      .fragmentSideEffects                      = false,
+      .shaderTessellationPointSize              = false,
+      .shaderGeometryPointSize                  = true,
+      .shaderImageGatherExtended                = true,
+      .shaderStorageImageExtendedFormats        = false,
+      .shaderStorageImageMultisample            = false,
+      .shaderUniformBufferArrayDynamicIndexing  = true,
+      .shaderSampledImageArrayDynamicIndexing   = false,
+      .shaderStorageBufferArrayDynamicIndexing  = false,
+      .shaderStorageImageArrayDynamicIndexing   = false,
+      .shaderClipDistance                       = false,
+      .shaderCullDistance                       = false,
+      .shaderFloat64                            = false,
+      .shaderInt64                              = false,
+      .shaderInt16                              = false,
+      .alphaToOne                               = true,
+   };
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceProperties*                 pProperties)
+{
+   ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
+   const struct brw_device_info *devinfo = pdevice->info;
+
+   anv_finishme("Get correct values for VkPhysicalDeviceLimits");
+
+   VkPhysicalDeviceLimits limits = {
+      .maxImageDimension1D                      = (1 << 14),
+      .maxImageDimension2D                      = (1 << 14),
+      .maxImageDimension3D                      = (1 << 10),
+      .maxImageDimensionCube                    = (1 << 14),
+      .maxImageArrayLayers                      = (1 << 10),
+
+      /* Broadwell supports 1, 2, 4, and 8 samples. */
+      .sampleCounts                             = 4,
+
+      .maxTexelBufferSize                       = (1 << 14),
+      .maxUniformBufferSize                     = UINT32_MAX,
+      .maxStorageBufferSize                     = UINT32_MAX,
+      .maxPushConstantsSize                     = MAX_PUSH_CONSTANTS_SIZE,
+      .maxMemoryAllocationCount                 = UINT32_MAX,
+      .bufferImageGranularity                   = 64, /* A cache line */
+      .sparseAddressSpaceSize                   = 0,
+      .maxBoundDescriptorSets                   = MAX_SETS,
+      .maxDescriptorSets                        = UINT32_MAX,
+      .maxPerStageDescriptorSamplers            = 64,
+      .maxPerStageDescriptorUniformBuffers      = 64,
+      .maxPerStageDescriptorStorageBuffers      = 64,
+      .maxPerStageDescriptorSampledImages       = 64,
+      .maxPerStageDescriptorStorageImages       = 64,
+      .maxDescriptorSetSamplers                 = 256,
+      .maxDescriptorSetUniformBuffers           = 256,
+      .maxDescriptorSetUniformBuffersDynamic    = 256,
+      .maxDescriptorSetStorageBuffers           = 256,
+      .maxDescriptorSetStorageBuffersDynamic    = 256,
+      .maxDescriptorSetSampledImages            = 256,
+      .maxDescriptorSetStorageImages            = 256,
+      .maxVertexInputAttributes                 = 32,
+      .maxVertexInputBindings                   = 32,
+      .maxVertexInputAttributeOffset            = 256,
+      .maxVertexInputBindingStride              = 256,
+      .maxVertexOutputComponents                = 32,
+      .maxTessGenLevel                          = 0,
+      .maxTessPatchSize                         = 0,
+      .maxTessControlPerVertexInputComponents   = 0,
+      .maxTessControlPerVertexOutputComponents  = 0,
+      .maxTessControlPerPatchOutputComponents   = 0,
+      .maxTessControlTotalOutputComponents      = 0,
+      .maxTessEvaluationInputComponents         = 0,
+      .maxTessEvaluationOutputComponents        = 0,
+      .maxGeometryShaderInvocations             = 6,
+      .maxGeometryInputComponents               = 16,
+      .maxGeometryOutputComponents              = 16,
+      .maxGeometryOutputVertices                = 16,
+      .maxGeometryTotalOutputComponents         = 16,
+      .maxFragmentInputComponents               = 16,
+      .maxFragmentOutputBuffers                 = 8,
+      .maxFragmentDualSourceBuffers             = 2,
+      .maxFragmentCombinedOutputResources       = 8,
+      .maxComputeSharedMemorySize               = 1024,
+      .maxComputeWorkGroupCount = {
+         16 * devinfo->max_cs_threads,
+         16 * devinfo->max_cs_threads,
+         16 * devinfo->max_cs_threads,
+      },
+      .maxComputeWorkGroupInvocations           = 16 * devinfo->max_cs_threads,
+      .maxComputeWorkGroupSize = {
+         16 * devinfo->max_cs_threads,
+         16 * devinfo->max_cs_threads,
+         16 * devinfo->max_cs_threads,
+      },
+      .subPixelPrecisionBits                    = 4 /* FIXME */,
+      .subTexelPrecisionBits                    = 4 /* FIXME */,
+      .mipmapPrecisionBits                      = 4 /* FIXME */,
+      .maxDrawIndexedIndexValue                 = UINT32_MAX,
+      .maxDrawIndirectInstanceCount             = UINT32_MAX,
+      .primitiveRestartForPatches               = UINT32_MAX,
+      .maxSamplerLodBias                        = 16,
+      .maxSamplerAnisotropy                     = 16,
+      .maxViewports                             = MAX_VIEWPORTS,
+      .maxViewportDimensions                    = { (1 << 14), (1 << 14) },
+      .viewportBoundsRange                      = { -1.0, 1.0 }, /* FIXME */
+      .viewportSubPixelBits                     = 13, /* We take a float? */
+      .minMemoryMapAlignment                    = 64, /* A cache line */
+      .minTexelBufferOffsetAlignment            = 1,
+      .minUniformBufferOffsetAlignment          = 1,
+      .minStorageBufferOffsetAlignment          = 1,
+      .minTexelOffset                           = 0, /* FIXME */
+      .maxTexelOffset                           = 0, /* FIXME */
+      .minTexelGatherOffset                     = 0, /* FIXME */
+      .maxTexelGatherOffset                     = 0, /* FIXME */
+      .minInterpolationOffset                   = 0, /* FIXME */
+      .maxInterpolationOffset                   = 0, /* FIXME */
+      .subPixelInterpolationOffsetBits          = 0, /* FIXME */
+      .maxFramebufferWidth                      = (1 << 14),
+      .maxFramebufferHeight                     = (1 << 14),
+      .maxFramebufferLayers                     = (1 << 10),
+      .maxFramebufferColorSamples               = 8,
+      .maxFramebufferDepthSamples               = 8,
+      .maxFramebufferStencilSamples             = 8,
+      .maxColorAttachments                      = MAX_RTS,
+      .maxSampledImageColorSamples              = 8,
+      .maxSampledImageDepthSamples              = 8,
+      .maxSampledImageIntegerSamples            = 1,
+      .maxStorageImageSamples                   = 1,
+      .maxSampleMaskWords                       = 1,
+      .timestampFrequency                       = 1000 * 1000 * 1000 / 80,
+      .maxClipDistances                         = 0 /* FIXME */,
+      .maxCullDistances                         = 0 /* FIXME */,
+      .maxCombinedClipAndCullDistances          = 0 /* FIXME */,
+      .pointSizeRange                           = { 0.125, 255.875 },
+      .lineWidthRange                           = { 0.0, 7.9921875 },
+      .pointSizeGranularity                     = (1.0 / 8.0),
+      .lineWidthGranularity                     = (1.0 / 128.0),
+   };
+
+   *pProperties = (VkPhysicalDeviceProperties) {
+      .apiVersion = VK_MAKE_VERSION(0, 170, 2),
+      .driverVersion = 1,
+      .vendorId = 0x8086,
+      .deviceId = pdevice->chipset_id,
+      .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
+      .limits = limits,
+      .sparseProperties = {0}, /* Broadwell doesn't do sparse. */
+   };
+
+   strcpy(pProperties->deviceName, pdevice->name);
+   snprintf((char *)pProperties->pipelineCacheUUID, VK_UUID_LENGTH,
+            "anv-%s", MESA_GIT_SHA1 + 4);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceQueueFamilyProperties(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pCount,
+    VkQueueFamilyProperties*                    pQueueFamilyProperties)
+{
+   if (pQueueFamilyProperties == NULL) {
+      *pCount = 1;
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= 1);
+
+   *pQueueFamilyProperties = (VkQueueFamilyProperties) {
+      .queueFlags = VK_QUEUE_GRAPHICS_BIT |
+                    VK_QUEUE_COMPUTE_BIT |
+                    VK_QUEUE_DMA_BIT,
+      .queueCount = 1,
+      .supportsTimestamps = true,
+   };
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceMemoryProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceMemoryProperties*           pMemoryProperties)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   VkDeviceSize heap_size;
+
+   /* Reserve some wiggle room for the driver by exposing only 75% of the
+    * aperture to the heap.
+    */
+   heap_size = 3 * physical_device->aperture_size / 4;
+
+   /* The property flags below are valid only for llc platforms. */
+   pMemoryProperties->memoryTypeCount = 1;
+   pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
+      .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+      .heapIndex = 1,
+   };
+
+   pMemoryProperties->memoryHeapCount = 1;
+   pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
+      .size = heap_size,
+      .flags = VK_MEMORY_HEAP_HOST_LOCAL_BIT,
+   };
+
+   return VK_SUCCESS;
+}
+
+PFN_vkVoidFunction anv_GetInstanceProcAddr(
+    VkInstance                                  instance,
+    const char*                                 pName)
+{
+   return anv_lookup_entrypoint(pName);
+}
+
+PFN_vkVoidFunction anv_GetDeviceProcAddr(
+    VkDevice                                    device,
+    const char*                                 pName)
+{
+   return anv_lookup_entrypoint(pName);
+}
+
+static VkResult
+anv_queue_init(struct anv_device *device, struct anv_queue *queue)
+{
+   queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
+   queue->device = device;
+   queue->pool = &device->surface_state_pool;
+
+   return VK_SUCCESS;
+}
+
+static void
+anv_queue_finish(struct anv_queue *queue)
+{
+}
+
+static void
+anv_device_init_border_colors(struct anv_device *device)
+{
+   static const VkClearColorValue border_colors[] = {
+      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .float32 = { 0.0, 0.0, 0.0, 0.0 } },
+      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =       { .float32 = { 0.0, 0.0, 0.0, 1.0 } },
+      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =       { .float32 = { 1.0, 1.0, 1.0, 1.0 } },
+      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =    { .uint32 = { 0, 0, 0, 0 } },
+      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =         { .uint32 = { 0, 0, 0, 1 } },
+      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =         { .uint32 = { 1, 1, 1, 1 } },
+   };
+
+   device->border_colors =
+      anv_state_pool_alloc(&device->dynamic_state_pool,
+                           sizeof(border_colors), 32);
+   memcpy(device->border_colors.map, border_colors, sizeof(border_colors));
+}
+
+VkResult anv_CreateDevice(
+    VkPhysicalDevice                            physicalDevice,
+    const VkDeviceCreateInfo*                   pCreateInfo,
+    VkDevice*                                   pDevice)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   struct anv_instance *instance = physical_device->instance;
+   struct anv_device *device;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
+
+   for (uint32_t i = 0; i < pCreateInfo->extensionCount; i++) {
+      bool found = false;
+      for (uint32_t j = 0; j < ARRAY_SIZE(device_extensions); j++) {
+         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
+                    device_extensions[j].extName) == 0) {
+            found = true;
+            break;
+         }
+      }
+      if (!found)
+         return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
+   }
+
+   anv_set_dispatch_gen(physical_device->info->gen);
+
+   device = anv_instance_alloc(instance, sizeof(*device), 8,
+                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!device)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
+   device->instance = physical_device->instance;
+
+   /* XXX(chadv): Can we dup() physicalDevice->fd here? */
+   device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
+   if (device->fd == -1)
+      goto fail_device;
+
+   device->context_id = anv_gem_create_context(device);
+   if (device->context_id == -1)
+      goto fail_fd;
+
+   pthread_mutex_init(&device->mutex, NULL);
+
+   anv_bo_pool_init(&device->batch_bo_pool, device, ANV_CMD_BUFFER_BATCH_SIZE);
+
+   anv_block_pool_init(&device->dynamic_state_block_pool, device, 2048);
+
+   anv_state_pool_init(&device->dynamic_state_pool,
+                       &device->dynamic_state_block_pool);
+
+   anv_block_pool_init(&device->instruction_block_pool, device, 4096);
+   anv_block_pool_init(&device->surface_state_block_pool, device, 4096);
+
+   anv_state_pool_init(&device->surface_state_pool,
+                       &device->surface_state_block_pool);
+
+   anv_bo_init_new(&device->workaround_bo, device, 1024);
+
+   anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
+
+   device->info = *physical_device->info;
+   device->isl_dev = physical_device->isl_dev;
+
+   anv_queue_init(device, &device->queue);
+
+   anv_device_init_meta(device);
+
+   anv_device_init_border_colors(device);
+
+   *pDevice = anv_device_to_handle(device);
+
+   return VK_SUCCESS;
+
+ fail_fd:
+   close(device->fd);
+ fail_device:
+   anv_device_free(device, device);
+
+   return vk_error(VK_ERROR_INITIALIZATION_FAILED);
+}
+
+void anv_DestroyDevice(
+    VkDevice                                    _device)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   anv_queue_finish(&device->queue);
+
+   anv_device_finish_meta(device);
+
+#ifdef HAVE_VALGRIND
+   /* We only need to free these to prevent valgrind errors.  The backing
+    * BO will go away in a couple of lines so we don't actually leak.
+    */
+   anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
+#endif
+
+   anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size);
+   anv_gem_close(device, device->workaround_bo.gem_handle);
+
+   anv_bo_pool_finish(&device->batch_bo_pool);
+   anv_state_pool_finish(&device->dynamic_state_pool);
+   anv_block_pool_finish(&device->dynamic_state_block_pool);
+   anv_block_pool_finish(&device->instruction_block_pool);
+   anv_state_pool_finish(&device->surface_state_pool);
+   anv_block_pool_finish(&device->surface_state_block_pool);
+   anv_block_pool_finish(&device->scratch_block_pool);
+
+   close(device->fd);
+
+   anv_instance_free(device->instance, device);
+}
+
+VkResult anv_EnumerateInstanceExtensionProperties(
+    const char*                                 pLayerName,
+    uint32_t*                                   pCount,
+    VkExtensionProperties*                      pProperties)
+{
+   if (pProperties == NULL) {
+      *pCount = ARRAY_SIZE(global_extensions);
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= ARRAY_SIZE(global_extensions));
+
+   *pCount = ARRAY_SIZE(global_extensions);
+   memcpy(pProperties, global_extensions, sizeof(global_extensions));
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_EnumerateDeviceExtensionProperties(
+    VkPhysicalDevice                            physicalDevice,
+    const char*                                 pLayerName,
+    uint32_t*                                   pCount,
+    VkExtensionProperties*                      pProperties)
+{
+   if (pProperties == NULL) {
+      *pCount = ARRAY_SIZE(device_extensions);
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= ARRAY_SIZE(device_extensions));
+
+   *pCount = ARRAY_SIZE(device_extensions);
+   memcpy(pProperties, device_extensions, sizeof(device_extensions));
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_EnumerateInstanceLayerProperties(
+    uint32_t*                                   pCount,
+    VkLayerProperties*                          pProperties)
+{
+   if (pProperties == NULL) {
+      *pCount = 0;
+      return VK_SUCCESS;
+   }
+
+   /* None supported at this time */
+   return vk_error(VK_ERROR_LAYER_NOT_PRESENT);
+}
+
+VkResult anv_EnumerateDeviceLayerProperties(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pCount,
+    VkLayerProperties*                          pProperties)
+{
+   if (pProperties == NULL) {
+      *pCount = 0;
+      return VK_SUCCESS;
+   }
+
+   /* None supported at this time */
+   return vk_error(VK_ERROR_LAYER_NOT_PRESENT);
+}
+
+VkResult anv_GetDeviceQueue(
+    VkDevice                                    _device,
+    uint32_t                                    queueNodeIndex,
+    uint32_t                                    queueIndex,
+    VkQueue*                                    pQueue)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   assert(queueIndex == 0);
+
+   *pQueue = anv_queue_to_handle(&device->queue);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_QueueSubmit(
+    VkQueue                                     _queue,
+    uint32_t                                    cmdBufferCount,
+    const VkCmdBuffer*                          pCmdBuffers,
+    VkFence                                     _fence)
+{
+   ANV_FROM_HANDLE(anv_queue, queue, _queue);
+   ANV_FROM_HANDLE(anv_fence, fence, _fence);
+   struct anv_device *device = queue->device;
+   int ret;
+
+   for (uint32_t i = 0; i < cmdBufferCount; i++) {
+      ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCmdBuffers[i]);
+
+      assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+
+      ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf2.execbuf);
+      if (ret != 0) {
+         /* We don't know the real error. */
+         return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                          "execbuf2 failed: %m");
+      }
+
+      if (fence) {
+         ret = anv_gem_execbuffer(device, &fence->execbuf);
+         if (ret != 0) {
+            /* We don't know the real error. */
+            return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                             "execbuf2 failed: %m");
+         }
+      }
+
+      for (uint32_t i = 0; i < cmd_buffer->execbuf2.bo_count; i++)
+         cmd_buffer->execbuf2.bos[i]->offset = cmd_buffer->execbuf2.objects[i].offset;
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_QueueWaitIdle(
+    VkQueue                                     _queue)
+{
+   ANV_FROM_HANDLE(anv_queue, queue, _queue);
+
+   return ANV_CALL(DeviceWaitIdle)(anv_device_to_handle(queue->device));
+}
+
+VkResult anv_DeviceWaitIdle(
+    VkDevice                                    _device)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_state state;
+   struct anv_batch batch;
+   struct drm_i915_gem_execbuffer2 execbuf;
+   struct drm_i915_gem_exec_object2 exec2_objects[1];
+   struct anv_bo *bo = NULL;
+   VkResult result;
+   int64_t timeout;
+   int ret;
+
+   state = anv_state_pool_alloc(&device->dynamic_state_pool, 32, 32);
+   bo = &device->dynamic_state_pool.block_pool->bo;
+   batch.start = batch.next = state.map;
+   batch.end = state.map + 32;
+   anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END);
+   anv_batch_emit(&batch, GEN7_MI_NOOP);
+
+   exec2_objects[0].handle = bo->gem_handle;
+   exec2_objects[0].relocation_count = 0;
+   exec2_objects[0].relocs_ptr = 0;
+   exec2_objects[0].alignment = 0;
+   exec2_objects[0].offset = bo->offset;
+   exec2_objects[0].flags = 0;
+   exec2_objects[0].rsvd1 = 0;
+   exec2_objects[0].rsvd2 = 0;
+
+   execbuf.buffers_ptr = (uintptr_t) exec2_objects;
+   execbuf.buffer_count = 1;
+   execbuf.batch_start_offset = state.offset;
+   execbuf.batch_len = batch.next - state.map;
+   execbuf.cliprects_ptr = 0;
+   execbuf.num_cliprects = 0;
+   execbuf.DR1 = 0;
+   execbuf.DR4 = 0;
+
+   execbuf.flags =
+      I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
+   execbuf.rsvd1 = device->context_id;
+   execbuf.rsvd2 = 0;
+
+   ret = anv_gem_execbuffer(device, &execbuf);
+   if (ret != 0) {
+      /* We don't know the real error. */
+      result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, "execbuf2 failed: %m");
+      goto fail;
+   }
+
+   timeout = INT64_MAX;
+   ret = anv_gem_wait(device, bo->gem_handle, &timeout);
+   if (ret != 0) {
+      /* We don't know the real error. */
+      result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, "execbuf2 failed: %m");
+      goto fail;
+   }
+
+   anv_state_pool_free(&device->dynamic_state_pool, state);
+
+   return VK_SUCCESS;
+
+ fail:
+   anv_state_pool_free(&device->dynamic_state_pool, state);
+
+   return result;
+}
+
+void *
+anv_device_alloc(struct anv_device *            device,
+                 size_t                         size,
+                 size_t                         alignment,
+                 VkSystemAllocType              allocType)
+{
+   return anv_instance_alloc(device->instance, size, alignment, allocType);
+}
+
+void
+anv_device_free(struct anv_device *             device,
+                void *                          mem)
+{
+   anv_instance_free(device->instance, mem);
+}
+
+VkResult
+anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
+{
+   bo->gem_handle = anv_gem_create(device, size);
+   if (!bo->gem_handle)
+      return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+
+   bo->map = NULL;
+   bo->index = 0;
+   bo->offset = 0;
+   bo->size = size;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_AllocMemory(
+    VkDevice                                    _device,
+    const VkMemoryAllocInfo*                    pAllocInfo,
+    VkDeviceMemory*                             pMem)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_device_memory *mem;
+   VkResult result;
+
+   assert(pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO);
+
+   /* We support exactly one memory heap. */
+   assert(pAllocInfo->memoryTypeIndex == 0);
+
+   /* FINISHME: Fail if allocation request exceeds heap size. */
+
+   mem = anv_device_alloc(device, sizeof(*mem), 8,
+                          VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (mem == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   result = anv_bo_init_new(&mem->bo, device, pAllocInfo->allocationSize);
+   if (result != VK_SUCCESS)
+      goto fail;
+
+   *pMem = anv_device_memory_to_handle(mem);
+
+   return VK_SUCCESS;
+
+ fail:
+   anv_device_free(device, mem);
+
+   return result;
+}
+
+void anv_FreeMemory(
+    VkDevice                                    _device,
+    VkDeviceMemory                              _mem)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
+
+   if (mem->bo.map)
+      anv_gem_munmap(mem->bo.map, mem->bo.size);
+
+   if (mem->bo.gem_handle != 0)
+      anv_gem_close(device, mem->bo.gem_handle);
+
+   anv_device_free(device, mem);
+}
+
+VkResult anv_MapMemory(
+    VkDevice                                    _device,
+    VkDeviceMemory                              _mem,
+    VkDeviceSize                                offset,
+    VkDeviceSize                                size,
+    VkMemoryMapFlags                            flags,
+    void**                                      ppData)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
+
+   /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
+    * takes a VkDeviceMemory pointer, it seems like only one map of the memory
+    * at a time is valid. We could just mmap up front and return an offset
+    * pointer here, but that may exhaust virtual memory on 32 bit
+    * userspace. */
+
+   mem->map = anv_gem_mmap(device, mem->bo.gem_handle, offset, size);
+   mem->map_size = size;
+
+   *ppData = mem->map;
+
+   return VK_SUCCESS;
+}
+
+void anv_UnmapMemory(
+    VkDevice                                    _device,
+    VkDeviceMemory                              _mem)
+{
+   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
+
+   anv_gem_munmap(mem->map, mem->map_size);
+}
+
+VkResult anv_FlushMappedMemoryRanges(
+    VkDevice                                    device,
+    uint32_t                                    memRangeCount,
+    const VkMappedMemoryRange*                  pMemRanges)
+{
+   /* clflush here for !llc platforms */
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_InvalidateMappedMemoryRanges(
+    VkDevice                                    device,
+    uint32_t                                    memRangeCount,
+    const VkMappedMemoryRange*                  pMemRanges)
+{
+   return anv_FlushMappedMemoryRanges(device, memRangeCount, pMemRanges);
+}
+
+VkResult anv_GetBufferMemoryRequirements(
+    VkDevice                                    device,
+    VkBuffer                                    _buffer,
+    VkMemoryRequirements*                       pMemoryRequirements)
+{
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   /* The Vulkan spec (git aaed022) says:
+    *
+    *    memoryTypeBits is a bitfield and contains one bit set for every
+    *    supported memory type for the resource. The bit `1<<i` is set if and
+    *    only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
+    *    structure for the physical device is supported.
+    *
+    * We support exactly one memory type.
+    */
+   pMemoryRequirements->memoryTypeBits = 1;
+
+   pMemoryRequirements->size = buffer->size;
+   pMemoryRequirements->alignment = 16;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetImageMemoryRequirements(
+    VkDevice                                    device,
+    VkImage                                     _image,
+    VkMemoryRequirements*                       pMemoryRequirements)
+{
+   ANV_FROM_HANDLE(anv_image, image, _image);
+
+   /* The Vulkan spec (git aaed022) says:
+    *
+    *    memoryTypeBits is a bitfield and contains one bit set for every
+    *    supported memory type for the resource. The bit `1<<i` is set if and
+    *    only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
+    *    structure for the physical device is supported.
+    *
+    * We support exactly one memory type.
+    */
+   pMemoryRequirements->memoryTypeBits = 1;
+
+   pMemoryRequirements->size = image->size;
+   pMemoryRequirements->alignment = image->alignment;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetImageSparseMemoryRequirements(
+    VkDevice                                    device,
+    VkImage                                     image,
+    uint32_t*                                   pNumRequirements,
+    VkSparseImageMemoryRequirements*            pSparseMemoryRequirements)
+{
+   return vk_error(VK_UNSUPPORTED);
+}
+
+VkResult anv_GetDeviceMemoryCommitment(
+    VkDevice                                    device,
+    VkDeviceMemory                              memory,
+    VkDeviceSize*                               pCommittedMemoryInBytes)
+{
+   *pCommittedMemoryInBytes = 0;
+   stub_return(VK_SUCCESS);
+}
+
+VkResult anv_BindBufferMemory(
+    VkDevice                                    device,
+    VkBuffer                                    _buffer,
+    VkDeviceMemory                              _mem,
+    VkDeviceSize                                memOffset)
+{
+   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   buffer->bo = &mem->bo;
+   buffer->offset = memOffset;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_BindImageMemory(
+    VkDevice                                    device,
+    VkImage                                     _image,
+    VkDeviceMemory                              _mem,
+    VkDeviceSize                                memOffset)
+{
+   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
+   ANV_FROM_HANDLE(anv_image, image, _image);
+
+   image->bo = &mem->bo;
+   image->offset = memOffset;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_QueueBindSparseBufferMemory(
+    VkQueue                                     queue,
+    VkBuffer                                    buffer,
+    uint32_t                                    numBindings,
+    const VkSparseMemoryBindInfo*               pBindInfo)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_QueueBindSparseImageOpaqueMemory(
+    VkQueue                                     queue,
+    VkImage                                     image,
+    uint32_t                                    numBindings,
+    const VkSparseMemoryBindInfo*               pBindInfo)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_QueueBindSparseImageMemory(
+    VkQueue                                     queue,
+    VkImage                                     image,
+    uint32_t                                    numBindings,
+    const VkSparseImageMemoryBindInfo*          pBindInfo)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_CreateFence(
+    VkDevice                                    _device,
+    const VkFenceCreateInfo*                    pCreateInfo,
+    VkFence*                                    pFence)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_fence *fence;
+   struct anv_batch batch;
+   VkResult result;
+
+   const uint32_t fence_size = 128;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
+
+   fence = anv_device_alloc(device, sizeof(*fence), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (fence == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   result = anv_bo_init_new(&fence->bo, device, fence_size);
+   if (result != VK_SUCCESS)
+      goto fail;
+
+   fence->bo.map =
+      anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
+   batch.next = batch.start = fence->bo.map;
+   batch.end = fence->bo.map + fence->bo.size;
+   anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END);
+   anv_batch_emit(&batch, GEN7_MI_NOOP);
+
+   fence->exec2_objects[0].handle = fence->bo.gem_handle;
+   fence->exec2_objects[0].relocation_count = 0;
+   fence->exec2_objects[0].relocs_ptr = 0;
+   fence->exec2_objects[0].alignment = 0;
+   fence->exec2_objects[0].offset = fence->bo.offset;
+   fence->exec2_objects[0].flags = 0;
+   fence->exec2_objects[0].rsvd1 = 0;
+   fence->exec2_objects[0].rsvd2 = 0;
+
+   fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
+   fence->execbuf.buffer_count = 1;
+   fence->execbuf.batch_start_offset = 0;
+   fence->execbuf.batch_len = batch.next - fence->bo.map;
+   fence->execbuf.cliprects_ptr = 0;
+   fence->execbuf.num_cliprects = 0;
+   fence->execbuf.DR1 = 0;
+   fence->execbuf.DR4 = 0;
+
+   fence->execbuf.flags =
+      I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
+   fence->execbuf.rsvd1 = device->context_id;
+   fence->execbuf.rsvd2 = 0;
+
+   *pFence = anv_fence_to_handle(fence);
+
+   return VK_SUCCESS;
+
+ fail:
+   anv_device_free(device, fence);
+
+   return result;
+}
+
+void anv_DestroyFence(
+    VkDevice                                    _device,
+    VkFence                                     _fence)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_fence, fence, _fence);
+
+   anv_gem_munmap(fence->bo.map, fence->bo.size);
+   anv_gem_close(device, fence->bo.gem_handle);
+   anv_device_free(device, fence);
+}
+
+VkResult anv_ResetFences(
+    VkDevice                                    _device,
+    uint32_t                                    fenceCount,
+    const VkFence*                              pFences)
+{
+   for (uint32_t i = 0; i < fenceCount; i++) {
+      ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
+      fence->ready = false;
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetFenceStatus(
+    VkDevice                                    _device,
+    VkFence                                     _fence)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_fence, fence, _fence);
+   int64_t t = 0;
+   int ret;
+
+   if (fence->ready)
+      return VK_SUCCESS;
+
+   ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
+   if (ret == 0) {
+      fence->ready = true;
+      return VK_SUCCESS;
+   }
+
+   return VK_NOT_READY;
+}
+
+VkResult anv_WaitForFences(
+    VkDevice                                    _device,
+    uint32_t                                    fenceCount,
+    const VkFence*                              pFences,
+    VkBool32                                    waitAll,
+    uint64_t                                    timeout)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   /* DRM_IOCTL_I915_GEM_WAIT uses a signed 64 bit timeout and is supposed
+    * to block indefinitely timeouts <= 0.  Unfortunately, this was broken
+    * for a couple of kernel releases.  Since there's no way to know
+    * whether or not the kernel we're using is one of the broken ones, the
+    * best we can do is to clamp the timeout to INT64_MAX.  This limits the
+    * maximum timeout from 584 years to 292 years - likely not a big deal.
+    */
+   if (timeout > INT64_MAX)
+      timeout = INT64_MAX;
+
+   int64_t t = timeout;
+
+   /* FIXME: handle !waitAll */
+
+   for (uint32_t i = 0; i < fenceCount; i++) {
+      ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
+      int ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
+      if (ret == -1 && errno == ETIME) {
+         return VK_TIMEOUT;
+      } else if (ret == -1) {
+         /* We don't know the real error. */
+         return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                          "gem wait failed: %m");
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+// Queue semaphore functions
+
+VkResult anv_CreateSemaphore(
+    VkDevice                                    device,
+    const VkSemaphoreCreateInfo*                pCreateInfo,
+    VkSemaphore*                                pSemaphore)
+{
+   pSemaphore->handle = 1;
+   stub_return(VK_SUCCESS);
+}
+
+void anv_DestroySemaphore(
+    VkDevice                                    device,
+    VkSemaphore                                 semaphore)
+{
+   stub();
+}
+
+VkResult anv_QueueSignalSemaphore(
+    VkQueue                                     queue,
+    VkSemaphore                                 semaphore)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_QueueWaitSemaphore(
+    VkQueue                                     queue,
+    VkSemaphore                                 semaphore)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+// Event functions
+
+VkResult anv_CreateEvent(
+    VkDevice                                    device,
+    const VkEventCreateInfo*                    pCreateInfo,
+    VkEvent*                                    pEvent)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+void anv_DestroyEvent(
+    VkDevice                                    device,
+    VkEvent                                     event)
+{
+   stub();
+}
+
+VkResult anv_GetEventStatus(
+    VkDevice                                    device,
+    VkEvent                                     event)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_SetEvent(
+    VkDevice                                    device,
+    VkEvent                                     event)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_ResetEvent(
+    VkDevice                                    device,
+    VkEvent                                     event)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+// Buffer functions
+
+VkResult anv_CreateBuffer(
+    VkDevice                                    _device,
+    const VkBufferCreateInfo*                   pCreateInfo,
+    VkBuffer*                                   pBuffer)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_buffer *buffer;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
+
+   buffer = anv_device_alloc(device, sizeof(*buffer), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (buffer == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   buffer->size = pCreateInfo->size;
+   buffer->bo = NULL;
+   buffer->offset = 0;
+
+   *pBuffer = anv_buffer_to_handle(buffer);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyBuffer(
+    VkDevice                                    _device,
+    VkBuffer                                    _buffer)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   anv_device_free(device, buffer);
+}
+
+void
+anv_fill_buffer_surface_state(struct anv_device *device, void *state,
+                              const struct anv_format *format,
+                              uint32_t offset, uint32_t range, uint32_t stride)
+{
+   switch (device->info.gen) {
+   case 7:
+      gen7_fill_buffer_surface_state(state, format, offset, range, stride);
+      break;
+   case 8:
+      gen8_fill_buffer_surface_state(state, format, offset, range, stride);
+      break;
+   default:
+      unreachable("unsupported gen\n");
+   }
+}
+
+VkResult anv_CreateBufferView(
+    VkDevice                                    _device,
+    const VkBufferViewCreateInfo*               pCreateInfo,
+    VkBufferView*                               pView)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+void anv_DestroyBufferView(
+    VkDevice                                    _device,
+    VkBufferView                                _bview)
+{
+   stub();
+}
+
+void anv_DestroySampler(
+    VkDevice                                    _device,
+    VkSampler                                   _sampler)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);
+
+   anv_device_free(device, sampler);
+}
+
+// Descriptor set functions
+
+VkResult anv_CreateDescriptorSetLayout(
+    VkDevice                                    _device,
+    const VkDescriptorSetLayoutCreateInfo*      pCreateInfo,
+    VkDescriptorSetLayout*                      pSetLayout)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_descriptor_set_layout *set_layout;
+   uint32_t s;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
+
+   uint32_t immutable_sampler_count = 0;
+   for (uint32_t b = 0; b < pCreateInfo->count; b++) {
+      if (pCreateInfo->pBinding[b].pImmutableSamplers)
+         immutable_sampler_count += pCreateInfo->pBinding[b].arraySize;
+   }
+
+   size_t size = sizeof(struct anv_descriptor_set_layout) +
+                 pCreateInfo->count * sizeof(set_layout->binding[0]) +
+                 immutable_sampler_count * sizeof(struct anv_sampler *);
+
+   set_layout = anv_device_alloc(device, size, 8,
+                                 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!set_layout)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   /* We just allocate all the samplers at the end of the struct */
+   struct anv_sampler **samplers =
+      (struct anv_sampler **)&set_layout->binding[pCreateInfo->count];
+
+   set_layout->binding_count = pCreateInfo->count;
+   set_layout->shader_stages = 0;
+   set_layout->size = 0;
+
+   /* Initialize all binding_layout entries to -1 */
+   memset(set_layout->binding, -1,
+          pCreateInfo->count * sizeof(set_layout->binding[0]));
+
+   /* Initialize all samplers to 0 */
+   memset(samplers, 0, immutable_sampler_count * sizeof(*samplers));
+
+   uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
+   uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
+   uint32_t dynamic_offset_count = 0;
+
+   for (uint32_t b = 0; b < pCreateInfo->count; b++) {
+      uint32_t array_size = MAX2(1, pCreateInfo->pBinding[b].arraySize);
+      set_layout->binding[b].array_size = array_size;
+      set_layout->binding[b].descriptor_index = set_layout->size;
+      set_layout->size += array_size;
+
+      switch (pCreateInfo->pBinding[b].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         for_each_bit(s, pCreateInfo->pBinding[b].stageFlags) {
+            set_layout->binding[b].stage[s].sampler_index = sampler_count[s];
+            sampler_count[s] += array_size;
+         }
+         break;
+      default:
+         break;
+      }
+
+      switch (pCreateInfo->pBinding[b].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+         for_each_bit(s, pCreateInfo->pBinding[b].stageFlags) {
+            set_layout->binding[b].stage[s].surface_index = surface_count[s];
+            surface_count[s] += array_size;
+         }
+         break;
+      default:
+         break;
+      }
+
+      switch (pCreateInfo->pBinding[b].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+         set_layout->binding[b].dynamic_offset_index = dynamic_offset_count;
+         dynamic_offset_count += array_size;
+         break;
+      default:
+         break;
+      }
+
+      if (pCreateInfo->pBinding[b].pImmutableSamplers) {
+         set_layout->binding[b].immutable_samplers = samplers;
+         samplers += array_size;
+
+         for (uint32_t i = 0; i < array_size; i++)
+            set_layout->binding[b].immutable_samplers[i] =
+               anv_sampler_from_handle(pCreateInfo->pBinding[b].pImmutableSamplers[i]);
+      } else {
+         set_layout->binding[b].immutable_samplers = NULL;
+      }
+
+      set_layout->shader_stages |= pCreateInfo->pBinding[b].stageFlags;
+   }
+
+   set_layout->dynamic_offset_count = dynamic_offset_count;
+
+   *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyDescriptorSetLayout(
+    VkDevice                                    _device,
+    VkDescriptorSetLayout                       _set_layout)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout, _set_layout);
+
+   anv_device_free(device, set_layout);
+}
+
+VkResult anv_CreateDescriptorPool(
+    VkDevice                                    device,
+    const VkDescriptorPoolCreateInfo*           pCreateInfo,
+    VkDescriptorPool*                           pDescriptorPool)
+{
+   anv_finishme("VkDescriptorPool is a stub");
+   pDescriptorPool->handle = 1;
+   return VK_SUCCESS;
+}
+
+void anv_DestroyDescriptorPool(
+    VkDevice                                    _device,
+    VkDescriptorPool                            _pool)
+{
+   anv_finishme("VkDescriptorPool is a stub: free the pool's descriptor sets");
+}
+
+VkResult anv_ResetDescriptorPool(
+    VkDevice                                    device,
+    VkDescriptorPool                            descriptorPool)
+{
+   anv_finishme("VkDescriptorPool is a stub: free the pool's descriptor sets");
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_descriptor_set_create(struct anv_device *device,
+                          const struct anv_descriptor_set_layout *layout,
+                          struct anv_descriptor_set **out_set)
+{
+   struct anv_descriptor_set *set;
+   size_t size = sizeof(*set) + layout->size * sizeof(set->descriptors[0]);
+
+   set = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!set)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   /* A descriptor set may not be 100% filled. Clear the set so we can can
+    * later detect holes in it.
+    */
+   memset(set, 0, size);
+
+   set->layout = layout;
+
+   /* Go through and fill out immutable samplers if we have any */
+   struct anv_descriptor *desc = set->descriptors;
+   for (uint32_t b = 0; b < layout->binding_count; b++) {
+      if (layout->binding[b].immutable_samplers) {
+         for (uint32_t i = 0; i < layout->binding[b].array_size; i++)
+            desc[i].sampler = layout->binding[b].immutable_samplers[i];
+      }
+      desc += layout->binding[b].array_size;
+   }
+
+   *out_set = set;
+
+   return VK_SUCCESS;
+}
+
+void
+anv_descriptor_set_destroy(struct anv_device *device,
+                           struct anv_descriptor_set *set)
+{
+   anv_device_free(device, set);
+}
+
+VkResult anv_AllocDescriptorSets(
+    VkDevice                                    _device,
+    VkDescriptorPool                            descriptorPool,
+    VkDescriptorSetUsage                        setUsage,
+    uint32_t                                    count,
+    const VkDescriptorSetLayout*                pSetLayouts,
+    VkDescriptorSet*                            pDescriptorSets)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   VkResult result = VK_SUCCESS;
+   struct anv_descriptor_set *set;
+   uint32_t i;
+
+   for (i = 0; i < count; i++) {
+      ANV_FROM_HANDLE(anv_descriptor_set_layout, layout, pSetLayouts[i]);
+
+      result = anv_descriptor_set_create(device, layout, &set);
+      if (result != VK_SUCCESS)
+         break;
+
+      pDescriptorSets[i] = anv_descriptor_set_to_handle(set);
+   }
+
+   if (result != VK_SUCCESS)
+      anv_FreeDescriptorSets(_device, descriptorPool, i, pDescriptorSets);
+
+   return result;
+}
+
+VkResult anv_FreeDescriptorSets(
+    VkDevice                                    _device,
+    VkDescriptorPool                            descriptorPool,
+    uint32_t                                    count,
+    const VkDescriptorSet*                      pDescriptorSets)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   for (uint32_t i = 0; i < count; i++) {
+      ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
+
+      anv_descriptor_set_destroy(device, set);
+   }
+
+   return VK_SUCCESS;
+}
+
+void anv_UpdateDescriptorSets(
+    VkDevice                                    device,
+    uint32_t                                    writeCount,
+    const VkWriteDescriptorSet*                 pDescriptorWrites,
+    uint32_t                                    copyCount,
+    const VkCopyDescriptorSet*                  pDescriptorCopies)
+{
+   for (uint32_t i = 0; i < writeCount; i++) {
+      const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
+      ANV_FROM_HANDLE(anv_descriptor_set, set, write->destSet);
+      const struct anv_descriptor_set_binding_layout *bind_layout =
+         &set->layout->binding[write->destBinding];
+      struct anv_descriptor *desc =
+         &set->descriptors[bind_layout->descriptor_index];
+
+      switch (write->descriptorType) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+         for (uint32_t j = 0; j < write->count; j++) {
+            ANV_FROM_HANDLE(anv_sampler, sampler,
+                            write->pDescriptors[j].sampler);
+
+            desc[j] = (struct anv_descriptor) {
+               .type = VK_DESCRIPTOR_TYPE_SAMPLER,
+               .sampler = sampler,
+            };
+         }
+         break;
+
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         for (uint32_t j = 0; j < write->count; j++) {
+            ANV_FROM_HANDLE(anv_image_view, iview,
+                            write->pDescriptors[j].imageView);
+            ANV_FROM_HANDLE(anv_sampler, sampler,
+                            write->pDescriptors[j].sampler);
+
+            desc[j].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
+            desc[j].image_view = iview;
+
+            /* If this descriptor has an immutable sampler, we don't want
+             * to stomp on it.
+             */
+            if (sampler)
+               desc->sampler = sampler;
+         }
+         break;
+
+      case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+      case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+         for (uint32_t j = 0; j < write->count; j++) {
+            ANV_FROM_HANDLE(anv_image_view, iview,
+                            write->pDescriptors[j].imageView);
+
+            desc[j] = (struct anv_descriptor) {
+               .type = write->descriptorType,
+               .image_view = iview,
+            };
+         }
+         break;
+
+      case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+      case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+         anv_finishme("texel buffers not implemented");
+         break;
+
+      case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+         anv_finishme("input attachments not implemented");
+         break;
+
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+         for (uint32_t j = 0; j < write->count; j++) {
+            assert(write->pDescriptors[j].bufferInfo.buffer.handle);
+            ANV_FROM_HANDLE(anv_buffer, buffer,
+                            write->pDescriptors[j].bufferInfo.buffer);
+            assert(buffer);
+
+            desc[j] = (struct anv_descriptor) {
+               .type = write->descriptorType,
+               .buffer = buffer,
+               .offset = write->pDescriptors[j].bufferInfo.offset,
+               .range = write->pDescriptors[j].bufferInfo.range,
+            };
+
+            /* For buffers with dynamic offsets, we use the full possible
+             * range in the surface state and do the actual range-checking
+             * in the shader.
+             */
+            if (bind_layout->dynamic_offset_index >= 0)
+               desc[j].range = buffer->size - desc[j].offset;
+         }
+
+      default:
+         break;
+      }
+   }
+
+   for (uint32_t i = 0; i < copyCount; i++) {
+      const VkCopyDescriptorSet *copy = &pDescriptorCopies[i];
+      ANV_FROM_HANDLE(anv_descriptor_set, src, copy->destSet);
+      ANV_FROM_HANDLE(anv_descriptor_set, dest, copy->destSet);
+      for (uint32_t j = 0; j < copy->count; j++) {
+         dest->descriptors[copy->destBinding + j] =
+            src->descriptors[copy->srcBinding + j];
+      }
+   }
+}
+
+VkResult anv_CreateFramebuffer(
+    VkDevice                                    _device,
+    const VkFramebufferCreateInfo*              pCreateInfo,
+    VkFramebuffer*                              pFramebuffer)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_framebuffer *framebuffer;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
+
+   size_t size = sizeof(*framebuffer) +
+                 sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount;
+   framebuffer = anv_device_alloc(device, size, 8,
+                                  VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (framebuffer == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   framebuffer->attachment_count = pCreateInfo->attachmentCount;
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      VkImageView _iview = pCreateInfo->pAttachments[i];
+      framebuffer->attachments[i] = anv_image_view_from_handle(_iview);
+   }
+
+   framebuffer->width = pCreateInfo->width;
+   framebuffer->height = pCreateInfo->height;
+   framebuffer->layers = pCreateInfo->layers;
+
+   *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyFramebuffer(
+    VkDevice                                    _device,
+    VkFramebuffer                               _fb)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
+
+   anv_device_free(device, fb);
+}
+
+void vkCmdDbgMarkerBegin(
+    VkCmdBuffer                              cmdBuffer,
+    const char*                                 pMarker)
+   __attribute__ ((visibility ("default")));
+
+void vkCmdDbgMarkerEnd(
+   VkCmdBuffer                              cmdBuffer)
+   __attribute__ ((visibility ("default")));
+
+void vkCmdDbgMarkerBegin(
+    VkCmdBuffer                              cmdBuffer,
+    const char*                                 pMarker)
+{
+}
+
+void vkCmdDbgMarkerEnd(
+    VkCmdBuffer                              cmdBuffer)
+{
+}
diff --git a/src/vulkan/anv_dump.c b/src/vulkan/anv_dump.c
new file mode 100644 (file)
index 0000000..3878941
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_private.h"
+
+/* This file contains utility functions for help debugging.  They can be
+ * called from GDB or similar to help inspect images and buffers.
+ */
+
+void
+anv_dump_image_to_ppm(struct anv_device *device,
+                      struct anv_image *image, unsigned miplevel,
+                      unsigned array_layer, const char *filename)
+{
+   VkDevice vk_device = anv_device_to_handle(device);
+   VkResult result;
+
+   VkExtent2D extent = { image->extent.width, image->extent.height };
+   for (unsigned i = 0; i < miplevel; i++) {
+      extent.width = MAX2(1, extent.width / 2);
+      extent.height = MAX2(1, extent.height / 2);
+   }
+
+   VkImage copy_image;
+   result = anv_CreateImage(vk_device,
+      &(VkImageCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+         .imageType = VK_IMAGE_TYPE_2D,
+         .format = VK_FORMAT_R8G8B8A8_UNORM,
+         .extent = (VkExtent3D) { extent.width, extent.height, 1 },
+         .mipLevels = 1,
+         .arraySize = 1,
+         .samples = 1,
+         .tiling = VK_IMAGE_TILING_LINEAR,
+         .usage = VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT,
+         .flags = 0,
+      }, &copy_image);
+   assert(result == VK_SUCCESS);
+
+   VkMemoryRequirements reqs;
+   result = anv_GetImageMemoryRequirements(vk_device, copy_image, &reqs);
+
+   VkDeviceMemory memory;
+   result = anv_AllocMemory(vk_device,
+      &(VkMemoryAllocInfo) {
+         .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
+         .allocationSize = reqs.size,
+         .memoryTypeIndex = 0,
+      }, &memory);
+   assert(result == VK_SUCCESS);
+
+   result = anv_BindImageMemory(vk_device, copy_image, memory, 0);
+   assert(result == VK_SUCCESS);
+
+   VkCmdPool cmdPool;
+   result = anv_CreateCommandPool(vk_device,
+      &(VkCmdPoolCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
+         .queueFamilyIndex = 0,
+         .flags = 0,
+      }, &cmdPool);
+   assert(result == VK_SUCCESS);
+
+   VkCmdBuffer cmd;
+   result = anv_CreateCommandBuffer(vk_device,
+      &(VkCmdBufferCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
+         .cmdPool = cmdPool,
+         .level = VK_CMD_BUFFER_LEVEL_PRIMARY,
+         .flags = 0,
+      }, &cmd);
+   assert(result == VK_SUCCESS);
+
+   result = anv_BeginCommandBuffer(cmd,
+      &(VkCmdBufferBeginInfo) {
+         .sType = VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
+         .flags = VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT,
+      });
+   assert(result == VK_SUCCESS);
+
+   anv_CmdBlitImage(cmd,
+      anv_image_to_handle(image), VK_IMAGE_LAYOUT_GENERAL,
+      copy_image, VK_IMAGE_LAYOUT_GENERAL, 1,
+      &(VkImageBlit) {
+         .srcSubresource = {
+            .aspect = VK_IMAGE_ASPECT_COLOR,
+            .mipLevel = miplevel,
+            .arrayLayer = array_layer,
+            .arraySize = 1,
+         },
+         .srcOffset = (VkOffset3D) { 0, 0, 0 },
+         .srcExtent = (VkExtent3D) {
+            extent.width,
+            extent.height,
+            1
+         },
+         .destSubresource = {
+            .aspect = VK_IMAGE_ASPECT_COLOR,
+            .mipLevel = 0,
+            .arrayLayer = 0,
+            .arraySize = 1,
+         },
+         .destOffset = (VkOffset3D) { 0, 0, 0 },
+         .destExtent = (VkExtent3D) {
+            extent.width,
+            extent.height,
+            1
+         },
+      }, VK_TEX_FILTER_NEAREST);
+
+   ANV_CALL(CmdPipelineBarrier)(cmd,
+      VK_PIPELINE_STAGE_TRANSFER_BIT,
+      VK_PIPELINE_STAGE_TRANSFER_BIT,
+      true, 1,
+      (const void * []) { &(VkImageMemoryBarrier) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+         .outputMask = VK_MEMORY_OUTPUT_TRANSFER_BIT,
+         .inputMask = VK_MEMORY_INPUT_HOST_READ_BIT,
+         .oldLayout = VK_IMAGE_LAYOUT_GENERAL,
+         .newLayout = VK_IMAGE_LAYOUT_GENERAL,
+         .srcQueueFamilyIndex = 0,
+         .destQueueFamilyIndex = 0,
+         .image = copy_image,
+         .subresourceRange = (VkImageSubresourceRange) {
+            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+            .baseMipLevel = 0,
+            .mipLevels = 1,
+            .baseArrayLayer = 0,
+            .arraySize = 1,
+         },
+      }});
+
+   result = anv_EndCommandBuffer(cmd);
+   assert(result == VK_SUCCESS);
+
+   VkFence fence;
+   result = anv_CreateFence(vk_device,
+      &(VkFenceCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+         .flags = 0,
+      }, &fence);
+   assert(result == VK_SUCCESS);
+
+   result = anv_QueueSubmit(anv_queue_to_handle(&device->queue),
+                            1, &cmd, fence);
+   assert(result == VK_SUCCESS);
+
+   result = anv_WaitForFences(vk_device, 1, &fence, true, UINT64_MAX);
+   assert(result == VK_SUCCESS);
+
+   anv_DestroyFence(vk_device, fence);
+   anv_DestroyCommandPool(vk_device, cmdPool);
+
+   uint8_t *map;
+   result = anv_MapMemory(vk_device, memory, 0, reqs.size, 0, (void **)&map);
+   assert(result == VK_SUCCESS);
+
+   VkSubresourceLayout layout;
+   result = anv_GetImageSubresourceLayout(vk_device, copy_image,
+      &(VkImageSubresource) {
+         .aspect = VK_IMAGE_ASPECT_COLOR,
+         .mipLevel = 0,
+         .arrayLayer = 0,
+      }, &layout);
+   assert(result == VK_SUCCESS);
+
+   map += layout.offset;
+
+   /* Now we can finally write the PPM file */
+   FILE *file = fopen(filename, "wb");
+   assert(file);
+
+   fprintf(file, "P6\n%d %d\n255\n", extent.width, extent.height);
+   for (unsigned y = 0; y < extent.height; y++) {
+      uint8_t row[extent.width * 3];
+      for (unsigned x = 0; x < extent.width; x++) {
+         row[x * 3 + 0] = map[x * 4 + 0];
+         row[x * 3 + 1] = map[x * 4 + 1];
+         row[x * 3 + 2] = map[x * 4 + 2];
+      }
+      fwrite(row, 3, extent.width, file);
+
+      map += layout.rowPitch;
+   }
+   fclose(file);
+
+   anv_UnmapMemory(vk_device, memory);
+   anv_DestroyImage(vk_device, copy_image);
+   anv_FreeMemory(vk_device, memory);
+}
diff --git a/src/vulkan/anv_entrypoints_gen.py b/src/vulkan/anv_entrypoints_gen.py
new file mode 100644 (file)
index 0000000..0fa677b
--- /dev/null
@@ -0,0 +1,310 @@
+# coding=utf-8
+#
+# Copyright © 2015 Intel Corporation
+#
+# 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 (including the next
+# paragraph) 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.
+#
+
+import fileinput, re, sys
+
+# Each function typedef in the vulkan.h header is all on one line and matches
+# this regepx. We hope that won't change.
+
+p = re.compile('typedef ([^ ]*) *\(VKAPI \*PFN_vk([^(]*)\)(.*);')
+
+entrypoints = []
+
+# We generate a static hash table for entry point lookup
+# (vkGetProcAddress). We use a linear congruential generator for our hash
+# function and a power-of-two size table. The prime numbers are determined
+# experimentally.
+
+none = 0xffff
+hash_size = 256
+u32_mask = 2**32 - 1
+hash_mask = hash_size - 1
+
+prime_factor = 5024183
+prime_step = 19
+
+def hash(name):
+    h = 0;
+    for c in name:
+        h = (h * prime_factor + ord(c)) & u32_mask
+
+    return h
+
+opt_header = False
+opt_code = False
+
+if (sys.argv[1] == "header"):
+    opt_header = True
+    sys.argv.pop()
+elif (sys.argv[1] == "code"):
+    opt_code = True
+    sys.argv.pop()
+
+# Parse the entry points in the header
+
+i = 0
+for line in fileinput.input():
+    m  = p.match(line)
+    if (m):
+        if m.group(2) == 'VoidFunction':
+            continue
+        fullname = "vk" + m.group(2)
+        h = hash(fullname)
+        entrypoints.append((m.group(1), m.group(2), m.group(3), i, h))
+        i = i + 1
+
+# For outputting entrypoints.h we generate a anv_EntryPoint() prototype
+# per entry point.
+
+if opt_header:
+    print "/* This file generated from vk_gen.py, don't edit directly. */\n"
+
+    print "struct anv_dispatch_table {"
+    print "   union {"
+    print "      void *entrypoints[%d];" % len(entrypoints)
+    print "      struct {"
+
+    for type, name, args, num, h in entrypoints:
+        print "         %s (*%s)%s;" % (type, name, args)
+    print "      };\n"
+    print "   };\n"
+    print "};\n"
+
+    print "void anv_set_dispatch_gen(uint32_t gen);\n"
+
+    for type, name, args, num, h in entrypoints:
+        print "%s anv_%s%s;" % (type, name, args)
+        print "%s gen7_%s%s;" % (type, name, args)
+        print "%s gen8_%s%s;" % (type, name, args)
+        print "%s anv_validate_%s%s;" % (type, name, args)
+    exit()
+
+
+
+print """/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+/* DO NOT EDIT! This is a generated file. */
+
+#include "anv_private.h"
+
+struct anv_entrypoint {
+   uint32_t name;
+   uint32_t hash;
+};
+
+/* We use a big string constant to avoid lots of reloctions from the entry
+ * point table to lots of little strings. The entries in the entry point table
+ * store the index into this big string.
+ */
+
+static const char strings[] ="""
+
+offsets = []
+i = 0;
+for type, name, args, num, h in entrypoints:
+    print "   \"vk%s\\0\"" % name
+    offsets.append(i)
+    i += 2 + len(name) + 1
+print """   ;
+
+/* Weak aliases for all potential validate functions. These will resolve to
+ * NULL if they're not defined, which lets the resolve_entrypoint() function
+ * either pick a validate wrapper if available or just plug in the actual
+ * entry point.
+ */
+"""
+
+# Now generate the table of all entry points and their validation functions
+
+print "\nstatic const struct anv_entrypoint entrypoints[] = {"
+for type, name, args, num, h in entrypoints:
+    print "   { %5d, 0x%08x }," % (offsets[num], h)
+print "};\n"
+
+for layer in [ "anv", "validate", "gen7", "gen8" ]:
+    for type, name, args, num, h in entrypoints:
+        print "%s %s_%s%s __attribute__ ((weak));" % (type, layer, name, args)
+    print "\nconst struct anv_dispatch_table %s_layer = {" % layer
+    for type, name, args, num, h in entrypoints:
+        print "   .%s = %s_%s," % (name, layer, name)
+    print "};\n"
+
+print """
+#ifdef DEBUG
+static bool enable_validate = true;
+#else
+static bool enable_validate = false;
+#endif
+
+/* We can't use symbols that need resolving (like, oh, getenv) in the resolve
+ * function. This means that we have to determine whether or not to use the
+ * validation layer sometime before that. The constructor function attribute asks
+ * the dynamic linker to invoke determine_validate() at dlopen() time which
+ * works.
+ */
+static void __attribute__ ((constructor))
+determine_validate(void)
+{
+   const char *s = getenv("ANV_VALIDATE");
+
+   if (s)
+      enable_validate = atoi(s);
+}
+
+static uint32_t dispatch_gen;
+
+void
+anv_set_dispatch_gen(uint32_t gen)
+{
+   dispatch_gen = gen;   
+}
+
+void * __attribute__ ((noinline))
+anv_resolve_entrypoint(uint32_t index)
+{
+   if (enable_validate && validate_layer.entrypoints[index])
+      return validate_layer.entrypoints[index];
+
+   switch (dispatch_gen) {
+   case 8:
+      if (gen8_layer.entrypoints[index])
+         return gen8_layer.entrypoints[index];
+      /* fall through */
+   case 7:
+      if (gen7_layer.entrypoints[index])
+         return gen7_layer.entrypoints[index];
+      /* fall through */
+   case 0:
+      return anv_layer.entrypoints[index];
+   default:
+      unreachable("unsupported gen\\n");
+   }
+}
+"""
+
+# Now output ifuncs and their resolve helpers for all entry points. The
+# resolve helper calls resolve_entrypoint() with the entry point index, which
+# lets the resolver look it up in the table.
+
+for type, name, args, num, h in entrypoints:
+    print "static void *resolve_%s(void) { return anv_resolve_entrypoint(%d); }" % (name, num)
+    print "%s vk%s%s\n   __attribute__ ((ifunc (\"resolve_%s\"), visibility (\"default\")));\n" % (type, name, args, name)
+
+
+# Now generate the hash table used for entry point look up.  This is a
+# uint16_t table of entry point indices. We use 0xffff to indicate an entry
+# in the hash table is empty.
+
+map = [none for f in xrange(hash_size)]
+collisions = [0 for f in xrange(10)]
+for type, name, args, num, h in entrypoints:
+    level = 0
+    while map[h & hash_mask] != none:
+        h = h + prime_step
+        level = level + 1
+    if level > 9:
+        collisions[9] += 1
+    else:
+        collisions[level] += 1
+    map[h & hash_mask] = num
+
+print "/* Hash table stats:"
+print " * size %d entries" % hash_size
+print " * collisions  entries"
+for i in xrange(10):
+    if (i == 9):
+        plus = "+"
+    else:
+        plus = " "
+
+    print " *     %2d%s     %4d" % (i, plus, collisions[i])
+print " */\n"
+
+print "#define none 0x%04x\n" % none
+
+print "static const uint16_t map[] = {"
+for i in xrange(0, hash_size, 8):
+    print "   ",
+    for j in xrange(i, i + 8):
+        if map[j] & 0xffff == 0xffff:
+            print "  none,",
+        else:
+            print "0x%04x," % (map[j] & 0xffff),
+    print
+
+print "};"    
+
+# Finally we generate the hash table lookup function.  The hash function and
+# linear probing algorithm matches the hash table generated above.
+
+print """
+void *
+anv_lookup_entrypoint(const char *name)
+{
+   static const uint32_t prime_factor = %d;
+   static const uint32_t prime_step = %d;
+   const struct anv_entrypoint *e;
+   uint32_t hash, h, i;
+   const char *p;
+
+   hash = 0;
+   for (p = name; *p; p++)
+      hash = hash * prime_factor + *p;
+
+   h = hash;
+   do {
+      i = map[h & %d];
+      if (i == none)
+         return NULL;
+      e = &entrypoints[i];
+      h += prime_step;
+   } while (e->hash != hash);
+
+   if (strcmp(name, strings + e->name) != 0)
+      return NULL;
+
+   return anv_resolve_entrypoint(i);
+}
+""" % (prime_factor, prime_step, hash_mask)
diff --git a/src/vulkan/anv_formats.c b/src/vulkan/anv_formats.c
new file mode 100644 (file)
index 0000000..942e7cf
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_private.h"
+#include "brw_surface_formats.h"
+
+#define fmt(__vk_fmt, __hw_fmt, ...) \
+   [__vk_fmt] = { \
+      .vk_format = __vk_fmt, \
+      .name = #__vk_fmt, \
+      .surface_format = __hw_fmt, \
+      .isl_layout = &isl_format_layouts[__hw_fmt], \
+      __VA_ARGS__ \
+   }
+
+static const struct anv_format anv_formats[] = {
+   fmt(VK_FORMAT_UNDEFINED,               ISL_FORMAT_RAW,                    .num_channels = 1),
+   fmt(VK_FORMAT_R4G4_UNORM,              ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R4G4_USCALED,            ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R4G4B4A4_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R4G4B4A4_USCALED,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R5G6B5_UNORM,            ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R5G6B5_USCALED,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R5G5B5A1_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R5G5B5A1_USCALED,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R8_UNORM,                ISL_FORMAT_R8_UNORM,               .num_channels = 1),
+   fmt(VK_FORMAT_R8_SNORM,                ISL_FORMAT_R8_SNORM,               .num_channels = 1,),
+   fmt(VK_FORMAT_R8_USCALED,              ISL_FORMAT_R8_USCALED,             .num_channels = 1),
+   fmt(VK_FORMAT_R8_SSCALED,              ISL_FORMAT_R8_SSCALED,             .num_channels = 1),
+   fmt(VK_FORMAT_R8_UINT,                 ISL_FORMAT_R8_UINT,                .num_channels = 1),
+   fmt(VK_FORMAT_R8_SINT,                 ISL_FORMAT_R8_SINT,                .num_channels = 1),
+   fmt(VK_FORMAT_R8_SRGB,                 ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_R8G8_UNORM,              ISL_FORMAT_R8G8_UNORM,             .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SNORM,              ISL_FORMAT_R8G8_SNORM,             .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_USCALED,            ISL_FORMAT_R8G8_USCALED,           .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SSCALED,            ISL_FORMAT_R8G8_SSCALED,           .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_UINT,               ISL_FORMAT_R8G8_UINT,              .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SINT,               ISL_FORMAT_R8G8_SINT,              .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SRGB,               ISL_FORMAT_UNSUPPORTED), /* L8A8_UNORM_SRGB */
+   fmt(VK_FORMAT_R8G8B8_UNORM,            ISL_FORMAT_R8G8B8X8_UNORM,         .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SNORM,            ISL_FORMAT_R8G8B8_SNORM,           .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_USCALED,          ISL_FORMAT_R8G8B8_USCALED,         .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SSCALED,          ISL_FORMAT_R8G8B8_SSCALED,         .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_UINT,             ISL_FORMAT_R8G8B8_UINT,            .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SINT,             ISL_FORMAT_R8G8B8_SINT,            .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SRGB,             ISL_FORMAT_UNSUPPORTED), /* B8G8R8A8_UNORM_SRGB */
+   fmt(VK_FORMAT_R8G8B8A8_UNORM,          ISL_FORMAT_R8G8B8A8_UNORM,         .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SNORM,          ISL_FORMAT_R8G8B8A8_SNORM,         .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_USCALED,        ISL_FORMAT_R8G8B8A8_USCALED,       .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SSCALED,        ISL_FORMAT_R8G8B8A8_SSCALED,       .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_UINT,           ISL_FORMAT_R8G8B8A8_UINT,          .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SINT,           ISL_FORMAT_R8G8B8A8_SINT,          .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SRGB,           ISL_FORMAT_R8G8B8A8_UNORM_SRGB,    .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_UNORM,       ISL_FORMAT_R10G10B10A2_UNORM,      .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_SNORM,       ISL_FORMAT_R10G10B10A2_SNORM,      .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_USCALED,     ISL_FORMAT_R10G10B10A2_USCALED,    .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_SSCALED,     ISL_FORMAT_R10G10B10A2_SSCALED,    .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_UINT,        ISL_FORMAT_R10G10B10A2_UINT,       .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_SINT,        ISL_FORMAT_R10G10B10A2_SINT,       .num_channels = 4),
+   fmt(VK_FORMAT_R16_UNORM,               ISL_FORMAT_R16_UNORM,              .num_channels = 1),
+   fmt(VK_FORMAT_R16_SNORM,               ISL_FORMAT_R16_SNORM,              .num_channels = 1),
+   fmt(VK_FORMAT_R16_USCALED,             ISL_FORMAT_R16_USCALED,            .num_channels = 1),
+   fmt(VK_FORMAT_R16_SSCALED,             ISL_FORMAT_R16_SSCALED,            .num_channels = 1),
+   fmt(VK_FORMAT_R16_UINT,                ISL_FORMAT_R16_UINT,               .num_channels = 1),
+   fmt(VK_FORMAT_R16_SINT,                ISL_FORMAT_R16_SINT,               .num_channels = 1),
+   fmt(VK_FORMAT_R16_SFLOAT,              ISL_FORMAT_R16_FLOAT,              .num_channels = 1),
+   fmt(VK_FORMAT_R16G16_UNORM,            ISL_FORMAT_R16G16_UNORM,           .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SNORM,            ISL_FORMAT_R16G16_SNORM,           .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_USCALED,          ISL_FORMAT_R16G16_USCALED,         .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SSCALED,          ISL_FORMAT_R16G16_SSCALED,         .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_UINT,             ISL_FORMAT_R16G16_UINT,            .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SINT,             ISL_FORMAT_R16G16_SINT,            .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SFLOAT,           ISL_FORMAT_R16G16_FLOAT,           .num_channels = 2),
+   fmt(VK_FORMAT_R16G16B16_UNORM,         ISL_FORMAT_R16G16B16_UNORM,        .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SNORM,         ISL_FORMAT_R16G16B16_SNORM,        .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_USCALED,       ISL_FORMAT_R16G16B16_USCALED,      .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SSCALED,       ISL_FORMAT_R16G16B16_SSCALED,      .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_UINT,          ISL_FORMAT_R16G16B16_UINT,         .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SINT,          ISL_FORMAT_R16G16B16_SINT,         .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SFLOAT,        ISL_FORMAT_R16G16B16_FLOAT,        .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16A16_UNORM,      ISL_FORMAT_R16G16B16A16_UNORM,     .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SNORM,      ISL_FORMAT_R16G16B16A16_SNORM,     .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_USCALED,    ISL_FORMAT_R16G16B16A16_USCALED,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SSCALED,    ISL_FORMAT_R16G16B16A16_SSCALED,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_UINT,       ISL_FORMAT_R16G16B16A16_UINT,      .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SINT,       ISL_FORMAT_R16G16B16A16_SINT,      .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SFLOAT,     ISL_FORMAT_R16G16B16A16_FLOAT,     .num_channels = 4),
+   fmt(VK_FORMAT_R32_UINT,                ISL_FORMAT_R32_UINT,               .num_channels = 1,),
+   fmt(VK_FORMAT_R32_SINT,                ISL_FORMAT_R32_SINT,               .num_channels = 1,),
+   fmt(VK_FORMAT_R32_SFLOAT,              ISL_FORMAT_R32_FLOAT,              .num_channels = 1,),
+   fmt(VK_FORMAT_R32G32_UINT,             ISL_FORMAT_R32G32_UINT,            .num_channels = 2,),
+   fmt(VK_FORMAT_R32G32_SINT,             ISL_FORMAT_R32G32_SINT,            .num_channels = 2,),
+   fmt(VK_FORMAT_R32G32_SFLOAT,           ISL_FORMAT_R32G32_FLOAT,           .num_channels = 2,),
+   fmt(VK_FORMAT_R32G32B32_UINT,          ISL_FORMAT_R32G32B32_UINT,         .num_channels = 3,),
+   fmt(VK_FORMAT_R32G32B32_SINT,          ISL_FORMAT_R32G32B32_SINT,         .num_channels = 3,),
+   fmt(VK_FORMAT_R32G32B32_SFLOAT,        ISL_FORMAT_R32G32B32_FLOAT,        .num_channels = 3,),
+   fmt(VK_FORMAT_R32G32B32A32_UINT,       ISL_FORMAT_R32G32B32A32_UINT,      .num_channels = 4,),
+   fmt(VK_FORMAT_R32G32B32A32_SINT,       ISL_FORMAT_R32G32B32A32_SINT,      .num_channels = 4,),
+   fmt(VK_FORMAT_R32G32B32A32_SFLOAT,     ISL_FORMAT_R32G32B32A32_FLOAT,     .num_channels = 4,),
+   fmt(VK_FORMAT_R64_SFLOAT,              ISL_FORMAT_R64_FLOAT,              .num_channels = 1),
+   fmt(VK_FORMAT_R64G64_SFLOAT,           ISL_FORMAT_R64G64_FLOAT,           .num_channels = 2),
+   fmt(VK_FORMAT_R64G64B64_SFLOAT,        ISL_FORMAT_R64G64B64_FLOAT,        .num_channels = 3),
+   fmt(VK_FORMAT_R64G64B64A64_SFLOAT,     ISL_FORMAT_R64G64B64A64_FLOAT,     .num_channels = 4),
+   fmt(VK_FORMAT_R11G11B10_UFLOAT,        ISL_FORMAT_R11G11B10_FLOAT,        .num_channels = 3),
+   fmt(VK_FORMAT_R9G9B9E5_UFLOAT,         ISL_FORMAT_R9G9B9E5_SHAREDEXP,     .num_channels = 3),
+
+   fmt(VK_FORMAT_D16_UNORM,               ISL_FORMAT_R16_UNORM,              .num_channels = 1, .depth_format = D16_UNORM),
+   fmt(VK_FORMAT_D24_UNORM_X8,            ISL_FORMAT_R24_UNORM_X8_TYPELESS,  .num_channels = 1, .depth_format = D24_UNORM_X8_UINT),
+   fmt(VK_FORMAT_D32_SFLOAT,              ISL_FORMAT_R32_FLOAT,              .num_channels = 1, .depth_format = D32_FLOAT),
+   fmt(VK_FORMAT_S8_UINT,                 ISL_FORMAT_R8_UINT,                .num_channels = 1,                                       .has_stencil = true),
+   fmt(VK_FORMAT_D16_UNORM_S8_UINT,       ISL_FORMAT_R16_UNORM,              .num_channels = 2, .depth_format = D16_UNORM,            .has_stencil = true),
+   fmt(VK_FORMAT_D24_UNORM_S8_UINT,       ISL_FORMAT_R24_UNORM_X8_TYPELESS,  .num_channels = 2, .depth_format = D24_UNORM_X8_UINT,    .has_stencil = true),
+   fmt(VK_FORMAT_D32_SFLOAT_S8_UINT,      ISL_FORMAT_R32_FLOAT,              .num_channels = 2, .depth_format = D32_FLOAT,            .has_stencil = true),
+
+   fmt(VK_FORMAT_BC1_RGB_UNORM,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC1_RGB_SRGB,            ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC1_RGBA_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC1_RGBA_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC2_UNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC2_SRGB,                ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC3_UNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC3_SRGB,                ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC4_UNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC4_SNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC5_UNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC5_SNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC6H_UFLOAT,             ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC6H_SFLOAT,             ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC7_UNORM,               ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_BC7_SRGB,                ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8_UNORM,       ISL_FORMAT_ETC2_RGB8),
+   fmt(VK_FORMAT_ETC2_R8G8B8_SRGB,        ISL_FORMAT_ETC2_SRGB8),
+   fmt(VK_FORMAT_ETC2_R8G8B8A1_UNORM,     ISL_FORMAT_ETC2_RGB8_PTA),
+   fmt(VK_FORMAT_ETC2_R8G8B8A1_SRGB,      ISL_FORMAT_ETC2_SRGB8_PTA),
+   fmt(VK_FORMAT_ETC2_R8G8B8A8_UNORM,     ISL_FORMAT_ETC2_EAC_RGBA8),
+   fmt(VK_FORMAT_ETC2_R8G8B8A8_SRGB,      ISL_FORMAT_ETC2_EAC_SRGB8_A8),
+   fmt(VK_FORMAT_EAC_R11_UNORM,           ISL_FORMAT_EAC_R11),
+   fmt(VK_FORMAT_EAC_R11_SNORM,           ISL_FORMAT_EAC_SIGNED_R11),
+   fmt(VK_FORMAT_EAC_R11G11_UNORM,        ISL_FORMAT_EAC_RG11),
+   fmt(VK_FORMAT_EAC_R11G11_SNORM,        ISL_FORMAT_EAC_SIGNED_RG11),
+   fmt(VK_FORMAT_ASTC_4x4_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_4x4_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x4_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x4_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x5_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x5_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x5_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x5_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x6_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x6_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x5_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x5_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x6_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x6_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x8_UNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x8_SRGB,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x5_UNORM,         ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x5_SRGB,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x6_UNORM,         ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x6_SRGB,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x8_UNORM,         ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x8_SRGB,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x10_UNORM,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x10_SRGB,         ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x10_UNORM,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x10_SRGB,         ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x12_UNORM,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x12_SRGB,         ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B4G4R4A4_UNORM,          ISL_FORMAT_B4G4R4A4_UNORM,         .num_channels = 4),
+   fmt(VK_FORMAT_B5G5R5A1_UNORM,          ISL_FORMAT_B5G5R5A1_UNORM,         .num_channels = 4),
+   fmt(VK_FORMAT_B5G6R5_UNORM,            ISL_FORMAT_B5G6R5_UNORM,           .num_channels = 3),
+   fmt(VK_FORMAT_B5G6R5_USCALED,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_UNORM,            ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SNORM,            ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_USCALED,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SSCALED,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_UINT,             ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SINT,             ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SRGB,             ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_UNORM,          ISL_FORMAT_B8G8R8A8_UNORM,         .num_channels = 4),
+   fmt(VK_FORMAT_B8G8R8A8_SNORM,          ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_USCALED,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_SSCALED,        ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_UINT,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_SINT,           ISL_FORMAT_UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_SRGB,           ISL_FORMAT_B8G8R8A8_UNORM_SRGB,    .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_UNORM,       ISL_FORMAT_B10G10R10A2_UNORM,      .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_SNORM,       ISL_FORMAT_B10G10R10A2_SNORM,      .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_USCALED,     ISL_FORMAT_B10G10R10A2_USCALED,    .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_SSCALED,     ISL_FORMAT_B10G10R10A2_SSCALED,    .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_UINT,        ISL_FORMAT_B10G10R10A2_UINT,       .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_SINT,        ISL_FORMAT_B10G10R10A2_SINT,       .num_channels = 4)
+};
+
+#undef fmt
+
+const struct anv_format *const
+anv_format_s8_uint = &anv_formats[VK_FORMAT_S8_UINT];
+
+const struct anv_format *
+anv_format_for_vk_format(VkFormat format)
+{
+   return &anv_formats[format];
+}
+
+// Format capabilities
+
+VkResult anv_validate_GetPhysicalDeviceFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    _format,
+    VkFormatProperties*                         pFormatProperties)
+{
+   const struct anv_format *format = anv_format_for_vk_format(_format);
+   fprintf(stderr, "vkGetFormatProperties(%s)\n", format->name);
+   return anv_GetPhysicalDeviceFormatProperties(physicalDevice, _format, pFormatProperties);
+}
+
+static VkResult
+anv_physical_device_get_format_properties(struct anv_physical_device *physical_device,
+                                          const struct anv_format *format,
+                                          VkFormatProperties *out_properties)
+{
+   const struct brw_surface_format_info *info;
+   int gen;
+   VkFormatFeatureFlags flags;
+
+   assert(format != NULL);
+
+   gen = physical_device->info->gen * 10;
+   if (physical_device->info->is_haswell)
+      gen += 5;
+
+   if (format->surface_format== ISL_FORMAT_UNSUPPORTED)
+      goto unsupported;
+
+   uint32_t linear = 0, tiled = 0;
+   if (anv_format_is_depth_or_stencil(format)) {
+      tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
+      tiled |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+      tiled |= VK_FORMAT_FEATURE_BLIT_SOURCE_BIT;
+      if (format->depth_format) {
+         tiled |= VK_FORMAT_FEATURE_BLIT_DESTINATION_BIT;
+      }
+   } else {
+      /* The surface_formats table only contains color formats */
+      info = &surface_formats[format->surface_format];
+      if (!info->exists)
+         goto unsupported;
+
+      if (info->sampling <= gen) {
+         flags = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+                 VK_FORMAT_FEATURE_BLIT_SOURCE_BIT;
+         linear |= flags;
+         tiled |= flags;
+      }
+      if (info->render_target <= gen) {
+         flags = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+                 VK_FORMAT_FEATURE_BLIT_DESTINATION_BIT;
+         linear |= flags;
+         tiled |= flags;
+      }
+      if (info->alpha_blend <= gen) {
+         linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+         tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+      }
+      if (info->input_vb <= gen) {
+         linear |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
+      }
+   }
+
+   out_properties->linearTilingFeatures = linear;
+   out_properties->optimalTilingFeatures = tiled;
+   out_properties->bufferFeatures = 0; /* FINISHME */
+
+   return VK_SUCCESS;
+
+ unsupported:
+   out_properties->linearTilingFeatures = 0;
+   out_properties->optimalTilingFeatures = 0;
+
+   return VK_SUCCESS;
+}
+
+
+VkResult anv_GetPhysicalDeviceFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkFormatProperties*                         pFormatProperties)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   VkResult result;
+
+   result = anv_physical_device_get_format_properties(
+               physical_device,
+               anv_format_for_vk_format(format),
+               pFormatProperties);
+   if (result != VK_SUCCESS)
+      return vk_error(result);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceImageFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    _format,
+    VkImageType                                 type,
+    VkImageTiling                               tiling,
+    VkImageUsageFlags                           usage,
+    VkImageCreateFlags                          flags,
+    VkImageFormatProperties*                    pImageFormatProperties)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   const struct anv_format *format = anv_format_for_vk_format(_format);
+   VkFormatProperties format_props;
+   VkFormatFeatureFlags format_feature_flags;
+   VkExtent3D maxExtent;
+   uint32_t maxMipLevels;
+   uint32_t maxArraySize;
+   VkResult result;
+
+   result = anv_physical_device_get_format_properties(physical_device, format,
+                                                      &format_props);
+   if (result != VK_SUCCESS)
+      return vk_error(result);
+
+   /* Extract the VkFormatFeatureFlags that are relevant for the queried
+    * tiling.
+    */
+   if (tiling == VK_IMAGE_TILING_LINEAR) {
+      format_feature_flags = format_props.linearTilingFeatures;
+   } else if (tiling == VK_IMAGE_TILING_OPTIMAL) {
+      format_feature_flags = format_props.optimalTilingFeatures;
+   } else {
+      unreachable("bad VkImageTiling");
+   }
+
+   switch (type) {
+   default:
+      unreachable("bad VkImageType");
+   case VK_IMAGE_TYPE_1D:
+      maxExtent.width = 16384;
+      maxExtent.height = 1;
+      maxExtent.depth = 1;
+      maxMipLevels = 15; /* log2(maxWidth) + 1 */
+      maxArraySize = 2048;
+      break;
+   case VK_IMAGE_TYPE_2D:
+      /* FINISHME: Does this really differ for cube maps? The documentation
+       * for RENDER_SURFACE_STATE suggests so.
+       */
+      maxExtent.width = 16384;
+      maxExtent.height = 16384;
+      maxExtent.depth = 1;
+      maxMipLevels = 15; /* log2(maxWidth) + 1 */
+      maxArraySize = 2048;
+      break;
+   case VK_IMAGE_TYPE_3D:
+      maxExtent.width = 2048;
+      maxExtent.height = 2048;
+      maxExtent.depth = 2048;
+      maxMipLevels = 12; /* log2(maxWidth) + 1 */
+      maxArraySize = 1;
+      break;
+   }
+
+   if (usage & VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT) {
+      /* Meta implements transfers by sampling from the source image. */
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
+         goto unsupported;
+      }
+   }
+
+   if (usage & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) {
+      if (format->has_stencil) {
+         /* Not yet implemented because copying to a W-tiled surface is crazy
+          * hard.
+          */
+         anv_finishme("support VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT for "
+                      "stencil format");
+         goto unsupported;
+      }
+   }
+
+   if (usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
+         goto unsupported;
+      }
+   }
+
+   if (usage & VK_IMAGE_USAGE_STORAGE_BIT) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
+         goto unsupported;
+      }
+   }
+
+   if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
+         goto unsupported;
+      }
+   }
+
+   if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
+      if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+         goto unsupported;
+      }
+   }
+
+   if (usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
+      /* Nothing to check. */
+   }
+
+   if (usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
+      /* Ignore this flag because it was removed from the
+       * provisional_I_20150910 header.
+       */
+   }
+
+   *pImageFormatProperties = (VkImageFormatProperties) {
+      .maxExtent = maxExtent,
+      .maxMipLevels = maxMipLevels,
+      .maxArraySize = maxArraySize,
+
+      /* FINISHME: Support multisampling */
+      .sampleCounts = VK_SAMPLE_COUNT_1_BIT,
+
+      /* FINISHME: Accurately calculate
+       * VkImageFormatProperties::maxResourceSize.
+       */
+      .maxResourceSize = UINT32_MAX,
+   };
+
+    return VK_SUCCESS;
+
+unsupported:
+   *pImageFormatProperties = (VkImageFormatProperties) {
+      .maxExtent = { 0, 0, 0 },
+      .maxMipLevels = 0,
+      .maxArraySize = 0,
+      .sampleCounts = 0,
+      .maxResourceSize = 0,
+   };
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceSparseImageFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkImageType                                 type,
+    uint32_t                                    samples,
+    VkImageUsageFlags                           usage,
+    VkImageTiling                               tiling,
+    uint32_t*                                   pNumProperties,
+    VkSparseImageFormatProperties*              pProperties)
+{
+   /* Sparse images are not yet supported. */
+   *pNumProperties = 0;
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/anv_gem.c b/src/vulkan/anv_gem.c
new file mode 100644 (file)
index 0000000..01671d2
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#define _DEFAULT_SOURCE
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+#define VG_CLEAR(s) VG(memset(&s, 0, sizeof(s)))
+
+static int
+anv_ioctl(int fd, unsigned long request, void *arg)
+{
+   int ret;
+
+   do {
+      ret = ioctl(fd, request, arg);
+   } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+   return ret;
+}
+
+/**
+ * Wrapper around DRM_IOCTL_I915_GEM_CREATE.
+ *
+ * Return gem handle, or 0 on failure. Gem handles are never 0.
+ */
+uint32_t
+anv_gem_create(struct anv_device *device, size_t size)
+{
+   struct drm_i915_gem_create gem_create;
+   int ret;
+
+   VG_CLEAR(gem_create);
+   gem_create.size = size;
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_CREATE, &gem_create);
+   if (ret != 0) {
+      /* FIXME: What do we do if this fails? */
+      return 0;
+   }
+
+   return gem_create.handle;
+}
+
+void
+anv_gem_close(struct anv_device *device, int gem_handle)
+{
+   struct drm_gem_close close;
+
+   VG_CLEAR(close);
+   close.handle = gem_handle;
+   anv_ioctl(device->fd, DRM_IOCTL_GEM_CLOSE, &close);
+}
+
+/**
+ * Wrapper around DRM_IOCTL_I915_GEM_MMAP.
+ */
+void*
+anv_gem_mmap(struct anv_device *device, uint32_t gem_handle,
+             uint64_t offset, uint64_t size)
+{
+   struct drm_i915_gem_mmap gem_mmap;
+   int ret;
+
+   gem_mmap.handle = gem_handle;
+   VG_CLEAR(gem_mmap.pad);
+   gem_mmap.offset = offset;
+   gem_mmap.size = size;
+   VG_CLEAR(gem_mmap.addr_ptr);
+
+#ifdef I915_MMAP_WC
+   gem_mmap.flags = 0;
+#endif
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_mmap);
+   if (ret != 0) {
+      /* FIXME: Is NULL the right error return? Cf MAP_INVALID */
+      return NULL;
+   }
+
+   VG(VALGRIND_MALLOCLIKE_BLOCK(gem_mmap.addr_ptr, gem_mmap.size, 0, 1));
+   return (void *)(uintptr_t) gem_mmap.addr_ptr;
+}
+
+/* This is just a wrapper around munmap, but it also notifies valgrind that
+ * this map is no longer valid.  Pair this with anv_gem_mmap().
+ */
+void
+anv_gem_munmap(void *p, uint64_t size)
+{
+   VG(VALGRIND_FREELIKE_BLOCK(p, 0));
+   munmap(p, size);
+}
+
+int
+anv_gem_userptr(struct anv_device *device, void *mem, size_t size)
+{
+   struct drm_i915_gem_userptr userptr;
+   int ret;
+
+   VG_CLEAR(userptr);
+   userptr.user_ptr = (__u64)((unsigned long) mem);
+   userptr.user_size = size;
+   userptr.flags = 0;
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_USERPTR, &userptr);
+   if (ret == -1)
+      return 0;
+
+   return userptr.handle;
+}
+
+/**
+ * On error, \a timeout_ns holds the remaining time.
+ */
+int
+anv_gem_wait(struct anv_device *device, int gem_handle, int64_t *timeout_ns)
+{
+   struct drm_i915_gem_wait wait;
+   int ret;
+
+   VG_CLEAR(wait);
+   wait.bo_handle = gem_handle;
+   wait.timeout_ns = *timeout_ns;
+   wait.flags = 0;
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_WAIT, &wait);
+   *timeout_ns = wait.timeout_ns;
+
+   return ret;
+}
+
+int
+anv_gem_execbuffer(struct anv_device *device,
+                   struct drm_i915_gem_execbuffer2 *execbuf)
+{
+   return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, execbuf);
+}
+
+int
+anv_gem_set_tiling(struct anv_device *device,
+                   int gem_handle, uint32_t stride, uint32_t tiling)
+{
+   struct drm_i915_gem_set_tiling set_tiling;
+   int ret;
+
+   /* set_tiling overwrites the input on the error path, so we have to open
+    * code anv_ioctl.
+    */
+
+   do {
+      VG_CLEAR(set_tiling);
+      set_tiling.handle = gem_handle;
+      set_tiling.tiling_mode = I915_TILING_X;
+      set_tiling.stride = stride;
+
+      ret = ioctl(device->fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
+   } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+   return ret;
+}
+
+int
+anv_gem_get_param(int fd, uint32_t param)
+{
+   drm_i915_getparam_t gp;
+   int ret, tmp;
+
+   VG_CLEAR(gp);
+   gp.param = param;
+   gp.value = &tmp;
+   ret = anv_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+   if (ret == 0)
+      return tmp;
+
+   return 0;
+}
+
+int
+anv_gem_create_context(struct anv_device *device)
+{
+   struct drm_i915_gem_context_create create;
+   int ret;
+
+   VG_CLEAR(create);
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &create);
+   if (ret == -1)
+      return -1;
+
+   return create.ctx_id;
+}
+
+int
+anv_gem_destroy_context(struct anv_device *device, int context)
+{
+   struct drm_i915_gem_context_destroy destroy;
+
+   VG_CLEAR(destroy);
+   destroy.ctx_id = context;
+
+   return anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_CONTEXT_DESTROY, &destroy);
+}
+
+int
+anv_gem_get_aperture(int fd, uint64_t *size)
+{
+   struct drm_i915_gem_get_aperture aperture;
+   int ret;
+
+   VG_CLEAR(aperture);
+   ret = anv_ioctl(fd, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+   if (ret == -1)
+      return -1;
+
+   *size = aperture.aper_available_size;
+
+   return 0;
+}
+
+int
+anv_gem_handle_to_fd(struct anv_device *device, int gem_handle)
+{
+   struct drm_prime_handle args;
+   int ret;
+
+   VG_CLEAR(args);
+   args.handle = gem_handle;
+   args.flags = DRM_CLOEXEC;
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
+   if (ret == -1)
+      return -1;
+
+   return args.fd;
+}
+
+int
+anv_gem_fd_to_handle(struct anv_device *device, int fd)
+{
+   struct drm_prime_handle args;
+   int ret;
+
+   VG_CLEAR(args);
+   args.fd = fd;
+
+   ret = anv_ioctl(device->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
+   if (ret == -1)
+      return 0;
+
+   return args.handle;
+}
diff --git a/src/vulkan/anv_gem_stubs.c b/src/vulkan/anv_gem_stubs.c
new file mode 100644 (file)
index 0000000..d036314
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#define _DEFAULT_SOURCE
+
+#include <linux/memfd.h>
+#include <sys/mman.h>
+#include <sys/syscall.h>
+
+#include "anv_private.h"
+
+static inline int
+memfd_create(const char *name, unsigned int flags)
+{
+   return syscall(SYS_memfd_create, name, flags);
+}
+
+uint32_t
+anv_gem_create(struct anv_device *device, size_t size)
+{
+   int fd = memfd_create("fake bo", MFD_CLOEXEC);
+   if (fd == -1)
+      return 0;
+
+   assert(fd != 0);
+
+   if (ftruncate(fd, size) == -1)
+      return 0;
+
+   return fd;
+}
+
+void
+anv_gem_close(struct anv_device *device, int gem_handle)
+{
+   close(gem_handle);
+}
+
+void*
+anv_gem_mmap(struct anv_device *device, uint32_t gem_handle,
+             uint64_t offset, uint64_t size)
+{
+   return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
+               gem_handle, offset);
+}
+
+/* This is just a wrapper around munmap, but it also notifies valgrind that
+ * this map is no longer valid.  Pair this with anv_gem_mmap().
+ */
+void
+anv_gem_munmap(void *p, uint64_t size)
+{
+   munmap(p, size);
+}
+
+int
+anv_gem_userptr(struct anv_device *device, void *mem, size_t size)
+{
+   return -1;
+}
+
+int
+anv_gem_wait(struct anv_device *device, int gem_handle, int64_t *timeout_ns)
+{
+   return 0;
+}
+
+int
+anv_gem_execbuffer(struct anv_device *device,
+                   struct drm_i915_gem_execbuffer2 *execbuf)
+{
+   return 0;
+}
+
+int
+anv_gem_set_tiling(struct anv_device *device,
+                   int gem_handle, uint32_t stride, uint32_t tiling)
+{
+   return 0;
+}
+
+int
+anv_gem_get_param(int fd, uint32_t param)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_create_context(struct anv_device *device)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_destroy_context(struct anv_device *device, int context)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_get_aperture(int fd, uint64_t *size)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_handle_to_fd(struct anv_device *device, int gem_handle)
+{
+   unreachable("Unused");
+}
+
+int
+anv_gem_fd_to_handle(struct anv_device *device, int fd)
+{
+   unreachable("Unused");
+}
diff --git a/src/vulkan/anv_icd.json.in b/src/vulkan/anv_icd.json.in
new file mode 100644 (file)
index 0000000..8520dd5
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "file_format_version": "1.0.0",
+    "ICD": {
+        "library_path": "@abs_top_builddir@/lib/libvulkan.so.0.0.0",
+        "abi_versions": "0.138.2"
+    }
+}
+
diff --git a/src/vulkan/anv_image.c b/src/vulkan/anv_image.c
new file mode 100644 (file)
index 0000000..e90257e
--- /dev/null
@@ -0,0 +1,698 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static const uint8_t anv_halign[] = {
+    [4] = HALIGN4,
+    [8] = HALIGN8,
+    [16] = HALIGN16,
+};
+
+static const uint8_t anv_valign[] = {
+    [4] = VALIGN4,
+    [8] = VALIGN8,
+    [16] = VALIGN16,
+};
+
+static const uint8_t anv_surf_type_from_image_type[] = {
+   [VK_IMAGE_TYPE_1D] = SURFTYPE_1D,
+   [VK_IMAGE_TYPE_2D] = SURFTYPE_2D,
+   [VK_IMAGE_TYPE_3D] = SURFTYPE_3D,
+};
+
+static const struct anv_image_view_info
+anv_image_view_info_table[] = {
+   #define INFO(s, ...) { .surface_type = s, __VA_ARGS__ }
+   [VK_IMAGE_VIEW_TYPE_1D]          = INFO(SURFTYPE_1D),
+   [VK_IMAGE_VIEW_TYPE_2D]          = INFO(SURFTYPE_2D),
+   [VK_IMAGE_VIEW_TYPE_3D]          = INFO(SURFTYPE_3D),
+   [VK_IMAGE_VIEW_TYPE_CUBE]        = INFO(SURFTYPE_CUBE,                  .is_cube = 1),
+   [VK_IMAGE_VIEW_TYPE_1D_ARRAY]    = INFO(SURFTYPE_1D,     .is_array = 1),
+   [VK_IMAGE_VIEW_TYPE_2D_ARRAY]    = INFO(SURFTYPE_2D,     .is_array = 1),
+   [VK_IMAGE_VIEW_TYPE_CUBE_ARRAY]  = INFO(SURFTYPE_CUBE,   .is_array = 1, .is_cube = 1),
+   #undef INFO
+};
+
+struct anv_image_view_info
+anv_image_view_info_for_vk_image_view_type(VkImageViewType type)
+{
+   return anv_image_view_info_table[type];
+}
+
+static const struct anv_surf_type_limits {
+   int32_t width;
+   int32_t height;
+   int32_t depth;
+} anv_surf_type_limits[] = {
+   [SURFTYPE_1D]     = {16384,       1,   2048},
+   [SURFTYPE_2D]     = {16384,   16384,   2048},
+   [SURFTYPE_3D]     = {2048,     2048,   2048},
+   [SURFTYPE_CUBE]   = {16384,   16384,    340},
+   [SURFTYPE_BUFFER] = {128,     16384,     64},
+   [SURFTYPE_STRBUF] = {128,     16384,     64},
+};
+
+static const struct anv_tile_info {
+   /**
+    * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
+    *
+    * To simplify calculations, the alignments defined in the table are
+    * sometimes larger than required.  For example, Skylake requires that X and
+    * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
+    * alignment. We choose 4K to accomodate both chipsets.  The alignment of
+    * a linear buffer depends on its element type and usage. Linear depth
+    * buffers have the largest alignment, 64B, so we choose that for all linear
+    * buffers.
+    */
+   uint32_t surface_alignment;
+} anv_tile_info_table[] = {
+   [ISL_TILING_LINEAR]  = {   64 },
+   [ISL_TILING_X]       = { 4096 },
+   [ISL_TILING_Y]       = { 4096 },
+   [ISL_TILING_Yf]      = { 4096 },
+   [ISL_TILING_Ys]      = { 4096 },
+   [ISL_TILING_W]       = { 4096 },
+};
+
+static enum isl_tiling
+anv_image_choose_tiling(const struct anv_image_create_info *anv_info)
+{
+   if (anv_info->force_tiling)
+      return anv_info->tiling;
+
+   /* The Sandybridge PRM says that the stencil buffer "is supported
+    * only in Tile W memory".
+    */
+
+   switch (anv_info->vk_info->tiling) {
+   case VK_IMAGE_TILING_LINEAR:
+      assert(anv_info->vk_info->format != VK_FORMAT_S8_UINT);
+      return ISL_TILING_LINEAR;
+   case VK_IMAGE_TILING_OPTIMAL:
+      if (unlikely(anv_info->vk_info->format == VK_FORMAT_S8_UINT)) {
+         return ISL_TILING_W;
+      } else {
+         return ISL_TILING_Y;
+      }
+   default:
+      assert(!"bad VKImageTiling");
+      return ISL_TILING_LINEAR;
+   }
+}
+
+
+/**
+ * The \a format argument is required and overrides any format in
+ * struct anv_image_create_info.
+ */
+static VkResult
+anv_image_make_surface(const struct anv_device *dev,
+                       const struct anv_image_create_info *create_info,
+                       const struct anv_format *format,
+                       uint64_t *inout_image_size,
+                       uint32_t *inout_image_alignment,
+                       struct anv_surface *out_surface)
+{
+   /* See RENDER_SURFACE_STATE.SurfaceQPitch */
+   static const uint16_t min_qpitch UNUSED = 0x4;
+   static const uint16_t max_qpitch UNUSED = 0x1ffc;
+
+   const VkExtent3D *restrict extent = &create_info->vk_info->extent;
+   const uint32_t levels = create_info->vk_info->mipLevels;
+   const uint32_t array_size = create_info->vk_info->arraySize;
+   const enum isl_tiling tiling = anv_image_choose_tiling(create_info);
+
+   const struct anv_tile_info *tile_info =
+       &anv_tile_info_table[tiling];
+
+   const uint32_t bs = format->isl_layout->bs;
+   const uint32_t bw = format->isl_layout->bw;
+   const uint32_t bh = format->isl_layout->bh;
+
+   struct isl_extent2d tile_extent;
+   isl_tiling_get_extent(&dev->isl_dev, tiling, bs, &tile_extent);
+
+   const uint32_t i = MAX(4, bw); /* FINISHME: Stop hardcoding subimage alignment */
+   const uint32_t j = MAX(4, bh); /* FINISHME: Stop hardcoding subimage alignment */
+   assert(i == 4 || i == 8 || i == 16);
+   assert(j == 4 || j == 8 || j == 16);
+
+   uint16_t qpitch = min_qpitch;
+   uint32_t mt_width = 0;
+   uint32_t mt_height = 0;
+
+   switch (create_info->vk_info->imageType) {
+   case VK_IMAGE_TYPE_1D:
+      /* From the Broadwell PRM >> Memory Views >> Common Surface Formats >>
+       * Surface Layout >> 1D Surfaces:
+       *
+       *    One-dimensional surfaces are identical to 2D surfaces with height of one.
+       *
+       * So fallthrough...
+       */
+   case VK_IMAGE_TYPE_2D: {
+      const uint32_t w0 = align_u32(extent->width, i);
+      const uint32_t h0 = align_u32(extent->height, j);
+
+      if (levels == 1 && array_size == 1) {
+         qpitch = min_qpitch;
+         mt_width = w0;
+         mt_height = h0;
+      } else {
+         uint32_t w1 = align_u32(anv_minify(extent->width, 1), i);
+         uint32_t h1 = align_u32(anv_minify(extent->height, 1), j);
+         uint32_t w2 = align_u32(anv_minify(extent->width, 2), i);
+
+         /* The QPitch equation is found in the Broadwell PRM >> Volume 5: Memory
+          * Views >> Common Surface Formats >> Surface Layout >> 2D Surfaces >>
+          * Surface Arrays >> For All Surface Other Than Separate Stencil Buffer:
+          */
+         assert(bh ==1 || bh == 4);
+         qpitch = (h0 + h1 + 11 * j) / bh;
+         mt_width = MAX(w0, w1 + w2);
+         mt_height = array_size * qpitch;
+      }
+      break;
+   }
+   case VK_IMAGE_TYPE_3D:
+      /* The layout of 3D surfaces is described by the Broadwell PRM >>
+       * Volume 5: Memory Views >> Common Surface Formats >> Surface Layout >>
+       * 3D Surfaces.
+       */
+      for (uint32_t l = 0; l < levels; ++l) {
+         const uint32_t w_l = align_u32(anv_minify(extent->width, l), i);
+         const uint32_t h_l = align_u32(anv_minify(extent->height, l), j);
+         const uint32_t d_l = anv_minify(extent->depth, l);
+
+         const uint32_t max_layers_horiz = MIN(d_l, 1u << l);
+         const uint32_t max_layers_vert = align_u32(d_l, 1u << l) / (1u << l);
+
+         mt_width = MAX(mt_width, w_l * max_layers_horiz);
+         mt_height += h_l * max_layers_vert;
+      }
+      break;
+   default:
+      unreachable(!"bad VkImageType");
+   }
+
+   assert(qpitch >= min_qpitch);
+   if (qpitch > max_qpitch) {
+      anv_loge("image qpitch > 0x%x\n", max_qpitch);
+      return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+   }
+
+   /* From the Broadwell PRM, RENDER_SURFACE_STATE.SurfaceQpitch:
+    *
+    *   This field must be set an integer multiple of the Surface Vertical
+    *   Alignment.
+    */
+   assert(anv_is_aligned(qpitch, j));
+
+   uint32_t stride = align_u32(mt_width * bs / bw, tile_extent.width);
+   if (create_info->stride > 0)
+      stride = create_info->stride;
+
+  /* The padding requirement is found in the Broadwell PRM >> Volume 5: Memory
+   * Views >> Common Surface Formats >> Surface Padding Requirements >>
+   * Sampling Engine Surfaces >> Buffer Padding Requirements:
+   */
+   const uint32_t mem_rows = align_u32(mt_height / bh, 2 * bh);
+   const uint32_t size = stride * align_u32(mem_rows, tile_extent.height);
+   const uint32_t offset = align_u32(*inout_image_size,
+                                     tile_info->surface_alignment);
+
+   *inout_image_size = offset + size;
+   *inout_image_alignment = MAX(*inout_image_alignment,
+                                tile_info->surface_alignment);
+
+   *out_surface = (struct anv_surface) {
+      .offset = offset,
+      .stride = stride,
+      .tiling = tiling,
+      .qpitch = qpitch,
+      .h_align = i,
+      .v_align = j,
+   };
+
+   return VK_SUCCESS;
+}
+
+static VkImageUsageFlags
+anv_image_get_full_usage(const VkImageCreateInfo *info)
+{
+   VkImageUsageFlags usage = info->usage;
+
+   if (usage & VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT) {
+      /* Meta will transfer from the image by binding it as a texture. */
+      usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+   }
+
+   if (usage & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) {
+      /* Meta will transfer to the image by binding it as a color attachment,
+       * even if the image format is not a color format.
+       */
+      usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+   }
+
+   return usage;
+}
+
+VkResult
+anv_image_create(VkDevice _device,
+                 const struct anv_image_create_info *create_info,
+                 VkImage *pImage)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
+   const VkExtent3D *restrict extent = &pCreateInfo->extent;
+   struct anv_image *image = NULL;
+   VkResult r;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
+
+   anv_assert(pCreateInfo->mipLevels > 0);
+   anv_assert(pCreateInfo->arraySize > 0);
+   anv_assert(pCreateInfo->samples == 1);
+   anv_assert(pCreateInfo->extent.width > 0);
+   anv_assert(pCreateInfo->extent.height > 0);
+   anv_assert(pCreateInfo->extent.depth > 0);
+
+   /* TODO(chadv): How should we validate inputs? */
+   const uint8_t surf_type =
+      anv_surf_type_from_image_type[pCreateInfo->imageType];
+
+   const struct anv_surf_type_limits *limits =
+      &anv_surf_type_limits[surf_type];
+
+   /* Errors should be caught by VkImageFormatProperties. */
+   assert(extent->width <= limits->width);
+   assert(extent->height <= limits->height);
+   assert(extent->depth <= limits->depth);
+
+   image = anv_device_alloc(device, sizeof(*image), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!image)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   memset(image, 0, sizeof(*image));
+   image->type = pCreateInfo->imageType;
+   image->extent = pCreateInfo->extent;
+   image->format = anv_format_for_vk_format(pCreateInfo->format);
+   image->levels = pCreateInfo->mipLevels;
+   image->array_size = pCreateInfo->arraySize;
+   image->usage = anv_image_get_full_usage(pCreateInfo);
+   image->surface_type = surf_type;
+
+   if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+                       VK_IMAGE_USAGE_STORAGE_BIT)) {
+      image->needs_nonrt_surface_state = true;
+   }
+
+   if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      image->needs_color_rt_surface_state = true;
+   }
+
+   if (likely(anv_format_is_color(image->format))) {
+      r = anv_image_make_surface(device, create_info, image->format,
+                                 &image->size, &image->alignment,
+                                 &image->color_surface);
+      if (r != VK_SUCCESS)
+         goto fail;
+   } else {
+      if (image->format->depth_format) {
+         r = anv_image_make_surface(device, create_info, image->format,
+                                    &image->size, &image->alignment,
+                                    &image->depth_surface);
+         if (r != VK_SUCCESS)
+            goto fail;
+      }
+
+      if (image->format->has_stencil) {
+         r = anv_image_make_surface(device, create_info, anv_format_s8_uint,
+                                    &image->size, &image->alignment,
+                                    &image->stencil_surface);
+         if (r != VK_SUCCESS)
+            goto fail;
+      }
+   }
+
+   *pImage = anv_image_to_handle(image);
+
+   return VK_SUCCESS;
+
+fail:
+   if (image)
+      anv_device_free(device, image);
+
+   return r;
+}
+
+VkResult
+anv_CreateImage(VkDevice device,
+                const VkImageCreateInfo *pCreateInfo,
+                VkImage *pImage)
+{
+   return anv_image_create(device,
+      &(struct anv_image_create_info) {
+         .vk_info = pCreateInfo,
+      },
+      pImage);
+}
+
+void
+anv_DestroyImage(VkDevice _device, VkImage _image)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   anv_device_free(device, anv_image_from_handle(_image));
+}
+
+static void
+anv_surface_get_subresource_layout(struct anv_image *image,
+                                   struct anv_surface *surface,
+                                   const VkImageSubresource *subresource,
+                                   VkSubresourceLayout *layout)
+{
+   /* If we are on a non-zero mip level or array slice, we need to
+    * calculate a real offset.
+    */
+   anv_assert(subresource->mipLevel == 0);
+   anv_assert(subresource->arrayLayer == 0);
+
+   layout->offset = surface->offset;
+   layout->rowPitch = surface->stride;
+   layout->depthPitch = surface->qpitch;
+
+   /* FINISHME: We really shouldn't be doing this calculation here */
+   if (image->array_size > 1)
+      layout->size = surface->qpitch * image->array_size;
+   else
+      layout->size = surface->stride * image->extent.height;
+}
+
+VkResult anv_GetImageSubresourceLayout(
+    VkDevice                                    device,
+    VkImage                                     _image,
+    const VkImageSubresource*                   pSubresource,
+    VkSubresourceLayout*                        pLayout)
+{
+   ANV_FROM_HANDLE(anv_image, image, _image);
+
+   switch (pSubresource->aspect) {
+   case VK_IMAGE_ASPECT_COLOR:
+      anv_surface_get_subresource_layout(image, &image->color_surface,
+                                         pSubresource, pLayout);
+      break;
+   case VK_IMAGE_ASPECT_DEPTH:
+      anv_surface_get_subresource_layout(image, &image->depth_surface,
+                                         pSubresource, pLayout);
+      break;
+   case VK_IMAGE_ASPECT_STENCIL:
+      anv_surface_get_subresource_layout(image, &image->stencil_surface,
+                                         pSubresource, pLayout);
+      break;
+   default:
+      return vk_error(VK_UNSUPPORTED);
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_validate_CreateImageView(VkDevice _device,
+                             const VkImageViewCreateInfo *pCreateInfo,
+                             VkImageView *pView)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   const VkImageSubresourceRange *subresource;
+   const struct anv_image_view_info *view_info;
+   const struct anv_format *view_format_info;
+
+   /* Validate structure type before dereferencing it. */
+   assert(pCreateInfo);
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
+   subresource = &pCreateInfo->subresourceRange;
+
+   /* Validate viewType is in range before using it. */
+   assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
+   assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
+   view_info = &anv_image_view_info_table[pCreateInfo->viewType];
+
+   /* Validate format is in range before using it. */
+   assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
+   assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
+   view_format_info = anv_format_for_vk_format(pCreateInfo->format);
+
+   /* Validate channel swizzles. */
+   assert(pCreateInfo->channels.r >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
+   assert(pCreateInfo->channels.r <= VK_CHANNEL_SWIZZLE_END_RANGE);
+   assert(pCreateInfo->channels.g >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
+   assert(pCreateInfo->channels.g <= VK_CHANNEL_SWIZZLE_END_RANGE);
+   assert(pCreateInfo->channels.b >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
+   assert(pCreateInfo->channels.b <= VK_CHANNEL_SWIZZLE_END_RANGE);
+   assert(pCreateInfo->channels.a >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
+   assert(pCreateInfo->channels.a <= VK_CHANNEL_SWIZZLE_END_RANGE);
+
+   /* Validate subresource. */
+   assert(subresource->aspectMask != 0);
+   assert(subresource->mipLevels > 0);
+   assert(subresource->arraySize > 0);
+   assert(subresource->baseMipLevel < image->levels);
+   assert(subresource->baseMipLevel + subresource->mipLevels <= image->levels);
+   assert(subresource->baseArrayLayer < image->array_size);
+   assert(subresource->baseArrayLayer + subresource->arraySize <= image->array_size);
+   assert(pView);
+
+   if (view_info->is_cube) {
+      assert(subresource->baseArrayLayer % 6 == 0);
+      assert(subresource->arraySize % 6 == 0);
+   }
+
+   const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
+                                     | VK_IMAGE_ASPECT_STENCIL_BIT;
+
+   /* Validate format. */
+   if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
+      assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
+      assert(!image->format->depth_format);
+      assert(!image->format->has_stencil);
+      assert(!view_format_info->depth_format);
+      assert(!view_format_info->has_stencil);
+      assert(view_format_info->isl_layout->bs ==
+             image->format->isl_layout->bs);
+   } else if (subresource->aspectMask & ds_flags) {
+      assert((subresource->aspectMask & ~ds_flags) == 0);
+
+      if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
+         assert(image->format->depth_format);
+         assert(view_format_info->depth_format);
+         assert(view_format_info->isl_layout->bs ==
+                image->format->isl_layout->bs);
+      }
+
+      if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL) {
+         /* FINISHME: Is it legal to have an R8 view of S8? */
+         assert(image->format->has_stencil);
+         assert(view_format_info->has_stencil);
+      }
+   } else {
+      assert(!"bad VkImageSubresourceRange::aspectFlags");
+   }
+
+   return anv_CreateImageView(_device, pCreateInfo, pView);
+}
+
+void
+anv_image_view_init(struct anv_image_view *iview,
+                    struct anv_device *device,
+                    const VkImageViewCreateInfo* pCreateInfo,
+                    struct anv_cmd_buffer *cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+
+   assert(range->arraySize > 0);
+   assert(range->baseMipLevel < image->levels);
+   assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+                          VK_IMAGE_USAGE_STORAGE_BIT |
+                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                          VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
+
+   switch (image->type) {
+   default:
+      unreachable("bad VkImageType");
+   case VK_IMAGE_TYPE_1D:
+   case VK_IMAGE_TYPE_2D:
+      assert(range->baseArrayLayer + range->arraySize - 1 <= image->array_size);
+      break;
+   case VK_IMAGE_TYPE_3D:
+      assert(range->baseArrayLayer + range->arraySize - 1
+             <= anv_minify(image->extent.depth, range->baseMipLevel));
+      break;
+   }
+
+   switch (device->info.gen) {
+   case 7:
+      gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
+      break;
+   case 8:
+      gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
+      break;
+   default:
+      unreachable("unsupported gen\n");
+   }
+}
+
+VkResult
+anv_CreateImageView(VkDevice _device,
+                    const VkImageViewCreateInfo *pCreateInfo,
+                    VkImageView *pView)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_image_view *view;
+
+   view = anv_device_alloc(device, sizeof(*view), 8,
+                           VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (view == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   anv_image_view_init(view, device, pCreateInfo, NULL);
+
+   *pView = anv_image_view_to_handle(view);
+
+   return VK_SUCCESS;
+}
+
+static void
+anv_image_view_destroy(struct anv_device *device,
+                       struct anv_image_view *iview)
+{
+   if (iview->image->needs_color_rt_surface_state) {
+      anv_state_pool_free(&device->surface_state_pool,
+                          iview->color_rt_surface_state);
+   }
+
+   if (iview->image->needs_nonrt_surface_state) {
+      anv_state_pool_free(&device->surface_state_pool,
+                          iview->nonrt_surface_state);
+   }
+
+   anv_device_free(device, iview);
+}
+
+void
+anv_DestroyImageView(VkDevice _device, VkImageView _iview)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_image_view, iview, _iview);
+
+   anv_image_view_destroy(device, iview);
+}
+
+struct anv_surface *
+anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
+{
+   switch (aspect_mask) {
+   case VK_IMAGE_ASPECT_COLOR_BIT:
+      /* Dragons will eat you.
+       *
+       * Meta attaches all destination surfaces as color render targets. Guess
+       * what surface the Meta Dragons really want.
+       */
+      if (image->format->depth_format && image->format->has_stencil) {
+         anv_finishme("combined depth stencil formats");
+         return &image->depth_surface;
+      } else if (image->format->depth_format) {
+         return &image->depth_surface;
+      } else if (image->format->has_stencil) {
+         return &image->stencil_surface;
+      } else {
+         return &image->color_surface;
+      }
+      break;
+   case VK_IMAGE_ASPECT_DEPTH_BIT:
+      assert(image->format->depth_format);
+      return &image->depth_surface;
+   case VK_IMAGE_ASPECT_STENCIL_BIT:
+      assert(image->format->has_stencil);
+      return &image->stencil_surface;
+   case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
+      if (image->format->depth_format && image->format->has_stencil) {
+         /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
+          * depth stencil formats. Specifically, it states:
+          *
+          *    At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
+          *    ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
+          */
+         anv_finishme("combined depthstencil aspect");
+         return &image->depth_surface;
+      } else if (image->format->depth_format) {
+         return &image->depth_surface;
+      } else if (image->format->has_stencil) {
+         return &image->stencil_surface;
+      }
+      /* fallthrough */
+    default:
+       unreachable("image does not have aspect");
+       return NULL;
+   }
+}
+
+#if 0
+   VkImageAspectFlags aspect_mask = 0;
+   if (format->depth_format)
+      aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
+   if (format->has_stencil)
+      aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+   if (!aspect_mask)
+      aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
+
+   anv_image_view_init(iview, device,
+      &(VkImageViewCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+         .image = info->image,
+         .viewType = VK_IMAGE_VIEW_TYPE_2D,
+         .format = info->format,
+         .channels = {
+            .r = VK_CHANNEL_SWIZZLE_R,
+            .g = VK_CHANNEL_SWIZZLE_G,
+            .b = VK_CHANNEL_SWIZZLE_B,
+            .a = VK_CHANNEL_SWIZZLE_A,
+         },
+         .subresourceRange = {
+            .aspectMask = aspect_mask,
+            .baseMipLevel = info->mipLevel,
+            .mipLevels = 1,
+            .baseArrayLayer = info->baseArraySlice,
+            .arraySize = info->arraySize,
+         },
+      },
+      NULL);
+#endif
diff --git a/src/vulkan/anv_intel.c b/src/vulkan/anv_intel.c
new file mode 100644 (file)
index 0000000..48ac183
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+VkResult anv_CreateDmaBufImageINTEL(
+    VkDevice                                    _device,
+    const VkDmaBufImageCreateInfo*              pCreateInfo,
+    VkDeviceMemory*                             pMem,
+    VkImage*                                    pImage)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_device_memory *mem;
+   struct anv_image *image;
+   VkResult result;
+   VkImage image_h;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DMA_BUF_IMAGE_CREATE_INFO_INTEL);
+
+   mem = anv_device_alloc(device, sizeof(*mem), 8,
+                          VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (mem == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   mem->bo.gem_handle = anv_gem_fd_to_handle(device, pCreateInfo->fd);
+   if (!mem->bo.gem_handle) {
+      result = vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+      goto fail;
+   }
+
+   mem->bo.map = NULL;
+   mem->bo.index = 0;
+   mem->bo.offset = 0;
+   mem->bo.size = pCreateInfo->strideInBytes * pCreateInfo->extent.height;
+
+   image = anv_device_alloc(device, sizeof(*image), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (image == NULL) {
+      result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto fail_mem;
+   }
+
+   anv_image_create(_device,
+      &(struct anv_image_create_info) {
+         .force_tiling = true,
+         .tiling = ISL_TILING_X,
+         .stride = pCreateInfo->strideInBytes,
+         .vk_info =
+      &(VkImageCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+         .imageType = VK_IMAGE_TYPE_2D,
+         .format = pCreateInfo->format,
+         .extent = pCreateInfo->extent,
+         .mipLevels = 1,
+         .arraySize = 1,
+         .samples = 1,
+         /* FIXME: Need a way to use X tiling to allow scanout */
+         .tiling = VK_IMAGE_TILING_OPTIMAL,
+         .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+         .flags = 0,
+      }},
+      &image_h);
+
+   image = anv_image_from_handle(image_h);
+   image->bo = &mem->bo;
+   image->offset = 0;
+
+   assert(image->extent.width > 0);
+   assert(image->extent.height > 0);
+   assert(image->extent.depth == 1);
+
+   *pMem = anv_device_memory_to_handle(mem);
+   *pImage = anv_image_to_handle(image);
+
+   return VK_SUCCESS;
+
+ fail_mem:
+   anv_gem_close(device, mem->bo.gem_handle);
+ fail:
+   anv_device_free(device, mem);
+
+   return result;
+}
diff --git a/src/vulkan/anv_meta.c b/src/vulkan/anv_meta.c
new file mode 100644 (file)
index 0000000..c96a9de
--- /dev/null
@@ -0,0 +1,1335 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_meta.h"
+#include "anv_meta_clear.h"
+#include "anv_private.h"
+#include "anv_nir_builder.h"
+
+struct anv_render_pass anv_meta_dummy_renderpass = {0};
+
+static nir_shader *
+build_nir_vertex_shader(bool attr_flat)
+{
+   nir_builder b;
+
+   const struct glsl_type *vertex_type = glsl_vec4_type();
+
+   nir_builder_init_simple_shader(&b, MESA_SHADER_VERTEX);
+
+   nir_variable *pos_in = nir_variable_create(b.shader, nir_var_shader_in,
+                                              vertex_type, "a_pos");
+   pos_in->data.location = VERT_ATTRIB_GENERIC0;
+   nir_variable *pos_out = nir_variable_create(b.shader, nir_var_shader_out,
+                                               vertex_type, "gl_Position");
+   pos_in->data.location = VARYING_SLOT_POS;
+   nir_copy_var(&b, pos_out, pos_in);
+
+   /* Add one more pass-through attribute.  For clear shaders, this is used
+    * to store the color and for blit shaders it's the texture coordinate.
+    */
+   const struct glsl_type *attr_type = glsl_vec4_type();
+   nir_variable *attr_in = nir_variable_create(b.shader, nir_var_shader_in,
+                                               attr_type, "a_attr");
+   attr_in->data.location = VERT_ATTRIB_GENERIC1;
+   nir_variable *attr_out = nir_variable_create(b.shader, nir_var_shader_out,
+                                                attr_type, "v_attr");
+   attr_out->data.location = VARYING_SLOT_VAR0;
+   attr_out->data.interpolation = attr_flat ? INTERP_QUALIFIER_FLAT :
+                                              INTERP_QUALIFIER_SMOOTH;
+   nir_copy_var(&b, attr_out, attr_in);
+
+   return b.shader;
+}
+
+static nir_shader *
+build_nir_copy_fragment_shader(enum glsl_sampler_dim tex_dim)
+{
+   nir_builder b;
+
+   nir_builder_init_simple_shader(&b, MESA_SHADER_FRAGMENT);
+
+   const struct glsl_type *color_type = glsl_vec4_type();
+
+   nir_variable *tex_pos_in = nir_variable_create(b.shader, nir_var_shader_in,
+                                                  glsl_vec4_type(), "v_attr");
+   tex_pos_in->data.location = VARYING_SLOT_VAR0;
+
+   const struct glsl_type *sampler_type =
+      glsl_sampler_type(tex_dim, false, false, glsl_get_base_type(color_type));
+   nir_variable *sampler = nir_variable_create(b.shader, nir_var_uniform,
+                                               sampler_type, "s_tex");
+   sampler->data.descriptor_set = 0;
+   sampler->data.binding = 0;
+
+   nir_tex_instr *tex = nir_tex_instr_create(b.shader, 1);
+   tex->sampler_dim = tex_dim;
+   tex->op = nir_texop_tex;
+   tex->src[0].src_type = nir_tex_src_coord;
+   tex->src[0].src = nir_src_for_ssa(nir_load_var(&b, tex_pos_in));
+   tex->dest_type = nir_type_float; /* TODO */
+
+   switch (tex_dim) {
+   case GLSL_SAMPLER_DIM_2D:
+      tex->coord_components = 2;
+      break;
+   case GLSL_SAMPLER_DIM_3D:
+      tex->coord_components = 3;
+      break;
+   default:
+      assert(!"Unsupported texture dimension");
+   }
+
+   tex->sampler = nir_deref_var_create(tex, sampler);
+
+   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, "tex");
+   nir_builder_instr_insert(&b, &tex->instr);
+
+   nir_variable *color_out = nir_variable_create(b.shader, nir_var_shader_out,
+                                                 color_type, "f_color");
+   color_out->data.location = FRAG_RESULT_DATA0;
+   nir_store_var(&b, color_out, &tex->dest.ssa);
+
+   return b.shader;
+}
+
+void
+anv_meta_save(struct anv_meta_saved_state *state,
+              const struct anv_cmd_buffer *cmd_buffer,
+              uint32_t dynamic_mask)
+{
+   state->old_pipeline = cmd_buffer->state.pipeline;
+   state->old_descriptor_set0 = cmd_buffer->state.descriptors[0];
+   memcpy(state->old_vertex_bindings, cmd_buffer->state.vertex_bindings,
+          sizeof(state->old_vertex_bindings));
+
+   state->dynamic_mask = dynamic_mask;
+   anv_dynamic_state_copy(&state->dynamic, &cmd_buffer->state.dynamic,
+                          dynamic_mask);
+}
+
+void
+anv_meta_restore(const struct anv_meta_saved_state *state,
+                 struct anv_cmd_buffer *cmd_buffer)
+{
+   cmd_buffer->state.pipeline = state->old_pipeline;
+   cmd_buffer->state.descriptors[0] = state->old_descriptor_set0;
+   memcpy(cmd_buffer->state.vertex_bindings, state->old_vertex_bindings,
+          sizeof(state->old_vertex_bindings));
+
+   cmd_buffer->state.vb_dirty |= (1 << ANV_META_VERTEX_BINDING_COUNT) - 1;
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_PIPELINE;
+   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_VERTEX_BIT;
+
+   anv_dynamic_state_copy(&cmd_buffer->state.dynamic, &state->dynamic,
+                          state->dynamic_mask);
+   cmd_buffer->state.dirty |= state->dynamic_mask;
+}
+
+static VkImageViewType
+meta_blit_get_src_image_view_type(const struct anv_image *src_image)
+{
+   switch (src_image->type) {
+   case VK_IMAGE_TYPE_1D:
+      return VK_IMAGE_VIEW_TYPE_1D;
+   case VK_IMAGE_TYPE_2D:
+      return VK_IMAGE_VIEW_TYPE_2D;
+   case VK_IMAGE_TYPE_3D:
+      return VK_IMAGE_VIEW_TYPE_3D;
+   default:
+      assert(!"bad VkImageType");
+      return 0;
+   }
+}
+
+static uint32_t
+meta_blit_get_dest_view_base_array_slice(const struct anv_image *dest_image,
+                                         const VkImageSubresourceCopy *dest_subresource,
+                                         const VkOffset3D *dest_offset)
+{
+   switch (dest_image->type) {
+   case VK_IMAGE_TYPE_1D:
+   case VK_IMAGE_TYPE_2D:
+      return dest_subresource->arrayLayer;
+   case VK_IMAGE_TYPE_3D:
+      /* HACK: Vulkan does not allow attaching a 3D image to a framebuffer,
+       * but meta does it anyway. When doing so, we translate the
+       * destination's z offset into an array offset.
+       */
+      return dest_offset->z;
+   default:
+      assert(!"bad VkImageType");
+      return 0;
+   }
+}
+
+static void
+anv_device_init_meta_blit_state(struct anv_device *device)
+{
+   anv_CreateRenderPass(anv_device_to_handle(device),
+      &(VkRenderPassCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+         .attachmentCount = 1,
+         .pAttachments = &(VkAttachmentDescription) {
+            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
+            .format = VK_FORMAT_UNDEFINED, /* Our shaders don't care */
+            .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+            .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+            .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
+            .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
+         },
+         .subpassCount = 1,
+         .pSubpasses = &(VkSubpassDescription) {
+            .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
+            .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+            .inputCount = 0,
+            .colorCount = 1,
+            .pColorAttachments = &(VkAttachmentReference) {
+               .attachment = 0,
+               .layout = VK_IMAGE_LAYOUT_GENERAL,
+            },
+            .pResolveAttachments = NULL,
+            .depthStencilAttachment = (VkAttachmentReference) {
+               .attachment = VK_ATTACHMENT_UNUSED,
+               .layout = VK_IMAGE_LAYOUT_GENERAL,
+            },
+            .preserveCount = 1,
+            .pPreserveAttachments = &(VkAttachmentReference) {
+               .attachment = 0,
+               .layout = VK_IMAGE_LAYOUT_GENERAL,
+            },
+         },
+         .dependencyCount = 0,
+      }, &device->meta_state.blit.render_pass);
+
+   /* We don't use a vertex shader for clearing, but instead build and pass
+    * the VUEs directly to the rasterization backend.  However, we do need
+    * to provide GLSL source for the vertex shader so that the compiler
+    * does not dead-code our inputs.
+    */
+   struct anv_shader_module vsm = {
+      .nir = build_nir_vertex_shader(false),
+   };
+
+   struct anv_shader_module fsm_2d = {
+      .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_2D),
+   };
+
+   struct anv_shader_module fsm_3d = {
+      .nir = build_nir_copy_fragment_shader(GLSL_SAMPLER_DIM_3D),
+   };
+
+   VkShader vs;
+   anv_CreateShader(anv_device_to_handle(device),
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = anv_shader_module_to_handle(&vsm),
+         .pName = "main",
+      }, &vs);
+
+   VkShader fs_2d;
+   anv_CreateShader(anv_device_to_handle(device),
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = anv_shader_module_to_handle(&fsm_2d),
+         .pName = "main",
+      }, &fs_2d);
+
+   VkShader fs_3d;
+   anv_CreateShader(anv_device_to_handle(device),
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = anv_shader_module_to_handle(&fsm_3d),
+         .pName = "main",
+      }, &fs_3d);
+
+   VkPipelineVertexInputStateCreateInfo vi_create_info = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+      .bindingCount = 2,
+      .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
+         {
+            .binding = 0,
+            .strideInBytes = 0,
+            .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
+         },
+         {
+            .binding = 1,
+            .strideInBytes = 5 * sizeof(float),
+            .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
+         },
+      },
+      .attributeCount = 3,
+      .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
+         {
+            /* VUE Header */
+            .location = 0,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32B32A32_UINT,
+            .offsetInBytes = 0
+         },
+         {
+            /* Position */
+            .location = 1,
+            .binding = 1,
+            .format = VK_FORMAT_R32G32_SFLOAT,
+            .offsetInBytes = 0
+         },
+         {
+            /* Texture Coordinate */
+            .location = 2,
+            .binding = 1,
+            .format = VK_FORMAT_R32G32B32_SFLOAT,
+            .offsetInBytes = 8
+         }
+      }
+   };
+
+   VkDescriptorSetLayoutCreateInfo ds_layout_info = {
+      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+      .count = 1,
+      .pBinding = (VkDescriptorSetLayoutBinding[]) {
+         {
+            .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            .arraySize = 1,
+            .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
+            .pImmutableSamplers = NULL
+         },
+      }
+   };
+   anv_CreateDescriptorSetLayout(anv_device_to_handle(device), &ds_layout_info,
+                                 &device->meta_state.blit.ds_layout);
+
+   anv_CreatePipelineLayout(anv_device_to_handle(device),
+      &(VkPipelineLayoutCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+         .descriptorSetCount = 1,
+         .pSetLayouts = &device->meta_state.blit.ds_layout,
+      },
+      &device->meta_state.blit.pipeline_layout);
+
+   VkPipelineShaderStageCreateInfo pipeline_shader_stages[] = {
+      {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+         .stage = VK_SHADER_STAGE_VERTEX,
+         .shader = vs,
+         .pSpecializationInfo = NULL
+      }, {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+         .stage = VK_SHADER_STAGE_FRAGMENT,
+         .shader = {0}, /* TEMPLATE VALUE! FILL ME IN! */
+         .pSpecializationInfo = NULL
+      },
+   };
+
+   const VkGraphicsPipelineCreateInfo vk_pipeline_info = {
+      .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+      .stageCount = ARRAY_SIZE(pipeline_shader_stages),
+      .pStages = pipeline_shader_stages,
+      .pVertexInputState = &vi_create_info,
+      .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+         .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+         .primitiveRestartEnable = false,
+      },
+      .pViewportState = &(VkPipelineViewportStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+         .viewportCount = 1,
+         .scissorCount = 1,
+      },
+      .pRasterState = &(VkPipelineRasterStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
+         .depthClipEnable = true,
+         .rasterizerDiscardEnable = false,
+         .fillMode = VK_FILL_MODE_SOLID,
+         .cullMode = VK_CULL_MODE_NONE,
+         .frontFace = VK_FRONT_FACE_CCW
+      },
+      .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+         .rasterSamples = 1,
+         .sampleShadingEnable = false,
+         .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
+      },
+      .pColorBlendState = &(VkPipelineColorBlendStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+         .attachmentCount = 1,
+         .pAttachments = (VkPipelineColorBlendAttachmentState []) {
+            { .channelWriteMask = VK_CHANNEL_A_BIT |
+                 VK_CHANNEL_R_BIT | VK_CHANNEL_G_BIT | VK_CHANNEL_B_BIT },
+         }
+      },
+      .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+         .dynamicStateCount = 9,
+         .pDynamicStates = (VkDynamicState[]) {
+            VK_DYNAMIC_STATE_VIEWPORT,
+            VK_DYNAMIC_STATE_SCISSOR,
+            VK_DYNAMIC_STATE_LINE_WIDTH,
+            VK_DYNAMIC_STATE_DEPTH_BIAS,
+            VK_DYNAMIC_STATE_BLEND_CONSTANTS,
+            VK_DYNAMIC_STATE_DEPTH_BOUNDS,
+            VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
+            VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
+            VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+         },
+      },
+      .flags = 0,
+      .layout = device->meta_state.blit.pipeline_layout,
+      .renderPass = device->meta_state.blit.render_pass,
+      .subpass = 0,
+   };
+
+   const struct anv_graphics_pipeline_create_info anv_pipeline_info = {
+      .use_repclear = false,
+      .disable_viewport = true,
+      .disable_scissor = true,
+      .disable_vs = true,
+      .use_rectlist = true
+   };
+
+   pipeline_shader_stages[1].shader = fs_2d;
+   anv_graphics_pipeline_create(anv_device_to_handle(device),
+      &vk_pipeline_info, &anv_pipeline_info,
+      &device->meta_state.blit.pipeline_2d_src);
+
+   pipeline_shader_stages[1].shader = fs_3d;
+   anv_graphics_pipeline_create(anv_device_to_handle(device),
+      &vk_pipeline_info, &anv_pipeline_info,
+      &device->meta_state.blit.pipeline_3d_src);
+
+   anv_DestroyShader(anv_device_to_handle(device), vs);
+   anv_DestroyShader(anv_device_to_handle(device), fs_2d);
+   anv_DestroyShader(anv_device_to_handle(device), fs_3d);
+   ralloc_free(vsm.nir);
+   ralloc_free(fsm_2d.nir);
+   ralloc_free(fsm_3d.nir);
+}
+
+static void
+meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
+                  struct anv_meta_saved_state *saved_state)
+{
+   anv_meta_save(saved_state, cmd_buffer,
+                 (1 << VK_DYNAMIC_STATE_VIEWPORT));
+}
+
+struct blit_region {
+   VkOffset3D src_offset;
+   VkExtent3D src_extent;
+   VkOffset3D dest_offset;
+   VkExtent3D dest_extent;
+};
+
+static void
+meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
+               struct anv_image *src_image,
+               struct anv_image_view *src_iview,
+               VkOffset3D src_offset,
+               VkExtent3D src_extent,
+               struct anv_image *dest_image,
+               struct anv_image_view *dest_iview,
+               VkOffset3D dest_offset,
+               VkExtent3D dest_extent,
+               VkTexFilter blit_filter)
+{
+   struct anv_device *device = cmd_buffer->device;
+   VkDescriptorPool dummy_desc_pool = { .handle = 1 };
+
+   struct blit_vb_data {
+      float pos[2];
+      float tex_coord[3];
+   } *vb_data;
+
+   unsigned vb_size = sizeof(struct anv_vue_header) + 3 * sizeof(*vb_data);
+
+   struct anv_state vb_state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, vb_size, 16);
+   memset(vb_state.map, 0, sizeof(struct anv_vue_header));
+   vb_data = vb_state.map + sizeof(struct anv_vue_header);
+
+   vb_data[0] = (struct blit_vb_data) {
+      .pos = {
+         dest_offset.x + dest_extent.width,
+         dest_offset.y + dest_extent.height,
+      },
+      .tex_coord = {
+         (float)(src_offset.x + src_extent.width) / (float)src_iview->extent.width,
+         (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
+         (float)(src_offset.z + src_extent.depth) / (float)src_iview->extent.depth,
+      },
+   };
+
+   vb_data[1] = (struct blit_vb_data) {
+      .pos = {
+         dest_offset.x,
+         dest_offset.y + dest_extent.height,
+      },
+      .tex_coord = {
+         (float)src_offset.x / (float)src_iview->extent.width,
+         (float)(src_offset.y + src_extent.height) / (float)src_iview->extent.height,
+         (float)(src_offset.z + src_extent.depth) / (float)src_iview->extent.depth,
+      },
+   };
+
+   vb_data[2] = (struct blit_vb_data) {
+      .pos = {
+         dest_offset.x,
+         dest_offset.y,
+      },
+      .tex_coord = {
+         (float)src_offset.x / (float)src_iview->extent.width,
+         (float)src_offset.y / (float)src_iview->extent.height,
+         (float)src_offset.z / (float)src_iview->extent.depth,
+      },
+   };
+
+   struct anv_buffer vertex_buffer = {
+      .device = device,
+      .size = vb_size,
+      .bo = &device->dynamic_state_block_pool.bo,
+      .offset = vb_state.offset,
+   };
+
+   anv_CmdBindVertexBuffers(anv_cmd_buffer_to_handle(cmd_buffer), 0, 2,
+      (VkBuffer[]) {
+         anv_buffer_to_handle(&vertex_buffer),
+         anv_buffer_to_handle(&vertex_buffer)
+      },
+      (VkDeviceSize[]) {
+         0,
+         sizeof(struct anv_vue_header),
+      });
+
+   VkSampler sampler;
+   ANV_CALL(CreateSampler)(anv_device_to_handle(device),
+      &(VkSamplerCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
+         .magFilter = blit_filter,
+         .minFilter = blit_filter,
+      }, &sampler);
+
+   VkDescriptorSet set;
+   anv_AllocDescriptorSets(anv_device_to_handle(device), dummy_desc_pool,
+                           VK_DESCRIPTOR_SET_USAGE_ONE_SHOT,
+                           1, &device->meta_state.blit.ds_layout, &set);
+   anv_UpdateDescriptorSets(anv_device_to_handle(device),
+      1, /* writeCount */
+      (VkWriteDescriptorSet[]) {
+         {
+            .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+            .destSet = set,
+            .destBinding = 0,
+            .destArrayElement = 0,
+            .count = 1,
+            .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+            .pDescriptors = (VkDescriptorInfo[]) {
+               {
+                  .imageView = anv_image_view_to_handle(src_iview),
+                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL,
+                  .sampler = sampler,
+               },
+            }
+         }
+      }, 0, NULL);
+
+   VkFramebuffer fb;
+   anv_CreateFramebuffer(anv_device_to_handle(device),
+      &(VkFramebufferCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+         .attachmentCount = 1,
+         .pAttachments = (VkImageView[]) {
+            anv_image_view_to_handle(dest_iview),
+         },
+         .width = dest_iview->extent.width,
+         .height = dest_iview->extent.height,
+         .layers = 1
+      }, &fb);
+
+   ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
+      &(VkRenderPassBeginInfo) {
+         .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+         .renderPass = device->meta_state.blit.render_pass,
+         .framebuffer = fb,
+         .renderArea = {
+            .offset = { dest_offset.x, dest_offset.y },
+            .extent = { dest_extent.width, dest_extent.height },
+         },
+         .clearValueCount = 0,
+         .pClearValues = NULL,
+      }, VK_RENDER_PASS_CONTENTS_INLINE);
+
+   VkPipeline pipeline;
+
+   switch (src_image->type) {
+   case VK_IMAGE_TYPE_1D:
+      anv_finishme("VK_IMAGE_TYPE_1D");
+      pipeline = device->meta_state.blit.pipeline_2d_src;
+      break;
+   case VK_IMAGE_TYPE_2D:
+      pipeline = device->meta_state.blit.pipeline_2d_src;
+      break;
+   case VK_IMAGE_TYPE_3D:
+      pipeline = device->meta_state.blit.pipeline_3d_src;
+      break;
+   default:
+      unreachable(!"bad VkImageType");
+   }
+
+   if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(pipeline)) {
+      anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
+                          VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
+   }
+
+   anv_CmdSetViewport(anv_cmd_buffer_to_handle(cmd_buffer), 1,
+                      &(VkViewport) {
+                        .originX = 0.0f,
+                        .originY = 0.0f,
+                        .width = dest_iview->extent.width,
+                        .height = dest_iview->extent.height,
+                        .minDepth = 0.0f,
+                        .maxDepth = 1.0f,
+                      });
+
+   anv_CmdBindDescriptorSets(anv_cmd_buffer_to_handle(cmd_buffer),
+                             VK_PIPELINE_BIND_POINT_GRAPHICS,
+                             device->meta_state.blit.pipeline_layout, 0, 1,
+                             &set, 0, NULL);
+
+   ANV_CALL(CmdDraw)(anv_cmd_buffer_to_handle(cmd_buffer), 3, 1, 0, 0);
+
+   ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
+
+   /* At the point where we emit the draw call, all data from the
+    * descriptor sets, etc. has been used.  We are free to delete it.
+    */
+   anv_descriptor_set_destroy(device, anv_descriptor_set_from_handle(set));
+   anv_DestroySampler(anv_device_to_handle(device), sampler);
+   anv_DestroyFramebuffer(anv_device_to_handle(device), fb);
+}
+
+static void
+meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
+                 const struct anv_meta_saved_state *saved_state)
+{
+   anv_meta_restore(saved_state, cmd_buffer);
+}
+
+static VkFormat
+vk_format_for_size(int bs)
+{
+   switch (bs) {
+   case 1: return VK_FORMAT_R8_UINT;
+   case 2: return VK_FORMAT_R8G8_UINT;
+   case 3: return VK_FORMAT_R8G8B8_UINT;
+   case 4: return VK_FORMAT_R8G8B8A8_UINT;
+   case 6: return VK_FORMAT_R16G16B16_UINT;
+   case 8: return VK_FORMAT_R16G16B16A16_UINT;
+   case 12: return VK_FORMAT_R32G32B32_UINT;
+   case 16: return VK_FORMAT_R32G32B32A32_UINT;
+   default:
+      unreachable("Invalid format block size");
+   }
+}
+
+static void
+do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
+               struct anv_bo *src, uint64_t src_offset,
+               struct anv_bo *dest, uint64_t dest_offset,
+               int width, int height, VkFormat copy_format)
+{
+   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+
+   VkImageCreateInfo image_info = {
+      .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+      .imageType = VK_IMAGE_TYPE_2D,
+      .format = copy_format,
+      .extent = {
+         .width = width,
+         .height = height,
+         .depth = 1,
+      },
+      .mipLevels = 1,
+      .arraySize = 1,
+      .samples = 1,
+      .tiling = VK_IMAGE_TILING_LINEAR,
+      .usage = 0,
+      .flags = 0,
+   };
+
+   VkImage src_image;
+   image_info.usage = VK_IMAGE_USAGE_SAMPLED_BIT;
+   anv_CreateImage(vk_device, &image_info, &src_image);
+
+   VkImage dest_image;
+   image_info.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+   anv_CreateImage(vk_device, &image_info, &dest_image);
+
+   /* We could use a vk call to bind memory, but that would require
+    * creating a dummy memory object etc. so there's really no point.
+    */
+   anv_image_from_handle(src_image)->bo = src;
+   anv_image_from_handle(src_image)->offset = src_offset;
+   anv_image_from_handle(dest_image)->bo = dest;
+   anv_image_from_handle(dest_image)->offset = dest_offset;
+
+   struct anv_image_view src_iview;
+   anv_image_view_init(&src_iview, cmd_buffer->device,
+      &(VkImageViewCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+         .image = src_image,
+         .viewType = VK_IMAGE_VIEW_TYPE_2D,
+         .format = copy_format,
+         .channels = {
+            VK_CHANNEL_SWIZZLE_R,
+            VK_CHANNEL_SWIZZLE_G,
+            VK_CHANNEL_SWIZZLE_B,
+            VK_CHANNEL_SWIZZLE_A
+         },
+         .subresourceRange = {
+            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+            .baseMipLevel = 0,
+            .mipLevels = 1,
+            .baseArrayLayer = 0,
+            .arraySize = 1
+         },
+      },
+      cmd_buffer);
+
+   struct anv_image_view dest_iview;
+   anv_image_view_init(&dest_iview, cmd_buffer->device,
+      &(VkImageViewCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+         .image = dest_image,
+         .viewType = VK_IMAGE_VIEW_TYPE_2D,
+         .format = copy_format,
+         .channels = {
+            .r = VK_CHANNEL_SWIZZLE_R,
+            .g = VK_CHANNEL_SWIZZLE_G,
+            .b = VK_CHANNEL_SWIZZLE_B,
+            .a = VK_CHANNEL_SWIZZLE_A,
+         },
+         .subresourceRange = {
+            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+            .baseMipLevel = 0,
+            .mipLevels = 1,
+            .baseArrayLayer = 0,
+            .arraySize = 1,
+         },
+      },
+      cmd_buffer);
+
+   meta_emit_blit(cmd_buffer,
+                  anv_image_from_handle(src_image),
+                  &src_iview,
+                  (VkOffset3D) { 0, 0, 0 },
+                  (VkExtent3D) { width, height, 1 },
+                  anv_image_from_handle(dest_image),
+                  &dest_iview,
+                  (VkOffset3D) { 0, 0, 0 },
+                  (VkExtent3D) { width, height, 1 },
+                  VK_TEX_FILTER_NEAREST);
+
+   anv_DestroyImage(vk_device, src_image);
+   anv_DestroyImage(vk_device, dest_image);
+}
+
+void anv_CmdCopyBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    srcBuffer,
+    VkBuffer                                    destBuffer,
+    uint32_t                                    regionCount,
+    const VkBufferCopy*                         pRegions)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, src_buffer, srcBuffer);
+   ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
+
+   struct anv_meta_saved_state saved_state;
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      uint64_t src_offset = src_buffer->offset + pRegions[r].srcOffset;
+      uint64_t dest_offset = dest_buffer->offset + pRegions[r].destOffset;
+      uint64_t copy_size = pRegions[r].copySize;
+
+      /* First, we compute the biggest format that can be used with the
+       * given offsets and size.
+       */
+      int bs = 16;
+
+      int fs = ffs(src_offset) - 1;
+      if (fs != -1)
+         bs = MIN2(bs, 1 << fs);
+      assert(src_offset % bs == 0);
+
+      fs = ffs(dest_offset) - 1;
+      if (fs != -1)
+         bs = MIN2(bs, 1 << fs);
+      assert(dest_offset % bs == 0);
+
+      fs = ffs(pRegions[r].copySize) - 1;
+      if (fs != -1)
+         bs = MIN2(bs, 1 << fs);
+      assert(pRegions[r].copySize % bs == 0);
+
+      VkFormat copy_format = vk_format_for_size(bs);
+
+      /* This is maximum possible width/height our HW can handle */
+      uint64_t max_surface_dim = 1 << 14;
+
+      /* First, we make a bunch of max-sized copies */
+      uint64_t max_copy_size = max_surface_dim * max_surface_dim * bs;
+      while (copy_size > max_copy_size) {
+         do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
+                        dest_buffer->bo, dest_offset,
+                        max_surface_dim, max_surface_dim, copy_format);
+         copy_size -= max_copy_size;
+         src_offset += max_copy_size;
+         dest_offset += max_copy_size;
+      }
+
+      uint64_t height = copy_size / (max_surface_dim * bs);
+      assert(height < max_surface_dim);
+      if (height != 0) {
+         uint64_t rect_copy_size = height * max_surface_dim * bs;
+         do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
+                        dest_buffer->bo, dest_offset,
+                        max_surface_dim, height, copy_format);
+         copy_size -= rect_copy_size;
+         src_offset += rect_copy_size;
+         dest_offset += rect_copy_size;
+      }
+
+      if (copy_size != 0) {
+         do_buffer_copy(cmd_buffer, src_buffer->bo, src_offset,
+                        dest_buffer->bo, dest_offset,
+                        copy_size / bs, 1, copy_format);
+      }
+   }
+
+   meta_finish_blit(cmd_buffer, &saved_state);
+}
+
+void anv_CmdCopyImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkImageCopy*                          pRegions)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_image, src_image, srcImage);
+   ANV_FROM_HANDLE(anv_image, dest_image, destImage);
+
+   const VkImageViewType src_iview_type =
+      meta_blit_get_src_image_view_type(src_image);
+
+   struct anv_meta_saved_state saved_state;
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      struct anv_image_view src_iview;
+      anv_image_view_init(&src_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = src_iview_type,
+            .format = src_image->format->vk_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = 1 << pRegions[r].srcSubresource.aspect,
+               .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      const VkOffset3D dest_offset = {
+         .x = pRegions[r].destOffset.x,
+         .y = pRegions[r].destOffset.y,
+         .z = 0,
+      };
+
+      const uint32_t dest_array_slice =
+         meta_blit_get_dest_view_base_array_slice(dest_image,
+                                                  &pRegions[r].destSubresource,
+                                                  &pRegions[r].destOffset);
+
+      if (pRegions[r].srcSubresource.arraySize > 1)
+         anv_finishme("FINISHME: copy multiple array layers");
+
+      if (pRegions[r].extent.depth > 1)
+         anv_finishme("FINISHME: copy multiple depth layers");
+
+      struct anv_image_view dest_iview;
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = destImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = dest_image->format->vk_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = pRegions[r].destSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = dest_array_slice,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     src_image, &src_iview,
+                     pRegions[r].srcOffset,
+                     pRegions[r].extent,
+                     dest_image, &dest_iview,
+                     dest_offset,
+                     pRegions[r].extent,
+                     VK_TEX_FILTER_NEAREST);
+   }
+
+   meta_finish_blit(cmd_buffer, &saved_state);
+}
+
+void anv_CmdBlitImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkImageBlit*                          pRegions,
+    VkTexFilter                                 filter)
+
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_image, src_image, srcImage);
+   ANV_FROM_HANDLE(anv_image, dest_image, destImage);
+
+   const VkImageViewType src_iview_type =
+      meta_blit_get_src_image_view_type(src_image);
+
+   struct anv_meta_saved_state saved_state;
+
+   anv_finishme("respect VkTexFilter");
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      struct anv_image_view src_iview;
+      anv_image_view_init(&src_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = src_iview_type,
+            .format = src_image->format->vk_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = 1 << pRegions[r].srcSubresource.aspect,
+               .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = pRegions[r].srcSubresource.arrayLayer,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      const VkOffset3D dest_offset = {
+         .x = pRegions[r].destOffset.x,
+         .y = pRegions[r].destOffset.y,
+         .z = 0,
+      };
+
+      const uint32_t dest_array_slice =
+         meta_blit_get_dest_view_base_array_slice(dest_image,
+                                                  &pRegions[r].destSubresource,
+                                                  &pRegions[r].destOffset);
+
+      if (pRegions[r].srcSubresource.arraySize > 1)
+         anv_finishme("FINISHME: copy multiple array layers");
+
+      if (pRegions[r].destExtent.depth > 1)
+         anv_finishme("FINISHME: copy multiple depth layers");
+
+      struct anv_image_view dest_iview;
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = destImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = dest_image->format->vk_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = pRegions[r].destSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = dest_array_slice,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     src_image, &src_iview,
+                     pRegions[r].srcOffset,
+                     pRegions[r].srcExtent,
+                     dest_image, &dest_iview,
+                     dest_offset,
+                     pRegions[r].destExtent,
+                     filter);
+   }
+
+   meta_finish_blit(cmd_buffer, &saved_state);
+}
+
+static VkImage
+make_image_for_buffer(VkDevice vk_device, VkBuffer vk_buffer, VkFormat format,
+                      VkImageUsageFlags usage,
+                      const VkBufferImageCopy *copy)
+{
+   ANV_FROM_HANDLE(anv_buffer, buffer, vk_buffer);
+
+   VkExtent3D extent = copy->imageExtent;
+   if (copy->bufferRowLength)
+      extent.width = copy->bufferRowLength;
+   if (copy->bufferImageHeight)
+      extent.height = copy->bufferImageHeight;
+   extent.depth = 1;
+
+   VkImage vk_image;
+   VkResult result = anv_CreateImage(vk_device,
+      &(VkImageCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+         .imageType = VK_IMAGE_TYPE_2D,
+         .format = format,
+         .extent = extent,
+         .mipLevels = 1,
+         .arraySize = 1,
+         .samples = 1,
+         .tiling = VK_IMAGE_TILING_LINEAR,
+         .usage = usage,
+         .flags = 0,
+      }, &vk_image);
+   assert(result == VK_SUCCESS);
+
+   ANV_FROM_HANDLE(anv_image, image, vk_image);
+
+   /* We could use a vk call to bind memory, but that would require
+    * creating a dummy memory object etc. so there's really no point.
+    */
+   image->bo = buffer->bo;
+   image->offset = buffer->offset + copy->bufferOffset;
+
+   return anv_image_to_handle(image);
+}
+
+void anv_CmdCopyBufferToImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    srcBuffer,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkBufferImageCopy*                    pRegions)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_image, dest_image, destImage);
+   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+   const VkFormat orig_format = dest_image->format->vk_format;
+   struct anv_meta_saved_state saved_state;
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      VkFormat proxy_format = orig_format;
+      VkImageAspect proxy_aspect = pRegions[r].imageSubresource.aspect;
+
+      if (orig_format == VK_FORMAT_S8_UINT) {
+         proxy_format = VK_FORMAT_R8_UINT;
+         proxy_aspect = VK_IMAGE_ASPECT_COLOR;
+      }
+
+      VkImage srcImage = make_image_for_buffer(vk_device, srcBuffer,
+            proxy_format, VK_IMAGE_USAGE_SAMPLED_BIT, &pRegions[r]);
+
+      struct anv_image_view src_iview;
+      anv_image_view_init(&src_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = proxy_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = 1 << proxy_aspect,
+               .baseMipLevel = 0,
+               .mipLevels = 1,
+               .baseArrayLayer = 0,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      const VkOffset3D dest_offset = {
+         .x = pRegions[r].imageOffset.x,
+         .y = pRegions[r].imageOffset.y,
+         .z = 0,
+      };
+
+      const uint32_t dest_array_slice =
+         meta_blit_get_dest_view_base_array_slice(dest_image,
+                                                  &pRegions[r].imageSubresource,
+                                                  &pRegions[r].imageOffset);
+
+      if (pRegions[r].imageExtent.depth > 1)
+         anv_finishme("FINISHME: copy multiple depth layers");
+
+      struct anv_image_view dest_iview;
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = anv_image_to_handle(dest_image),
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = proxy_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = dest_array_slice,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     anv_image_from_handle(srcImage),
+                     &src_iview,
+                     (VkOffset3D) { 0, 0, 0 },
+                     pRegions[r].imageExtent,
+                     dest_image,
+                     &dest_iview,
+                     dest_offset,
+                     pRegions[r].imageExtent,
+                     VK_TEX_FILTER_NEAREST);
+
+      anv_DestroyImage(vk_device, srcImage);
+   }
+
+   meta_finish_blit(cmd_buffer, &saved_state);
+}
+
+void anv_CmdCopyImageToBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkBuffer                                    destBuffer,
+    uint32_t                                    regionCount,
+    const VkBufferImageCopy*                    pRegions)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_image, src_image, srcImage);
+   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+   struct anv_meta_saved_state saved_state;
+
+   const VkImageViewType src_iview_type =
+      meta_blit_get_src_image_view_type(src_image);
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      if (pRegions[r].imageSubresource.arraySize > 1)
+         anv_finishme("FINISHME: copy multiple array layers");
+
+      if (pRegions[r].imageExtent.depth > 1)
+         anv_finishme("FINISHME: copy multiple depth layers");
+
+      struct anv_image_view src_iview;
+      anv_image_view_init(&src_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = src_iview_type,
+            .format = src_image->format->vk_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = 1 << pRegions[r].imageSubresource.aspect,
+               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = pRegions[r].imageSubresource.arrayLayer,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      VkFormat dest_format = src_image->format->vk_format;
+      if (dest_format == VK_FORMAT_S8_UINT) {
+         dest_format = VK_FORMAT_R8_UINT;
+      }
+
+      VkImage destImage = make_image_for_buffer(vk_device, destBuffer,
+            dest_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &pRegions[r]);
+
+      struct anv_image_view dest_iview;
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = destImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = dest_format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = 0,
+               .mipLevels = 1,
+               .baseArrayLayer = 0,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     anv_image_from_handle(srcImage),
+                     &src_iview,
+                     pRegions[r].imageOffset,
+                     pRegions[r].imageExtent,
+                     anv_image_from_handle(destImage),
+                     &dest_iview,
+                     (VkOffset3D) { 0, 0, 0 },
+                     pRegions[r].imageExtent,
+                     VK_TEX_FILTER_NEAREST);
+
+      anv_DestroyImage(vk_device, destImage);
+   }
+
+   meta_finish_blit(cmd_buffer, &saved_state);
+}
+
+void anv_CmdUpdateBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                dataSize,
+    const uint32_t*                             pData)
+{
+   stub();
+}
+
+void anv_CmdFillBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                fillSize,
+    uint32_t                                    data)
+{
+   stub();
+}
+
+void anv_CmdResolveImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     srcImage,
+    VkImageLayout                               srcImageLayout,
+    VkImage                                     destImage,
+    VkImageLayout                               destImageLayout,
+    uint32_t                                    regionCount,
+    const VkImageResolve*                       pRegions)
+{
+   stub();
+}
+
+void
+anv_device_init_meta(struct anv_device *device)
+{
+   anv_device_init_meta_clear_state(device);
+   anv_device_init_meta_blit_state(device);
+}
+
+void
+anv_device_finish_meta(struct anv_device *device)
+{
+   anv_device_finish_meta_clear_state(device);
+
+   /* Blit */
+   anv_DestroyRenderPass(anv_device_to_handle(device),
+                         device->meta_state.blit.render_pass);
+   anv_DestroyPipeline(anv_device_to_handle(device),
+                       device->meta_state.blit.pipeline_2d_src);
+   anv_DestroyPipeline(anv_device_to_handle(device),
+                       device->meta_state.blit.pipeline_3d_src);
+   anv_DestroyPipelineLayout(anv_device_to_handle(device),
+                             device->meta_state.blit.pipeline_layout);
+   anv_DestroyDescriptorSetLayout(anv_device_to_handle(device),
+                                  device->meta_state.blit.ds_layout);
+}
diff --git a/src/vulkan/anv_meta.h b/src/vulkan/anv_meta.h
new file mode 100644 (file)
index 0000000..d798c6e
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANV_META_VERTEX_BINDING_COUNT 2
+
+struct anv_meta_saved_state {
+   struct anv_vertex_binding old_vertex_bindings[ANV_META_VERTEX_BINDING_COUNT];
+   struct anv_descriptor_set *old_descriptor_set0;
+   struct anv_pipeline *old_pipeline;
+
+   /**
+    * Bitmask of (1 << VK_DYNAMIC_STATE_*). Defines the set of saved dynamic
+    * state.
+    */
+   uint32_t dynamic_mask;
+   struct anv_dynamic_state dynamic;
+};
+
+void
+anv_meta_save(struct anv_meta_saved_state *state,
+              const struct anv_cmd_buffer *cmd_buffer,
+              uint32_t dynamic_mask);
+
+void
+anv_meta_restore(const struct anv_meta_saved_state *state,
+                 struct anv_cmd_buffer *cmd_buffer);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/vulkan/anv_meta_clear.c b/src/vulkan/anv_meta_clear.c
new file mode 100644 (file)
index 0000000..7eb4c55
--- /dev/null
@@ -0,0 +1,799 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_meta.h"
+#include "anv_meta_clear.h"
+#include "anv_nir_builder.h"
+#include "anv_private.h"
+
+/** Vertex attributes for color clears.  */
+struct color_clear_vattrs {
+   struct anv_vue_header vue_header;
+   float position[2]; /**< 3DPRIM_RECTLIST */
+   VkClearColorValue color;
+};
+
+/** Vertex attributes for depthstencil clears.  */
+struct depthstencil_clear_vattrs {
+   struct anv_vue_header vue_header;
+   float position[2]; /*<< 3DPRIM_RECTLIST */
+};
+
+static void
+meta_clear_begin(struct anv_meta_saved_state *saved_state,
+                 struct anv_cmd_buffer *cmd_buffer)
+{
+   anv_meta_save(saved_state, cmd_buffer,
+                 (1 << VK_DYNAMIC_STATE_VIEWPORT) |
+                 (1 << VK_DYNAMIC_STATE_SCISSOR) |
+                 (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE));
+
+   cmd_buffer->state.dynamic.viewport.count = 0;
+   cmd_buffer->state.dynamic.scissor.count = 0;
+}
+
+static void
+meta_clear_end(struct anv_meta_saved_state *saved_state,
+               struct anv_cmd_buffer *cmd_buffer)
+{
+   anv_meta_restore(saved_state, cmd_buffer);
+}
+
+static void
+build_color_shaders(struct nir_shader **out_vs,
+                    struct nir_shader **out_fs)
+{
+   nir_builder vs_b;
+   nir_builder fs_b;
+
+   nir_builder_init_simple_shader(&vs_b, MESA_SHADER_VERTEX);
+   nir_builder_init_simple_shader(&fs_b, MESA_SHADER_FRAGMENT);
+
+   const struct glsl_type *position_type = glsl_vec4_type();
+   const struct glsl_type *color_type = glsl_vec4_type();
+
+   nir_variable *vs_in_pos =
+      nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
+                          "a_position");
+   vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
+
+   nir_variable *vs_out_pos =
+      nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
+                          "gl_Position");
+   vs_out_pos->data.location = VARYING_SLOT_POS;
+
+   nir_variable *vs_in_color =
+      nir_variable_create(vs_b.shader, nir_var_shader_in, color_type,
+                          "a_color");
+   vs_in_color->data.location = VERT_ATTRIB_GENERIC1;
+
+   nir_variable *vs_out_color =
+      nir_variable_create(vs_b.shader, nir_var_shader_out, color_type,
+                          "v_color");
+   vs_out_color->data.location = VARYING_SLOT_VAR0;
+   vs_out_color->data.interpolation = INTERP_QUALIFIER_FLAT;
+
+   nir_variable *fs_in_color =
+      nir_variable_create(fs_b.shader, nir_var_shader_in, color_type,
+                          "v_color");
+   fs_in_color->data.location = vs_out_color->data.location;
+   fs_in_color->data.interpolation = vs_out_color->data.interpolation;
+
+   nir_variable *fs_out_color =
+      nir_variable_create(fs_b.shader, nir_var_shader_out, color_type,
+                          "f_color");
+   fs_out_color->data.location = FRAG_RESULT_DATA0;
+
+   nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
+   nir_copy_var(&vs_b, vs_out_color, vs_in_color);
+   nir_copy_var(&fs_b, fs_out_color, fs_in_color);
+
+   *out_vs = vs_b.shader;
+   *out_fs = fs_b.shader;
+}
+
+static struct anv_pipeline *
+create_pipeline(struct anv_device *device,
+                struct nir_shader *vs_nir,
+                struct nir_shader *fs_nir,
+                const VkPipelineVertexInputStateCreateInfo *vi_state,
+                const VkPipelineDepthStencilStateCreateInfo *ds_state,
+                const VkPipelineColorBlendStateCreateInfo *cb_state)
+{
+   VkDevice device_h = anv_device_to_handle(device);
+
+   struct anv_shader_module vs_m = { .nir = vs_nir };
+   struct anv_shader_module fs_m = { .nir = fs_nir };
+
+   VkShader vs_h;
+   ANV_CALL(CreateShader)(device_h,
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = anv_shader_module_to_handle(&vs_m),
+         .pName = "main",
+      },
+      &vs_h);
+
+   VkShader fs_h;
+   ANV_CALL(CreateShader)(device_h,
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = anv_shader_module_to_handle(&fs_m),
+         .pName = "main",
+      },
+      &fs_h);
+
+   VkPipeline pipeline_h;
+   anv_graphics_pipeline_create(device_h,
+      &(VkGraphicsPipelineCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+         .stageCount = 2,
+         .pStages = (VkPipelineShaderStageCreateInfo[]) {
+            {
+               .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+               .stage = VK_SHADER_STAGE_VERTEX,
+               .shader = vs_h,
+            },
+            {
+               .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+               .stage = VK_SHADER_STAGE_FRAGMENT,
+               .shader = fs_h,
+            },
+         },
+         .pVertexInputState = vi_state,
+         .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+            .primitiveRestartEnable = false,
+         },
+         .pViewportState = &(VkPipelineViewportStateCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
+            .viewportCount = 1,
+            .pViewports = NULL, /* dynamic */
+            .scissorCount = 1,
+            .pScissors = NULL, /* dynamic */
+         },
+         .pRasterState = &(VkPipelineRasterStateCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
+            .depthClipEnable = false,
+            .rasterizerDiscardEnable = false,
+            .fillMode = VK_FILL_MODE_SOLID,
+            .cullMode = VK_CULL_MODE_NONE,
+            .frontFace = VK_FRONT_FACE_CCW,
+            .depthBiasEnable = false,
+            .depthClipEnable = false,
+         },
+         .pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
+            .rasterSamples = 1, /* FINISHME: Multisampling */
+            .sampleShadingEnable = false,
+            .pSampleMask = (VkSampleMask[]) { UINT32_MAX },
+         },
+         .pDepthStencilState = ds_state,
+         .pColorBlendState = cb_state,
+         .pDynamicState = &(VkPipelineDynamicStateCreateInfo) {
+            /* The meta clear pipeline declares all state as dynamic.
+             * As a consequence, vkCmdBindPipeline writes no dynamic state
+             * to the cmd buffer. Therefore, at the end of the meta clear,
+             * we need only restore dynamic state was vkCmdSet.
+             */
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
+            .dynamicStateCount = 9,
+            .pDynamicStates = (VkDynamicState[]) {
+               VK_DYNAMIC_STATE_VIEWPORT,
+               VK_DYNAMIC_STATE_SCISSOR,
+               VK_DYNAMIC_STATE_LINE_WIDTH,
+               VK_DYNAMIC_STATE_DEPTH_BIAS,
+               VK_DYNAMIC_STATE_BLEND_CONSTANTS,
+               VK_DYNAMIC_STATE_DEPTH_BOUNDS,
+               VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
+               VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
+               VK_DYNAMIC_STATE_STENCIL_REFERENCE,
+            },
+         },
+         .flags = 0,
+         .renderPass = anv_render_pass_to_handle(&anv_meta_dummy_renderpass),
+         .subpass = 0,
+      },
+      &(struct anv_graphics_pipeline_create_info) {
+         .use_repclear = true,
+         .disable_viewport = true,
+         .disable_vs = true,
+         .use_rectlist = true
+      },
+      &pipeline_h);
+
+   ANV_CALL(DestroyShader)(device_h, vs_h);
+   ANV_CALL(DestroyShader)(device_h, fs_h);
+
+   ralloc_free(vs_nir);
+   ralloc_free(fs_nir);
+
+   return anv_pipeline_from_handle(pipeline_h);
+}
+
+static void
+init_color_pipeline(struct anv_device *device)
+{
+   struct nir_shader *vs_nir;
+   struct nir_shader *fs_nir;
+   build_color_shaders(&vs_nir, &fs_nir);
+
+   const VkPipelineVertexInputStateCreateInfo vi_state = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+      .bindingCount = 1,
+      .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
+         {
+            .binding = 0,
+            .strideInBytes = sizeof(struct color_clear_vattrs),
+            .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
+         },
+      },
+      .attributeCount = 3,
+      .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
+         {
+            /* VUE Header */
+            .location = 0,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32B32A32_UINT,
+            .offsetInBytes = offsetof(struct color_clear_vattrs, vue_header),
+         },
+         {
+            /* Position */
+            .location = 1,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32_SFLOAT,
+            .offsetInBytes = offsetof(struct color_clear_vattrs, position),
+         },
+         {
+            /* Color */
+            .location = 2,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+            .offsetInBytes = offsetof(struct color_clear_vattrs, color),
+         },
+      },
+   };
+
+   const VkPipelineDepthStencilStateCreateInfo ds_state = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+      .depthTestEnable = false,
+      .depthWriteEnable = false,
+      .depthBoundsTestEnable = false,
+      .stencilTestEnable = false,
+   };
+
+   const VkPipelineColorBlendStateCreateInfo cb_state = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+      .alphaToCoverageEnable = false,
+      .alphaToOneEnable = false,
+      .logicOpEnable = false,
+      .attachmentCount = 1,
+      .pAttachments = (VkPipelineColorBlendAttachmentState []) {
+         {
+            .blendEnable = false,
+            .channelWriteMask = VK_CHANNEL_A_BIT |
+                                VK_CHANNEL_R_BIT |
+                                VK_CHANNEL_G_BIT |
+                                VK_CHANNEL_B_BIT,
+         },
+      },
+   };
+
+   device->meta_state.clear.color_pipeline =
+      create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
+                      &cb_state);
+}
+
+static void
+emit_load_color_clear(struct anv_cmd_buffer *cmd_buffer,
+                      uint32_t attachment,
+                      VkClearColorValue clear_value)
+{
+   struct anv_device *device = cmd_buffer->device;
+   VkCmdBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
+   const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   VkPipeline pipeline_h =
+      anv_pipeline_to_handle(device->meta_state.clear.color_pipeline);
+
+   const struct color_clear_vattrs vertex_data[3] = {
+      {
+         .vue_header = { 0 },
+         .position = { 0.0, 0.0 },
+         .color = clear_value,
+      },
+      {
+         .vue_header = { 0 },
+         .position = { fb->width, 0.0 },
+         .color = clear_value,
+      },
+      {
+         .vue_header = { 0 },
+         .position = { fb->width, fb->height },
+         .color = clear_value,
+      },
+   };
+
+   struct anv_state state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, sizeof(vertex_data), 16);
+   memcpy(state.map, vertex_data, sizeof(vertex_data));
+
+   struct anv_buffer vertex_buffer = {
+      .device = device,
+      .size = sizeof(vertex_data),
+      .bo = &device->dynamic_state_block_pool.bo,
+      .offset = state.offset,
+   };
+
+   anv_cmd_buffer_begin_subpass(cmd_buffer,
+      &(struct anv_subpass) {
+         .color_count = 1,
+         .color_attachments = (uint32_t[]) { attachment },
+         .depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
+      });
+
+   ANV_CALL(CmdSetViewport)(cmd_buffer_h, 1,
+      (VkViewport[]) {
+         {
+            .originX = 0,
+            .originY = 0,
+            .width = fb->width,
+            .height = fb->height,
+            .minDepth = 0.0,
+            .maxDepth = 1.0,
+         },
+      });
+
+   ANV_CALL(CmdSetScissor)(cmd_buffer_h, 1,
+      (VkRect2D[]) {
+         {
+            .offset = { 0, 0 },
+            .extent = { fb->width, fb->height },
+         }
+      });
+
+   ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
+      (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
+      (VkDeviceSize[]) { 0 });
+
+   if (cmd_buffer->state.pipeline != device->meta_state.clear.color_pipeline) {
+      ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                pipeline_h);
+   }
+
+   ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
+}
+
+
+static void
+build_depthstencil_shaders(struct nir_shader **out_vs,
+                           struct nir_shader **out_fs)
+{
+   nir_builder vs_b;
+   nir_builder fs_b;
+
+   nir_builder_init_simple_shader(&vs_b, MESA_SHADER_VERTEX);
+   nir_builder_init_simple_shader(&fs_b, MESA_SHADER_FRAGMENT);
+
+   const struct glsl_type *position_type = glsl_vec4_type();
+
+   nir_variable *vs_in_pos =
+      nir_variable_create(vs_b.shader, nir_var_shader_in, position_type,
+                          "a_position");
+   vs_in_pos->data.location = VERT_ATTRIB_GENERIC0;
+
+   nir_variable *vs_out_pos =
+      nir_variable_create(vs_b.shader, nir_var_shader_out, position_type,
+                          "gl_Position");
+   vs_out_pos->data.location = VARYING_SLOT_POS;
+
+   nir_copy_var(&vs_b, vs_out_pos, vs_in_pos);
+
+   *out_vs = vs_b.shader;
+   *out_fs = fs_b.shader;
+}
+
+static struct anv_pipeline *
+create_depthstencil_pipeline(struct anv_device *device,
+                             VkImageAspectFlags aspects)
+{
+   struct nir_shader *vs_nir;
+   struct nir_shader *fs_nir;
+
+   build_depthstencil_shaders(&vs_nir, &fs_nir);
+
+   const VkPipelineVertexInputStateCreateInfo vi_state = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+      .bindingCount = 1,
+      .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
+         {
+            .binding = 0,
+            .strideInBytes = sizeof(struct depthstencil_clear_vattrs),
+            .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
+         },
+      },
+      .attributeCount = 2,
+      .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
+         {
+            /* VUE Header */
+            .location = 0,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32B32A32_UINT,
+            .offsetInBytes = offsetof(struct depthstencil_clear_vattrs, vue_header),
+         },
+         {
+            /* Position */
+            .location = 1,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32_SFLOAT,
+            .offsetInBytes = offsetof(struct depthstencil_clear_vattrs, position),
+         },
+      },
+   };
+
+   const VkPipelineDepthStencilStateCreateInfo ds_state = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
+      .depthTestEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
+      .depthCompareOp = VK_COMPARE_OP_ALWAYS,
+      .depthWriteEnable = (aspects & VK_IMAGE_ASPECT_DEPTH_BIT),
+      .depthBoundsTestEnable = false,
+      .stencilTestEnable = (aspects & VK_IMAGE_ASPECT_STENCIL_BIT),
+      .front = {
+         .stencilPassOp = VK_STENCIL_OP_REPLACE,
+         .stencilCompareOp = VK_COMPARE_OP_ALWAYS,
+         .stencilWriteMask = UINT32_MAX,
+         .stencilReference = 0, /* dynamic */
+      },
+      .back = { 0 /* dont care */ },
+   };
+
+   const VkPipelineColorBlendStateCreateInfo cb_state = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
+      .alphaToCoverageEnable = false,
+      .alphaToOneEnable = false,
+      .logicOpEnable = false,
+      .attachmentCount = 0,
+      .pAttachments = NULL,
+   };
+
+   return create_pipeline(device, vs_nir, fs_nir, &vi_state, &ds_state,
+                          &cb_state);
+}
+
+static void
+emit_load_depthstencil_clear(struct anv_cmd_buffer *cmd_buffer,
+                             uint32_t attachment,
+                             VkImageAspectFlags aspects,
+                             VkClearDepthStencilValue clear_value)
+{
+   struct anv_device *device = cmd_buffer->device;
+   VkCmdBuffer cmd_buffer_h = anv_cmd_buffer_to_handle(cmd_buffer);
+   const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+
+   const struct depthstencil_clear_vattrs vertex_data[3] = {
+      {
+         .vue_header = { 0 },
+         .position = { 0.0, 0.0 },
+      },
+      {
+         .vue_header = { 0 },
+         .position = { fb->width, 0.0 },
+      },
+      {
+         .vue_header = { 0 },
+         .position = { fb->width, fb->height },
+      },
+   };
+
+   struct anv_state state =
+      anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, sizeof(vertex_data), 16);
+   memcpy(state.map, vertex_data, sizeof(vertex_data));
+
+   struct anv_buffer vertex_buffer = {
+      .device = device,
+      .size = sizeof(vertex_data),
+      .bo = &device->dynamic_state_block_pool.bo,
+      .offset = state.offset,
+   };
+
+   anv_cmd_buffer_begin_subpass(cmd_buffer,
+      &(struct anv_subpass) {
+         .color_count = 0,
+         .depth_stencil_attachment = attachment,
+      });
+
+   ANV_CALL(CmdSetViewport)(cmd_buffer_h, 1,
+      (VkViewport[]) {
+         {
+            .originX = 0,
+            .originY = 0,
+            .width = fb->width,
+            .height = fb->height,
+
+            /* Ignored when clearing only stencil. */
+            .minDepth = clear_value.depth,
+            .maxDepth = clear_value.depth,
+         },
+      });
+
+   ANV_CALL(CmdSetScissor)(cmd_buffer_h, 1,
+      (VkRect2D[]) {
+         {
+            .offset = { 0, 0 },
+            .extent = { fb->width, fb->height },
+         }
+      });
+
+   if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
+      ANV_CALL(CmdSetStencilReference)(cmd_buffer_h, VK_STENCIL_FACE_FRONT_BIT,
+                                       clear_value.stencil);
+   }
+
+   ANV_CALL(CmdBindVertexBuffers)(cmd_buffer_h, 0, 1,
+      (VkBuffer[]) { anv_buffer_to_handle(&vertex_buffer) },
+      (VkDeviceSize[]) { 0 });
+
+   struct anv_pipeline *pipeline;
+   switch (aspects) {
+   case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
+      pipeline = device->meta_state.clear.depthstencil_pipeline;
+      break;
+   case VK_IMAGE_ASPECT_DEPTH_BIT:
+      pipeline = device->meta_state.clear.depth_only_pipeline;
+      break;
+   case VK_IMAGE_ASPECT_STENCIL_BIT:
+      pipeline = device->meta_state.clear.stencil_only_pipeline;
+      break;
+   default:
+      unreachable("expected depth or stencil aspect");
+   }
+
+   if (cmd_buffer->state.pipeline != pipeline) {
+      ANV_CALL(CmdBindPipeline)(cmd_buffer_h, VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                anv_pipeline_to_handle(pipeline));
+   }
+
+   ANV_CALL(CmdDraw)(cmd_buffer_h, 3, 1, 0, 0);
+}
+
+static void
+init_depthstencil_pipelines(struct anv_device *device)
+{
+   device->meta_state.clear.depth_only_pipeline =
+      create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT);
+
+   device->meta_state.clear.stencil_only_pipeline =
+      create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_STENCIL_BIT);
+
+   device->meta_state.clear.depthstencil_pipeline =
+      create_depthstencil_pipeline(device, VK_IMAGE_ASPECT_DEPTH_BIT |
+                                           VK_IMAGE_ASPECT_STENCIL_BIT);
+}
+
+void
+anv_device_init_meta_clear_state(struct anv_device *device)
+{
+   init_color_pipeline(device);
+   init_depthstencil_pipelines(device);
+}
+
+void
+anv_device_finish_meta_clear_state(struct anv_device *device)
+{
+   VkDevice device_h = anv_device_to_handle(device);
+
+   ANV_CALL(DestroyPipeline)(device_h,
+      anv_pipeline_to_handle(device->meta_state.clear.color_pipeline));
+   ANV_CALL(DestroyPipeline)(device_h,
+      anv_pipeline_to_handle(device->meta_state.clear.depth_only_pipeline));
+   ANV_CALL(DestroyPipeline)(device_h,
+      anv_pipeline_to_handle(device->meta_state.clear.stencil_only_pipeline));
+   ANV_CALL(DestroyPipeline)(device_h,
+      anv_pipeline_to_handle(device->meta_state.clear.depthstencil_pipeline));
+}
+
+void
+anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
+                                 struct anv_render_pass *pass,
+                                 const VkClearValue *clear_values)
+{
+   struct anv_meta_saved_state saved_state;
+
+   meta_clear_begin(&saved_state, cmd_buffer);
+
+   for (uint32_t a = 0; a < pass->attachment_count; ++a) {
+      struct anv_render_pass_attachment *att = &pass->attachments[a];
+
+      if (anv_format_is_color(att->format)) {
+         if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+            emit_load_color_clear(cmd_buffer, a, clear_values[a].color);
+         }
+      } else {
+         VkImageAspectFlags aspects = 0;
+
+         if (att->format->depth_format &&
+             att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+            aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
+         }
+
+         if (att->format->has_stencil &&
+             att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+            aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
+         }
+
+         emit_load_depthstencil_clear(cmd_buffer, a, aspects,
+                                      clear_values[a].depthStencil);
+      }
+   }
+
+   meta_clear_end(&saved_state, cmd_buffer);
+}
+
+void anv_CmdClearColorImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     _image,
+    VkImageLayout                               imageLayout,
+    const VkClearColorValue*                    pColor,
+    uint32_t                                    rangeCount,
+    const VkImageSubresourceRange*              pRanges)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_image, image, _image);
+   struct anv_meta_saved_state saved_state;
+
+   meta_clear_begin(&saved_state, cmd_buffer);
+
+   for (uint32_t r = 0; r < rangeCount; r++) {
+      for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) {
+         for (uint32_t s = 0; s < pRanges[r].arraySize; s++) {
+            struct anv_image_view iview;
+            anv_image_view_init(&iview, cmd_buffer->device,
+               &(VkImageViewCreateInfo) {
+                  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+                  .image = _image,
+                  .viewType = VK_IMAGE_VIEW_TYPE_2D,
+                  .format = image->format->vk_format,
+                  .channels = {
+                     VK_CHANNEL_SWIZZLE_R,
+                     VK_CHANNEL_SWIZZLE_G,
+                     VK_CHANNEL_SWIZZLE_B,
+                     VK_CHANNEL_SWIZZLE_A
+                  },
+                  .subresourceRange = {
+                     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                     .baseMipLevel = pRanges[r].baseMipLevel + l,
+                     .mipLevels = 1,
+                     .baseArrayLayer = pRanges[r].baseArrayLayer + s,
+                     .arraySize = 1
+                  },
+               },
+               cmd_buffer);
+
+            VkFramebuffer fb;
+            anv_CreateFramebuffer(anv_device_to_handle(cmd_buffer->device),
+               &(VkFramebufferCreateInfo) {
+                  .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+                  .attachmentCount = 1,
+                  .pAttachments = (VkImageView[]) {
+                     anv_image_view_to_handle(&iview),
+                  },
+                  .width = iview.extent.width,
+                  .height = iview.extent.height,
+                  .layers = 1
+               }, &fb);
+
+            VkRenderPass pass;
+            anv_CreateRenderPass(anv_device_to_handle(cmd_buffer->device),
+               &(VkRenderPassCreateInfo) {
+                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                  .attachmentCount = 1,
+                  .pAttachments = &(VkAttachmentDescription) {
+                     .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
+                     .format = iview.format->vk_format,
+                     .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD,
+                     .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+                     .initialLayout = VK_IMAGE_LAYOUT_GENERAL,
+                     .finalLayout = VK_IMAGE_LAYOUT_GENERAL,
+                  },
+                  .subpassCount = 1,
+                  .pSubpasses = &(VkSubpassDescription) {
+                     .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
+                     .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+                     .inputCount = 0,
+                     .colorCount = 1,
+                     .pColorAttachments = &(VkAttachmentReference) {
+                        .attachment = 0,
+                        .layout = VK_IMAGE_LAYOUT_GENERAL,
+                     },
+                     .pResolveAttachments = NULL,
+                     .depthStencilAttachment = (VkAttachmentReference) {
+                        .attachment = VK_ATTACHMENT_UNUSED,
+                        .layout = VK_IMAGE_LAYOUT_GENERAL,
+                     },
+                     .preserveCount = 1,
+                     .pPreserveAttachments = &(VkAttachmentReference) {
+                        .attachment = 0,
+                        .layout = VK_IMAGE_LAYOUT_GENERAL,
+                     },
+                  },
+                  .dependencyCount = 0,
+               }, &pass);
+
+            ANV_CALL(CmdBeginRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer),
+               &(VkRenderPassBeginInfo) {
+                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+                  .renderArea = {
+                     .offset = { 0, 0, },
+                     .extent = {
+                        .width = iview.extent.width,
+                        .height = iview.extent.height,
+                     },
+                  },
+                  .renderPass = pass,
+                  .framebuffer = fb,
+                  .clearValueCount = 1,
+                  .pClearValues = (VkClearValue[]) {
+                     { .color = *pColor },
+                  },
+               }, VK_RENDER_PASS_CONTENTS_INLINE);
+
+            ANV_CALL(CmdEndRenderPass)(anv_cmd_buffer_to_handle(cmd_buffer));
+         }
+      }
+   }
+
+   meta_clear_end(&saved_state, cmd_buffer);
+}
+
+void anv_CmdClearDepthStencilImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     image,
+    VkImageLayout                               imageLayout,
+    const VkClearDepthStencilValue*             pDepthStencil,
+    uint32_t                                    rangeCount,
+    const VkImageSubresourceRange*              pRanges)
+{
+   stub();
+}
+
+void anv_CmdClearColorAttachment(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    colorAttachment,
+    VkImageLayout                               imageLayout,
+    const VkClearColorValue*                    pColor,
+    uint32_t                                    rectCount,
+    const VkRect3D*                             pRects)
+{
+   stub();
+}
+
+void anv_CmdClearDepthStencilAttachment(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImageAspectFlags                          aspectMask,
+    VkImageLayout                               imageLayout,
+    const VkClearDepthStencilValue*             pDepthStencil,
+    uint32_t                                    rectCount,
+    const VkRect3D*                             pRects)
+{
+   stub();
+}
diff --git a/src/vulkan/anv_meta_clear.h b/src/vulkan/anv_meta_clear.h
new file mode 100644 (file)
index 0000000..e53bd97
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct anv_device;
+
+void anv_device_init_meta_clear_state(struct anv_device *device);
+void anv_device_finish_meta_clear_state(struct anv_device *device);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/vulkan/anv_nir.h b/src/vulkan/anv_nir.h
new file mode 100644 (file)
index 0000000..b164ae5
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "glsl/nir/nir.h"
+#include "anv_private.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline VkShaderStage
+anv_vk_shader_stage_for_mesa_stage(gl_shader_stage stage)
+{
+   /* The two enums happen to line up. */
+   return (VkShaderStage)(int)stage;
+}
+
+void anv_nir_lower_push_constants(nir_shader *shader, bool is_scalar);
+
+void anv_nir_apply_dynamic_offsets(struct anv_pipeline *pipeline,
+                                   nir_shader *shader,
+                                   struct brw_stage_prog_data *prog_data);
+bool anv_nir_apply_pipeline_layout(nir_shader *shader,
+                                   const struct anv_pipeline_layout *layout);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/vulkan/anv_nir_apply_dynamic_offsets.c b/src/vulkan/anv_nir_apply_dynamic_offsets.c
new file mode 100644 (file)
index 0000000..dd4f5df
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_nir.h"
+#include "glsl/nir/nir_builder.h"
+
+struct apply_dynamic_offsets_state {
+   nir_shader *shader;
+   nir_builder builder;
+
+   VkShaderStage stage;
+   struct anv_pipeline_layout *layout;
+
+   uint32_t indices_start;
+};
+
+static bool
+apply_dynamic_offsets_block(nir_block *block, void *void_state)
+{
+   struct apply_dynamic_offsets_state *state = void_state;
+   struct anv_descriptor_set_layout *set_layout;
+
+   nir_builder *b = &state->builder;
+
+   nir_foreach_instr_safe(block, instr) {
+      if (instr->type != nir_instr_type_intrinsic)
+         continue;
+
+      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+
+      unsigned block_idx_src;
+      switch (intrin->intrinsic) {
+      case nir_intrinsic_load_ubo:
+      case nir_intrinsic_load_ubo_indirect:
+      case nir_intrinsic_load_ssbo:
+      case nir_intrinsic_load_ssbo_indirect:
+         block_idx_src = 0;
+         break;
+      case nir_intrinsic_store_ssbo:
+      case nir_intrinsic_store_ssbo_indirect:
+         block_idx_src = 1;
+         break;
+      default:
+         continue; /* the loop */
+      }
+
+      nir_instr *res_instr = intrin->src[block_idx_src].ssa->parent_instr;
+      assert(res_instr->type == nir_instr_type_intrinsic);
+      nir_intrinsic_instr *res_intrin = nir_instr_as_intrinsic(res_instr);
+      assert(res_intrin->intrinsic == nir_intrinsic_vulkan_resource_index);
+
+      unsigned set = res_intrin->const_index[0];
+      unsigned binding = res_intrin->const_index[1];
+
+      set_layout = state->layout->set[set].layout;
+      if (set_layout->binding[binding].dynamic_offset_index < 0)
+         continue;
+
+      b->cursor = nir_before_instr(&intrin->instr);
+
+      int indirect_src;
+      switch (intrin->intrinsic) {
+      case nir_intrinsic_load_ubo_indirect:
+      case nir_intrinsic_load_ssbo_indirect:
+         indirect_src = 1;
+         break;
+      case nir_intrinsic_store_ssbo_indirect:
+         indirect_src = 2;
+         break;
+      default:
+         indirect_src = -1;
+         break;
+      }
+
+      /* First, we need to generate the uniform load for the buffer offset */
+      uint32_t index = state->layout->set[set].dynamic_offset_start +
+                       set_layout->binding[binding].dynamic_offset_index;
+
+      nir_const_value *const_arr_idx =
+         nir_src_as_const_value(res_intrin->src[0]);
+
+      nir_intrinsic_op offset_load_op;
+      if (const_arr_idx)
+         offset_load_op = nir_intrinsic_load_uniform;
+      else
+         offset_load_op = nir_intrinsic_load_uniform_indirect;
+
+      nir_intrinsic_instr *offset_load =
+         nir_intrinsic_instr_create(state->shader, offset_load_op);
+      offset_load->num_components = 2;
+      offset_load->const_index[0] = state->indices_start + index * 2;
+
+      if (const_arr_idx) {
+         offset_load->const_index[1] = const_arr_idx->u[0] * 2;
+      } else {
+         offset_load->const_index[1] = 0;
+         offset_load->src[0] = nir_src_for_ssa(
+            nir_imul(b, nir_ssa_for_src(b, res_intrin->src[0], 1),
+                     nir_imm_int(b, 2)));
+      }
+
+      nir_ssa_dest_init(&offset_load->instr, &offset_load->dest, 2, NULL);
+      nir_builder_instr_insert(b, &offset_load->instr);
+
+      /* We calculate the full offset and don't bother with the base
+       * offset.  We need the full offset for the predicate anyway.
+       */
+      nir_ssa_def *rel_offset = nir_imm_int(b, intrin->const_index[0]);
+      if (indirect_src >= 0) {
+         assert(intrin->src[indirect_src].is_ssa);
+         rel_offset = nir_iadd(b, intrin->src[indirect_src].ssa, rel_offset);
+      }
+      nir_ssa_def *global_offset = nir_iadd(b, rel_offset,
+                                            &offset_load->dest.ssa);
+
+      /* Now we replace the load/store intrinsic */
+
+      nir_intrinsic_op indirect_op;
+      switch (intrin->intrinsic) {
+      case nir_intrinsic_load_ubo:
+         indirect_op = nir_intrinsic_load_ubo_indirect;
+         break;
+      case nir_intrinsic_load_ssbo:
+         indirect_op = nir_intrinsic_load_ssbo_indirect;
+         break;
+      case nir_intrinsic_store_ssbo:
+         indirect_op = nir_intrinsic_store_ssbo_indirect;
+         break;
+      default:
+         unreachable("Invalid direct load/store intrinsic");
+      }
+
+      nir_intrinsic_instr *copy =
+         nir_intrinsic_instr_create(state->shader, indirect_op);
+      copy->num_components = intrin->num_components;
+
+      /* The indirect is always the last source */
+      indirect_src = nir_intrinsic_infos[indirect_op].num_srcs - 1;
+
+      for (unsigned i = 0; i < (unsigned)indirect_src; i++)
+         nir_src_copy(&copy->src[i], &intrin->src[i], &copy->instr);
+
+      copy->src[indirect_src] = nir_src_for_ssa(global_offset);
+      nir_ssa_dest_init(&copy->instr, &copy->dest,
+                        intrin->dest.ssa.num_components,
+                        intrin->dest.ssa.name);
+
+      /* In order to avoid out-of-bounds access, we predicate */
+      nir_ssa_def *pred = nir_fge(b, nir_channel(b, &offset_load->dest.ssa, 1),
+                                  rel_offset);
+      nir_if *if_stmt = nir_if_create(b->shader);
+      if_stmt->condition = nir_src_for_ssa(pred);
+      nir_cf_node_insert(b->cursor, &if_stmt->cf_node);
+
+      nir_instr_insert_after_cf_list(&if_stmt->then_list, &copy->instr);
+
+      if (indirect_op != nir_intrinsic_store_ssbo) {
+         /* It's a load, we need a phi node */
+         nir_phi_instr *phi = nir_phi_instr_create(b->shader);
+         nir_ssa_dest_init(&phi->instr, &phi->dest,
+                           intrin->num_components, NULL);
+
+         nir_phi_src *src1 = ralloc(phi, nir_phi_src);
+         struct exec_node *tnode = exec_list_get_tail(&if_stmt->then_list);
+         src1->pred = exec_node_data(nir_block, tnode, cf_node.node);
+         src1->src = nir_src_for_ssa(&copy->dest.ssa);
+         exec_list_push_tail(&phi->srcs, &src1->node);
+
+         b->cursor = nir_after_cf_list(&if_stmt->else_list);
+         nir_ssa_def *zero = nir_build_imm(b, intrin->num_components,
+            (nir_const_value) { .u = { 0, 0, 0, 0 } });
+
+         nir_phi_src *src2 = ralloc(phi, nir_phi_src);
+         struct exec_node *enode = exec_list_get_tail(&if_stmt->else_list);
+         src2->pred = exec_node_data(nir_block, enode, cf_node.node);
+         src2->src = nir_src_for_ssa(zero);
+         exec_list_push_tail(&phi->srcs, &src2->node);
+
+         nir_instr_insert_after_cf(&if_stmt->cf_node, &phi->instr);
+
+         assert(intrin->dest.is_ssa);
+         nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
+                                  nir_src_for_ssa(&phi->dest.ssa));
+      }
+
+      nir_instr_remove(&intrin->instr);
+   }
+
+   return true;
+}
+
+void
+anv_nir_apply_dynamic_offsets(struct anv_pipeline *pipeline,
+                              nir_shader *shader,
+                              struct brw_stage_prog_data *prog_data)
+{
+   struct apply_dynamic_offsets_state state = {
+      .shader = shader,
+      .stage = anv_vk_shader_stage_for_mesa_stage(shader->stage),
+      .layout = pipeline->layout,
+      .indices_start = shader->num_uniforms,
+   };
+
+   if (!state.layout || !state.layout->stage[state.stage].has_dynamic_offsets)
+      return;
+
+   nir_foreach_overload(shader, overload) {
+      if (overload->impl) {
+         nir_builder_init(&state.builder, overload->impl);
+         nir_foreach_block(overload->impl, apply_dynamic_offsets_block, &state);
+         nir_metadata_preserve(overload->impl, nir_metadata_block_index |
+                                               nir_metadata_dominance);
+      }
+   }
+
+   struct anv_push_constants *null_data = NULL;
+   for (unsigned i = 0; i < MAX_DYNAMIC_BUFFERS; i++) {
+      prog_data->param[i * 2 + shader->num_uniforms] =
+         (const gl_constant_value *)&null_data->dynamic[i].offset;
+      prog_data->param[i * 2 + 1 + shader->num_uniforms] =
+         (const gl_constant_value *)&null_data->dynamic[i].range;
+   }
+
+   shader->num_uniforms += MAX_DYNAMIC_BUFFERS * 2;
+}
diff --git a/src/vulkan/anv_nir_apply_pipeline_layout.c b/src/vulkan/anv_nir_apply_pipeline_layout.c
new file mode 100644 (file)
index 0000000..8270dc1
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_nir.h"
+#include "glsl/nir/nir_builder.h"
+
+struct apply_pipeline_layout_state {
+   nir_shader *shader;
+   nir_builder builder;
+
+   VkShaderStage stage;
+   const struct anv_pipeline_layout *layout;
+
+   bool progress;
+};
+
+static uint32_t
+get_surface_index(unsigned set, unsigned binding,
+                  struct apply_pipeline_layout_state *state)
+{
+   assert(set < state->layout->num_sets);
+   struct anv_descriptor_set_layout *set_layout =
+      state->layout->set[set].layout;
+
+   assert(binding < set_layout->binding_count);
+
+   assert(set_layout->binding[binding].stage[state->stage].surface_index >= 0);
+
+   uint32_t surface_index =
+      state->layout->set[set].stage[state->stage].surface_start +
+      set_layout->binding[binding].stage[state->stage].surface_index;
+
+   assert(surface_index < state->layout->stage[state->stage].surface_count);
+
+   return surface_index;
+}
+
+static void
+lower_res_index_intrinsic(nir_intrinsic_instr *intrin,
+                          struct apply_pipeline_layout_state *state)
+{
+   nir_builder *b = &state->builder;
+
+   b->cursor = nir_before_instr(&intrin->instr);
+
+   uint32_t set = intrin->const_index[0];
+   uint32_t binding = intrin->const_index[1];
+
+   uint32_t surface_index = get_surface_index(set, binding, state);
+
+   nir_const_value *const_block_idx =
+      nir_src_as_const_value(intrin->src[0]);
+
+   nir_ssa_def *block_index;
+   if (const_block_idx) {
+      block_index = nir_imm_int(b, surface_index + const_block_idx->u[0]);
+   } else {
+      block_index = nir_iadd(b, nir_imm_int(b, surface_index),
+                             nir_ssa_for_src(b, intrin->src[0], 1));
+   }
+
+   assert(intrin->dest.is_ssa);
+   nir_ssa_def_rewrite_uses(&intrin->dest.ssa, nir_src_for_ssa(block_index));
+   nir_instr_remove(&intrin->instr);
+}
+
+static void
+lower_tex(nir_tex_instr *tex, struct apply_pipeline_layout_state *state)
+{
+   /* No one should have come by and lowered it already */
+   assert(tex->sampler);
+
+   unsigned set = tex->sampler->var->data.descriptor_set;
+   unsigned binding = tex->sampler->var->data.binding;
+
+   tex->sampler_index = get_surface_index(set, binding, state);
+
+   if (tex->sampler->deref.child) {
+      assert(tex->sampler->deref.child->deref_type == nir_deref_type_array);
+      nir_deref_array *deref_array =
+         nir_deref_as_array(tex->sampler->deref.child);
+
+      tex->sampler_index += deref_array->base_offset;
+
+      if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
+         nir_tex_src *new_srcs = rzalloc_array(tex, nir_tex_src,
+                                               tex->num_srcs + 1);
+
+         for (unsigned i = 0; i < tex->num_srcs; i++) {
+            new_srcs[i].src_type = tex->src[i].src_type;
+            nir_instr_move_src(&tex->instr, &new_srcs[i].src, &tex->src[i].src);
+         }
+
+         ralloc_free(tex->src);
+         tex->src = new_srcs;
+
+         /* Now we can go ahead and move the source over to being a
+          * first-class texture source.
+          */
+         tex->src[tex->num_srcs].src_type = nir_tex_src_sampler_offset;
+         tex->num_srcs++;
+         nir_instr_move_src(&tex->instr, &tex->src[tex->num_srcs - 1].src,
+                            &deref_array->indirect);
+      }
+   }
+
+   tex->sampler = NULL;
+}
+
+static bool
+apply_pipeline_layout_block(nir_block *block, void *void_state)
+{
+   struct apply_pipeline_layout_state *state = void_state;
+
+   nir_foreach_instr_safe(block, instr) {
+      switch (instr->type) {
+      case nir_instr_type_intrinsic: {
+         nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+         if (intrin->intrinsic == nir_intrinsic_vulkan_resource_index) {
+            lower_res_index_intrinsic(intrin, state);
+            state->progress = true;
+         }
+         break;
+      }
+      case nir_instr_type_tex:
+         lower_tex(nir_instr_as_tex(instr), state);
+         /* All texture instructions need lowering */
+         state->progress = true;
+         break;
+      default:
+         continue;
+      }
+   }
+
+   return true;
+}
+
+bool
+anv_nir_apply_pipeline_layout(nir_shader *shader,
+                              const struct anv_pipeline_layout *layout)
+{
+   struct apply_pipeline_layout_state state = {
+      .shader = shader,
+      .stage = anv_vk_shader_stage_for_mesa_stage(shader->stage),
+      .layout = layout,
+   };
+
+   nir_foreach_overload(shader, overload) {
+      if (overload->impl) {
+         nir_builder_init(&state.builder, overload->impl);
+         nir_foreach_block(overload->impl, apply_pipeline_layout_block, &state);
+         nir_metadata_preserve(overload->impl, nir_metadata_block_index |
+                                               nir_metadata_dominance);
+      }
+   }
+
+   return state.progress;
+}
diff --git a/src/vulkan/anv_nir_builder.h b/src/vulkan/anv_nir_builder.h
new file mode 100644 (file)
index 0000000..f26cb04
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_nir.h"
+#include "glsl/nir/nir_builder.h"
+#include "util/ralloc.h"
+
+/* This file includes NIR helpers used by meta shaders in the Vulkan
+ * driver.  Eventually, these will all be merged into nir_builder.
+ * However, for now, keeping them in their own file helps to prevent merge
+ * conflicts.
+ */
+
+static inline void
+nir_builder_init_simple_shader(nir_builder *b, gl_shader_stage stage)
+{
+   b->shader = nir_shader_create(NULL, stage, NULL);
+
+   nir_function *func = nir_function_create(b->shader,
+                                            ralloc_strdup(b->shader, "main"));
+   nir_function_overload *overload = nir_function_overload_create(func);
+   overload->num_params = 0;
+
+   b->impl = nir_function_impl_create(overload);
+   b->cursor = nir_after_cf_list(&b->impl->body);
+}
+
+static inline void
+nir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src)
+{
+   nir_intrinsic_instr *copy =
+      nir_intrinsic_instr_create(build->shader, nir_intrinsic_copy_var);
+   copy->variables[0] = nir_deref_var_create(copy, dest);
+   copy->variables[1] = nir_deref_var_create(copy, src);
+   nir_builder_instr_insert(build, &copy->instr);
+}
diff --git a/src/vulkan/anv_nir_lower_push_constants.c b/src/vulkan/anv_nir_lower_push_constants.c
new file mode 100644 (file)
index 0000000..4917bdc
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_nir.h"
+
+struct lower_push_constants_state {
+   nir_shader *shader;
+   bool is_scalar;
+};
+
+static bool
+lower_push_constants_block(nir_block *block, void *void_state)
+{
+   struct lower_push_constants_state *state = void_state;
+
+   nir_foreach_instr(block, instr) {
+      if (instr->type != nir_instr_type_intrinsic)
+         continue;
+
+      nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
+
+      /* TODO: Handle indirect push constants */
+      if (intrin->intrinsic != nir_intrinsic_load_push_constant)
+         continue;
+
+      assert(intrin->const_index[0] % 4 == 0);
+      unsigned dword_offset = intrin->const_index[0] / 4;
+
+      /* We just turn them into uniform loads with the appropreate offset */
+      intrin->intrinsic = nir_intrinsic_load_uniform;
+      intrin->const_index[0] = 0;
+      if (state->is_scalar) {
+         intrin->const_index[1] = dword_offset;
+      } else {
+         unsigned shift = dword_offset % 4;
+         /* Can't cross the vec4 boundary */
+         assert(shift + intrin->num_components <= 4);
+
+         /* vec4 shifts are in units of vec4's */
+         intrin->const_index[1] = dword_offset / 4;
+
+         if (shift) {
+            /* If there's a non-zero shift then we need to load a whole vec4
+             * and use a move to swizzle it into place.
+             */
+            assert(intrin->dest.is_ssa);
+            nir_alu_instr *mov = nir_alu_instr_create(state->shader,
+                                                      nir_op_imov);
+            mov->src[0].src = nir_src_for_ssa(&intrin->dest.ssa);
+            for (unsigned i = 0; i < intrin->num_components; i++)
+               mov->src[0].swizzle[i] = i + shift;
+            mov->dest.write_mask = (1 << intrin->num_components) - 1;
+            nir_ssa_dest_init(&mov->instr, &mov->dest.dest,
+                              intrin->num_components, NULL);
+
+            nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
+                                     nir_src_for_ssa(&mov->dest.dest.ssa));
+            nir_instr_insert_after(&intrin->instr, &mov->instr);
+
+            /* Stomp the number of components to 4 */
+            intrin->num_components = 4;
+            intrin->dest.ssa.num_components = 4;
+         }
+      }
+   }
+
+   return true;
+}
+
+void
+anv_nir_lower_push_constants(nir_shader *shader, bool is_scalar)
+{
+   struct lower_push_constants_state state = {
+      .shader = shader,
+      .is_scalar = is_scalar,
+   };
+
+   nir_foreach_overload(shader, overload) {
+      if (overload->impl)
+         nir_foreach_block(overload->impl, lower_push_constants_block, &state);
+   }
+
+   assert(shader->num_uniforms % 4 == 0);
+   if (is_scalar)
+      shader->num_uniforms /= 4;
+   else
+      shader->num_uniforms = DIV_ROUND_UP(shader->num_uniforms, 16);
+}
diff --git a/src/vulkan/anv_pass.c b/src/vulkan/anv_pass.c
new file mode 100644 (file)
index 0000000..bf0f830
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_private.h"
+
+VkResult anv_CreateRenderPass(
+    VkDevice                                    _device,
+    const VkRenderPassCreateInfo*               pCreateInfo,
+    VkRenderPass*                               pRenderPass)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_render_pass *pass;
+   size_t size;
+   size_t attachments_offset;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
+
+   size = sizeof(*pass);
+   size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]);
+   attachments_offset = size;
+   size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]);
+
+   pass = anv_device_alloc(device, size, 8,
+                           VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pass == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   /* Clear the subpasses along with the parent pass. This required because
+    * each array member of anv_subpass must be a valid pointer if not NULL.
+    */
+   memset(pass, 0, size);
+   pass->attachment_count = pCreateInfo->attachmentCount;
+   pass->subpass_count = pCreateInfo->subpassCount;
+   pass->attachments = (void *) pass + attachments_offset;
+
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      struct anv_render_pass_attachment *att = &pass->attachments[i];
+
+      att->format = anv_format_for_vk_format(pCreateInfo->pAttachments[i].format);
+      att->samples = pCreateInfo->pAttachments[i].samples;
+      att->load_op = pCreateInfo->pAttachments[i].loadOp;
+      att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
+      // att->store_op = pCreateInfo->pAttachments[i].storeOp;
+      // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
+   }
+
+   for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
+      const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
+      struct anv_subpass *subpass = &pass->subpasses[i];
+
+      subpass->input_count = desc->inputCount;
+      subpass->color_count = desc->colorCount;
+
+      if (desc->inputCount > 0) {
+         subpass->input_attachments =
+            anv_device_alloc(device, desc->inputCount * sizeof(uint32_t),
+                             8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+
+         for (uint32_t j = 0; j < desc->inputCount; j++) {
+            subpass->input_attachments[j]
+               = desc->pInputAttachments[j].attachment;
+         }
+      }
+
+      if (desc->colorCount > 0) {
+         subpass->color_attachments =
+            anv_device_alloc(device, desc->colorCount * sizeof(uint32_t),
+                             8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+
+         for (uint32_t j = 0; j < desc->colorCount; j++) {
+            subpass->color_attachments[j]
+               = desc->pColorAttachments[j].attachment;
+         }
+      }
+
+      if (desc->pResolveAttachments) {
+         subpass->resolve_attachments =
+            anv_device_alloc(device, desc->colorCount * sizeof(uint32_t),
+                             8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+
+         for (uint32_t j = 0; j < desc->colorCount; j++) {
+            subpass->resolve_attachments[j]
+               = desc->pResolveAttachments[j].attachment;
+         }
+      }
+
+      subpass->depth_stencil_attachment = desc->depthStencilAttachment.attachment;
+   }
+
+   *pRenderPass = anv_render_pass_to_handle(pass);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyRenderPass(
+    VkDevice                                    _device,
+    VkRenderPass                                _pass)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
+
+   for (uint32_t i = 0; i < pass->subpass_count; i++) {
+      /* In VkSubpassCreateInfo, each of the attachment arrays may be null.
+       * Don't free the null arrays.
+       */
+      struct anv_subpass *subpass = &pass->subpasses[i];
+
+      anv_device_free(device, subpass->input_attachments);
+      anv_device_free(device, subpass->color_attachments);
+      anv_device_free(device, subpass->resolve_attachments);
+   }
+
+   anv_device_free(device, pass);
+}
+
+VkResult anv_GetRenderAreaGranularity(
+    VkDevice                                    device,
+    VkRenderPass                                renderPass,
+    VkExtent2D*                                 pGranularity)
+{
+   *pGranularity = (VkExtent2D) { 1, 1 };
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/anv_pipeline.c b/src/vulkan/anv_pipeline.c
new file mode 100644 (file)
index 0000000..a9cf16f
--- /dev/null
@@ -0,0 +1,1279 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+#include "brw_nir.h"
+#include "anv_nir.h"
+#include "glsl/nir/nir_spirv.h"
+
+/* Needed for SWIZZLE macros */
+#include "program/prog_instruction.h"
+
+// Shader functions
+
+VkResult anv_CreateShaderModule(
+    VkDevice                                    _device,
+    const VkShaderModuleCreateInfo*             pCreateInfo,
+    VkShaderModule*                             pShaderModule)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_shader_module *module;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO);
+   assert(pCreateInfo->flags == 0);
+
+   module = anv_device_alloc(device, sizeof(*module) + pCreateInfo->codeSize, 8,
+                             VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (module == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   module->nir = NULL;
+   module->size = pCreateInfo->codeSize;
+   memcpy(module->data, pCreateInfo->pCode, module->size);
+
+   *pShaderModule = anv_shader_module_to_handle(module);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyShaderModule(
+    VkDevice                                    _device,
+    VkShaderModule                              _module)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_shader_module, module, _module);
+
+   anv_device_free(device, module);
+}
+
+VkResult anv_CreateShader(
+    VkDevice                                    _device,
+    const VkShaderCreateInfo*                   pCreateInfo,
+    VkShader*                                   pShader)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_shader_module, module, pCreateInfo->module);
+   struct anv_shader *shader;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_CREATE_INFO);
+   assert(pCreateInfo->flags == 0);
+
+   const char *name = pCreateInfo->pName ? pCreateInfo->pName : "main";
+   size_t name_len = strlen(name);
+
+   shader = anv_device_alloc(device, sizeof(*shader) + name_len + 1, 8,
+                             VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (shader == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   shader->module = module,
+   memcpy(shader->entrypoint, name, name_len + 1);
+
+   *pShader = anv_shader_to_handle(shader);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyShader(
+    VkDevice                                    _device,
+    VkShader                                    _shader)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_shader, shader, _shader);
+
+   anv_device_free(device, shader);
+}
+
+#define SPIR_V_MAGIC_NUMBER 0x07230203
+
+static const gl_shader_stage vk_shader_stage_to_mesa_stage[] = {
+   [VK_SHADER_STAGE_VERTEX] = MESA_SHADER_VERTEX,
+   [VK_SHADER_STAGE_TESS_CONTROL] = -1,
+   [VK_SHADER_STAGE_TESS_EVALUATION] = -1,
+   [VK_SHADER_STAGE_GEOMETRY] = MESA_SHADER_GEOMETRY,
+   [VK_SHADER_STAGE_FRAGMENT] = MESA_SHADER_FRAGMENT,
+   [VK_SHADER_STAGE_COMPUTE] = MESA_SHADER_COMPUTE,
+};
+
+bool
+anv_is_scalar_shader_stage(const struct brw_compiler *compiler,
+                           VkShaderStage stage)
+{
+   switch (stage) {
+   case VK_SHADER_STAGE_VERTEX:
+      return compiler->scalar_vs;
+   case VK_SHADER_STAGE_GEOMETRY:
+      return false;
+   case VK_SHADER_STAGE_FRAGMENT:
+   case VK_SHADER_STAGE_COMPUTE:
+      return true;
+   default:
+      unreachable("Unsupported shader stage");
+   }
+}
+
+/* Eventually, this will become part of anv_CreateShader.  Unfortunately,
+ * we can't do that yet because we don't have the ability to copy nir.
+ */
+static nir_shader *
+anv_shader_compile_to_nir(struct anv_device *device,
+                          struct anv_shader *shader, VkShaderStage vk_stage)
+{
+   if (strcmp(shader->entrypoint, "main") != 0) {
+      anv_finishme("Multiple shaders per module not really supported");
+   }
+
+   gl_shader_stage stage = vk_shader_stage_to_mesa_stage[vk_stage];
+   const struct brw_compiler *compiler =
+      device->instance->physicalDevice.compiler;
+   const nir_shader_compiler_options *nir_options =
+      compiler->glsl_compiler_options[stage].NirOptions;
+
+   nir_shader *nir;
+   if (shader->module->nir) {
+      /* Some things such as our meta clear/blit code will give us a NIR
+       * shader directly.  In that case, we just ignore the SPIR-V entirely
+       * and just use the NIR shader */
+      nir = shader->module->nir;
+      nir->options = nir_options;
+   } else {
+      uint32_t *spirv = (uint32_t *) shader->module->data;
+      assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
+      assert(shader->module->size % 4 == 0);
+
+      nir = spirv_to_nir(spirv, shader->module->size / 4, stage, nir_options);
+   }
+   nir_validate_shader(nir);
+
+   /* Vulkan uses the separate-shader linking model */
+   nir->info.separate_shader = true;
+
+   /* Make sure the provided shader has exactly one entrypoint and that the
+    * name matches the name that came in from the VkShader.
+    */
+   nir_function_impl *entrypoint = NULL;
+   nir_foreach_overload(nir, overload) {
+      if (strcmp(shader->entrypoint, overload->function->name) == 0 &&
+          overload->impl) {
+         assert(entrypoint == NULL);
+         entrypoint = overload->impl;
+      }
+   }
+   assert(entrypoint != NULL);
+
+   brw_preprocess_nir(nir, &device->info,
+                      anv_is_scalar_shader_stage(compiler, vk_stage));
+
+   nir_shader_gather_info(nir, entrypoint);
+
+   return nir;
+}
+
+VkResult anv_CreatePipelineCache(
+    VkDevice                                    device,
+    const VkPipelineCacheCreateInfo*            pCreateInfo,
+    VkPipelineCache*                            pPipelineCache)
+{
+   pPipelineCache->handle = 1;
+
+   stub_return(VK_SUCCESS);
+}
+
+void anv_DestroyPipelineCache(
+    VkDevice                                    _device,
+    VkPipelineCache                             _cache)
+{
+}
+
+size_t anv_GetPipelineCacheSize(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache)
+{
+   stub_return(0);
+}
+
+VkResult anv_GetPipelineCacheData(
+    VkDevice                                    device,
+    VkPipelineCache                             pipelineCache,
+    void*                                       pData)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_MergePipelineCaches(
+    VkDevice                                    device,
+    VkPipelineCache                             destCache,
+    uint32_t                                    srcCacheCount,
+    const VkPipelineCache*                      pSrcCaches)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+void anv_DestroyPipeline(
+    VkDevice                                    _device,
+    VkPipeline                                  _pipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
+
+   anv_reloc_list_finish(&pipeline->batch_relocs, pipeline->device);
+   anv_state_stream_finish(&pipeline->program_stream);
+   if (pipeline->blend_state.map)
+      anv_state_pool_free(&device->dynamic_state_pool, pipeline->blend_state);
+   anv_device_free(pipeline->device, pipeline);
+}
+
+static const uint32_t vk_to_gen_primitive_type[] = {
+   [VK_PRIMITIVE_TOPOLOGY_POINT_LIST]           = _3DPRIM_POINTLIST,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_LIST]            = _3DPRIM_LINELIST,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP]           = _3DPRIM_LINESTRIP,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST]        = _3DPRIM_TRILIST,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP]       = _3DPRIM_TRISTRIP,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN]         = _3DPRIM_TRIFAN,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ]        = _3DPRIM_LINELIST_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ]       = _3DPRIM_LINESTRIP_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ]    = _3DPRIM_TRILIST_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ]   = _3DPRIM_TRISTRIP_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_PATCH]                = _3DPRIM_PATCHLIST_1
+};
+
+static void
+populate_sampler_prog_key(const struct brw_device_info *devinfo,
+                          struct brw_sampler_prog_key_data *key)
+{
+   /* XXX: Handle texture swizzle on HSW- */
+   for (int i = 0; i < MAX_SAMPLERS; i++) {
+      /* Assume color sampler, no swizzling. (Works for BDW+) */
+      key->swizzles[i] = SWIZZLE_XYZW;
+   }
+}
+
+static void
+populate_vs_prog_key(const struct brw_device_info *devinfo,
+                     struct brw_vs_prog_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   populate_sampler_prog_key(devinfo, &key->tex);
+
+   /* XXX: Handle vertex input work-arounds */
+
+   /* XXX: Handle sampler_prog_key */
+}
+
+static void
+populate_gs_prog_key(const struct brw_device_info *devinfo,
+                     struct brw_gs_prog_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   populate_sampler_prog_key(devinfo, &key->tex);
+}
+
+static void
+populate_wm_prog_key(const struct brw_device_info *devinfo,
+                     const VkGraphicsPipelineCreateInfo *info,
+                     struct brw_wm_prog_key *key)
+{
+   ANV_FROM_HANDLE(anv_render_pass, render_pass, info->renderPass);
+
+   memset(key, 0, sizeof(*key));
+
+   populate_sampler_prog_key(devinfo, &key->tex);
+
+   /* TODO: Fill out key->input_slots_valid */
+
+   /* Vulkan doesn't specify a default */
+   key->high_quality_derivatives = false;
+
+   /* XXX Vulkan doesn't appear to specify */
+   key->clamp_fragment_color = false;
+
+   /* Vulkan always specifies upper-left coordinates */
+   key->drawable_height = 0;
+   key->render_to_fbo = false;
+
+   key->nr_color_regions = render_pass->subpasses[info->subpass].color_count;
+
+   key->replicate_alpha = key->nr_color_regions > 1 &&
+                          info->pColorBlendState->alphaToCoverageEnable;
+
+   if (info->pMultisampleState && info->pMultisampleState->rasterSamples > 1) {
+      /* We should probably pull this out of the shader, but it's fairly
+       * harmless to compute it and then let dead-code take care of it.
+       */
+      key->persample_shading = info->pMultisampleState->sampleShadingEnable;
+      if (key->persample_shading)
+         key->persample_2x = info->pMultisampleState->rasterSamples == 2;
+
+      key->compute_pos_offset = info->pMultisampleState->sampleShadingEnable;
+      key->compute_sample_id = info->pMultisampleState->sampleShadingEnable;
+   }
+}
+
+static void
+populate_cs_prog_key(const struct brw_device_info *devinfo,
+                     struct brw_cs_prog_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   populate_sampler_prog_key(devinfo, &key->tex);
+}
+
+static nir_shader *
+anv_pipeline_compile(struct anv_pipeline *pipeline,
+                     struct anv_shader *shader,
+                     VkShaderStage stage,
+                     struct brw_stage_prog_data *prog_data)
+{
+   const struct brw_compiler *compiler =
+      pipeline->device->instance->physicalDevice.compiler;
+
+   nir_shader *nir = anv_shader_compile_to_nir(pipeline->device, shader, stage);
+   if (nir == NULL)
+      return NULL;
+
+   anv_nir_lower_push_constants(nir, anv_is_scalar_shader_stage(compiler, stage));
+
+   /* Figure out the number of parameters */
+   prog_data->nr_params = 0;
+
+   if (nir->num_uniforms > 0) {
+      /* If the shader uses any push constants at all, we'll just give
+       * them the maximum possible number
+       */
+      prog_data->nr_params += MAX_PUSH_CONSTANTS_SIZE / sizeof(float);
+   }
+
+   if (pipeline->layout && pipeline->layout->stage[stage].has_dynamic_offsets)
+      prog_data->nr_params += MAX_DYNAMIC_BUFFERS * 2;
+
+   if (prog_data->nr_params > 0) {
+      prog_data->param = (const gl_constant_value **)
+         anv_device_alloc(pipeline->device,
+                          prog_data->nr_params * sizeof(gl_constant_value *),
+                          8, VK_SYSTEM_ALLOC_TYPE_INTERNAL_SHADER);
+
+      /* We now set the param values to be offsets into a
+       * anv_push_constant_data structure.  Since the compiler doesn't
+       * actually dereference any of the gl_constant_value pointers in the
+       * params array, it doesn't really matter what we put here.
+       */
+      struct anv_push_constants *null_data = NULL;
+      if (nir->num_uniforms > 0) {
+         /* Fill out the push constants section of the param array */
+         for (unsigned i = 0; i < MAX_PUSH_CONSTANTS_SIZE / sizeof(float); i++)
+            prog_data->param[i] = (const gl_constant_value *)
+               &null_data->client_data[i * sizeof(float)];
+      }
+   }
+
+   /* Set up dynamic offsets */
+   anv_nir_apply_dynamic_offsets(pipeline, nir, prog_data);
+
+   /* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
+   anv_nir_apply_pipeline_layout(nir, pipeline->layout);
+
+   /* All binding table offsets provided by apply_pipeline_layout() are
+    * relative to the start of the bindint table (plus MAX_RTS for VS).
+    */
+   unsigned bias = stage == VK_SHADER_STAGE_FRAGMENT ? MAX_RTS : 0;
+   prog_data->binding_table.size_bytes = 0;
+   prog_data->binding_table.texture_start = bias;
+   prog_data->binding_table.ubo_start = bias;
+   prog_data->binding_table.ssbo_start = bias;
+   prog_data->binding_table.image_start = bias;
+
+   /* Finish the optimization and compilation process */
+   brw_postprocess_nir(nir, &pipeline->device->info,
+                       anv_is_scalar_shader_stage(compiler, stage));
+
+   /* nir_lower_io will only handle the push constants; we need to set this
+    * to the full number of possible uniforms.
+    */
+   nir->num_uniforms = prog_data->nr_params;
+
+   return nir;
+}
+
+static uint32_t
+anv_pipeline_upload_kernel(struct anv_pipeline *pipeline,
+                           const void *data, size_t size)
+{
+   struct anv_state state =
+      anv_state_stream_alloc(&pipeline->program_stream, size, 64);
+
+   assert(size < pipeline->program_stream.block_pool->block_size);
+
+   memcpy(state.map, data, size);
+
+   return state.offset;
+}
+static void
+anv_pipeline_add_compiled_stage(struct anv_pipeline *pipeline,
+                                VkShaderStage stage,
+                                struct brw_stage_prog_data *prog_data)
+{
+   struct brw_device_info *devinfo = &pipeline->device->info;
+   uint32_t max_threads[] = {
+      [VK_SHADER_STAGE_VERTEX]                  = devinfo->max_vs_threads,
+      [VK_SHADER_STAGE_TESS_CONTROL]            = 0,
+      [VK_SHADER_STAGE_TESS_EVALUATION]         = 0,
+      [VK_SHADER_STAGE_GEOMETRY]                = devinfo->max_gs_threads,
+      [VK_SHADER_STAGE_FRAGMENT]                = devinfo->max_wm_threads,
+      [VK_SHADER_STAGE_COMPUTE]                 = devinfo->max_cs_threads,
+   };
+
+   pipeline->prog_data[stage] = prog_data;
+   pipeline->active_stages |= 1 << stage;
+   pipeline->scratch_start[stage] = pipeline->total_scratch;
+   pipeline->total_scratch =
+      align_u32(pipeline->total_scratch, 1024) +
+      prog_data->total_scratch * max_threads[stage];
+}
+
+static VkResult
+anv_pipeline_compile_vs(struct anv_pipeline *pipeline,
+                        const VkGraphicsPipelineCreateInfo *info,
+                        struct anv_shader *shader)
+{
+   const struct brw_compiler *compiler =
+      pipeline->device->instance->physicalDevice.compiler;
+   struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
+   struct brw_vs_prog_key key;
+
+   populate_vs_prog_key(&pipeline->device->info, &key);
+
+   /* TODO: Look up shader in cache */
+
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   nir_shader *nir = anv_pipeline_compile(pipeline, shader,
+                                          VK_SHADER_STAGE_VERTEX,
+                                          &prog_data->base.base);
+   if (nir == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   void *mem_ctx = ralloc_context(NULL);
+
+   if (shader->module->nir == NULL)
+      ralloc_steal(mem_ctx, nir);
+
+   prog_data->inputs_read = nir->info.inputs_read;
+   pipeline->writes_point_size = nir->info.outputs_written & VARYING_SLOT_PSIZ;
+
+   brw_compute_vue_map(&pipeline->device->info,
+                       &prog_data->base.vue_map,
+                       nir->info.outputs_written,
+                       nir->info.separate_shader);
+
+   unsigned code_size;
+   const unsigned *shader_code =
+      brw_compile_vs(compiler, NULL, mem_ctx, &key, prog_data, nir,
+                     NULL, false, -1, &code_size, NULL);
+   if (shader_code == NULL) {
+      ralloc_free(mem_ctx);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+
+   const uint32_t offset =
+      anv_pipeline_upload_kernel(pipeline, shader_code, code_size);
+   if (prog_data->base.dispatch_mode == DISPATCH_MODE_SIMD8) {
+      pipeline->vs_simd8 = offset;
+      pipeline->vs_vec4 = NO_KERNEL;
+   } else {
+      pipeline->vs_simd8 = NO_KERNEL;
+      pipeline->vs_vec4 = offset;
+   }
+
+   ralloc_free(mem_ctx);
+
+   anv_pipeline_add_compiled_stage(pipeline, VK_SHADER_STAGE_VERTEX,
+                                   &prog_data->base.base);
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
+                        const VkGraphicsPipelineCreateInfo *info,
+                        struct anv_shader *shader)
+{
+   const struct brw_compiler *compiler =
+      pipeline->device->instance->physicalDevice.compiler;
+   struct brw_gs_prog_data *prog_data = &pipeline->gs_prog_data;
+   struct brw_gs_prog_key key;
+
+   populate_gs_prog_key(&pipeline->device->info, &key);
+
+   /* TODO: Look up shader in cache */
+
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   nir_shader *nir = anv_pipeline_compile(pipeline, shader,
+                                          VK_SHADER_STAGE_GEOMETRY,
+                                          &prog_data->base.base);
+   if (nir == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   void *mem_ctx = ralloc_context(NULL);
+
+   if (shader->module->nir == NULL)
+      ralloc_steal(mem_ctx, nir);
+
+   brw_compute_vue_map(&pipeline->device->info,
+                       &prog_data->base.vue_map,
+                       nir->info.outputs_written,
+                       nir->info.separate_shader);
+
+   unsigned code_size;
+   const unsigned *shader_code =
+      brw_compile_gs(compiler, NULL, mem_ctx, &key, prog_data, nir,
+                     NULL, -1, &code_size, NULL);
+   if (shader_code == NULL) {
+      ralloc_free(mem_ctx);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+
+   /* TODO: SIMD8 GS */
+   pipeline->gs_vec4 =
+      anv_pipeline_upload_kernel(pipeline, shader_code, code_size);
+   pipeline->gs_vertex_count = nir->info.gs.vertices_in;
+
+   ralloc_free(mem_ctx);
+
+   anv_pipeline_add_compiled_stage(pipeline, VK_SHADER_STAGE_GEOMETRY,
+                                   &prog_data->base.base);
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
+                        const VkGraphicsPipelineCreateInfo *info,
+                        struct anv_shader *shader)
+{
+   const struct brw_compiler *compiler =
+      pipeline->device->instance->physicalDevice.compiler;
+   struct brw_wm_prog_data *prog_data = &pipeline->wm_prog_data;
+   struct brw_wm_prog_key key;
+
+   populate_wm_prog_key(&pipeline->device->info, info, &key);
+
+   if (pipeline->use_repclear)
+      key.nr_color_regions = 1;
+
+   /* TODO: Look up shader in cache */
+
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   prog_data->binding_table.render_target_start = 0;
+
+   nir_shader *nir = anv_pipeline_compile(pipeline, shader,
+                                          VK_SHADER_STAGE_FRAGMENT,
+                                          &prog_data->base);
+   if (nir == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   void *mem_ctx = ralloc_context(NULL);
+
+   if (shader->module->nir == NULL)
+      ralloc_steal(mem_ctx, nir);
+
+   unsigned code_size;
+   const unsigned *shader_code =
+      brw_compile_fs(compiler, NULL, mem_ctx, &key, prog_data, nir,
+                     NULL, -1, -1, pipeline->use_repclear, &code_size, NULL);
+   if (shader_code == NULL) {
+      ralloc_free(mem_ctx);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+
+   uint32_t offset = anv_pipeline_upload_kernel(pipeline,
+                                                shader_code, code_size);
+   if (prog_data->no_8)
+      pipeline->ps_simd8 = NO_KERNEL;
+   else
+      pipeline->ps_simd8 = offset;
+
+   if (prog_data->no_8 || prog_data->prog_offset_16) {
+      pipeline->ps_simd16 = offset + prog_data->prog_offset_16;
+   } else {
+      pipeline->ps_simd16 = NO_KERNEL;
+   }
+
+   pipeline->ps_ksp2 = 0;
+   pipeline->ps_grf_start2 = 0;
+   if (pipeline->ps_simd8 != NO_KERNEL) {
+      pipeline->ps_ksp0 = pipeline->ps_simd8;
+      pipeline->ps_grf_start0 = prog_data->base.dispatch_grf_start_reg;
+      if (pipeline->ps_simd16 != NO_KERNEL) {
+         pipeline->ps_ksp2 = pipeline->ps_simd16;
+         pipeline->ps_grf_start2 = prog_data->dispatch_grf_start_reg_16;
+      }
+   } else if (pipeline->ps_simd16 != NO_KERNEL) {
+      pipeline->ps_ksp0 = pipeline->ps_simd16;
+      pipeline->ps_grf_start0 = prog_data->dispatch_grf_start_reg_16;
+   }
+
+   ralloc_free(mem_ctx);
+
+   anv_pipeline_add_compiled_stage(pipeline, VK_SHADER_STAGE_FRAGMENT,
+                                   &prog_data->base);
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
+                        const VkComputePipelineCreateInfo *info,
+                        struct anv_shader *shader)
+{
+   const struct brw_compiler *compiler =
+      pipeline->device->instance->physicalDevice.compiler;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+   struct brw_cs_prog_key key;
+
+   populate_cs_prog_key(&pipeline->device->info, &key);
+
+   /* TODO: Look up shader in cache */
+
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   nir_shader *nir = anv_pipeline_compile(pipeline, shader,
+                                          VK_SHADER_STAGE_COMPUTE,
+                                          &prog_data->base);
+   if (nir == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   void *mem_ctx = ralloc_context(NULL);
+
+   if (shader->module->nir == NULL)
+      ralloc_steal(mem_ctx, nir);
+
+   unsigned code_size;
+   const unsigned *shader_code =
+      brw_compile_cs(compiler, NULL, mem_ctx, &key, prog_data, nir,
+                     -1, &code_size, NULL);
+   if (shader_code == NULL) {
+      ralloc_free(mem_ctx);
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+   }
+
+   pipeline->cs_simd = anv_pipeline_upload_kernel(pipeline,
+                                                  shader_code, code_size);
+   ralloc_free(mem_ctx);
+
+   anv_pipeline_add_compiled_stage(pipeline, VK_SHADER_STAGE_COMPUTE,
+                                   &prog_data->base);
+
+   return VK_SUCCESS;
+}
+
+static const int gen8_push_size = 32 * 1024;
+
+static void
+gen7_compute_urb_partition(struct anv_pipeline *pipeline)
+{
+   const struct brw_device_info *devinfo = &pipeline->device->info;
+   bool vs_present = pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT;
+   unsigned vs_size = vs_present ? pipeline->vs_prog_data.base.urb_entry_size : 1;
+   unsigned vs_entry_size_bytes = vs_size * 64;
+   bool gs_present = pipeline->active_stages & VK_SHADER_STAGE_GEOMETRY_BIT;
+   unsigned gs_size = gs_present ? pipeline->gs_prog_data.base.urb_entry_size : 1;
+   unsigned gs_entry_size_bytes = gs_size * 64;
+
+   /* From p35 of the Ivy Bridge PRM (section 1.7.1: 3DSTATE_URB_GS):
+    *
+    *     VS Number of URB Entries must be divisible by 8 if the VS URB Entry
+    *     Allocation Size is less than 9 512-bit URB entries.
+    *
+    * Similar text exists for GS.
+    */
+   unsigned vs_granularity = (vs_size < 9) ? 8 : 1;
+   unsigned gs_granularity = (gs_size < 9) ? 8 : 1;
+
+   /* URB allocations must be done in 8k chunks. */
+   unsigned chunk_size_bytes = 8192;
+
+   /* Determine the size of the URB in chunks. */
+   unsigned urb_chunks = devinfo->urb.size * 1024 / chunk_size_bytes;
+
+   /* Reserve space for push constants */
+   unsigned push_constant_bytes = gen8_push_size;
+   unsigned push_constant_chunks =
+      push_constant_bytes / chunk_size_bytes;
+
+   /* Initially, assign each stage the minimum amount of URB space it needs,
+    * and make a note of how much additional space it "wants" (the amount of
+    * additional space it could actually make use of).
+    */
+
+   /* VS has a lower limit on the number of URB entries */
+   unsigned vs_chunks =
+      ALIGN(devinfo->urb.min_vs_entries * vs_entry_size_bytes,
+            chunk_size_bytes) / chunk_size_bytes;
+   unsigned vs_wants =
+      ALIGN(devinfo->urb.max_vs_entries * vs_entry_size_bytes,
+            chunk_size_bytes) / chunk_size_bytes - vs_chunks;
+
+   unsigned gs_chunks = 0;
+   unsigned gs_wants = 0;
+   if (gs_present) {
+      /* There are two constraints on the minimum amount of URB space we can
+       * allocate:
+       *
+       * (1) We need room for at least 2 URB entries, since we always operate
+       * the GS in DUAL_OBJECT mode.
+       *
+       * (2) We can't allocate less than nr_gs_entries_granularity.
+       */
+      gs_chunks = ALIGN(MAX2(gs_granularity, 2) * gs_entry_size_bytes,
+                        chunk_size_bytes) / chunk_size_bytes;
+      gs_wants =
+         ALIGN(devinfo->urb.max_gs_entries * gs_entry_size_bytes,
+               chunk_size_bytes) / chunk_size_bytes - gs_chunks;
+   }
+
+   /* There should always be enough URB space to satisfy the minimum
+    * requirements of each stage.
+    */
+   unsigned total_needs = push_constant_chunks + vs_chunks + gs_chunks;
+   assert(total_needs <= urb_chunks);
+
+   /* Mete out remaining space (if any) in proportion to "wants". */
+   unsigned total_wants = vs_wants + gs_wants;
+   unsigned remaining_space = urb_chunks - total_needs;
+   if (remaining_space > total_wants)
+      remaining_space = total_wants;
+   if (remaining_space > 0) {
+      unsigned vs_additional = (unsigned)
+         round(vs_wants * (((double) remaining_space) / total_wants));
+      vs_chunks += vs_additional;
+      remaining_space -= vs_additional;
+      gs_chunks += remaining_space;
+   }
+
+   /* Sanity check that we haven't over-allocated. */
+   assert(push_constant_chunks + vs_chunks + gs_chunks <= urb_chunks);
+
+   /* Finally, compute the number of entries that can fit in the space
+    * allocated to each stage.
+    */
+   unsigned nr_vs_entries = vs_chunks * chunk_size_bytes / vs_entry_size_bytes;
+   unsigned nr_gs_entries = gs_chunks * chunk_size_bytes / gs_entry_size_bytes;
+
+   /* Since we rounded up when computing *_wants, this may be slightly more
+    * than the maximum allowed amount, so correct for that.
+    */
+   nr_vs_entries = MIN2(nr_vs_entries, devinfo->urb.max_vs_entries);
+   nr_gs_entries = MIN2(nr_gs_entries, devinfo->urb.max_gs_entries);
+
+   /* Ensure that we program a multiple of the granularity. */
+   nr_vs_entries = ROUND_DOWN_TO(nr_vs_entries, vs_granularity);
+   nr_gs_entries = ROUND_DOWN_TO(nr_gs_entries, gs_granularity);
+
+   /* Finally, sanity check to make sure we have at least the minimum number
+    * of entries needed for each stage.
+    */
+   assert(nr_vs_entries >= devinfo->urb.min_vs_entries);
+   if (gs_present)
+      assert(nr_gs_entries >= 2);
+
+   /* Lay out the URB in the following order:
+    * - push constants
+    * - VS
+    * - GS
+    */
+   pipeline->urb.vs_start = push_constant_chunks;
+   pipeline->urb.vs_size = vs_size;
+   pipeline->urb.nr_vs_entries = nr_vs_entries;
+
+   pipeline->urb.gs_start = push_constant_chunks + vs_chunks;
+   pipeline->urb.gs_size = gs_size;
+   pipeline->urb.nr_gs_entries = nr_gs_entries;
+}
+
+static void
+anv_pipeline_init_dynamic_state(struct anv_pipeline *pipeline,
+                                const VkGraphicsPipelineCreateInfo *pCreateInfo)
+{
+   anv_cmd_dirty_mask_t states = ANV_CMD_DIRTY_DYNAMIC_ALL;
+   ANV_FROM_HANDLE(anv_render_pass, pass, pCreateInfo->renderPass);
+   struct anv_subpass *subpass = &pass->subpasses[pCreateInfo->subpass];
+
+   pipeline->dynamic_state = default_dynamic_state;
+
+   if (pCreateInfo->pDynamicState) {
+      /* Remove all of the states that are marked as dynamic */
+      uint32_t count = pCreateInfo->pDynamicState->dynamicStateCount;
+      for (uint32_t s = 0; s < count; s++)
+         states &= ~(1 << pCreateInfo->pDynamicState->pDynamicStates[s]);
+   }
+
+   struct anv_dynamic_state *dynamic = &pipeline->dynamic_state;
+
+   dynamic->viewport.count = pCreateInfo->pViewportState->viewportCount;
+   if (states & (1 << VK_DYNAMIC_STATE_VIEWPORT)) {
+      typed_memcpy(dynamic->viewport.viewports,
+                   pCreateInfo->pViewportState->pViewports,
+                   pCreateInfo->pViewportState->viewportCount);
+   }
+
+   dynamic->scissor.count = pCreateInfo->pViewportState->scissorCount;
+   if (states & (1 << VK_DYNAMIC_STATE_SCISSOR)) {
+      typed_memcpy(dynamic->scissor.scissors,
+                   pCreateInfo->pViewportState->pScissors,
+                   pCreateInfo->pViewportState->scissorCount);
+   }
+
+   if (states & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) {
+      assert(pCreateInfo->pRasterState);
+      dynamic->line_width = pCreateInfo->pRasterState->lineWidth;
+   }
+
+   if (states & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) {
+      assert(pCreateInfo->pRasterState);
+      dynamic->depth_bias.bias = pCreateInfo->pRasterState->depthBias;
+      dynamic->depth_bias.clamp = pCreateInfo->pRasterState->depthBiasClamp;
+      dynamic->depth_bias.slope_scaled =
+         pCreateInfo->pRasterState->slopeScaledDepthBias;
+   }
+
+   if (states & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) {
+      assert(pCreateInfo->pColorBlendState);
+      typed_memcpy(dynamic->blend_constants,
+                   pCreateInfo->pColorBlendState->blendConst, 4);
+   }
+
+   /* If there is no depthstencil attachment, then don't read
+    * pDepthStencilState. The Vulkan spec states that pDepthStencilState may
+    * be NULL in this case. Even if pDepthStencilState is non-NULL, there is
+    * no need to override the depthstencil defaults in
+    * anv_pipeline::dynamic_state when there is no depthstencil attachment.
+    *
+    * From the Vulkan spec (20 Oct 2015, git-aa308cb):
+    *
+    *    pDepthStencilState [...] may only be NULL if renderPass and subpass
+    *    specify a subpass that has no depth/stencil attachment.
+    */
+   if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
+      if (states & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) {
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->depth_bounds.min =
+            pCreateInfo->pDepthStencilState->minDepthBounds;
+         dynamic->depth_bounds.max =
+            pCreateInfo->pDepthStencilState->maxDepthBounds;
+      }
+
+      if (states & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->stencil_compare_mask.front =
+            pCreateInfo->pDepthStencilState->front.stencilCompareMask;
+         dynamic->stencil_compare_mask.back =
+            pCreateInfo->pDepthStencilState->back.stencilCompareMask;
+      }
+
+      if (states & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->stencil_write_mask.front =
+            pCreateInfo->pDepthStencilState->front.stencilWriteMask;
+         dynamic->stencil_write_mask.back =
+            pCreateInfo->pDepthStencilState->back.stencilWriteMask;
+      }
+
+      if (states & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
+         assert(pCreateInfo->pDepthStencilState);
+         dynamic->stencil_reference.front =
+            pCreateInfo->pDepthStencilState->front.stencilReference;
+         dynamic->stencil_reference.back =
+            pCreateInfo->pDepthStencilState->back.stencilReference;
+      }
+   }
+
+   pipeline->dynamic_state_mask = states;
+}
+
+static void
+anv_pipeline_validate_create_info(const VkGraphicsPipelineCreateInfo *info)
+{
+   struct anv_render_pass *renderpass = NULL;
+   struct anv_subpass *subpass = NULL;
+
+   /* Assert that all required members of VkGraphicsPipelineCreateInfo are
+    * present, as explained by the Vulkan (20 Oct 2015, git-aa308cb), Section
+    * 4.2 Graphics Pipeline.
+    */
+   assert(info->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
+
+   renderpass = anv_render_pass_from_handle(info->renderPass);
+   assert(renderpass);
+
+   if (renderpass != &anv_meta_dummy_renderpass) {
+      assert(info->subpass < renderpass->subpass_count);
+      subpass = &renderpass->subpasses[info->subpass];
+   }
+
+   assert(info->stageCount >= 1);
+   assert(info->pVertexInputState);
+   assert(info->pInputAssemblyState);
+   assert(info->pViewportState);
+   assert(info->pRasterState);
+   assert(info->pMultisampleState);
+
+   if (subpass && subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED)
+      assert(info->pDepthStencilState);
+
+   if (subpass && subpass->color_count > 0)
+      assert(info->pColorBlendState);
+
+   for (uint32_t i = 0; i < info->stageCount; ++i) {
+      switch (info->pStages[i].stage) {
+      case VK_SHADER_STAGE_TESS_CONTROL:
+      case VK_SHADER_STAGE_TESS_EVALUATION:
+         assert(info->pTessellationState);
+         break;
+      default:
+         break;
+      }
+   }
+}
+
+VkResult
+anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
+                  const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                  const struct anv_graphics_pipeline_create_info *extra)
+{
+   VkResult result;
+
+   anv_validate {
+      anv_pipeline_validate_create_info(pCreateInfo);
+   }
+
+   pipeline->device = device;
+   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
+
+   result = anv_reloc_list_init(&pipeline->batch_relocs, device);
+   if (result != VK_SUCCESS) {
+      anv_device_free(device, pipeline);
+      return result;
+   }
+   pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
+   pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
+   pipeline->batch.relocs = &pipeline->batch_relocs;
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   anv_pipeline_init_dynamic_state(pipeline, pCreateInfo);
+
+   if (pCreateInfo->pTessellationState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
+   if (pCreateInfo->pMultisampleState &&
+       pCreateInfo->pMultisampleState->rasterSamples > 1)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
+
+   pipeline->use_repclear = extra && extra->use_repclear;
+   pipeline->writes_point_size = false;
+
+   /* When we free the pipeline, we detect stages based on the NULL status
+    * of various prog_data pointers.  Make them NULL by default.
+    */
+   memset(pipeline->prog_data, 0, sizeof(pipeline->prog_data));
+   memset(pipeline->scratch_start, 0, sizeof(pipeline->scratch_start));
+
+   pipeline->vs_simd8 = NO_KERNEL;
+   pipeline->vs_vec4 = NO_KERNEL;
+   pipeline->gs_vec4 = NO_KERNEL;
+
+   pipeline->active_stages = 0;
+   pipeline->total_scratch = 0;
+
+   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
+      ANV_FROM_HANDLE(anv_shader, shader, pCreateInfo->pStages[i].shader);
+
+      switch (pCreateInfo->pStages[i].stage) {
+      case VK_SHADER_STAGE_VERTEX:
+         anv_pipeline_compile_vs(pipeline, pCreateInfo, shader);
+         break;
+      case VK_SHADER_STAGE_GEOMETRY:
+         anv_pipeline_compile_gs(pipeline, pCreateInfo, shader);
+         break;
+      case VK_SHADER_STAGE_FRAGMENT:
+         anv_pipeline_compile_fs(pipeline, pCreateInfo, shader);
+         break;
+      default:
+         anv_finishme("Unsupported shader stage");
+      }
+   }
+
+   if (!(pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT)) {
+      /* Vertex is only optional if disable_vs is set */
+      assert(extra->disable_vs);
+      memset(&pipeline->vs_prog_data, 0, sizeof(pipeline->vs_prog_data));
+   }
+
+   gen7_compute_urb_partition(pipeline);
+
+   const VkPipelineVertexInputStateCreateInfo *vi_info =
+      pCreateInfo->pVertexInputState;
+   pipeline->vb_used = 0;
+   for (uint32_t i = 0; i < vi_info->bindingCount; i++) {
+      const VkVertexInputBindingDescription *desc =
+         &vi_info->pVertexBindingDescriptions[i];
+
+      pipeline->vb_used |= 1 << desc->binding;
+      pipeline->binding_stride[desc->binding] = desc->strideInBytes;
+
+      /* Step rate is programmed per vertex element (attribute), not
+       * binding. Set up a map of which bindings step per instance, for
+       * reference by vertex element setup. */
+      switch (desc->stepRate) {
+      default:
+      case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
+         pipeline->instancing_enable[desc->binding] = false;
+         break;
+      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
+         pipeline->instancing_enable[desc->binding] = true;
+         break;
+      }
+   }
+
+   const VkPipelineInputAssemblyStateCreateInfo *ia_info =
+      pCreateInfo->pInputAssemblyState;
+   pipeline->primitive_restart = ia_info->primitiveRestartEnable;
+   pipeline->topology = vk_to_gen_primitive_type[ia_info->topology];
+
+   if (extra && extra->use_rectlist)
+      pipeline->topology = _3DPRIM_RECTLIST;
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_graphics_pipeline_create(
+   VkDevice _device,
+   const VkGraphicsPipelineCreateInfo *pCreateInfo,
+   const struct anv_graphics_pipeline_create_info *extra,
+   VkPipeline *pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   switch (device->info.gen) {
+   case 7:
+      return gen7_graphics_pipeline_create(_device, pCreateInfo, extra, pPipeline);
+   case 8:
+      return gen8_graphics_pipeline_create(_device, pCreateInfo, extra, pPipeline);
+   default:
+      unreachable("unsupported gen\n");
+   }
+}
+
+VkResult anv_CreateGraphicsPipelines(
+    VkDevice                                    _device,
+    VkPipelineCache                             pipelineCache,
+    uint32_t                                    count,
+    const VkGraphicsPipelineCreateInfo*         pCreateInfos,
+    VkPipeline*                                 pPipelines)
+{
+   VkResult result = VK_SUCCESS;
+
+   unsigned i = 0;
+   for (; i < count; i++) {
+      result = anv_graphics_pipeline_create(_device, &pCreateInfos[i],
+                                            NULL, &pPipelines[i]);
+      if (result != VK_SUCCESS) {
+         for (unsigned j = 0; j < i; j++) {
+            anv_DestroyPipeline(_device, pPipelines[j]);
+         }
+
+         return result;
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+static VkResult anv_compute_pipeline_create(
+    VkDevice                                    _device,
+    const VkComputePipelineCreateInfo*          pCreateInfo,
+    VkPipeline*                                 pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   switch (device->info.gen) {
+   case 7:
+      return gen7_compute_pipeline_create(_device, pCreateInfo, pPipeline);
+   case 8:
+      return gen8_compute_pipeline_create(_device, pCreateInfo, pPipeline);
+   default:
+      unreachable("unsupported gen\n");
+   }
+}
+
+VkResult anv_CreateComputePipelines(
+    VkDevice                                    _device,
+    VkPipelineCache                             pipelineCache,
+    uint32_t                                    count,
+    const VkComputePipelineCreateInfo*          pCreateInfos,
+    VkPipeline*                                 pPipelines)
+{
+   VkResult result = VK_SUCCESS;
+
+   unsigned i = 0;
+   for (; i < count; i++) {
+      result = anv_compute_pipeline_create(_device, &pCreateInfos[i],
+                                           &pPipelines[i]);
+      if (result != VK_SUCCESS) {
+         for (unsigned j = 0; j < i; j++) {
+            anv_DestroyPipeline(_device, pPipelines[j]);
+         }
+
+         return result;
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+// Pipeline layout functions
+
+VkResult anv_CreatePipelineLayout(
+    VkDevice                                    _device,
+    const VkPipelineLayoutCreateInfo*           pCreateInfo,
+    VkPipelineLayout*                           pPipelineLayout)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_pipeline_layout l, *layout;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
+
+   l.num_sets = pCreateInfo->descriptorSetCount;
+
+   unsigned dynamic_offset_count = 0;
+
+   memset(l.stage, 0, sizeof(l.stage));
+   for (uint32_t set = 0; set < pCreateInfo->descriptorSetCount; set++) {
+      ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
+                      pCreateInfo->pSetLayouts[set]);
+      l.set[set].layout = set_layout;
+
+      l.set[set].dynamic_offset_start = dynamic_offset_count;
+      for (uint32_t b = 0; b < set_layout->binding_count; b++) {
+         if (set_layout->binding[b].dynamic_offset_index >= 0)
+            dynamic_offset_count += set_layout->binding[b].array_size;
+      }
+
+      for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+         l.set[set].stage[s].surface_start = l.stage[s].surface_count;
+         l.set[set].stage[s].sampler_start = l.stage[s].sampler_count;
+
+         for (uint32_t b = 0; b < set_layout->binding_count; b++) {
+            unsigned array_size = set_layout->binding[b].array_size;
+
+            if (set_layout->binding[b].stage[s].surface_index >= 0) {
+               l.stage[s].surface_count += array_size;
+
+               if (set_layout->binding[b].dynamic_offset_index >= 0)
+                  l.stage[s].has_dynamic_offsets = true;
+            }
+
+            if (set_layout->binding[b].stage[s].sampler_index >= 0)
+               l.stage[s].sampler_count += array_size;
+         }
+      }
+   }
+
+   unsigned num_bindings = 0;
+   for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++)
+      num_bindings += l.stage[s].surface_count + l.stage[s].sampler_count;
+
+   size_t size = sizeof(*layout) + num_bindings * sizeof(layout->entries[0]);
+
+   layout = anv_device_alloc(device, size, 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (layout == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   /* Now we can actually build our surface and sampler maps */
+   struct anv_pipeline_binding *entry = layout->entries;
+   for (VkShaderStage s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+      l.stage[s].surface_to_descriptor = entry;
+      entry += l.stage[s].surface_count;
+      l.stage[s].sampler_to_descriptor = entry;
+      entry += l.stage[s].sampler_count;
+
+      int surface = 0;
+      int sampler = 0;
+      for (uint32_t set = 0; set < pCreateInfo->descriptorSetCount; set++) {
+         struct anv_descriptor_set_layout *set_layout = l.set[set].layout;
+
+         for (uint32_t b = 0; b < set_layout->binding_count; b++) {
+            unsigned array_size = set_layout->binding[b].array_size;
+            unsigned set_offset = set_layout->binding[b].descriptor_index;
+
+            if (set_layout->binding[b].stage[s].surface_index >= 0) {
+               assert(surface == l.set[set].stage[s].surface_start +
+                                 set_layout->binding[b].stage[s].surface_index);
+               for (unsigned i = 0; i < array_size; i++) {
+                  l.stage[s].surface_to_descriptor[surface + i].set = set;
+                  l.stage[s].surface_to_descriptor[surface + i].offset = set_offset + i;
+               }
+               surface += array_size;
+            }
+
+            if (set_layout->binding[b].stage[s].sampler_index >= 0) {
+               assert(sampler == l.set[set].stage[s].sampler_start +
+                                 set_layout->binding[b].stage[s].sampler_index);
+               for (unsigned i = 0; i < array_size; i++) {
+                  l.stage[s].sampler_to_descriptor[sampler + i].set = set;
+                  l.stage[s].sampler_to_descriptor[sampler + i].offset = set_offset + i;
+               }
+               sampler += array_size;
+            }
+         }
+      }
+   }
+
+   /* Finally, we're done setting it up, copy into the allocated version */
+   *layout = l;
+
+   *pPipelineLayout = anv_pipeline_layout_to_handle(layout);
+
+   return VK_SUCCESS;
+}
+
+void anv_DestroyPipelineLayout(
+    VkDevice                                    _device,
+    VkPipelineLayout                            _pipelineLayout)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_pipeline_layout, pipeline_layout, _pipelineLayout);
+
+   anv_device_free(device, pipeline_layout);
+}
diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h
new file mode 100644 (file)
index 0000000..a672839
--- /dev/null
@@ -0,0 +1,1508 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <stdio.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+#include <i915_drm.h>
+
+#ifdef HAVE_VALGRIND
+#include <valgrind.h>
+#include <memcheck.h>
+#define VG(x) x
+#define __gen_validate_value(x) VALGRIND_CHECK_MEM_IS_DEFINED(&(x), sizeof(x))
+#else
+#define VG(x)
+#endif
+
+#include "brw_device_info.h"
+#include "util/macros.h"
+#include "util/list.h"
+
+#define VK_PROTOTYPES
+#include <vulkan/vulkan.h>
+#include <vulkan/vulkan_intel.h>
+#include <vulkan/vk_ext_khr_swapchain.h>
+#include <vulkan/vk_ext_khr_device_swapchain.h>
+
+#include "anv_entrypoints.h"
+#include "brw_context.h"
+#include "isl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICD_LOADER_MAGIC   0x01CDC0DE
+
+typedef union _VK_LOADER_DATA {
+  uintptr_t loaderMagic;
+  void *loaderData;
+} VK_LOADER_DATA;
+
+#define anv_noreturn __attribute__((__noreturn__))
+#define anv_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+static inline uint32_t
+align_u32(uint32_t v, uint32_t a)
+{
+   return (v + a - 1) & ~(a - 1);
+}
+
+static inline int32_t
+align_i32(int32_t v, int32_t a)
+{
+   return (v + a - 1) & ~(a - 1);
+}
+
+/** Alignment must be a power of 2. */
+static inline bool
+anv_is_aligned(uintmax_t n, uintmax_t a)
+{
+   assert(a == (a & -a));
+   return (n & (a - 1)) == 0;
+}
+
+static inline uint32_t
+anv_minify(uint32_t n, uint32_t levels)
+{
+   if (unlikely(n == 0))
+      return 0;
+   else
+      return MAX(n >> levels, 1);
+}
+
+static inline bool
+anv_clear_mask(uint32_t *inout_mask, uint32_t clear_mask)
+{
+   if (*inout_mask & clear_mask) {
+      *inout_mask &= ~clear_mask;
+      return true;
+   } else {
+      return false;
+   }
+}
+
+#define for_each_bit(b, dword)                          \
+   for (uint32_t __dword = (dword);                     \
+        (b) = __builtin_ffs(__dword) - 1, __dword;      \
+        __dword &= ~(1 << (b)))
+
+#define typed_memcpy(dest, src, count) ({ \
+   static_assert(sizeof(*src) == sizeof(*dest), ""); \
+   memcpy((dest), (src), (count) * sizeof(*(src))); \
+})
+
+/* Define no kernel as 1, since that's an illegal offset for a kernel */
+#define NO_KERNEL 1
+
+struct anv_common {
+    VkStructureType                             sType;
+    const void*                                 pNext;
+};
+
+/* Whenever we generate an error, pass it through this function. Useful for
+ * debugging, where we can break on it. Only call at error site, not when
+ * propagating errors. Might be useful to plug in a stack trace here.
+ */
+
+VkResult __vk_errorf(VkResult error, const char *file, int line, const char *format, ...);
+
+#ifdef DEBUG
+#define vk_error(error) __vk_errorf(error, __FILE__, __LINE__, NULL);
+#define vk_errorf(error, format, ...) __vk_errorf(error, __FILE__, __LINE__, format, ## __VA_ARGS__);
+#else
+#define vk_error(error) error
+#define vk_errorf(error, format, ...) error
+#endif
+
+void __anv_finishme(const char *file, int line, const char *format, ...)
+   anv_printflike(3, 4);
+void anv_loge(const char *format, ...) anv_printflike(1, 2);
+void anv_loge_v(const char *format, va_list va);
+
+/**
+ * Print a FINISHME message, including its source location.
+ */
+#define anv_finishme(format, ...) \
+   __anv_finishme(__FILE__, __LINE__, format, ##__VA_ARGS__);
+
+/* A non-fatal assert.  Useful for debugging. */
+#ifdef DEBUG
+#define anv_assert(x) ({ \
+   if (unlikely(!(x))) \
+      fprintf(stderr, "%s:%d ASSERT: %s\n", __FILE__, __LINE__, #x); \
+})
+#else
+#define anv_assert(x)
+#endif
+
+/**
+ * If a block of code is annotated with anv_validate, then the block runs only
+ * in debug builds.
+ */
+#ifdef DEBUG
+#define anv_validate if (1)
+#else
+#define anv_validate if (0)
+#endif
+
+void anv_abortf(const char *format, ...) anv_noreturn anv_printflike(1, 2);
+void anv_abortfv(const char *format, va_list va) anv_noreturn;
+
+#define stub_return(v) \
+   do { \
+      anv_finishme("stub %s", __func__); \
+      return (v); \
+   } while (0)
+
+#define stub() \
+   do { \
+      anv_finishme("stub %s", __func__); \
+      return; \
+   } while (0)
+
+/**
+ * A dynamically growable, circular buffer.  Elements are added at head and
+ * removed from tail. head and tail are free-running uint32_t indices and we
+ * only compute the modulo with size when accessing the array.  This way,
+ * number of bytes in the queue is always head - tail, even in case of
+ * wraparound.
+ */
+
+struct anv_vector {
+   uint32_t head;
+   uint32_t tail;
+   uint32_t element_size;
+   uint32_t size;
+   void *data;
+};
+
+int anv_vector_init(struct anv_vector *queue, uint32_t element_size, uint32_t size);
+void *anv_vector_add(struct anv_vector *queue);
+void *anv_vector_remove(struct anv_vector *queue);
+
+static inline int
+anv_vector_length(struct anv_vector *queue)
+{
+   return (queue->head - queue->tail) / queue->element_size;
+}
+
+static inline void *
+anv_vector_head(struct anv_vector *vector)
+{
+   assert(vector->tail < vector->head);
+   return (void *)((char *)vector->data +
+                   ((vector->head - vector->element_size) &
+                    (vector->size - 1)));
+}
+
+static inline void *
+anv_vector_tail(struct anv_vector *vector)
+{
+   return (void *)((char *)vector->data + (vector->tail & (vector->size - 1)));
+}
+
+static inline void
+anv_vector_finish(struct anv_vector *queue)
+{
+   free(queue->data);
+}
+
+#define anv_vector_foreach(elem, queue)                                  \
+   static_assert(__builtin_types_compatible_p(__typeof__(queue), struct anv_vector *), ""); \
+   for (uint32_t __anv_vector_offset = (queue)->tail;                                \
+        elem = (queue)->data + (__anv_vector_offset & ((queue)->size - 1)), __anv_vector_offset < (queue)->head; \
+        __anv_vector_offset += (queue)->element_size)
+
+struct anv_bo {
+   int gem_handle;
+
+   /* Index into the current validation list.  This is used by the
+    * validation list building alrogithm to track which buffers are already
+    * in the validation list so that we can ensure uniqueness.
+    */
+   uint32_t index;
+
+   /* Last known offset.  This value is provided by the kernel when we
+    * execbuf and is used as the presumed offset for the next bunch of
+    * relocations.
+    */
+   uint64_t offset;
+
+   uint64_t size;
+   void *map;
+};
+
+/* Represents a lock-free linked list of "free" things.  This is used by
+ * both the block pool and the state pools.  Unfortunately, in order to
+ * solve the ABA problem, we can't use a single uint32_t head.
+ */
+union anv_free_list {
+   struct {
+      int32_t offset;
+
+      /* A simple count that is incremented every time the head changes. */
+      uint32_t count;
+   };
+   uint64_t u64;
+};
+
+#define ANV_FREE_LIST_EMPTY ((union anv_free_list) { { 1, 0 } })
+
+struct anv_block_state {
+   union {
+      struct {
+         uint32_t next;
+         uint32_t end;
+      };
+      uint64_t u64;
+   };
+};
+
+struct anv_block_pool {
+   struct anv_device *device;
+
+   struct anv_bo bo;
+
+   /* The offset from the start of the bo to the "center" of the block
+    * pool.  Pointers to allocated blocks are given by
+    * bo.map + center_bo_offset + offsets.
+    */
+   uint32_t center_bo_offset;
+
+   /* Current memory map of the block pool.  This pointer may or may not
+    * point to the actual beginning of the block pool memory.  If
+    * anv_block_pool_alloc_back has ever been called, then this pointer
+    * will point to the "center" position of the buffer and all offsets
+    * (negative or positive) given out by the block pool alloc functions
+    * will be valid relative to this pointer.
+    *
+    * In particular, map == bo.map + center_offset
+    */
+   void *map;
+   int fd;
+
+   /**
+    * Array of mmaps and gem handles owned by the block pool, reclaimed when
+    * the block pool is destroyed.
+    */
+   struct anv_vector mmap_cleanups;
+
+   uint32_t block_size;
+
+   union anv_free_list free_list;
+   struct anv_block_state state;
+
+   union anv_free_list back_free_list;
+   struct anv_block_state back_state;
+};
+
+/* Block pools are backed by a fixed-size 2GB memfd */
+#define BLOCK_POOL_MEMFD_SIZE (1ull << 32)
+
+/* The center of the block pool is also the middle of the memfd.  This may
+ * change in the future if we decide differently for some reason.
+ */
+#define BLOCK_POOL_MEMFD_CENTER (BLOCK_POOL_MEMFD_SIZE / 2)
+
+static inline uint32_t
+anv_block_pool_size(struct anv_block_pool *pool)
+{
+   return pool->state.end + pool->back_state.end;
+}
+
+struct anv_state {
+   int32_t offset;
+   uint32_t alloc_size;
+   void *map;
+};
+
+struct anv_fixed_size_state_pool {
+   size_t state_size;
+   union anv_free_list free_list;
+   struct anv_block_state block;
+};
+
+#define ANV_MIN_STATE_SIZE_LOG2 6
+#define ANV_MAX_STATE_SIZE_LOG2 10
+
+#define ANV_STATE_BUCKETS (ANV_MAX_STATE_SIZE_LOG2 - ANV_MIN_STATE_SIZE_LOG2)
+
+struct anv_state_pool {
+   struct anv_block_pool *block_pool;
+   struct anv_fixed_size_state_pool buckets[ANV_STATE_BUCKETS];
+};
+
+struct anv_state_stream {
+   struct anv_block_pool *block_pool;
+   uint32_t next;
+   uint32_t current_block;
+   uint32_t end;
+};
+
+void anv_block_pool_init(struct anv_block_pool *pool,
+                         struct anv_device *device, uint32_t block_size);
+void anv_block_pool_finish(struct anv_block_pool *pool);
+int32_t anv_block_pool_alloc(struct anv_block_pool *pool);
+int32_t anv_block_pool_alloc_back(struct anv_block_pool *pool);
+void anv_block_pool_free(struct anv_block_pool *pool, int32_t offset);
+void anv_state_pool_init(struct anv_state_pool *pool,
+                         struct anv_block_pool *block_pool);
+void anv_state_pool_finish(struct anv_state_pool *pool);
+struct anv_state anv_state_pool_alloc(struct anv_state_pool *pool,
+                                      size_t state_size, size_t alignment);
+void anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state);
+void anv_state_stream_init(struct anv_state_stream *stream,
+                           struct anv_block_pool *block_pool);
+void anv_state_stream_finish(struct anv_state_stream *stream);
+struct anv_state anv_state_stream_alloc(struct anv_state_stream *stream,
+                                        uint32_t size, uint32_t alignment);
+
+/**
+ * Implements a pool of re-usable BOs.  The interface is identical to that
+ * of block_pool except that each block is its own BO.
+ */
+struct anv_bo_pool {
+   struct anv_device *device;
+
+   uint32_t bo_size;
+
+   void *free_list;
+};
+
+void anv_bo_pool_init(struct anv_bo_pool *pool,
+                      struct anv_device *device, uint32_t block_size);
+void anv_bo_pool_finish(struct anv_bo_pool *pool);
+VkResult anv_bo_pool_alloc(struct anv_bo_pool *pool, struct anv_bo *bo);
+void anv_bo_pool_free(struct anv_bo_pool *pool, const struct anv_bo *bo);
+
+
+void *anv_resolve_entrypoint(uint32_t index);
+
+extern struct anv_dispatch_table dtable;
+
+#define ANV_CALL(func) ({ \
+   if (dtable.func == NULL) { \
+      size_t idx = offsetof(struct anv_dispatch_table, func) / sizeof(void *); \
+      dtable.entrypoints[idx] = anv_resolve_entrypoint(idx); \
+   } \
+   dtable.func; \
+})
+
+
+struct anv_physical_device {
+    VK_LOADER_DATA                              _loader_data;
+
+    struct anv_instance *                       instance;
+    uint32_t                                    chipset_id;
+    const char *                                path;
+    const char *                                name;
+    const struct brw_device_info *              info;
+    uint64_t                                    aperture_size;
+    struct brw_compiler *                       compiler;
+    struct isl_device                           isl_dev;
+};
+
+bool anv_is_scalar_shader_stage(const struct brw_compiler *compiler,
+                                VkShaderStage stage);
+
+struct anv_instance {
+    VK_LOADER_DATA                              _loader_data;
+
+    void *                                      pAllocUserData;
+    PFN_vkAllocFunction                         pfnAlloc;
+    PFN_vkFreeFunction                          pfnFree;
+    uint32_t                                    apiVersion;
+    int                                         physicalDeviceCount;
+    struct anv_physical_device                  physicalDevice;
+
+    struct anv_wsi_implementation *             wsi_impl[VK_PLATFORM_NUM_KHR];
+};
+
+VkResult anv_init_wsi(struct anv_instance *instance);
+void anv_finish_wsi(struct anv_instance *instance);
+
+struct anv_meta_state {
+   struct {
+      struct anv_pipeline *color_pipeline;
+      struct anv_pipeline *depth_only_pipeline;
+      struct anv_pipeline *stencil_only_pipeline;
+      struct anv_pipeline *depthstencil_pipeline;
+   } clear;
+
+   struct {
+      VkRenderPass render_pass;
+
+      /** Pipeline that blits from a 2D image. */
+      VkPipeline pipeline_2d_src;
+
+      /** Pipeline that blits from a 3D image. */
+      VkPipeline pipeline_3d_src;
+
+      VkPipelineLayout                          pipeline_layout;
+      VkDescriptorSetLayout                     ds_layout;
+   } blit;
+};
+
+struct anv_queue {
+    VK_LOADER_DATA                              _loader_data;
+
+    struct anv_device *                         device;
+
+    struct anv_state_pool *                     pool;
+};
+
+struct anv_device {
+    VK_LOADER_DATA                              _loader_data;
+
+    struct anv_instance *                       instance;
+    uint32_t                                    chipset_id;
+    struct brw_device_info                      info;
+    struct isl_device                           isl_dev;
+    int                                         context_id;
+    int                                         fd;
+
+    struct anv_bo_pool                          batch_bo_pool;
+
+    struct anv_block_pool                       dynamic_state_block_pool;
+    struct anv_state_pool                       dynamic_state_pool;
+
+    struct anv_block_pool                       instruction_block_pool;
+    struct anv_block_pool                       surface_state_block_pool;
+    struct anv_state_pool                       surface_state_pool;
+
+    struct anv_bo                               workaround_bo;
+
+    struct anv_meta_state                       meta_state;
+
+    struct anv_state                            border_colors;
+
+    struct anv_queue                            queue;
+
+    struct anv_block_pool                       scratch_block_pool;
+
+    pthread_mutex_t                             mutex;
+};
+
+void *
+anv_instance_alloc(struct anv_instance *        instance,
+                   size_t                       size,
+                   size_t                       alignment,
+                   VkSystemAllocType            allocType);
+
+void
+anv_instance_free(struct anv_instance *         instance,
+                  void *                        mem);
+
+void *
+anv_device_alloc(struct anv_device *            device,
+                 size_t                         size,
+                 size_t                         alignment,
+                 VkSystemAllocType              allocType);
+
+void
+anv_device_free(struct anv_device *             device,
+                void *                          mem);
+
+void* anv_gem_mmap(struct anv_device *device,
+                   uint32_t gem_handle, uint64_t offset, uint64_t size);
+void anv_gem_munmap(void *p, uint64_t size);
+uint32_t anv_gem_create(struct anv_device *device, size_t size);
+void anv_gem_close(struct anv_device *device, int gem_handle);
+int anv_gem_userptr(struct anv_device *device, void *mem, size_t size);
+int anv_gem_wait(struct anv_device *device, int gem_handle, int64_t *timeout_ns);
+int anv_gem_execbuffer(struct anv_device *device,
+                       struct drm_i915_gem_execbuffer2 *execbuf);
+int anv_gem_set_tiling(struct anv_device *device, int gem_handle,
+                       uint32_t stride, uint32_t tiling);
+int anv_gem_create_context(struct anv_device *device);
+int anv_gem_destroy_context(struct anv_device *device, int context);
+int anv_gem_get_param(int fd, uint32_t param);
+int anv_gem_get_aperture(int fd, uint64_t *size);
+int anv_gem_handle_to_fd(struct anv_device *device, int gem_handle);
+int anv_gem_fd_to_handle(struct anv_device *device, int fd);
+int anv_gem_userptr(struct anv_device *device, void *mem, size_t size);
+
+VkResult anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size);
+
+struct anv_reloc_list {
+   size_t                                       num_relocs;
+   size_t                                       array_length;
+   struct drm_i915_gem_relocation_entry *       relocs;
+   struct anv_bo **                             reloc_bos;
+};
+
+VkResult anv_reloc_list_init(struct anv_reloc_list *list,
+                             struct anv_device *device);
+void anv_reloc_list_finish(struct anv_reloc_list *list,
+                           struct anv_device *device);
+
+uint64_t anv_reloc_list_add(struct anv_reloc_list *list,
+                            struct anv_device *device,
+                            uint32_t offset, struct anv_bo *target_bo,
+                            uint32_t delta);
+
+struct anv_batch_bo {
+   /* Link in the anv_cmd_buffer.owned_batch_bos list */
+   struct list_head                             link;
+
+   struct anv_bo                                bo;
+
+   /* Bytes actually consumed in this batch BO */
+   size_t                                       length;
+
+   /* Last seen surface state block pool bo offset */
+   uint32_t                                     last_ss_pool_bo_offset;
+
+   struct anv_reloc_list                        relocs;
+};
+
+struct anv_batch {
+   struct anv_device *                          device;
+
+   void *                                       start;
+   void *                                       end;
+   void *                                       next;
+
+   struct anv_reloc_list *                      relocs;
+
+   /* This callback is called (with the associated user data) in the event
+    * that the batch runs out of space.
+    */
+   VkResult (*extend_cb)(struct anv_batch *, void *);
+   void *                                       user_data;
+};
+
+void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords);
+void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other);
+uint64_t anv_batch_emit_reloc(struct anv_batch *batch,
+                              void *location, struct anv_bo *bo, uint32_t offset);
+
+struct anv_address {
+   struct anv_bo *bo;
+   uint32_t offset;
+};
+
+#define __gen_address_type struct anv_address
+#define __gen_user_data struct anv_batch
+
+static inline uint64_t
+__gen_combine_address(struct anv_batch *batch, void *location,
+                      const struct anv_address address, uint32_t delta)
+{
+   if (address.bo == NULL) {
+      return address.offset + delta;
+   } else {
+      assert(batch->start <= location && location < batch->end);
+
+      return anv_batch_emit_reloc(batch, location, address.bo, address.offset + delta);
+   }
+}
+
+#include "gen7_pack.h"
+#include "gen75_pack.h"
+#undef GEN8_3DSTATE_MULTISAMPLE
+#include "gen8_pack.h"
+
+#define anv_batch_emit(batch, cmd, ...) do {                            \
+      void *__dst = anv_batch_emit_dwords(batch, cmd ## _length);       \
+      struct cmd __template = {                                         \
+         cmd ## _header,                                                \
+         __VA_ARGS__                                                    \
+      };                                                                \
+      cmd ## _pack(batch, __dst, &__template);                          \
+      VG(VALGRIND_CHECK_MEM_IS_DEFINED(__dst, cmd ## _length * 4));     \
+   } while (0)
+
+#define anv_batch_emitn(batch, n, cmd, ...) ({          \
+      void *__dst = anv_batch_emit_dwords(batch, n);    \
+      struct cmd __template = {                         \
+         cmd ## _header,                                \
+        .DwordLength = n - cmd ## _length_bias,         \
+         __VA_ARGS__                                    \
+      };                                                \
+      cmd ## _pack(batch, __dst, &__template);          \
+      __dst;                                            \
+   })
+
+#define anv_batch_emit_merge(batch, dwords0, dwords1)                   \
+   do {                                                                 \
+      uint32_t *dw;                                                     \
+                                                                        \
+      assert(ARRAY_SIZE(dwords0) == ARRAY_SIZE(dwords1));               \
+      dw = anv_batch_emit_dwords((batch), ARRAY_SIZE(dwords0));         \
+      for (uint32_t i = 0; i < ARRAY_SIZE(dwords0); i++)                \
+         dw[i] = (dwords0)[i] | (dwords1)[i];                           \
+      VG(VALGRIND_CHECK_MEM_IS_DEFINED(dw, ARRAY_SIZE(dwords0) * 4));\
+   } while (0)
+
+static const struct GEN7_MEMORY_OBJECT_CONTROL_STATE GEN7_MOCS = {
+   .GraphicsDataTypeGFDT                        = 0,
+   .LLCCacheabilityControlLLCCC                 = 0,
+   .L3CacheabilityControlL3CC                   = 1
+};
+
+#define GEN8_MOCS {                                     \
+      .MemoryTypeLLCeLLCCacheabilityControl = WB,       \
+      .TargetCache = L3DefertoPATforLLCeLLCselection,   \
+      .AgeforQUADLRU = 0                                \
+   }
+
+struct anv_device_memory {
+   struct anv_bo                                bo;
+   VkDeviceSize                                 map_size;
+   void *                                       map;
+};
+
+/**
+ * Header for Vertex URB Entry (VUE)
+ */
+struct anv_vue_header {
+   uint32_t Reserved;
+   uint32_t RTAIndex; /* RenderTargetArrayIndex */
+   uint32_t ViewportIndex;
+   float PointWidth;
+};
+
+struct anv_descriptor_set_binding_layout {
+   /* Number of array elements in this binding */
+   uint16_t array_size;
+
+   /* Index into the flattend descriptor set */
+   uint16_t descriptor_index;
+
+   /* Index into the dynamic state array for a dynamic buffer */
+   int16_t dynamic_offset_index;
+
+   struct {
+      /* Index into the binding table for the associated surface */
+      int16_t surface_index;
+
+      /* Index into the sampler table for the associated sampler */
+      int16_t sampler_index;
+   } stage[VK_SHADER_STAGE_NUM];
+
+   /* Immutable samplers (or NULL if no immutable samplers) */
+   struct anv_sampler **immutable_samplers;
+};
+
+struct anv_descriptor_set_layout {
+   /* Number of bindings in this descriptor set */
+   uint16_t binding_count;
+
+   /* Total size of the descriptor set with room for all array entries */
+   uint16_t size;
+
+   /* Shader stages affected by this descriptor set */
+   uint16_t shader_stages;
+
+   /* Number of dynamic offsets used by this descriptor set */
+   uint16_t dynamic_offset_count;
+
+   /* Bindings in this descriptor set */
+   struct anv_descriptor_set_binding_layout binding[0];
+};
+
+struct anv_descriptor {
+   VkDescriptorType type;
+
+   union {
+      struct {
+         union {
+            struct anv_image_view *image_view;
+         };
+         struct anv_sampler *sampler;
+      };
+
+      struct {
+         struct anv_buffer *buffer;
+         uint64_t offset;
+         uint64_t range;
+      };
+   };
+};
+
+struct anv_descriptor_set {
+   const struct anv_descriptor_set_layout *layout;
+   struct anv_descriptor descriptors[0];
+};
+
+VkResult
+anv_descriptor_set_create(struct anv_device *device,
+                          const struct anv_descriptor_set_layout *layout,
+                          struct anv_descriptor_set **out_set);
+
+void
+anv_descriptor_set_destroy(struct anv_device *device,
+                           struct anv_descriptor_set *set);
+
+#define MAX_VBS         32
+#define MAX_SETS         8
+#define MAX_RTS          8
+#define MAX_VIEWPORTS   16
+#define MAX_SCISSORS    16
+#define MAX_PUSH_CONSTANTS_SIZE 128
+#define MAX_DYNAMIC_BUFFERS 16
+#define MAX_IMAGES 8
+
+struct anv_pipeline_binding {
+   /* The descriptor set this surface corresponds to */
+   uint16_t set;
+
+   /* Offset into the descriptor set */
+   uint16_t offset;
+};
+
+struct anv_pipeline_layout {
+   struct {
+      struct anv_descriptor_set_layout *layout;
+      uint32_t dynamic_offset_start;
+      struct {
+         uint32_t surface_start;
+         uint32_t sampler_start;
+      } stage[VK_SHADER_STAGE_NUM];
+   } set[MAX_SETS];
+
+   uint32_t num_sets;
+
+   struct {
+      bool has_dynamic_offsets;
+      uint32_t surface_count;
+      struct anv_pipeline_binding *surface_to_descriptor;
+      uint32_t sampler_count;
+      struct anv_pipeline_binding *sampler_to_descriptor;
+   } stage[VK_SHADER_STAGE_NUM];
+
+   struct anv_pipeline_binding entries[0];
+};
+
+struct anv_buffer {
+   struct anv_device *                          device;
+   VkDeviceSize                                 size;
+
+   /* Set when bound */
+   struct anv_bo *                              bo;
+   VkDeviceSize                                 offset;
+};
+
+enum anv_cmd_dirty_bits {
+   ANV_CMD_DIRTY_DYNAMIC_VIEWPORT                  = 1 << 0, /* VK_DYNAMIC_STATE_VIEWPORT */
+   ANV_CMD_DIRTY_DYNAMIC_SCISSOR                   = 1 << 1, /* VK_DYNAMIC_STATE_SCISSOR */
+   ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH                = 1 << 2, /* VK_DYNAMIC_STATE_LINE_WIDTH */
+   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS                = 1 << 3, /* VK_DYNAMIC_STATE_DEPTH_BIAS */
+   ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS           = 1 << 4, /* VK_DYNAMIC_STATE_BLEND_CONSTANTS */
+   ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS              = 1 << 5, /* VK_DYNAMIC_STATE_DEPTH_BOUNDS */
+   ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK      = 1 << 6, /* VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK */
+   ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK        = 1 << 7, /* VK_DYNAMIC_STATE_STENCIL_WRITE_MASK */
+   ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE         = 1 << 8, /* VK_DYNAMIC_STATE_STENCIL_REFERENCE */
+   ANV_CMD_DIRTY_DYNAMIC_ALL                       = (1 << 9) - 1,
+   ANV_CMD_DIRTY_PIPELINE                          = 1 << 9,
+   ANV_CMD_DIRTY_INDEX_BUFFER                      = 1 << 10,
+};
+typedef uint32_t anv_cmd_dirty_mask_t;
+
+struct anv_vertex_binding {
+   struct anv_buffer *                          buffer;
+   VkDeviceSize                                 offset;
+};
+
+struct anv_push_constants {
+   /* Current allocated size of this push constants data structure.
+    * Because a decent chunk of it may not be used (images on SKL, for
+    * instance), we won't actually allocate the entire structure up-front.
+    */
+   uint32_t size;
+
+   /* Push constant data provided by the client through vkPushConstants */
+   uint8_t client_data[MAX_PUSH_CONSTANTS_SIZE];
+
+   /* Our hardware only provides zero-based vertex and instance id so, in
+    * order to satisfy the vulkan requirements, we may have to push one or
+    * both of these into the shader.
+    */
+   uint32_t base_vertex;
+   uint32_t base_instance;
+
+   /* Offsets and ranges for dynamically bound buffers */
+   struct {
+      uint32_t offset;
+      uint32_t range;
+   } dynamic[MAX_DYNAMIC_BUFFERS];
+
+   /* Image data for image_load_store on pre-SKL */
+   struct brw_image_param images[MAX_IMAGES];
+};
+
+struct anv_dynamic_state {
+   struct {
+      uint32_t                                  count;
+      VkViewport                                viewports[MAX_VIEWPORTS];
+   } viewport;
+
+   struct {
+      uint32_t                                  count;
+      VkRect2D                                  scissors[MAX_SCISSORS];
+   } scissor;
+
+   float                                        line_width;
+
+   struct {
+      float                                     bias;
+      float                                     clamp;
+      float                                     slope_scaled;
+   } depth_bias;
+
+   float                                        blend_constants[4];
+
+   struct {
+      float                                     min;
+      float                                     max;
+   } depth_bounds;
+
+   struct {
+      uint32_t                                  front;
+      uint32_t                                  back;
+   } stencil_compare_mask;
+
+   struct {
+      uint32_t                                  front;
+      uint32_t                                  back;
+   } stencil_write_mask;
+
+   struct {
+      uint32_t                                  front;
+      uint32_t                                  back;
+   } stencil_reference;
+};
+
+extern const struct anv_dynamic_state default_dynamic_state;
+
+void anv_dynamic_state_copy(struct anv_dynamic_state *dest,
+                            const struct anv_dynamic_state *src,
+                            uint32_t copy_mask);
+
+/** State required while building cmd buffer */
+struct anv_cmd_state {
+   uint32_t                                     current_pipeline;
+   uint32_t                                     vb_dirty;
+   anv_cmd_dirty_mask_t                         dirty;
+   anv_cmd_dirty_mask_t                         compute_dirty;
+   VkShaderStageFlags                           descriptors_dirty;
+   VkShaderStageFlags                           push_constants_dirty;
+   uint32_t                                     scratch_size;
+   struct anv_pipeline *                        pipeline;
+   struct anv_pipeline *                        compute_pipeline;
+   struct anv_framebuffer *                     framebuffer;
+   struct anv_render_pass *                     pass;
+   struct anv_subpass *                         subpass;
+   uint32_t                                     state_vf[GEN8_3DSTATE_VF_length];
+   struct anv_vertex_binding                    vertex_bindings[MAX_VBS];
+   struct anv_descriptor_set *                  descriptors[MAX_SETS];
+   struct anv_push_constants *                  push_constants[VK_SHADER_STAGE_NUM];
+   struct anv_dynamic_state                     dynamic;
+
+   struct {
+      struct anv_buffer *                       index_buffer;
+      uint32_t                                  index_type; /**< 3DSTATE_INDEX_BUFFER.IndexFormat */
+      uint32_t                                  index_offset;
+   } gen7;
+};
+
+struct anv_cmd_pool {
+   struct list_head                             cmd_buffers;
+};
+
+#define ANV_CMD_BUFFER_BATCH_SIZE 8192
+
+enum anv_cmd_buffer_exec_mode {
+   ANV_CMD_BUFFER_EXEC_MODE_PRIMARY,
+   ANV_CMD_BUFFER_EXEC_MODE_EMIT,
+   ANV_CMD_BUFFER_EXEC_MODE_CHAIN,
+   ANV_CMD_BUFFER_EXEC_MODE_COPY_AND_CHAIN,
+};
+
+struct anv_cmd_buffer {
+   VK_LOADER_DATA                               _loader_data;
+
+   struct anv_device *                          device;
+
+   struct list_head                             pool_link;
+
+   struct anv_batch                             batch;
+
+   /* Fields required for the actual chain of anv_batch_bo's.
+    *
+    * These fields are initialized by anv_cmd_buffer_init_batch_bo_chain().
+    */
+   struct list_head                             batch_bos;
+   enum anv_cmd_buffer_exec_mode                exec_mode;
+
+   /* A vector of anv_batch_bo pointers for every batch or surface buffer
+    * referenced by this command buffer
+    *
+    * initialized by anv_cmd_buffer_init_batch_bo_chain()
+    */
+   struct anv_vector                            seen_bbos;
+
+   /* A vector of int32_t's for every block of binding tables.
+    *
+    * initialized by anv_cmd_buffer_init_batch_bo_chain()
+    */
+   struct anv_vector                            bt_blocks;
+   uint32_t                                     bt_next;
+   struct anv_reloc_list                        surface_relocs;
+
+   /* Information needed for execbuf
+    *
+    * These fields are generated by anv_cmd_buffer_prepare_execbuf().
+    */
+   struct {
+      struct drm_i915_gem_execbuffer2           execbuf;
+
+      struct drm_i915_gem_exec_object2 *        objects;
+      uint32_t                                  bo_count;
+      struct anv_bo **                          bos;
+
+      /* Allocated length of the 'objects' and 'bos' arrays */
+      uint32_t                                  array_length;
+
+      bool                                      need_reloc;
+   } execbuf2;
+
+   /* Serial for tracking buffer completion */
+   uint32_t                                     serial;
+
+   /* Stream objects for storing temporary data */
+   struct anv_state_stream                      surface_state_stream;
+   struct anv_state_stream                      dynamic_state_stream;
+
+   VkCmdBufferOptimizeFlags                     opt_flags;
+   VkCmdBufferLevel                             level;
+
+   struct anv_cmd_state                         state;
+};
+
+VkResult anv_cmd_buffer_init_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer);
+void anv_cmd_buffer_fini_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer);
+void anv_cmd_buffer_reset_batch_bo_chain(struct anv_cmd_buffer *cmd_buffer);
+void anv_cmd_buffer_end_batch_buffer(struct anv_cmd_buffer *cmd_buffer);
+void anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
+                                  struct anv_cmd_buffer *secondary);
+void anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer);
+
+VkResult anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
+                                           unsigned stage, struct anv_state *bt_state);
+VkResult anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
+                                      unsigned stage, struct anv_state *state);
+void anv_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer);
+
+struct anv_state anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
+                                             uint32_t *a, uint32_t dwords,
+                                             uint32_t alignment);
+struct anv_state anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
+                                              uint32_t *a, uint32_t *b,
+                                              uint32_t dwords, uint32_t alignment);
+void anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                  struct anv_subpass *subpass);
+
+struct anv_address
+anv_cmd_buffer_surface_base_address(struct anv_cmd_buffer *cmd_buffer);
+struct anv_state
+anv_cmd_buffer_alloc_binding_table(struct anv_cmd_buffer *cmd_buffer,
+                                   uint32_t entries, uint32_t *state_offset);
+struct anv_state
+anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer);
+struct anv_state
+anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
+                                   uint32_t size, uint32_t alignment);
+
+VkResult
+anv_cmd_buffer_new_binding_table_block(struct anv_cmd_buffer *cmd_buffer);
+
+void anv_cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer);
+void anv_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer);
+
+void gen7_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
+void gen8_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
+
+void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
+
+void gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                   struct anv_subpass *subpass);
+
+void gen8_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                   struct anv_subpass *subpass);
+
+void anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                  struct anv_subpass *subpass);
+
+struct anv_state
+anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
+                              VkShaderStage stage);
+
+void anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
+                                      struct anv_render_pass *pass,
+                                      const VkClearValue *clear_values);
+const struct anv_image_view *
+anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer);
+
+void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
+
+struct anv_fence {
+   struct anv_bo bo;
+   struct drm_i915_gem_execbuffer2 execbuf;
+   struct drm_i915_gem_exec_object2 exec2_objects[1];
+   bool ready;
+};
+
+struct nir_shader;
+
+struct anv_shader_module {
+   struct nir_shader *                          nir;
+
+   uint32_t                                     size;
+   char                                         data[0];
+};
+
+struct anv_shader {
+   struct anv_shader_module *                   module;
+   char                                         entrypoint[0];
+};
+
+struct anv_pipeline {
+   struct anv_device *                          device;
+   struct anv_batch                             batch;
+   uint32_t                                     batch_data[512];
+   struct anv_reloc_list                        batch_relocs;
+   uint32_t                                     dynamic_state_mask;
+   struct anv_dynamic_state                     dynamic_state;
+
+   struct anv_pipeline_layout *                 layout;
+   bool                                         use_repclear;
+
+   struct brw_vs_prog_data                      vs_prog_data;
+   struct brw_wm_prog_data                      wm_prog_data;
+   struct brw_gs_prog_data                      gs_prog_data;
+   struct brw_cs_prog_data                      cs_prog_data;
+   bool                                         writes_point_size;
+   struct brw_stage_prog_data *                 prog_data[VK_SHADER_STAGE_NUM];
+   uint32_t                                     scratch_start[VK_SHADER_STAGE_NUM];
+   uint32_t                                     total_scratch;
+   struct {
+      uint32_t                                  vs_start;
+      uint32_t                                  vs_size;
+      uint32_t                                  nr_vs_entries;
+      uint32_t                                  gs_start;
+      uint32_t                                  gs_size;
+      uint32_t                                  nr_gs_entries;
+   } urb;
+
+   VkShaderStageFlags                           active_stages;
+   struct anv_state_stream                      program_stream;
+   struct anv_state                             blend_state;
+   uint32_t                                     vs_simd8;
+   uint32_t                                     vs_vec4;
+   uint32_t                                     ps_simd8;
+   uint32_t                                     ps_simd16;
+   uint32_t                                     ps_ksp0;
+   uint32_t                                     ps_ksp2;
+   uint32_t                                     ps_grf_start0;
+   uint32_t                                     ps_grf_start2;
+   uint32_t                                     gs_vec4;
+   uint32_t                                     gs_vertex_count;
+   uint32_t                                     cs_simd;
+
+   uint32_t                                     vb_used;
+   uint32_t                                     binding_stride[MAX_VBS];
+   bool                                         instancing_enable[MAX_VBS];
+   bool                                         primitive_restart;
+   uint32_t                                     topology;
+
+   uint32_t                                     cs_thread_width_max;
+   uint32_t                                     cs_right_mask;
+
+   struct {
+      uint32_t                                  sf[GEN7_3DSTATE_SF_length];
+      uint32_t                                  depth_stencil_state[GEN7_DEPTH_STENCIL_STATE_length];
+   } gen7;
+
+   struct {
+      uint32_t                                  sf[GEN8_3DSTATE_SF_length];
+      uint32_t                                  vf[GEN8_3DSTATE_VF_length];
+      uint32_t                                  raster[GEN8_3DSTATE_RASTER_length];
+      uint32_t                                  wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
+   } gen8;
+};
+
+struct anv_graphics_pipeline_create_info {
+   bool                                         use_repclear;
+   bool                                         disable_viewport;
+   bool                                         disable_scissor;
+   bool                                         disable_vs;
+   bool                                         use_rectlist;
+};
+
+VkResult
+anv_pipeline_init(struct anv_pipeline *pipeline, struct anv_device *device,
+                  const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                  const struct anv_graphics_pipeline_create_info *extra);
+
+VkResult
+anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
+                        const VkComputePipelineCreateInfo *info,
+                        struct anv_shader *shader);
+
+VkResult
+anv_graphics_pipeline_create(VkDevice device,
+                             const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                             const struct anv_graphics_pipeline_create_info *extra,
+                             VkPipeline *pPipeline);
+
+VkResult
+gen7_graphics_pipeline_create(VkDevice _device,
+                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                              const struct anv_graphics_pipeline_create_info *extra,
+                              VkPipeline *pPipeline);
+
+VkResult
+gen8_graphics_pipeline_create(VkDevice _device,
+                              const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                              const struct anv_graphics_pipeline_create_info *extra,
+                              VkPipeline *pPipeline);
+VkResult
+gen7_compute_pipeline_create(VkDevice _device,
+                             const VkComputePipelineCreateInfo *pCreateInfo,
+                             VkPipeline *pPipeline);
+
+VkResult
+gen8_compute_pipeline_create(VkDevice _device,
+                             const VkComputePipelineCreateInfo *pCreateInfo,
+                             VkPipeline *pPipeline);
+
+struct anv_format {
+   const VkFormat vk_format;
+   const char *name;
+   enum isl_format surface_format; /**< RENDER_SURFACE_STATE.SurfaceFormat */
+   const struct isl_format_layout *isl_layout;
+   uint8_t num_channels;
+   uint16_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
+   bool has_stencil;
+};
+
+/**
+ * Stencil formats are often a special case. To reduce the number of lookups
+ * into the VkFormat-to-anv_format translation table when working with
+ * stencil, here is the handle to the table's entry for VK_FORMAT_S8_UINT.
+ */
+extern const struct anv_format *const anv_format_s8_uint;
+
+const struct anv_format *
+anv_format_for_vk_format(VkFormat format);
+
+static inline bool
+anv_format_is_color(const struct anv_format *format)
+{
+   return !format->depth_format && !format->has_stencil;
+}
+
+static inline bool
+anv_format_is_depth_or_stencil(const struct anv_format *format)
+{
+   return format->depth_format || format->has_stencil;
+}
+
+struct anv_image_view_info {
+   uint8_t surface_type; /**< RENDER_SURFACE_STATE.SurfaceType */
+   bool is_array:1; /**< RENDER_SURFACE_STATE.SurfaceArray */
+   bool is_cube:1; /**< RENDER_SURFACE_STATE.CubeFaceEnable* */
+};
+
+struct anv_image_view_info
+anv_image_view_info_for_vk_image_view_type(VkImageViewType type);
+
+/**
+ * A proxy for the color surfaces, depth surfaces, and stencil surfaces.
+ */
+struct anv_surface {
+   /**
+    * Offset from VkImage's base address, as bound by vkBindImageMemory().
+    */
+   uint32_t offset;
+
+   uint32_t stride; /**< RENDER_SURFACE_STATE.SurfacePitch */
+   uint16_t qpitch; /**< RENDER_SURFACE_STATE.QPitch */
+
+   /**
+    * \name Alignment of miptree images, in units of pixels.
+    *
+    * These fields contain the real alignment values, not the values to be
+    * given to the GPU.  For example, if h_align is 4, then program the GPU
+    * with HALIGN_4.
+    * \{
+    */
+   uint8_t h_align; /**< RENDER_SURFACE_STATE.SurfaceHorizontalAlignment */
+   uint8_t v_align; /**< RENDER_SURFACE_STATE.SurfaceVerticalAlignment */
+   /** \} */
+
+   enum isl_tiling tiling;
+};
+
+struct anv_image {
+   VkImageType type;
+   const struct anv_format *format;
+   VkExtent3D extent;
+   uint32_t levels;
+   uint32_t array_size;
+   VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
+
+   VkDeviceSize size;
+   uint32_t alignment;
+
+   /* Set when bound */
+   struct anv_bo *bo;
+   VkDeviceSize offset;
+
+   uint8_t surface_type; /**< RENDER_SURFACE_STATE.SurfaceType */
+
+   bool needs_nonrt_surface_state:1;
+   bool needs_color_rt_surface_state:1;
+
+   /**
+    * Image subsurfaces
+    *
+    * For each foo, anv_image::foo_surface is valid if and only if
+    * anv_image::format has a foo aspect.
+    *
+    * The hardware requires that the depth buffer and stencil buffer be
+    * separate surfaces.  From Vulkan's perspective, though, depth and stencil
+    * reside in the same VkImage.  To satisfy both the hardware and Vulkan, we
+    * allocate the depth and stencil buffers as separate surfaces in the same
+    * bo.
+    */
+   union {
+      struct anv_surface color_surface;
+
+      struct {
+         struct anv_surface depth_surface;
+         struct anv_surface stencil_surface;
+      };
+   };
+};
+
+struct anv_image_view {
+   const struct anv_image *image; /**< VkImageViewCreateInfo::image */
+   const struct anv_format *format; /**< VkImageViewCreateInfo::format */
+   struct anv_bo *bo;
+   uint32_t offset; /**< Offset into bo. */
+   VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
+
+   /** RENDER_SURFACE_STATE when using image as a color render target. */
+   struct anv_state color_rt_surface_state;
+
+   /** RENDER_SURFACE_STATE when using image as a non render target. */
+   struct anv_state nonrt_surface_state;
+};
+
+struct anv_image_create_info {
+   const VkImageCreateInfo *vk_info;
+   bool force_tiling;
+   enum isl_tiling tiling;
+   uint32_t stride;
+};
+
+VkResult anv_image_create(VkDevice _device,
+                          const struct anv_image_create_info *info,
+                          VkImage *pImage);
+
+struct anv_surface *
+anv_image_get_surface_for_aspect_mask(struct anv_image *image,
+                                      VkImageAspectFlags aspect_mask);
+
+void anv_image_view_init(struct anv_image_view *view,
+                         struct anv_device *device,
+                         const VkImageViewCreateInfo* pCreateInfo,
+                         struct anv_cmd_buffer *cmd_buffer);
+
+void
+gen7_image_view_init(struct anv_image_view *iview,
+                     struct anv_device *device,
+                     const VkImageViewCreateInfo* pCreateInfo,
+                     struct anv_cmd_buffer *cmd_buffer);
+
+void
+gen8_image_view_init(struct anv_image_view *iview,
+                     struct anv_device *device,
+                     const VkImageViewCreateInfo* pCreateInfo,
+                     struct anv_cmd_buffer *cmd_buffer);
+
+void anv_fill_buffer_surface_state(struct anv_device *device, void *state,
+                                   const struct anv_format *format,
+                                   uint32_t offset, uint32_t range,
+                                   uint32_t stride);
+
+void gen7_fill_buffer_surface_state(void *state, const struct anv_format *format,
+                                    uint32_t offset, uint32_t range,
+                                    uint32_t stride);
+void gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
+                                    uint32_t offset, uint32_t range,
+                                    uint32_t stride);
+
+struct anv_sampler {
+   uint32_t state[4];
+};
+
+struct anv_framebuffer {
+   uint32_t                                     width;
+   uint32_t                                     height;
+   uint32_t                                     layers;
+
+   uint32_t                                     attachment_count;
+   const struct anv_image_view *           attachments[0];
+};
+
+struct anv_subpass {
+   uint32_t                                     input_count;
+   uint32_t *                                   input_attachments;
+   uint32_t                                     color_count;
+   uint32_t *                                   color_attachments;
+   uint32_t *                                   resolve_attachments;
+   uint32_t                                     depth_stencil_attachment;
+};
+
+struct anv_render_pass_attachment {
+   const struct anv_format                      *format;
+   uint32_t                                     samples;
+   VkAttachmentLoadOp                           load_op;
+   VkAttachmentLoadOp                           stencil_load_op;
+};
+
+struct anv_render_pass {
+   uint32_t                                     attachment_count;
+   uint32_t                                     subpass_count;
+   struct anv_render_pass_attachment *          attachments;
+   struct anv_subpass                           subpasses[0];
+};
+
+extern struct anv_render_pass anv_meta_dummy_renderpass;
+
+struct anv_query_pool_slot {
+   uint64_t begin;
+   uint64_t end;
+   uint64_t available;
+};
+
+struct anv_query_pool {
+   VkQueryType                                  type;
+   uint32_t                                     slots;
+   struct anv_bo                                bo;
+};
+
+void anv_device_init_meta(struct anv_device *device);
+void anv_device_finish_meta(struct anv_device *device);
+
+void *anv_lookup_entrypoint(const char *name);
+
+void anv_dump_image_to_ppm(struct anv_device *device,
+                           struct anv_image *image, unsigned miplevel,
+                           unsigned array_layer, const char *filename);
+
+#define ANV_DEFINE_HANDLE_CASTS(__anv_type, __VkType)                      \
+                                                                           \
+   static inline struct __anv_type *                                       \
+   __anv_type ## _from_handle(__VkType _handle)                            \
+   {                                                                       \
+      return (struct __anv_type *) _handle;                                \
+   }                                                                       \
+                                                                           \
+   static inline __VkType                                                  \
+   __anv_type ## _to_handle(struct __anv_type *_obj)                       \
+   {                                                                       \
+      return (__VkType) _obj;                                              \
+   }
+
+#define ANV_DEFINE_NONDISP_HANDLE_CASTS(__anv_type, __VkType)              \
+                                                                           \
+   static inline struct __anv_type *                                       \
+   __anv_type ## _from_handle(__VkType _handle)                            \
+   {                                                                       \
+      return (struct __anv_type *) _handle.handle;                         \
+   }                                                                       \
+                                                                           \
+   static inline __VkType                                                  \
+   __anv_type ## _to_handle(struct __anv_type *_obj)                       \
+   {                                                                       \
+      return (__VkType) { .handle = (uint64_t) _obj };                     \
+   }
+
+#define ANV_FROM_HANDLE(__anv_type, __name, __handle) \
+   struct __anv_type *__name = __anv_type ## _from_handle(__handle)
+
+ANV_DEFINE_HANDLE_CASTS(anv_cmd_buffer, VkCmdBuffer)
+ANV_DEFINE_HANDLE_CASTS(anv_device, VkDevice)
+ANV_DEFINE_HANDLE_CASTS(anv_instance, VkInstance)
+ANV_DEFINE_HANDLE_CASTS(anv_physical_device, VkPhysicalDevice)
+ANV_DEFINE_HANDLE_CASTS(anv_queue, VkQueue)
+
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_cmd_pool, VkCmdPool)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer, VkBuffer)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set, VkDescriptorSet)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_descriptor_set_layout, VkDescriptorSetLayout)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_device_memory, VkDeviceMemory)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_fence, VkFence)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_framebuffer, VkFramebuffer)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_image, VkImage)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_image_view, VkImageView);
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline, VkPipeline)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_pipeline_layout, VkPipelineLayout)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_query_pool, VkQueryPool)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_render_pass, VkRenderPass)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_sampler, VkSampler)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader, VkShader)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_shader_module, VkShaderModule)
+
+#define ANV_DEFINE_STRUCT_CASTS(__anv_type, __VkType) \
+   \
+   static inline const __VkType * \
+   __anv_type ## _to_ ## __VkType(const struct __anv_type *__anv_obj) \
+   { \
+      return (const __VkType *) __anv_obj; \
+   }
+
+#define ANV_COMMON_TO_STRUCT(__VkType, __vk_name, __common_name) \
+   const __VkType *__vk_name = anv_common_to_ ## __VkType(__common_name)
+
+ANV_DEFINE_STRUCT_CASTS(anv_common, VkMemoryBarrier)
+ANV_DEFINE_STRUCT_CASTS(anv_common, VkBufferMemoryBarrier)
+ANV_DEFINE_STRUCT_CASTS(anv_common, VkImageMemoryBarrier)
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/vulkan/anv_query.c b/src/vulkan/anv_query.c
new file mode 100644 (file)
index 0000000..68535b4
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+VkResult anv_CreateQueryPool(
+    VkDevice                                    _device,
+    const VkQueryPoolCreateInfo*                pCreateInfo,
+    VkQueryPool*                                pQueryPool)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_query_pool *pool;
+   VkResult result;
+   size_t size;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO);
+
+   switch (pCreateInfo->queryType) {
+   case VK_QUERY_TYPE_OCCLUSION:
+      break;
+   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
+      return VK_UNSUPPORTED;
+   default:
+      unreachable("");
+   }
+
+   pool = anv_device_alloc(device, sizeof(*pool), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pool == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   size = pCreateInfo->slots * sizeof(struct anv_query_pool_slot);
+   result = anv_bo_init_new(&pool->bo, device, size);
+   if (result != VK_SUCCESS)
+      goto fail;
+
+   pool->bo.map = anv_gem_mmap(device, pool->bo.gem_handle, 0, size);
+
+   *pQueryPool = anv_query_pool_to_handle(pool);
+
+   return VK_SUCCESS;
+
+ fail:
+   anv_device_free(device, pool);
+
+   return result;
+}
+
+void anv_DestroyQueryPool(
+    VkDevice                                    _device,
+    VkQueryPool                                 _pool)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_query_pool, pool, _pool);
+
+   anv_gem_munmap(pool->bo.map, pool->bo.size);
+   anv_gem_close(device, pool->bo.gem_handle);
+   anv_device_free(device, pool);
+}
+
+VkResult anv_GetQueryPoolResults(
+    VkDevice                                    _device,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount,
+    size_t*                                     pDataSize,
+    void*                                       pData,
+    VkQueryResultFlags                          flags)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+   struct anv_query_pool_slot *slot = pool->bo.map;
+   int64_t timeout = INT64_MAX;
+   uint32_t *dst32 = pData;
+   uint64_t *dst64 = pData;
+   uint64_t result;
+   int ret;
+
+   if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
+      /* Where is the availabilty info supposed to go? */
+      anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
+      return VK_UNSUPPORTED;
+   }
+
+   assert(pool->type == VK_QUERY_TYPE_OCCLUSION);
+
+   if (flags & VK_QUERY_RESULT_64_BIT)
+      *pDataSize = queryCount * sizeof(uint64_t);
+   else
+      *pDataSize = queryCount * sizeof(uint32_t);
+
+   if (pData == NULL)
+      return VK_SUCCESS;
+
+   if (flags & VK_QUERY_RESULT_WAIT_BIT) {
+      ret = anv_gem_wait(device, pool->bo.gem_handle, &timeout);
+      if (ret == -1) {
+         /* We don't know the real error. */
+         return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                          "gem_wait failed %m");
+      }
+   }
+
+   for (uint32_t i = 0; i < queryCount; i++) {
+      result = slot[startQuery + i].end - slot[startQuery + i].begin;
+      if (flags & VK_QUERY_RESULT_64_BIT) {
+         *dst64++ = result;
+      } else {
+         if (result > UINT32_MAX)
+            result = UINT32_MAX;
+         *dst32++ = result;
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+void anv_CmdResetQueryPool(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount)
+{
+   stub();
+}
diff --git a/src/vulkan/anv_util.c b/src/vulkan/anv_util.c
new file mode 100644 (file)
index 0000000..22fd01c
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "anv_private.h"
+
+/** Log an error message.  */
+void anv_printflike(1, 2)
+anv_loge(const char *format, ...)
+{
+   va_list va;
+
+   va_start(va, format);
+   anv_loge_v(format, va);
+   va_end(va);
+}
+
+/** \see anv_loge() */
+void
+anv_loge_v(const char *format, va_list va)
+{
+   fprintf(stderr, "vk: error: ");
+   vfprintf(stderr, format, va);
+   fprintf(stderr, "\n");
+}
+
+void anv_printflike(3, 4)
+__anv_finishme(const char *file, int line, const char *format, ...)
+{
+   va_list ap;
+   char buffer[256];
+
+   va_start(ap, format);
+   vsnprintf(buffer, sizeof(buffer), format, ap);
+   va_end(ap);
+
+   fprintf(stderr, "%s:%d: FINISHME: %s\n", file, line, buffer);
+}
+
+void anv_noreturn anv_printflike(1, 2)
+anv_abortf(const char *format, ...)
+{
+   va_list va;
+
+   va_start(va, format);
+   anv_abortfv(format, va);
+   va_end(va);
+}
+
+void anv_noreturn
+anv_abortfv(const char *format, va_list va)
+{
+   fprintf(stderr, "vk: error: ");
+   vfprintf(stderr, format, va);
+   fprintf(stderr, "\n");
+   abort();
+}
+
+VkResult
+__vk_errorf(VkResult error, const char *file, int line, const char *format, ...)
+{
+   va_list ap;
+   char buffer[256];
+
+#define ERROR_CASE(error) case error: error_str = #error; break;
+
+   const char *error_str;
+   switch ((int32_t)error) {
+
+   /* Core errors */
+   ERROR_CASE(VK_ERROR_OUT_OF_HOST_MEMORY)
+   ERROR_CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY)
+   ERROR_CASE(VK_ERROR_INITIALIZATION_FAILED)
+   ERROR_CASE(VK_ERROR_DEVICE_LOST)
+   ERROR_CASE(VK_ERROR_MEMORY_MAP_FAILED)
+   ERROR_CASE(VK_ERROR_LAYER_NOT_PRESENT)
+   ERROR_CASE(VK_ERROR_EXTENSION_NOT_PRESENT)
+   ERROR_CASE(VK_ERROR_INCOMPATIBLE_DRIVER)
+
+   /* Extension errors */
+   ERROR_CASE(VK_ERROR_OUT_OF_DATE_KHR)
+
+   default:
+      assert(!"Unknown error");
+      error_str = "unknown error";
+   }
+
+#undef ERROR_CASE
+
+   if (format) {
+      va_start(ap, format);
+      vsnprintf(buffer, sizeof(buffer), format, ap);
+      va_end(ap);
+
+      fprintf(stderr, "%s:%d: %s (%s)\n", file, line, buffer, error_str);
+   } else {
+      fprintf(stderr, "%s:%d: %s\n", file, line, error_str);
+   }
+
+   return error;
+}
+
+int
+anv_vector_init(struct anv_vector *vector, uint32_t element_size, uint32_t size)
+{
+   assert(util_is_power_of_two(size));
+   assert(element_size < size && util_is_power_of_two(element_size));
+
+   vector->head = 0;
+   vector->tail = 0;
+   vector->element_size = element_size;
+   vector->size = size;
+   vector->data = malloc(size);
+
+   return vector->data != NULL;
+}
+
+void *
+anv_vector_add(struct anv_vector *vector)
+{
+   uint32_t offset, size, split, tail;
+   void *data;
+
+   if (vector->head - vector->tail == vector->size) {
+      size = vector->size * 2;
+      data = malloc(size);
+      if (data == NULL)
+         return NULL;
+      split = align_u32(vector->tail, vector->size);
+      tail = vector->tail & (vector->size - 1);
+      if (vector->head - split < vector->size) {
+         memcpy(data + tail,
+                vector->data + tail,
+                split - vector->tail);
+         memcpy(data + vector->size,
+                vector->data, vector->head - split);
+      } else {
+         memcpy(data + tail,
+                vector->data + tail,
+                vector->head - vector->tail);
+      }
+      free(vector->data);
+      vector->data = data;
+      vector->size = size;
+   }
+
+   assert(vector->head - vector->tail < vector->size);
+
+   offset = vector->head & (vector->size - 1);
+   vector->head += vector->element_size;
+
+   return vector->data + offset;
+}
+
+void *
+anv_vector_remove(struct anv_vector *vector)
+{
+   uint32_t offset;
+
+   if (vector->head == vector->tail)
+      return NULL;
+
+   assert(vector->head - vector->tail <= vector->size);
+
+   offset = vector->tail & (vector->size - 1);
+   vector->tail += vector->element_size;
+
+   return vector->data + offset;
+}
diff --git a/src/vulkan/anv_wsi.c b/src/vulkan/anv_wsi.c
new file mode 100644 (file)
index 0000000..f5c2d37
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_wsi.h"
+
+VkResult
+anv_init_wsi(struct anv_instance *instance)
+{
+   VkResult result;
+
+   memset(instance->wsi_impl, 0, sizeof(instance->wsi_impl));
+
+   result = anv_x11_init_wsi(instance);
+   if (result != VK_SUCCESS)
+      return result;
+
+#ifdef HAVE_WAYLAND_PLATFORM
+   result = anv_wl_init_wsi(instance);
+   if (result != VK_SUCCESS) {
+      anv_x11_finish_wsi(instance);
+      return result;
+   }
+#endif
+
+   return VK_SUCCESS;
+}
+
+void
+anv_finish_wsi(struct anv_instance *instance)
+{
+#ifdef HAVE_WAYLAND_PLATFORM
+   anv_wl_finish_wsi(instance);
+#endif
+   anv_x11_finish_wsi(instance);
+}
+
+VkResult
+anv_GetPhysicalDeviceSurfaceSupportKHR(
+    VkPhysicalDevice                        physicalDevice,
+    uint32_t                                queueFamilyIndex,
+    const VkSurfaceDescriptionKHR*          pSurfaceDescription,
+    VkBool32*                               pSupported)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+
+   assert(pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+
+   VkSurfaceDescriptionWindowKHR *window = (void *)pSurfaceDescription;
+
+   struct anv_wsi_implementation *impl =
+      physical_device->instance->wsi_impl[window->platform];
+
+   if (impl) {
+      return impl->get_window_supported(impl, physical_device,
+                                        window, pSupported);
+   } else {
+      *pSupported = false;
+      return VK_SUCCESS;
+   }
+}
+
+VkResult
+anv_GetSurfacePropertiesKHR(
+    VkDevice                                 _device,
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
+    VkSurfacePropertiesKHR*                  pSurfaceProperties)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   assert(pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+   VkSurfaceDescriptionWindowKHR *window =
+      (VkSurfaceDescriptionWindowKHR *)pSurfaceDescription;
+
+   struct anv_wsi_implementation *impl =
+      device->instance->wsi_impl[window->platform];
+
+   assert(impl);
+
+   return impl->get_surface_properties(impl, device, window,
+                                       pSurfaceProperties);
+}
+
+VkResult
+anv_GetSurfaceFormatsKHR(
+    VkDevice                                 _device,
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
+    uint32_t*                                pCount,
+    VkSurfaceFormatKHR*                      pSurfaceFormats)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   assert(pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+   VkSurfaceDescriptionWindowKHR *window =
+      (VkSurfaceDescriptionWindowKHR *)pSurfaceDescription;
+
+   struct anv_wsi_implementation *impl =
+      device->instance->wsi_impl[window->platform];
+
+   assert(impl);
+
+   return impl->get_surface_formats(impl, device, window,
+                                    pCount, pSurfaceFormats);
+}
+
+VkResult
+anv_GetSurfacePresentModesKHR(
+    VkDevice                                 _device,
+    const VkSurfaceDescriptionKHR*           pSurfaceDescription,
+    uint32_t*                                pCount,
+    VkPresentModeKHR*                        pPresentModes)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   assert(pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+   VkSurfaceDescriptionWindowKHR *window =
+      (VkSurfaceDescriptionWindowKHR *)pSurfaceDescription;
+
+   struct anv_wsi_implementation *impl =
+      device->instance->wsi_impl[window->platform];
+
+   assert(impl);
+
+   return impl->get_surface_present_modes(impl, device, window,
+                                          pCount, pPresentModes);
+}
+
+
+VkResult
+anv_CreateSwapchainKHR(
+    VkDevice                                 _device,
+    const VkSwapchainCreateInfoKHR*          pCreateInfo,
+    VkSwapchainKHR*                          pSwapchain)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_swapchain *swapchain;
+   VkResult result;
+
+   assert(pCreateInfo->pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+   VkSurfaceDescriptionWindowKHR *window =
+      (VkSurfaceDescriptionWindowKHR *)pCreateInfo->pSurfaceDescription;
+
+   struct anv_wsi_implementation *impl =
+      device->instance->wsi_impl[window->platform];
+
+   assert(impl);
+
+   result = impl->create_swapchain(impl, device, pCreateInfo, &swapchain);
+
+   if (result == VK_SUCCESS)
+      *pSwapchain = anv_swapchain_to_handle(swapchain);
+
+   return result;
+}
+
+VkResult
+anv_DestroySwapchainKHR(
+    VkDevice                                 device,
+    VkSwapchainKHR                           swapChain)
+{
+   ANV_FROM_HANDLE(anv_swapchain, swapchain, swapChain);
+
+   assert(swapchain->device == anv_device_from_handle(device));
+
+   return swapchain->destroy(swapchain);
+}
+
+VkResult
+anv_GetSwapchainImagesKHR(
+    VkDevice                                 device,
+    VkSwapchainKHR                           _swapchain,
+    uint32_t*                                pCount,
+    VkImage*                                 pSwapchainImages)
+{
+   ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
+
+   assert(swapchain->device == anv_device_from_handle(device));
+
+   return swapchain->get_images(swapchain, pCount, pSwapchainImages);
+}
+
+VkResult
+anv_AcquireNextImageKHR(
+    VkDevice                                 device,
+    VkSwapchainKHR                           _swapchain,
+    uint64_t                                 timeout,
+    VkSemaphore                              semaphore,
+    uint32_t*                                pImageIndex)
+{
+   ANV_FROM_HANDLE(anv_swapchain, swapchain, _swapchain);
+
+   assert(swapchain->device == anv_device_from_handle(device));
+
+   return swapchain->acquire_next_image(swapchain,
+                                        timeout, semaphore, pImageIndex);
+}
+
+VkResult
+anv_QueuePresentKHR(
+    VkQueue                                  _queue,
+    VkPresentInfoKHR*                        pPresentInfo)
+{
+   ANV_FROM_HANDLE(anv_queue, queue, _queue);
+   VkResult result;
+
+   for (uint32_t i = 0; i < pPresentInfo->swapchainCount; i++) {
+      ANV_FROM_HANDLE(anv_swapchain, swapchain, pPresentInfo->swapchains[i]);
+
+      assert(swapchain->device == queue->device);
+
+      result = swapchain->queue_present(swapchain, queue,
+                                        pPresentInfo->imageIndices[i]);
+      /* TODO: What if one of them returns OUT_OF_DATE? */
+      if (result != VK_SUCCESS)
+         return result;
+   }
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/anv_wsi.h b/src/vulkan/anv_wsi.h
new file mode 100644 (file)
index 0000000..280049b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 "anv_private.h"
+
+struct anv_swapchain {
+   struct anv_device *                          device;
+
+   VkResult (*destroy)(struct anv_swapchain *swapchain);
+   VkResult (*get_images)(struct anv_swapchain *swapchain,
+                          uint32_t *pCount, VkImage *pSwapchainImages);
+   VkResult (*acquire_next_image)(struct anv_swapchain *swap_chain,
+                                  uint64_t timeout, VkSemaphore semaphore,
+                                  uint32_t *image_index);
+   VkResult (*queue_present)(struct anv_swapchain *swap_chain,
+                             struct anv_queue *queue,
+                             uint32_t image_index);
+};
+
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_swapchain, VkSwapchainKHR)
+
+struct anv_wsi_implementation {
+   VkResult (*get_window_supported)(struct anv_wsi_implementation *impl,
+                                    struct anv_physical_device *physical_device,
+                                    const VkSurfaceDescriptionWindowKHR *window,
+                                    VkBool32 *pSupported);
+   VkResult (*get_surface_properties)(struct anv_wsi_implementation *impl,
+                                      struct anv_device *device,
+                                      const VkSurfaceDescriptionWindowKHR *window,
+                                      VkSurfacePropertiesKHR *properties);
+   VkResult (*get_surface_formats)(struct anv_wsi_implementation *impl,
+                                   struct anv_device *device,
+                                   const VkSurfaceDescriptionWindowKHR *window,
+                                   uint32_t *pCount,
+                                   VkSurfaceFormatKHR *pSurfaceFormats);
+   VkResult (*get_surface_present_modes)(struct anv_wsi_implementation *impl,
+                                         struct anv_device *device,
+                                         const VkSurfaceDescriptionWindowKHR *window,
+                                         uint32_t *pCount,
+                                         VkPresentModeKHR *pPresentModes);
+   VkResult (*create_swapchain)(struct anv_wsi_implementation *impl,
+                                struct anv_device *device,
+                                const VkSwapchainCreateInfoKHR *pCreateInfo,
+                                struct anv_swapchain **swapchain);
+};
+
+VkResult anv_x11_init_wsi(struct anv_instance *instance);
+void anv_x11_finish_wsi(struct anv_instance *instance);
+VkResult anv_wl_init_wsi(struct anv_instance *instance);
+void anv_wl_finish_wsi(struct anv_instance *instance);
diff --git a/src/vulkan/anv_wsi_wayland.c b/src/vulkan/anv_wsi_wayland.c
new file mode 100644 (file)
index 0000000..f32fda2
--- /dev/null
@@ -0,0 +1,803 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <wayland-client.h>
+#include <wayland-drm-client-protocol.h>
+
+#include "anv_wsi.h"
+
+#include <util/hash_table.h>
+
+#define MIN_NUM_IMAGES 2
+
+struct wsi_wl_display {
+   struct wl_display *                          display;
+   struct wl_drm *                              drm;
+
+   /* Vector of VkFormats supported */
+   struct anv_vector                            formats;
+
+   uint32_t                                     capabilities;
+};
+
+struct wsi_wayland {
+   struct anv_wsi_implementation                base;
+
+   struct anv_instance *                        instance;
+
+    pthread_mutex_t                             mutex;
+    /* Hash table of wl_display -> wsi_wl_display mappings */
+    struct hash_table *                         displays;
+};
+
+static void
+wsi_wl_display_add_vk_format(struct wsi_wl_display *display, VkFormat format)
+{
+   /* Don't add a format that's already in the list */
+   VkFormat *f;
+   anv_vector_foreach(f, &display->formats)
+      if (*f == format)
+         return;
+
+   /* Don't add formats which aren't supported by the driver */
+   if (anv_format_for_vk_format(format)->surface_format ==
+       ISL_FORMAT_UNSUPPORTED) {
+      return;
+   }
+
+   f = anv_vector_add(&display->formats);
+   if (f)
+      *f = format;
+}
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *name)
+{
+   fprintf(stderr, "wl_drm.device(%s)\n", name);
+}
+
+static uint32_t
+wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha)
+{
+   switch (vk_format) {
+   case VK_FORMAT_R4G4B4A4_UNORM:
+      return alpha ? WL_DRM_FORMAT_ABGR4444 : WL_DRM_FORMAT_XBGR4444;
+   case VK_FORMAT_R5G6B5_UNORM:
+      return WL_DRM_FORMAT_BGR565;
+   case VK_FORMAT_R5G5B5A1_UNORM:
+      return alpha ? WL_DRM_FORMAT_ABGR1555 : WL_DRM_FORMAT_XBGR1555;
+   case VK_FORMAT_R8G8B8_UNORM:
+      return WL_DRM_FORMAT_XBGR8888;
+   case VK_FORMAT_R8G8B8A8_UNORM:
+      return alpha ? WL_DRM_FORMAT_ABGR8888 : WL_DRM_FORMAT_XBGR8888;
+   case VK_FORMAT_R10G10B10A2_UNORM:
+      return alpha ? WL_DRM_FORMAT_ABGR2101010 : WL_DRM_FORMAT_XBGR2101010;
+   case VK_FORMAT_B4G4R4A4_UNORM:
+      return alpha ? WL_DRM_FORMAT_ARGB4444 : WL_DRM_FORMAT_XRGB4444;
+   case VK_FORMAT_B5G6R5_UNORM:
+      return WL_DRM_FORMAT_RGB565;
+   case VK_FORMAT_B5G5R5A1_UNORM:
+      return alpha ? WL_DRM_FORMAT_XRGB1555 : WL_DRM_FORMAT_XRGB1555;
+   case VK_FORMAT_B8G8R8_UNORM:
+      return WL_DRM_FORMAT_BGRX8888;
+   case VK_FORMAT_B8G8R8A8_UNORM:
+      return alpha ? WL_DRM_FORMAT_ARGB8888 : WL_DRM_FORMAT_XRGB8888;
+   case VK_FORMAT_B10G10R10A2_UNORM:
+      return alpha ? WL_DRM_FORMAT_ARGB2101010 : WL_DRM_FORMAT_XRGB2101010;
+
+   default:
+      assert("!Unsupported Vulkan format");
+      return 0;
+   }
+}
+
+static void
+drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format)
+{
+   struct wsi_wl_display *display = data;
+
+   switch (wl_format) {
+   case WL_DRM_FORMAT_ABGR4444:
+   case WL_DRM_FORMAT_XBGR4444:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_R4G4B4A4_UNORM);
+      break;
+   case WL_DRM_FORMAT_BGR565:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_R5G6B5_UNORM);
+      break;
+   case WL_DRM_FORMAT_ABGR1555:
+   case WL_DRM_FORMAT_XBGR1555:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_R5G5B5A1_UNORM);
+      break;
+   case WL_DRM_FORMAT_XBGR8888:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_R8G8B8_UNORM);
+      /* fallthrough */
+   case WL_DRM_FORMAT_ABGR8888:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_R8G8B8A8_UNORM);
+      break;
+   case WL_DRM_FORMAT_ABGR2101010:
+   case WL_DRM_FORMAT_XBGR2101010:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_R10G10B10A2_UNORM);
+      break;
+   case WL_DRM_FORMAT_ARGB4444:
+   case WL_DRM_FORMAT_XRGB4444:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_B4G4R4A4_UNORM);
+      break;
+   case WL_DRM_FORMAT_RGB565:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_B5G6R5_UNORM);
+      break;
+   case WL_DRM_FORMAT_ARGB1555:
+   case WL_DRM_FORMAT_XRGB1555:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_B5G5R5A1_UNORM);
+      break;
+   case WL_DRM_FORMAT_XRGB8888:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_B8G8R8_UNORM);
+      /* fallthrough */
+   case WL_DRM_FORMAT_ARGB8888:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_B8G8R8A8_UNORM);
+      break;
+   case WL_DRM_FORMAT_ARGB2101010:
+   case WL_DRM_FORMAT_XRGB2101010:
+      wsi_wl_display_add_vk_format(display, VK_FORMAT_B10G10R10A2_UNORM);
+      break;
+   }
+}
+
+static void
+drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+}
+
+static void
+drm_handle_capabilities(void *data, struct wl_drm *drm, uint32_t capabilities)
+{
+   struct wsi_wl_display *display = data;
+
+   display->capabilities = capabilities;
+}
+
+static const struct wl_drm_listener drm_listener = {
+   drm_handle_device,
+   drm_handle_format,
+   drm_handle_authenticated,
+   drm_handle_capabilities,
+};
+
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+                       uint32_t name, const char *interface, uint32_t version)
+{
+   struct wsi_wl_display *display = data;
+
+   if (strcmp(interface, "wl_drm") == 0) {
+      assert(display->drm == NULL);
+
+      assert(version >= 2);
+      display->drm = wl_registry_bind(registry, name, &wl_drm_interface, 2);
+
+      if (display->drm)
+         wl_drm_add_listener(display->drm, &drm_listener, display);
+   }
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+                              uint32_t name)
+{ /* No-op */ }
+
+static const struct wl_registry_listener registry_listener = {
+   registry_handle_global,
+   registry_handle_global_remove
+};
+
+static void
+wsi_wl_display_destroy(struct wsi_wayland *wsi, struct wsi_wl_display *display)
+{
+   anv_vector_finish(&display->formats);
+   if (display->drm)
+      wl_drm_destroy(display->drm);
+   anv_instance_free(wsi->instance, display);
+}
+
+static struct wsi_wl_display *
+wsi_wl_display_create(struct wsi_wayland *wsi, struct wl_display *wl_display)
+{
+   struct wsi_wl_display *display =
+      anv_instance_alloc(wsi->instance, sizeof(*display), 8,
+                         VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (!display)
+      return NULL;
+
+   memset(display, 0, sizeof(*display));
+
+   display->display = wl_display;
+
+   if (!anv_vector_init(&display->formats, sizeof(VkFormat), 8))
+      goto fail;
+
+   struct wl_registry *registry = wl_display_get_registry(wl_display);
+   if (!registry)
+      return NULL;
+
+   wl_registry_add_listener(registry, &registry_listener, display);
+
+   /* Round-rip to get the wl_drm global */
+   wl_display_roundtrip(wl_display);
+
+   if (!display->drm)
+      goto fail;
+
+   /* Round-rip to get wl_drm formats and capabilities */
+   wl_display_roundtrip(wl_display);
+
+   /* We need prime support */
+   if (!(display->capabilities & WL_DRM_CAPABILITY_PRIME))
+      goto fail;
+
+   /* We don't need this anymore */
+   wl_registry_destroy(registry);
+
+   return display;
+
+fail:
+   if (registry)
+      wl_registry_destroy(registry);
+
+   wsi_wl_display_destroy(wsi, display);
+   return NULL;
+}
+
+static struct wsi_wl_display *
+wsi_wl_get_display(struct wsi_wayland *wsi, struct wl_display *wl_display)
+{
+   pthread_mutex_lock(&wsi->mutex);
+
+   struct hash_entry *entry = _mesa_hash_table_search(wsi->displays,
+                                                      wl_display);
+   if (!entry) {
+      /* We're about to make a bunch of blocking calls.  Let's drop the
+       * mutex for now so we don't block up too badly.
+       */
+      pthread_mutex_unlock(&wsi->mutex);
+
+      struct wsi_wl_display *display = wsi_wl_display_create(wsi, wl_display);
+
+      pthread_mutex_lock(&wsi->mutex);
+
+      entry = _mesa_hash_table_search(wsi->displays, wl_display);
+      if (entry) {
+         /* Oops, someone raced us to it */
+         wsi_wl_display_destroy(wsi, display);
+      } else {
+         entry = _mesa_hash_table_insert(wsi->displays, wl_display, display);
+      }
+   }
+
+   pthread_mutex_unlock(&wsi->mutex);
+
+   return entry->data;
+}
+
+static VkResult
+wsi_wl_get_window_supported(struct anv_wsi_implementation *impl,
+                            struct anv_physical_device *physical_device,
+                            const VkSurfaceDescriptionWindowKHR *window,
+                            VkBool32 *pSupported)
+{
+   struct wsi_wayland *wsi = (struct wsi_wayland *)impl;
+
+   *pSupported = wsi_wl_get_display(wsi, window->pPlatformHandle) != NULL;
+
+   return VK_SUCCESS;
+}
+
+static const VkPresentModeKHR present_modes[] = {
+   VK_PRESENT_MODE_MAILBOX_KHR,
+   VK_PRESENT_MODE_FIFO_KHR,
+};
+
+static VkResult
+wsi_wl_get_surface_properties(struct anv_wsi_implementation *impl,
+                              struct anv_device *device,
+                              const VkSurfaceDescriptionWindowKHR *window,
+                              VkSurfacePropertiesKHR *props)
+{
+   props->minImageCount = MIN_NUM_IMAGES;
+   props->maxImageCount = 4;
+   props->currentExtent = (VkExtent2D) { -1, -1 };
+   props->minImageExtent = (VkExtent2D) { 1, 1 };
+   props->maxImageExtent = (VkExtent2D) { INT16_MAX, INT16_MAX };
+   props->supportedTransforms = VK_SURFACE_TRANSFORM_NONE_BIT_KHR;
+   props->currentTransform = VK_SURFACE_TRANSFORM_NONE_KHR;
+   props->maxImageArraySize = 1;
+   props->supportedUsageFlags =
+      VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT |
+      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+wsi_wl_get_surface_formats(struct anv_wsi_implementation *impl,
+                           struct anv_device *device,
+                           const VkSurfaceDescriptionWindowKHR *window,
+                           uint32_t *pCount,
+                           VkSurfaceFormatKHR *pSurfaceFormats)
+{
+   struct wsi_wayland *wsi = (struct wsi_wayland *)impl;
+   struct wsi_wl_display *display =
+      wsi_wl_get_display(wsi, window->pPlatformHandle);
+
+   uint32_t count = anv_vector_length(&display->formats);
+
+   if (pSurfaceFormats == NULL) {
+      *pCount = count;
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= count);
+   *pCount = count;
+
+   VkFormat *f;
+   anv_vector_foreach(f, &display->formats) {
+      *(pSurfaceFormats++) = (VkSurfaceFormatKHR) {
+         .format = *f,
+         /* TODO: We should get this from the compositor somehow */
+         .colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR,
+      };
+   }
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+wsi_wl_get_surface_present_modes(struct anv_wsi_implementation *impl,
+                                 struct anv_device *device,
+                                 const VkSurfaceDescriptionWindowKHR *window,
+                                 uint32_t *pCount,
+                                 VkPresentModeKHR *pPresentModes)
+{
+   if (pPresentModes == NULL) {
+      *pCount = ARRAY_SIZE(present_modes);
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= ARRAY_SIZE(present_modes));
+   typed_memcpy(pPresentModes, present_modes, *pCount);
+   *pCount = ARRAY_SIZE(present_modes);
+
+   return VK_SUCCESS;
+}
+
+struct wsi_wl_image {
+   struct anv_image *                           image;
+   struct anv_device_memory *                   memory;
+   struct wl_buffer *                           buffer;
+   bool                                         busy;
+};
+
+struct wsi_wl_swapchain {
+   struct anv_swapchain                        base;
+
+   struct wsi_wl_display *                      display;
+   struct wl_event_queue *                      queue;
+   struct wl_surface *                          surface;
+
+   VkExtent2D                                   extent;
+   VkFormat                                     vk_format;
+   uint32_t                                     drm_format;
+
+   VkPresentModeKHR                             present_mode;
+   bool                                         fifo_ready;
+
+   uint32_t                                     image_count;
+   struct wsi_wl_image                          images[0];
+};
+
+static VkResult
+wsi_wl_get_images(struct anv_swapchain *anv_chain,
+                  uint32_t *pCount, VkImage *pSwapchainImages)
+{
+   struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)anv_chain;
+
+   if (pSwapchainImages == NULL) {
+      *pCount = chain->image_count;
+      return VK_SUCCESS;
+   }
+
+   assert(chain->image_count <= *pCount);
+   for (uint32_t i = 0; i < chain->image_count; i++)
+      pSwapchainImages[i] = anv_image_to_handle(chain->images[i].image);
+
+   *pCount = chain->image_count;
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+wsi_wl_acquire_next_image(struct anv_swapchain *anv_chain,
+                          uint64_t timeout,
+                          VkSemaphore semaphore,
+                          uint32_t *image_index)
+{
+   struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)anv_chain;
+
+   int ret = wl_display_dispatch_queue_pending(chain->display->display,
+                                               chain->queue);
+   /* XXX: I'm not sure if out-of-date is the right error here.  If
+    * wl_display_dispatch_queue_pending fails it most likely means we got
+    * kicked by the server so this seems more-or-less correct.
+    */
+   if (ret < 0)
+      return vk_error(VK_ERROR_OUT_OF_DATE_KHR);
+
+   while (1) {
+      for (uint32_t i = 0; i < chain->image_count; i++) {
+         if (!chain->images[i].busy) {
+            /* We found a non-busy image */
+            *image_index = i;
+            return VK_SUCCESS;
+         }
+      }
+
+      /* This time we do a blocking dispatch because we can't go
+       * anywhere until we get an event.
+       */
+      int ret = wl_display_dispatch_queue(chain->display->display,
+                                          chain->queue);
+      if (ret < 0)
+         return vk_error(VK_ERROR_OUT_OF_DATE_KHR);
+   }
+}
+
+static void
+frame_handle_done(void *data, struct wl_callback *callback, uint32_t serial)
+{
+   struct wsi_wl_swapchain *chain = data;
+
+   chain->fifo_ready = true;
+
+   wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener frame_listener = {
+   frame_handle_done,
+};
+
+static VkResult
+wsi_wl_queue_present(struct anv_swapchain *anv_chain,
+                     struct anv_queue *queue,
+                     uint32_t image_index)
+{
+   struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)anv_chain;
+
+   if (chain->present_mode == VK_PRESENT_MODE_FIFO_KHR) {
+      while (!chain->fifo_ready) {
+         int ret = wl_display_dispatch_queue(chain->display->display,
+                                             chain->queue);
+         if (ret < 0)
+            return vk_error(VK_ERROR_OUT_OF_DATE_KHR);
+      }
+   }
+
+   assert(image_index < chain->image_count);
+   wl_surface_attach(chain->surface, chain->images[image_index].buffer, 0, 0);
+   wl_surface_damage(chain->surface, 0, 0, INT32_MAX, INT32_MAX);
+
+   if (chain->present_mode == VK_PRESENT_MODE_FIFO_KHR) {
+      struct wl_callback *frame = wl_surface_frame(chain->surface);
+      wl_proxy_set_queue((struct wl_proxy *)frame, chain->queue);
+      wl_callback_add_listener(frame, &frame_listener, chain);
+      chain->fifo_ready = false;
+   }
+
+   wl_surface_commit(chain->surface);
+   wl_display_flush(chain->display->display);
+
+   return VK_SUCCESS;
+}
+
+static void
+wsi_wl_image_finish(struct wsi_wl_swapchain *chain, struct wsi_wl_image *image)
+{
+   VkDevice vk_device = anv_device_to_handle(chain->base.device);
+   anv_FreeMemory(vk_device, anv_device_memory_to_handle(image->memory));
+   anv_DestroyImage(vk_device, anv_image_to_handle(image->image));
+}
+
+static void
+buffer_handle_release(void *data, struct wl_buffer *buffer)
+{
+   struct wsi_wl_image *image = data;
+
+   assert(image->buffer == buffer);
+
+   image->busy = false;
+}
+
+static const struct wl_buffer_listener buffer_listener = {
+   buffer_handle_release,
+};
+
+static VkResult
+wsi_wl_image_init(struct wsi_wl_swapchain *chain, struct wsi_wl_image *image)
+{
+   VkDevice vk_device = anv_device_to_handle(chain->base.device);
+   VkResult result;
+
+   VkImage vk_image;
+   result = anv_image_create(vk_device,
+      &(struct anv_image_create_info) {
+         .force_tiling = true,
+         .tiling = ISL_TILING_X,
+         .stride = 0,
+         .vk_info =
+      &(VkImageCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+         .imageType = VK_IMAGE_TYPE_2D,
+         .format = chain->vk_format,
+         .extent = {
+            .width = chain->extent.width,
+            .height = chain->extent.height,
+            .depth = 1
+         },
+         .mipLevels = 1,
+         .arraySize = 1,
+         .samples = 1,
+         /* FIXME: Need a way to use X tiling to allow scanout */
+         .tiling = VK_IMAGE_TILING_OPTIMAL,
+         .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+         .flags = 0,
+      }},
+      &vk_image);
+
+   if (result != VK_SUCCESS)
+      return result;
+
+   image->image = anv_image_from_handle(vk_image);
+   assert(anv_format_is_color(image->image->format));
+
+   struct anv_surface *surface = &image->image->color_surface;
+
+   VkDeviceMemory vk_memory;
+   result = anv_AllocMemory(vk_device,
+      &(VkMemoryAllocInfo) {
+         .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
+         .allocationSize = image->image->size,
+         .memoryTypeIndex = 0,
+      },
+      &vk_memory);
+
+   if (result != VK_SUCCESS)
+      goto fail_image;
+
+   image->memory = anv_device_memory_from_handle(vk_memory);
+
+   result = anv_BindImageMemory(vk_device, vk_image, vk_memory, 0);
+
+   if (result != VK_SUCCESS)
+      goto fail_mem;
+
+   int ret = anv_gem_set_tiling(chain->base.device,
+                                image->memory->bo.gem_handle,
+                                surface->stride, I915_TILING_X);
+   if (ret) {
+      /* FINISHME: Choose a better error. */
+      result = vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+      goto fail_mem;
+   }
+
+   int fd = anv_gem_handle_to_fd(chain->base.device,
+                                 image->memory->bo.gem_handle);
+   if (fd == -1) {
+      /* FINISHME: Choose a better error. */
+      result = vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+      goto fail_mem;
+   }
+
+   image->buffer = wl_drm_create_prime_buffer(chain->display->drm,
+                                              fd, /* name */
+                                              chain->extent.width,
+                                              chain->extent.height,
+                                              chain->drm_format,
+                                              surface->offset,
+                                              surface->stride,
+                                              0, 0, 0, 0 /* unused */);
+   wl_display_roundtrip(chain->display->display);
+   close(fd);
+
+   wl_proxy_set_queue((struct wl_proxy *)image->buffer, chain->queue);
+   wl_buffer_add_listener(image->buffer, &buffer_listener, image);
+
+   return VK_SUCCESS;
+
+fail_mem:
+   anv_FreeMemory(vk_device, vk_memory);
+fail_image:
+   anv_DestroyImage(vk_device, vk_image);
+
+   return result;
+}
+
+static VkResult
+wsi_wl_destroy_swapchain(struct anv_swapchain *anv_chain)
+{
+   struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)anv_chain;
+
+   for (uint32_t i = 0; i < chain->image_count; i++) {
+      if (chain->images[i].buffer)
+         wsi_wl_image_finish(chain, &chain->images[i]);
+   }
+
+   anv_device_free(chain->base.device, chain);
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+wsi_wl_create_swapchain(struct anv_wsi_implementation *impl,
+                         struct anv_device *device,
+                         const VkSwapchainCreateInfoKHR *pCreateInfo,
+                         struct anv_swapchain **swapchain_out)
+{
+   struct wsi_wayland *wsi = (struct wsi_wayland *)impl;
+   struct wsi_wl_swapchain *chain;
+   VkResult result;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
+
+   assert(pCreateInfo->pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+   VkSurfaceDescriptionWindowKHR *vk_window =
+      (VkSurfaceDescriptionWindowKHR *)pCreateInfo->pSurfaceDescription;
+   assert(vk_window->platform == VK_PLATFORM_WAYLAND_KHR);
+
+   int num_images = pCreateInfo->minImageCount;
+
+   assert(num_images >= MIN_NUM_IMAGES);
+
+   /* For true mailbox mode, we need at least 4 images:
+    *  1) One to scan out from
+    *  2) One to have queued for scan-out
+    *  3) One to be currently held by the Wayland compositor
+    *  4) One to render to
+    */
+   if (pCreateInfo->presentMode == VK_PRESENT_MODE_MAILBOX_KHR)
+      num_images = MAX2(num_images, 4);
+
+   size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
+   chain = anv_device_alloc(device, size, 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (chain == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   chain->base.device = device;
+   chain->base.destroy = wsi_wl_destroy_swapchain;
+   chain->base.get_images = wsi_wl_get_images;
+   chain->base.acquire_next_image = wsi_wl_acquire_next_image;
+   chain->base.queue_present = wsi_wl_queue_present;
+
+   chain->surface = vk_window->pPlatformWindow;
+   chain->extent = pCreateInfo->imageExtent;
+   chain->vk_format = pCreateInfo->imageFormat;
+   chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, false);
+
+   chain->present_mode = pCreateInfo->presentMode;
+   chain->fifo_ready = true;
+
+   chain->image_count = num_images;
+
+   /* Mark a bunch of stuff as NULL.  This way we can just call
+    * destroy_swapchain for cleanup.
+    */
+   for (uint32_t i = 0; i < chain->image_count; i++)
+      chain->images[i].buffer = NULL;
+   chain->queue = NULL;
+
+   chain->display = wsi_wl_get_display(wsi, vk_window->pPlatformHandle);
+   if (!chain->display)
+      goto fail;
+
+   chain->queue = wl_display_create_queue(chain->display->display);
+   if (!chain->queue)
+      goto fail;
+
+   for (uint32_t i = 0; i < chain->image_count; i++) {
+      result = wsi_wl_image_init(chain, &chain->images[i]);
+      if (result != VK_SUCCESS)
+         goto fail;
+      chain->images[i].busy = false;
+   }
+
+   *swapchain_out = &chain->base;
+
+   return VK_SUCCESS;
+
+fail:
+   wsi_wl_destroy_swapchain(&chain->base);
+
+   return result;
+}
+
+VkResult
+anv_wl_init_wsi(struct anv_instance *instance)
+{
+   struct wsi_wayland *wsi;
+   VkResult result;
+
+   wsi = anv_instance_alloc(instance, sizeof(*wsi), 8,
+                            VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (!wsi)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   wsi->base.get_window_supported = wsi_wl_get_window_supported;
+   wsi->base.get_surface_properties = wsi_wl_get_surface_properties;
+   wsi->base.get_surface_formats = wsi_wl_get_surface_formats;
+   wsi->base.get_surface_present_modes = wsi_wl_get_surface_present_modes;
+   wsi->base.create_swapchain = wsi_wl_create_swapchain;
+
+   wsi->instance = instance;
+
+   int ret = pthread_mutex_init(&wsi->mutex, NULL);
+   if (ret != 0) {
+      if (ret == ENOMEM) {
+         result = VK_ERROR_OUT_OF_HOST_MEMORY;
+      } else {
+         /* FINISHME: Choose a better error. */
+         result = VK_ERROR_OUT_OF_HOST_MEMORY;
+      }
+
+      goto fail_alloc;
+   }
+
+   wsi->displays = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
+                                           _mesa_key_pointer_equal);
+   if (!wsi->displays) {
+      result = VK_ERROR_OUT_OF_HOST_MEMORY;
+      goto fail_mutex;
+   }
+
+   instance->wsi_impl[VK_PLATFORM_WAYLAND_KHR] = &wsi->base;
+
+   return VK_SUCCESS;
+
+fail_mutex:
+   pthread_mutex_destroy(&wsi->mutex);
+
+fail_alloc:
+   anv_instance_free(instance, wsi);
+
+   return result;
+}
+
+void
+anv_wl_finish_wsi(struct anv_instance *instance)
+{
+   struct wsi_wayland *wsi =
+      (struct wsi_wayland *)instance->wsi_impl[VK_PLATFORM_WAYLAND_KHR];
+
+   _mesa_hash_table_destroy(wsi->displays, NULL);
+
+   pthread_mutex_destroy(&wsi->mutex);
+
+   anv_instance_free(instance, wsi);
+}
diff --git a/src/vulkan/anv_wsi_x11.c b/src/vulkan/anv_wsi_x11.c
new file mode 100644 (file)
index 0000000..9a5e41d
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <xcb/xcb.h>
+#include <xcb/dri3.h>
+#include <xcb/present.h>
+
+#include "anv_wsi.h"
+
+static const VkSurfaceFormatKHR formats[] = {
+   { .format = VK_FORMAT_B8G8R8A8_UNORM, },
+};
+
+static const VkPresentModeKHR present_modes[] = {
+   VK_PRESENT_MODE_MAILBOX_KHR,
+};
+
+static VkResult
+x11_get_window_supported(struct anv_wsi_implementation *impl,
+                         struct anv_physical_device *physical_device,
+                         const VkSurfaceDescriptionWindowKHR *window,
+                         VkBool32 *pSupported)
+{
+   *pSupported = true;
+   stub_return(VK_SUCCESS);
+}
+
+static VkResult
+x11_get_surface_properties(struct anv_wsi_implementation *impl,
+                           struct anv_device *device,
+                           const VkSurfaceDescriptionWindowKHR *vk_window,
+                           VkSurfacePropertiesKHR *props)
+{
+   VkPlatformHandleXcbKHR *vk_xcb_handle = vk_window->pPlatformHandle;
+   xcb_connection_t *conn = vk_xcb_handle->connection;
+   xcb_window_t win = *(xcb_window_t *)vk_window->pPlatformWindow;
+
+   xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, win);
+   xcb_generic_error_t *err;
+   xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(conn, cookie,
+                                                           &err);
+   if (geom) {
+      free(err);
+      VkExtent2D extent = { geom->width, geom->height };
+      props->currentExtent = extent;
+      props->minImageExtent = extent;
+      props->maxImageExtent = extent;
+   } else {
+      /* This can happen if the client didn't wait for the configure event
+       * to come back from the compositor.  In that case, we don't know the
+       * size of the window so we just return valid "I don't know" stuff.
+       */
+      free(geom);
+      props->currentExtent = (VkExtent2D) { -1, -1 };
+      props->minImageExtent = (VkExtent2D) { 1, 1 };
+      props->maxImageExtent = (VkExtent2D) { INT16_MAX, INT16_MAX };
+   }
+
+   props->minImageCount = 2;
+   props->maxImageCount = 4;
+   props->supportedTransforms = VK_SURFACE_TRANSFORM_NONE_BIT_KHR;
+   props->currentTransform = VK_SURFACE_TRANSFORM_NONE_KHR;
+   props->maxImageArraySize = 1;
+   props->supportedUsageFlags =
+      VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT |
+      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_get_surface_formats(struct anv_wsi_implementation *impl,
+                        struct anv_device *device,
+                        const VkSurfaceDescriptionWindowKHR *vk_window,
+                        uint32_t *pCount, VkSurfaceFormatKHR *pSurfaceFormats)
+{
+   if (pSurfaceFormats == NULL) {
+      *pCount = ARRAY_SIZE(formats);
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= ARRAY_SIZE(formats));
+   typed_memcpy(pSurfaceFormats, formats, *pCount);
+   *pCount = ARRAY_SIZE(formats);
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_get_surface_present_modes(struct anv_wsi_implementation *impl,
+                              struct anv_device *device,
+                              const VkSurfaceDescriptionWindowKHR *vk_window,
+                              uint32_t *pCount, VkPresentModeKHR *pPresentModes)
+{
+   if (pPresentModes == NULL) {
+      *pCount = ARRAY_SIZE(present_modes);
+      return VK_SUCCESS;
+   }
+
+   assert(*pCount >= ARRAY_SIZE(present_modes));
+   typed_memcpy(pPresentModes, present_modes, *pCount);
+   *pCount = ARRAY_SIZE(present_modes);
+
+   return VK_SUCCESS;
+}
+
+struct x11_image {
+   struct anv_image *                        image;
+   struct anv_device_memory *                memory;
+   xcb_pixmap_t                              pixmap;
+   xcb_get_geometry_cookie_t                 geom_cookie;
+   bool                                      busy;
+};
+
+struct x11_swapchain {
+   struct anv_swapchain                        base;
+
+   xcb_connection_t *                           conn;
+   xcb_window_t                                 window;
+   xcb_gc_t                                     gc;
+   VkExtent2D                                   extent;
+   uint32_t                                     image_count;
+   uint32_t                                     next_image;
+   struct x11_image                             images[0];
+};
+
+static VkResult
+x11_get_images(struct anv_swapchain *anv_chain,
+               uint32_t* pCount, VkImage *pSwapchainImages)
+{
+   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+
+   if (pSwapchainImages == NULL) {
+      *pCount = chain->image_count;
+      return VK_SUCCESS;
+   }
+
+   assert(chain->image_count <= *pCount);
+   for (uint32_t i = 0; i < chain->image_count; i++)
+      pSwapchainImages[i] = anv_image_to_handle(chain->images[i].image);
+
+   *pCount = chain->image_count;
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_acquire_next_image(struct anv_swapchain *anv_chain,
+                       uint64_t timeout,
+                       VkSemaphore semaphore,
+                       uint32_t *image_index)
+{
+   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+   struct x11_image *image = &chain->images[chain->next_image];
+
+   if (image->busy) {
+      xcb_generic_error_t *err;
+      xcb_get_geometry_reply_t *geom =
+         xcb_get_geometry_reply(chain->conn, image->geom_cookie, &err);
+      if (!geom) {
+         free(err);
+         return vk_error(VK_ERROR_OUT_OF_DATE_KHR);
+      }
+
+      if (geom->width != chain->extent.width ||
+          geom->height != chain->extent.height) {
+         free(geom);
+         return vk_error(VK_ERROR_OUT_OF_DATE_KHR);
+      }
+      free(geom);
+
+      image->busy = false;
+   }
+
+   *image_index = chain->next_image;
+   chain->next_image = (chain->next_image + 1) % chain->image_count;
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_queue_present(struct anv_swapchain *anv_chain,
+                  struct anv_queue *queue,
+                  uint32_t image_index)
+{
+   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+   struct x11_image *image = &chain->images[image_index];
+
+   assert(image_index < chain->image_count);
+
+   xcb_void_cookie_t cookie;
+
+   cookie = xcb_copy_area(chain->conn,
+                          image->pixmap,
+                          chain->window,
+                          chain->gc,
+                          0, 0,
+                          0, 0,
+                          chain->extent.width,
+                          chain->extent.height);
+   xcb_discard_reply(chain->conn, cookie.sequence);
+
+   image->geom_cookie = xcb_get_geometry(chain->conn, chain->window);
+   image->busy = true;
+
+   xcb_flush(chain->conn);
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_destroy_swapchain(struct anv_swapchain *anv_chain)
+{
+   struct x11_swapchain *chain = (struct x11_swapchain *)anv_chain;
+   xcb_void_cookie_t cookie;
+
+   for (uint32_t i = 0; i < chain->image_count; i++) {
+      struct x11_image *image = &chain->images[i];
+
+      if (image->busy)
+         xcb_discard_reply(chain->conn, image->geom_cookie.sequence);
+
+      cookie = xcb_free_pixmap(chain->conn, image->pixmap);
+      xcb_discard_reply(chain->conn, cookie.sequence);
+
+      /* TODO: Delete images and free memory */
+   }
+
+   anv_device_free(chain->base.device, chain);
+
+   return VK_SUCCESS;
+}
+
+static VkResult
+x11_create_swapchain(struct anv_wsi_implementation *impl,
+                      struct anv_device *device,
+                      const VkSwapchainCreateInfoKHR *pCreateInfo,
+                      struct anv_swapchain **swapchain_out)
+{
+   struct x11_swapchain *chain;
+   xcb_void_cookie_t cookie;
+   VkResult result;
+
+   assert(pCreateInfo->pSurfaceDescription->sType ==
+          VK_STRUCTURE_TYPE_SURFACE_DESCRIPTION_WINDOW_KHR);
+   VkSurfaceDescriptionWindowKHR *vk_window =
+      (VkSurfaceDescriptionWindowKHR *)pCreateInfo->pSurfaceDescription;
+   assert(vk_window->platform == VK_PLATFORM_XCB_KHR);
+
+   int num_images = pCreateInfo->minImageCount;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR);
+
+   size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]);
+   chain = anv_device_alloc(device, size, 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (chain == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   chain->base.device = device;
+   chain->base.destroy = x11_destroy_swapchain;
+   chain->base.get_images = x11_get_images;
+   chain->base.acquire_next_image = x11_acquire_next_image;
+   chain->base.queue_present = x11_queue_present;
+
+   VkPlatformHandleXcbKHR *vk_xcb_handle = vk_window->pPlatformHandle;
+
+   chain->conn = (xcb_connection_t *) vk_xcb_handle->connection;
+   chain->window = *(xcb_window_t *)vk_window->pPlatformWindow;
+   chain->extent = pCreateInfo->imageExtent;
+   chain->image_count = num_images;
+   chain->next_image = 0;
+
+   for (uint32_t i = 0; i < chain->image_count; i++) {
+      VkDeviceMemory memory_h;
+      VkImage image_h;
+      struct anv_image *image;
+      struct anv_surface *surface;
+      struct anv_device_memory *memory;
+
+      anv_image_create(anv_device_to_handle(device),
+         &(struct anv_image_create_info) {
+            .force_tiling = true,
+            .tiling = ISL_TILING_X,
+            .stride = 0,
+            .vk_info =
+         &(VkImageCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+            .imageType = VK_IMAGE_TYPE_2D,
+            .format = pCreateInfo->imageFormat,
+            .extent = {
+               .width = pCreateInfo->imageExtent.width,
+               .height = pCreateInfo->imageExtent.height,
+               .depth = 1
+            },
+            .mipLevels = 1,
+            .arraySize = 1,
+            .samples = 1,
+            /* FIXME: Need a way to use X tiling to allow scanout */
+            .tiling = VK_IMAGE_TILING_OPTIMAL,
+            .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+            .flags = 0,
+         }},
+         &image_h);
+
+      image = anv_image_from_handle(image_h);
+      assert(anv_format_is_color(image->format));
+
+      surface = &image->color_surface;
+
+      anv_AllocMemory(anv_device_to_handle(device),
+                      &(VkMemoryAllocInfo) {
+                         .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
+                         .allocationSize = image->size,
+                         .memoryTypeIndex = 0,
+                      },
+                      &memory_h);
+
+      memory = anv_device_memory_from_handle(memory_h);
+
+      anv_BindImageMemory(VK_NULL_HANDLE, anv_image_to_handle(image),
+                          memory_h, 0);
+
+      int ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
+                                   surface->stride, I915_TILING_X);
+      if (ret) {
+         /* FINISHME: Choose a better error. */
+         result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                            "set_tiling failed: %m");
+         goto fail;
+      }
+
+      int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle);
+      if (fd == -1) {
+         /* FINISHME: Choose a better error. */
+         result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
+                            "handle_to_fd failed: %m");
+         goto fail;
+      }
+
+      uint32_t bpp = 32;
+      uint32_t depth = 24;
+      xcb_pixmap_t pixmap = xcb_generate_id(chain->conn);
+
+      cookie =
+         xcb_dri3_pixmap_from_buffer_checked(chain->conn,
+                                             pixmap,
+                                             chain->window,
+                                             image->size,
+                                             pCreateInfo->imageExtent.width,
+                                             pCreateInfo->imageExtent.height,
+                                             surface->stride,
+                                             depth, bpp, fd);
+
+      chain->images[i].image = image;
+      chain->images[i].memory = memory;
+      chain->images[i].pixmap = pixmap;
+      chain->images[i].busy = false;
+
+      xcb_discard_reply(chain->conn, cookie.sequence);
+   }
+
+   chain->gc = xcb_generate_id(chain->conn);
+   if (!chain->gc) {
+      /* FINISHME: Choose a better error. */
+      result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+      goto fail;
+   }
+
+   cookie = xcb_create_gc(chain->conn,
+                          chain->gc,
+                          chain->window,
+                          XCB_GC_GRAPHICS_EXPOSURES,
+                          (uint32_t []) { 0 });
+   xcb_discard_reply(chain->conn, cookie.sequence);
+
+   *swapchain_out = &chain->base;
+
+   return VK_SUCCESS;
+
+ fail:
+   return result;
+}
+
+VkResult
+anv_x11_init_wsi(struct anv_instance *instance)
+{
+   struct anv_wsi_implementation *impl;
+
+   impl = anv_instance_alloc(instance, sizeof(*impl), 8,
+                             VK_SYSTEM_ALLOC_TYPE_INTERNAL);
+   if (!impl)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   impl->get_window_supported = x11_get_window_supported;
+   impl->get_surface_properties = x11_get_surface_properties;
+   impl->get_surface_formats = x11_get_surface_formats;
+   impl->get_surface_present_modes = x11_get_surface_present_modes;
+   impl->create_swapchain = x11_create_swapchain;
+
+   instance->wsi_impl[VK_PLATFORM_XCB_KHR] = impl;
+
+   return VK_SUCCESS;
+}
+
+void
+anv_x11_finish_wsi(struct anv_instance *instance)
+{
+   anv_instance_free(instance, instance->wsi_impl[VK_PLATFORM_XCB_KHR]);
+}
diff --git a/src/vulkan/gen75_pack.h b/src/vulkan/gen75_pack.h
new file mode 100644 (file)
index 0000000..3ed685b
--- /dev/null
@@ -0,0 +1,8391 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+
+/* Instructions, enums and structures for HSW.
+ *
+ * This file has been generated, do not hand edit.
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef __gen_validate_value
+#define __gen_validate_value(x)
+#endif
+
+#ifndef __gen_field_functions
+#define __gen_field_functions
+
+union __gen_value {
+   float f;
+   uint32_t dw;
+};
+
+static inline uint64_t
+__gen_mbo(uint32_t start, uint32_t end)
+{
+   return (~0ul >> (64 - (end - start + 1))) << start;
+}
+
+static inline uint64_t
+__gen_field(uint64_t v, uint32_t start, uint32_t end)
+{
+   __gen_validate_value(v);
+#if DEBUG
+   if (end - start + 1 < 64)
+      assert(v < 1ul << (end - start + 1));
+#endif
+
+   return v << start;
+}
+
+static inline uint64_t
+__gen_offset(uint64_t v, uint32_t start, uint32_t end)
+{
+   __gen_validate_value(v);
+#if DEBUG
+   uint64_t mask = (~0ul >> (64 - (end - start + 1))) << start;
+
+   assert((v & ~mask) == 0);
+#endif
+
+   return v;
+}
+
+static inline uint32_t
+__gen_float(float v)
+{
+   __gen_validate_value(v);
+   return ((union __gen_value) { .f = (v) }).dw;
+}
+
+#ifndef __gen_address_type
+#error #define __gen_address_type before including this file
+#endif
+
+#ifndef __gen_user_data
+#error #define __gen_combine_address before including this file
+#endif
+
+#endif
+
+#define GEN75_3DSTATE_URB_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_URB_VS_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 48,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_URB_VS_length 0x00000002
+
+struct GEN75_3DSTATE_URB_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     VSURBStartingAddress;
+   uint32_t                                     VSURBEntryAllocationSize;
+   uint32_t                                     VSNumberofURBEntries;
+};
+
+static inline void
+GEN75_3DSTATE_URB_VS_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_3DSTATE_URB_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->VSURBStartingAddress, 25, 30) |
+      __gen_field(values->VSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->VSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN75_GPGPU_CSR_BASE_ADDRESS_length_bias 0x00000002
+#define GEN75_GPGPU_CSR_BASE_ADDRESS_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  0
+
+#define GEN75_GPGPU_CSR_BASE_ADDRESS_length 0x00000002
+
+struct GEN75_GPGPU_CSR_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GPGPUCSRBaseAddress;
+};
+
+static inline void
+GEN75_GPGPU_CSR_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN75_GPGPU_CSR_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->GPGPUCSRBaseAddress, dw1);
+
+}
+
+#define GEN75_MI_STORE_REGISTER_MEM_length_bias 0x00000002
+#define GEN75_MI_STORE_REGISTER_MEM_header      \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 36,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_STORE_REGISTER_MEM_length 0x00000003
+
+struct GEN75_MI_STORE_REGISTER_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN75_MI_STORE_REGISTER_MEM_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN75_MI_STORE_REGISTER_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->PredicateEnable, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterAddress, 2, 22) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+}
+
+#define GEN75_PIPELINE_SELECT_length_bias 0x00000001
+#define GEN75_PIPELINE_SELECT_header            \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  1,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4
+
+#define GEN75_PIPELINE_SELECT_length 0x00000001
+
+struct GEN75_PIPELINE_SELECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+#define     _3D                                                0
+#define     Media                                              1
+#define     GPGPU                                              2
+   uint32_t                                     PipelineSelection;
+};
+
+static inline void
+GEN75_PIPELINE_SELECT_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN75_PIPELINE_SELECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->PipelineSelection, 0, 1) |
+      0;
+
+}
+
+#define GEN75_STATE_BASE_ADDRESS_length_bias 0x00000002
+#define GEN75_STATE_BASE_ADDRESS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  1,                  \
+   .DwordLength          =  8
+
+#define GEN75_STATE_BASE_ADDRESS_length 0x0000000a
+
+#define GEN75_MEMORY_OBJECT_CONTROL_STATE_length 0x00000001
+
+struct GEN75_MEMORY_OBJECT_CONTROL_STATE {
+   uint32_t                                     LLCeLLCCacheabilityControlLLCCC;
+   uint32_t                                     L3CacheabilityControlL3CC;
+};
+
+static inline void
+GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                       const struct GEN75_MEMORY_OBJECT_CONTROL_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->LLCeLLCCacheabilityControlLLCCC, 1, 2) |
+      __gen_field(values->L3CacheabilityControlL3CC, 0, 0) |
+      0;
+
+}
+
+struct GEN75_STATE_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GeneralStateBaseAddress;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     GeneralStateMemoryObjectControlState;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     StatelessDataPortAccessMemoryObjectControlState;
+   bool                                         GeneralStateBaseAddressModifyEnable;
+   __gen_address_type                           SurfaceStateBaseAddress;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     SurfaceStateMemoryObjectControlState;
+   bool                                         SurfaceStateBaseAddressModifyEnable;
+   __gen_address_type                           DynamicStateBaseAddress;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     DynamicStateMemoryObjectControlState;
+   bool                                         DynamicStateBaseAddressModifyEnable;
+   __gen_address_type                           IndirectObjectBaseAddress;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     IndirectObjectMemoryObjectControlState;
+   bool                                         IndirectObjectBaseAddressModifyEnable;
+   __gen_address_type                           InstructionBaseAddress;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     InstructionMemoryObjectControlState;
+   bool                                         InstructionBaseAddressModifyEnable;
+   __gen_address_type                           GeneralStateAccessUpperBound;
+   bool                                         GeneralStateAccessUpperBoundModifyEnable;
+   __gen_address_type                           DynamicStateAccessUpperBound;
+   bool                                         DynamicStateAccessUpperBoundModifyEnable;
+   __gen_address_type                           IndirectObjectAccessUpperBound;
+   bool                                         IndirectObjectAccessUpperBoundModifyEnable;
+   __gen_address_type                           InstructionAccessUpperBound;
+   bool                                         InstructionAccessUpperBoundModifyEnable;
+};
+
+static inline void
+GEN75_STATE_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN75_STATE_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_GeneralStateMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_GeneralStateMemoryObjectControlState, &values->GeneralStateMemoryObjectControlState);
+   uint32_t dw_StatelessDataPortAccessMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_StatelessDataPortAccessMemoryObjectControlState, &values->StatelessDataPortAccessMemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(dw_GeneralStateMemoryObjectControlState, 8, 11) |
+      __gen_field(dw_StatelessDataPortAccessMemoryObjectControlState, 4, 7) |
+      __gen_field(values->GeneralStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->GeneralStateBaseAddress, dw1);
+
+   uint32_t dw_SurfaceStateMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceStateMemoryObjectControlState, &values->SurfaceStateMemoryObjectControlState);
+   uint32_t dw2 =
+      __gen_field(dw_SurfaceStateMemoryObjectControlState, 8, 11) |
+      __gen_field(values->SurfaceStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceStateBaseAddress, dw2);
+
+   uint32_t dw_DynamicStateMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_DynamicStateMemoryObjectControlState, &values->DynamicStateMemoryObjectControlState);
+   uint32_t dw3 =
+      __gen_field(dw_DynamicStateMemoryObjectControlState, 8, 11) |
+      __gen_field(values->DynamicStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->DynamicStateBaseAddress, dw3);
+
+   uint32_t dw_IndirectObjectMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_IndirectObjectMemoryObjectControlState, &values->IndirectObjectMemoryObjectControlState);
+   uint32_t dw4 =
+      __gen_field(dw_IndirectObjectMemoryObjectControlState, 8, 11) |
+      __gen_field(values->IndirectObjectBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[4] =
+      __gen_combine_address(data, &dw[4], values->IndirectObjectBaseAddress, dw4);
+
+   uint32_t dw_InstructionMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_InstructionMemoryObjectControlState, &values->InstructionMemoryObjectControlState);
+   uint32_t dw5 =
+      __gen_field(dw_InstructionMemoryObjectControlState, 8, 11) |
+      __gen_field(values->InstructionBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[5] =
+      __gen_combine_address(data, &dw[5], values->InstructionBaseAddress, dw5);
+
+   uint32_t dw6 =
+      __gen_field(values->GeneralStateAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[6] =
+      __gen_combine_address(data, &dw[6], values->GeneralStateAccessUpperBound, dw6);
+
+   uint32_t dw7 =
+      __gen_field(values->DynamicStateAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[7] =
+      __gen_combine_address(data, &dw[7], values->DynamicStateAccessUpperBound, dw7);
+
+   uint32_t dw8 =
+      __gen_field(values->IndirectObjectAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[8] =
+      __gen_combine_address(data, &dw[8], values->IndirectObjectAccessUpperBound, dw8);
+
+   uint32_t dw9 =
+      __gen_field(values->InstructionAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[9] =
+      __gen_combine_address(data, &dw[9], values->InstructionAccessUpperBound, dw9);
+
+}
+
+#define GEN75_STATE_PREFETCH_length_bias 0x00000002
+#define GEN75_STATE_PREFETCH_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  3,                  \
+   .DwordLength          =  0
+
+#define GEN75_STATE_PREFETCH_length 0x00000002
+
+struct GEN75_STATE_PREFETCH {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           PrefetchPointer;
+   uint32_t                                     PrefetchCount;
+};
+
+static inline void
+GEN75_STATE_PREFETCH_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_STATE_PREFETCH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->PrefetchCount, 0, 2) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->PrefetchPointer, dw1);
+
+}
+
+#define GEN75_STATE_SIP_length_bias 0x00000002
+#define GEN75_STATE_SIP_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  2,                  \
+   .DwordLength          =  0
+
+#define GEN75_STATE_SIP_length 0x00000002
+
+struct GEN75_STATE_SIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SystemInstructionPointer;
+};
+
+static inline void
+GEN75_STATE_SIP_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN75_STATE_SIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SystemInstructionPointer, 4, 31) |
+      0;
+
+}
+
+#define GEN75_SWTESS_BASE_ADDRESS_length_bias 0x00000002
+#define GEN75_SWTESS_BASE_ADDRESS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  3,                  \
+   .DwordLength          =  0
+
+#define GEN75_SWTESS_BASE_ADDRESS_length 0x00000002
+
+struct GEN75_SWTESS_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           SWTessellationBaseAddress;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     SWTessellationMemoryObjectControlState;
+};
+
+static inline void
+GEN75_SWTESS_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_SWTESS_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SWTessellationMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SWTessellationMemoryObjectControlState, &values->SWTessellationMemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(dw_SWTessellationMemoryObjectControlState, 8, 11) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->SWTessellationBaseAddress, dw1);
+
+}
+
+#define GEN75_3DPRIMITIVE_length_bias 0x00000002
+#define GEN75_3DPRIMITIVE_header                \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  3,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DPRIMITIVE_length 0x00000007
+
+struct GEN75_3DPRIMITIVE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         IndirectParameterEnable;
+   uint32_t                                     UAVCoherencyRequired;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   bool                                         EndOffsetEnable;
+#define     SEQUENTIAL                                         0
+#define     RANDOM                                             1
+   uint32_t                                     VertexAccessType;
+   uint32_t                                     PrimitiveTopologyType;
+   uint32_t                                     VertexCountPerInstance;
+   uint32_t                                     StartVertexLocation;
+   uint32_t                                     InstanceCount;
+   uint32_t                                     StartInstanceLocation;
+   uint32_t                                     BaseVertexLocation;
+};
+
+static inline void
+GEN75_3DPRIMITIVE_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN75_3DPRIMITIVE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->IndirectParameterEnable, 10, 10) |
+      __gen_field(values->UAVCoherencyRequired, 9, 9) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->EndOffsetEnable, 9, 9) |
+      __gen_field(values->VertexAccessType, 8, 8) |
+      __gen_field(values->PrimitiveTopologyType, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->VertexCountPerInstance, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->StartVertexLocation, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->InstanceCount, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->StartInstanceLocation, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->BaseVertexLocation, 0, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_AA_LINE_PARAMETERS_length_bias 0x00000002
+#define GEN75_3DSTATE_AA_LINE_PARAMETERS_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 10,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_AA_LINE_PARAMETERS_length 0x00000003
+
+struct GEN75_3DSTATE_AA_LINE_PARAMETERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   float                                        AACoverageBias;
+   float                                        AACoverageSlope;
+   float                                        AACoverageEndCapBias;
+   float                                        AACoverageEndCapSlope;
+};
+
+static inline void
+GEN75_3DSTATE_AA_LINE_PARAMETERS_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_3DSTATE_AA_LINE_PARAMETERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AACoverageBias * (1 << 8), 16, 23) |
+      __gen_field(values->AACoverageSlope * (1 << 8), 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->AACoverageEndCapBias * (1 << 8), 16, 23) |
+      __gen_field(values->AACoverageEndCapSlope * (1 << 8), 0, 7) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 70
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_DS_length 0x00000000
+
+#define GEN75_BINDING_TABLE_EDIT_ENTRY_length 0x00000001
+
+struct GEN75_BINDING_TABLE_EDIT_ENTRY {
+   uint32_t                                     BindingTableIndex;
+   uint32_t                                     SurfaceStatePointer;
+};
+
+static inline void
+GEN75_BINDING_TABLE_EDIT_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN75_BINDING_TABLE_EDIT_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->BindingTableIndex, 16, 23) |
+      __gen_offset(values->SurfaceStatePointer, 0, 15) |
+      0;
+
+}
+
+struct GEN75_3DSTATE_BINDING_TABLE_EDIT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_EDIT_DS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_BINDING_TABLE_EDIT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 68
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_GS_length 0x00000000
+
+struct GEN75_3DSTATE_BINDING_TABLE_EDIT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_EDIT_GS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_BINDING_TABLE_EDIT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 69
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_HS_length 0x00000000
+
+struct GEN75_3DSTATE_BINDING_TABLE_EDIT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_EDIT_HS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_BINDING_TABLE_EDIT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 71
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_PS_length 0x00000000
+
+struct GEN75_3DSTATE_BINDING_TABLE_EDIT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_EDIT_PS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_BINDING_TABLE_EDIT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 67
+
+#define GEN75_3DSTATE_BINDING_TABLE_EDIT_VS_length 0x00000000
+
+struct GEN75_3DSTATE_BINDING_TABLE_EDIT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_EDIT_VS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_BINDING_TABLE_EDIT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 40,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_DS_length 0x00000002
+
+struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDSBindingTable;
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_POINTERS_DS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 41,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_GS_length 0x00000002
+
+struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoGSBindingTable;
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_POINTERS_GS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoGSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 39,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_HS_length 0x00000002
+
+struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoHSBindingTable;
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_POINTERS_HS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoHSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 42,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_PS_length 0x00000002
+
+struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoPSBindingTable;
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_POINTERS_PS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoPSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 38,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_BINDING_TABLE_POINTERS_VS_length 0x00000002
+
+struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoVSBindingTable;
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_POINTERS_VS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_BINDING_TABLE_POINTERS_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoVSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_BINDING_TABLE_POOL_ALLOC_length_bias 0x00000002
+#define GEN75_3DSTATE_BINDING_TABLE_POOL_ALLOC_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 25,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_BINDING_TABLE_POOL_ALLOC_length 0x00000003
+
+struct GEN75_3DSTATE_BINDING_TABLE_POOL_ALLOC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BindingTablePoolBaseAddress;
+   uint32_t                                     BindingTablePoolEnable;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     SurfaceObjectControlState;
+   __gen_address_type                           BindingTablePoolUpperBound;
+};
+
+static inline void
+GEN75_3DSTATE_BINDING_TABLE_POOL_ALLOC_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN75_3DSTATE_BINDING_TABLE_POOL_ALLOC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SurfaceObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceObjectControlState, &values->SurfaceObjectControlState);
+   uint32_t dw1 =
+      __gen_field(values->BindingTablePoolEnable, 11, 11) |
+      __gen_field(dw_SurfaceObjectControlState, 7, 10) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BindingTablePoolBaseAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->BindingTablePoolUpperBound, dw2);
+
+}
+
+#define GEN75_3DSTATE_BLEND_STATE_POINTERS_length_bias 0x00000002
+#define GEN75_3DSTATE_BLEND_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 36,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_BLEND_STATE_POINTERS_length 0x00000002
+
+struct GEN75_3DSTATE_BLEND_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BlendStatePointer;
+};
+
+static inline void
+GEN75_3DSTATE_BLEND_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN75_3DSTATE_BLEND_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->BlendStatePointer, 6, 31) |
+      __gen_mbo(0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_CC_STATE_POINTERS_length_bias 0x00000002
+#define GEN75_3DSTATE_CC_STATE_POINTERS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 14,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_CC_STATE_POINTERS_length 0x00000002
+
+struct GEN75_3DSTATE_CC_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ColorCalcStatePointer;
+};
+
+static inline void
+GEN75_3DSTATE_CC_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN75_3DSTATE_CC_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ColorCalcStatePointer, 6, 31) |
+      __gen_mbo(0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_CHROMA_KEY_length_bias 0x00000002
+#define GEN75_3DSTATE_CHROMA_KEY_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  2
+
+#define GEN75_3DSTATE_CHROMA_KEY_length 0x00000004
+
+struct GEN75_3DSTATE_CHROMA_KEY {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ChromaKeyTableIndex;
+   uint32_t                                     ChromaKeyLowValue;
+   uint32_t                                     ChromaKeyHighValue;
+};
+
+static inline void
+GEN75_3DSTATE_CHROMA_KEY_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN75_3DSTATE_CHROMA_KEY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ChromaKeyTableIndex, 30, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChromaKeyLowValue, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ChromaKeyHighValue, 0, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_CLEAR_PARAMS_length_bias 0x00000002
+#define GEN75_3DSTATE_CLEAR_PARAMS_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_CLEAR_PARAMS_length 0x00000003
+
+struct GEN75_3DSTATE_CLEAR_PARAMS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     DepthClearValue;
+   bool                                         DepthClearValueValid;
+};
+
+static inline void
+GEN75_3DSTATE_CLEAR_PARAMS_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_3DSTATE_CLEAR_PARAMS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DepthClearValue, 0, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DepthClearValueValid, 0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_CLIP_length_bias 0x00000002
+#define GEN75_3DSTATE_CLIP_header               \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 18,                  \
+   .DwordLength          =  2
+
+#define GEN75_3DSTATE_CLIP_length 0x00000004
+
+struct GEN75_3DSTATE_CLIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     FrontWinding;
+   uint32_t                                     VertexSubPixelPrecisionSelect;
+   bool                                         EarlyCullEnable;
+#define     CULLMODE_BOTH                                      0
+#define     CULLMODE_NONE                                      1
+#define     CULLMODE_FRONT                                     2
+#define     CULLMODE_BACK                                      3
+   uint32_t                                     CullMode;
+   bool                                         ClipperStatisticsEnable;
+   uint32_t                                     UserClipDistanceCullTestEnableBitmask;
+   bool                                         ClipEnable;
+#define     APIMODE_OGL                                        0
+   uint32_t                                     APIMode;
+   bool                                         ViewportXYClipTestEnable;
+   bool                                         ViewportZClipTestEnable;
+   bool                                         GuardbandClipTestEnable;
+   uint32_t                                     UserClipDistanceClipTestEnableBitmask;
+#define     CLIPMODE_NORMAL                                    0
+#define     CLIPMODE_REJECT_ALL                                3
+#define     CLIPMODE_ACCEPT_ALL                                4
+   uint32_t                                     ClipMode;
+   bool                                         PerspectiveDivideDisable;
+   bool                                         NonPerspectiveBarycentricEnable;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleStripListProvokingVertexSelect;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+   uint32_t                                     LineStripListProvokingVertexSelect;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleFanProvokingVertexSelect;
+   float                                        MinimumPointWidth;
+   float                                        MaximumPointWidth;
+   bool                                         ForceZeroRTAIndexEnable;
+   uint32_t                                     MaximumVPIndex;
+};
+
+static inline void
+GEN75_3DSTATE_CLIP_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_3DSTATE_CLIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->FrontWinding, 20, 20) |
+      __gen_field(values->VertexSubPixelPrecisionSelect, 19, 19) |
+      __gen_field(values->EarlyCullEnable, 18, 18) |
+      __gen_field(values->CullMode, 16, 17) |
+      __gen_field(values->ClipperStatisticsEnable, 10, 10) |
+      __gen_field(values->UserClipDistanceCullTestEnableBitmask, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClipEnable, 31, 31) |
+      __gen_field(values->APIMode, 30, 30) |
+      __gen_field(values->ViewportXYClipTestEnable, 28, 28) |
+      __gen_field(values->ViewportZClipTestEnable, 27, 27) |
+      __gen_field(values->GuardbandClipTestEnable, 26, 26) |
+      __gen_field(values->UserClipDistanceClipTestEnableBitmask, 16, 23) |
+      __gen_field(values->ClipMode, 13, 15) |
+      __gen_field(values->PerspectiveDivideDisable, 9, 9) |
+      __gen_field(values->NonPerspectiveBarycentricEnable, 8, 8) |
+      __gen_field(values->TriangleStripListProvokingVertexSelect, 4, 5) |
+      __gen_field(values->LineStripListProvokingVertexSelect, 2, 3) |
+      __gen_field(values->TriangleFanProvokingVertexSelect, 0, 1) |
+      0;
+
+   dw[3] =
+      __gen_field(values->MinimumPointWidth * (1 << 3), 17, 27) |
+      __gen_field(values->MaximumPointWidth * (1 << 3), 6, 16) |
+      __gen_field(values->ForceZeroRTAIndexEnable, 5, 5) |
+      __gen_field(values->MaximumVPIndex, 0, 3) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_CONSTANT_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_CONSTANT_DS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 26,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_CONSTANT_DS_length 0x00000007
+
+#define GEN75_3DSTATE_CONSTANT_BODY_length 0x00000006
+
+struct GEN75_3DSTATE_CONSTANT_BODY {
+   uint32_t                                     ConstantBuffer1ReadLength;
+   uint32_t                                     ConstantBuffer0ReadLength;
+   uint32_t                                     ConstantBuffer3ReadLength;
+   uint32_t                                     ConstantBuffer2ReadLength;
+   __gen_address_type                           PointerToConstantBuffer0;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     ConstantBufferObjectControlState;
+   __gen_address_type                           PointerToConstantBuffer1;
+   __gen_address_type                           PointerToConstantBuffer2;
+   __gen_address_type                           PointerToConstantBuffer3;
+};
+
+static inline void
+GEN75_3DSTATE_CONSTANT_BODY_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN75_3DSTATE_CONSTANT_BODY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ConstantBuffer1ReadLength, 16, 31) |
+      __gen_field(values->ConstantBuffer0ReadLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBuffer3ReadLength, 16, 31) |
+      __gen_field(values->ConstantBuffer2ReadLength, 0, 15) |
+      0;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   uint32_t dw2 =
+      __gen_field(dw_ConstantBufferObjectControlState, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->PointerToConstantBuffer0, dw2);
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->PointerToConstantBuffer1, dw3);
+
+   uint32_t dw4 =
+      0;
+
+   dw[4] =
+      __gen_combine_address(data, &dw[4], values->PointerToConstantBuffer2, dw4);
+
+   uint32_t dw5 =
+      0;
+
+   dw[5] =
+      __gen_combine_address(data, &dw[5], values->PointerToConstantBuffer3, dw5);
+
+}
+
+struct GEN75_3DSTATE_CONSTANT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN75_3DSTATE_CONSTANT_BODY           ConstantBody;
+};
+
+static inline void
+GEN75_3DSTATE_CONSTANT_DS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_CONSTANT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN75_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN75_3DSTATE_CONSTANT_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_CONSTANT_GS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 22,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_CONSTANT_GS_length 0x00000007
+
+struct GEN75_3DSTATE_CONSTANT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN75_3DSTATE_CONSTANT_BODY           ConstantBody;
+};
+
+static inline void
+GEN75_3DSTATE_CONSTANT_GS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_CONSTANT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN75_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN75_3DSTATE_CONSTANT_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_CONSTANT_HS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 25,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_CONSTANT_HS_length 0x00000007
+
+struct GEN75_3DSTATE_CONSTANT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN75_3DSTATE_CONSTANT_BODY           ConstantBody;
+};
+
+static inline void
+GEN75_3DSTATE_CONSTANT_HS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_CONSTANT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN75_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN75_3DSTATE_CONSTANT_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_CONSTANT_PS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 23,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_CONSTANT_PS_length 0x00000007
+
+struct GEN75_3DSTATE_CONSTANT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN75_3DSTATE_CONSTANT_BODY           ConstantBody;
+};
+
+static inline void
+GEN75_3DSTATE_CONSTANT_PS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_CONSTANT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN75_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN75_3DSTATE_CONSTANT_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_CONSTANT_VS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 21,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_CONSTANT_VS_length 0x00000007
+
+struct GEN75_3DSTATE_CONSTANT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN75_3DSTATE_CONSTANT_BODY           ConstantBody;
+};
+
+static inline void
+GEN75_3DSTATE_CONSTANT_VS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_CONSTANT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN75_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN75_3DSTATE_DEPTH_BUFFER_length_bias 0x00000002
+#define GEN75_3DSTATE_DEPTH_BUFFER_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  5,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_DEPTH_BUFFER_length 0x00000007
+
+struct GEN75_3DSTATE_DEPTH_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     SURFTYPE_1D                                        0
+#define     SURFTYPE_2D                                        1
+#define     SURFTYPE_3D                                        2
+#define     SURFTYPE_CUBE                                      3
+#define     SURFTYPE_NULL                                      7
+   uint32_t                                     SurfaceType;
+   bool                                         DepthWriteEnable;
+   bool                                         StencilWriteEnable;
+   bool                                         HierarchicalDepthBufferEnable;
+#define     D32_FLOAT                                          1
+#define     D24_UNORM_X8_UINT                                  3
+#define     D16_UNORM                                          5
+   uint32_t                                     SurfaceFormat;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     Height;
+   uint32_t                                     Width;
+   uint32_t                                     LOD;
+#define     SURFTYPE_CUBEmustbezero                            0
+   uint32_t                                     Depth;
+   uint32_t                                     MinimumArrayElement;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     DepthBufferObjectControlState;
+   uint32_t                                     DepthCoordinateOffsetY;
+   uint32_t                                     DepthCoordinateOffsetX;
+   uint32_t                                     RenderTargetViewExtent;
+};
+
+static inline void
+GEN75_3DSTATE_DEPTH_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_3DSTATE_DEPTH_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SurfaceType, 29, 31) |
+      __gen_field(values->DepthWriteEnable, 28, 28) |
+      __gen_field(values->StencilWriteEnable, 27, 27) |
+      __gen_field(values->HierarchicalDepthBufferEnable, 22, 22) |
+      __gen_field(values->SurfaceFormat, 18, 20) |
+      __gen_field(values->SurfacePitch, 0, 17) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   dw[3] =
+      __gen_field(values->Height, 18, 31) |
+      __gen_field(values->Width, 4, 17) |
+      __gen_field(values->LOD, 0, 3) |
+      0;
+
+   uint32_t dw_DepthBufferObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_DepthBufferObjectControlState, &values->DepthBufferObjectControlState);
+   dw[4] =
+      __gen_field(values->Depth, 21, 31) |
+      __gen_field(values->MinimumArrayElement, 10, 20) |
+      __gen_field(dw_DepthBufferObjectControlState, 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->DepthCoordinateOffsetY, 16, 31) |
+      __gen_field(values->DepthCoordinateOffsetX, 0, 15) |
+      0;
+
+   dw[6] =
+      __gen_field(values->RenderTargetViewExtent, 21, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_length_bias 0x00000002
+#define GEN75_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 37,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_length 0x00000002
+
+struct GEN75_3DSTATE_DEPTH_STENCIL_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDEPTH_STENCIL_STATE;
+};
+
+static inline void
+GEN75_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                                const struct GEN75_3DSTATE_DEPTH_STENCIL_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDEPTH_STENCIL_STATE, 6, 31) |
+      __gen_mbo(0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_DRAWING_RECTANGLE_length_bias 0x00000002
+#define GEN75_3DSTATE_DRAWING_RECTANGLE_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  2
+
+#define GEN75_3DSTATE_DRAWING_RECTANGLE_length 0x00000004
+
+struct GEN75_3DSTATE_DRAWING_RECTANGLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+#define     Legacy                                             0
+#define     Core0Enabled                                       1
+#define     Core1Enabled                                       2
+   uint32_t                                     CoreModeSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ClippedDrawingRectangleYMin;
+   uint32_t                                     ClippedDrawingRectangleXMin;
+   uint32_t                                     ClippedDrawingRectangleYMax;
+   uint32_t                                     ClippedDrawingRectangleXMax;
+   uint32_t                                     DrawingRectangleOriginY;
+   uint32_t                                     DrawingRectangleOriginX;
+};
+
+static inline void
+GEN75_3DSTATE_DRAWING_RECTANGLE_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN75_3DSTATE_DRAWING_RECTANGLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->CoreModeSelect, 14, 15) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ClippedDrawingRectangleYMin, 16, 31) |
+      __gen_field(values->ClippedDrawingRectangleXMin, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClippedDrawingRectangleYMax, 16, 31) |
+      __gen_field(values->ClippedDrawingRectangleXMax, 0, 15) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DrawingRectangleOriginY, 16, 31) |
+      __gen_field(values->DrawingRectangleOriginX, 0, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_DS_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 29,                  \
+   .DwordLength          =  4
+
+#define GEN75_3DSTATE_DS_length 0x00000006
+
+struct GEN75_3DSTATE_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleDomainPointDispatch;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         AccessesUAV;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     PatchURBEntryReadLength;
+   uint32_t                                     PatchURBEntryReadOffset;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         StatisticsEnable;
+   bool                                         ComputeWCoordinateEnable;
+   bool                                         DSCacheDisable;
+   bool                                         DSFunctionEnable;
+};
+
+static inline void
+GEN75_3DSTATE_DS_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleDomainPointDispatch, 31, 31) |
+      __gen_field(values->VectorMaskEnable, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->AccessesUAV, 14, 14) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 20, 24) |
+      __gen_field(values->PatchURBEntryReadLength, 11, 17) |
+      __gen_field(values->PatchURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[5] =
+      __gen_field(values->MaximumNumberofThreads, 21, 29) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->ComputeWCoordinateEnable, 2, 2) |
+      __gen_field(values->DSCacheDisable, 1, 1) |
+      __gen_field(values->DSFunctionEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_GATHER_CONSTANT_DS_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 55
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_DS_length 0x00000000
+
+#define GEN75_GATHER_CONSTANT_ENTRY_length 0x00000001
+
+struct GEN75_GATHER_CONSTANT_ENTRY {
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ChannelMask;
+   uint32_t                                     BindingTableIndexOffset;
+};
+
+static inline void
+GEN75_GATHER_CONSTANT_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN75_GATHER_CONSTANT_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->ConstantBufferOffset, 8, 15) |
+      __gen_field(values->ChannelMask, 4, 7) |
+      __gen_field(values->BindingTableIndexOffset, 0, 3) |
+      0;
+
+}
+
+struct GEN75_3DSTATE_GATHER_CONSTANT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_GATHER_CONSTANT_DS_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_3DSTATE_GATHER_CONSTANT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_GATHER_CONSTANT_GS_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 53
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_GS_length 0x00000000
+
+struct GEN75_3DSTATE_GATHER_CONSTANT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_GATHER_CONSTANT_GS_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_3DSTATE_GATHER_CONSTANT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_GATHER_CONSTANT_HS_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 54
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_HS_length 0x00000000
+
+struct GEN75_3DSTATE_GATHER_CONSTANT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_GATHER_CONSTANT_HS_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_3DSTATE_GATHER_CONSTANT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_GATHER_CONSTANT_PS_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 56
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_PS_length 0x00000000
+
+struct GEN75_3DSTATE_GATHER_CONSTANT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9Enable;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_GATHER_CONSTANT_PS_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_3DSTATE_GATHER_CONSTANT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9Enable, 4, 4) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_GATHER_CONSTANT_VS_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 52
+
+#define GEN75_3DSTATE_GATHER_CONSTANT_VS_length 0x00000000
+
+struct GEN75_3DSTATE_GATHER_CONSTANT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9Enable;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_GATHER_CONSTANT_VS_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_3DSTATE_GATHER_CONSTANT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9Enable, 4, 4) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_GATHER_POOL_ALLOC_length_bias 0x00000002
+#define GEN75_3DSTATE_GATHER_POOL_ALLOC_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 26,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_GATHER_POOL_ALLOC_length 0x00000003
+
+struct GEN75_3DSTATE_GATHER_POOL_ALLOC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GatherPoolBaseAddress;
+   bool                                         GatherPoolEnable;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     MemoryObjectControlState;
+   __gen_address_type                           GatherPoolUpperBound;
+};
+
+static inline void
+GEN75_3DSTATE_GATHER_POOL_ALLOC_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN75_3DSTATE_GATHER_POOL_ALLOC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(values->GatherPoolEnable, 11, 11) |
+      __gen_mbo(4, 5) |
+      __gen_field(dw_MemoryObjectControlState, 0, 3) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->GatherPoolBaseAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->GatherPoolUpperBound, dw2);
+
+}
+
+#define GEN75_3DSTATE_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_GS_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 17,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_GS_length 0x00000007
+
+struct GEN75_3DSTATE_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer;
+   uint32_t                                     SingleProgramFlowSPF;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnableVME;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     NormalPriority                                     0
+#define     HighPriority                                       1
+   uint32_t                                     ThreadPriority;
+#define     IEEE754                                            0
+#define     alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   uint32_t                                     GSaccessesUAV;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     OutputVertexSize;
+   uint32_t                                     OutputTopology;
+   uint32_t                                     VertexURBEntryReadLength;
+   bool                                         IncludeVertexHandles;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     DispatchGRFStartRegisterforURBData;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     ControlDataHeaderSize;
+   uint32_t                                     InstanceControl;
+   uint32_t                                     DefaultStreamID;
+#define     SINGLE                                             0
+#define     DUAL_INSTANCE                                      1
+#define     DUAL_OBJECT                                        2
+   uint32_t                                     DispatchMode;
+   uint32_t                                     GSStatisticsEnable;
+   uint32_t                                     GSInvocationsIncrementValue;
+   bool                                         IncludePrimitiveID;
+   uint32_t                                     Hint;
+#define     REORDER_LEADING                                    0
+#define     REORDER_TRAILING                                   1
+   uint32_t                                     ReorderMode;
+   bool                                         DiscardAdjacency;
+   bool                                         GSEnable;
+#define     GSCTL_CUT                                          0
+#define     GSCTL_SID                                          1
+   uint32_t                                     ControlDataFormat;
+   uint32_t                                     SemaphoreHandle;
+};
+
+static inline void
+GEN75_3DSTATE_GS_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleProgramFlowSPF, 31, 31) |
+      __gen_field(values->VectorMaskEnableVME, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->GSaccessesUAV, 12, 12) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->OutputVertexSize, 23, 28) |
+      __gen_field(values->OutputTopology, 17, 22) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->IncludeVertexHandles, 10, 10) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      __gen_field(values->DispatchGRFStartRegisterforURBData, 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->MaximumNumberofThreads, 24, 31) |
+      __gen_field(values->ControlDataHeaderSize, 20, 23) |
+      __gen_field(values->InstanceControl, 15, 19) |
+      __gen_field(values->DefaultStreamID, 13, 14) |
+      __gen_field(values->DispatchMode, 11, 12) |
+      __gen_field(values->GSStatisticsEnable, 10, 10) |
+      __gen_field(values->GSInvocationsIncrementValue, 5, 9) |
+      __gen_field(values->IncludePrimitiveID, 4, 4) |
+      __gen_field(values->Hint, 3, 3) |
+      __gen_field(values->ReorderMode, 2, 2) |
+      __gen_field(values->DiscardAdjacency, 1, 1) |
+      __gen_field(values->GSEnable, 0, 0) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ControlDataFormat, 31, 31) |
+      __gen_offset(values->SemaphoreHandle, 0, 12) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_HIER_DEPTH_BUFFER_length_bias 0x00000002
+#define GEN75_3DSTATE_HIER_DEPTH_BUFFER_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  7,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_HIER_DEPTH_BUFFER_length 0x00000003
+
+struct GEN75_3DSTATE_HIER_DEPTH_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     HierarchicalDepthBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+};
+
+static inline void
+GEN75_3DSTATE_HIER_DEPTH_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN75_3DSTATE_HIER_DEPTH_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_HierarchicalDepthBufferObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_HierarchicalDepthBufferObjectControlState, &values->HierarchicalDepthBufferObjectControlState);
+   dw[1] =
+      __gen_field(dw_HierarchicalDepthBufferObjectControlState, 25, 28) |
+      __gen_field(values->SurfacePitch, 0, 16) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+}
+
+#define GEN75_3DSTATE_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_HS_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 27,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_HS_length 0x00000007
+
+struct GEN75_3DSTATE_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         Enable;
+   bool                                         StatisticsEnable;
+   uint32_t                                     InstanceCount;
+   uint32_t                                     KernelStartPointer;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     SingleProgramFlow;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+   bool                                         HSaccessesUAV;
+   bool                                         IncludeVertexHandles;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     SemaphoreHandle;
+};
+
+static inline void
+GEN75_3DSTATE_HS_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 12, 12) |
+      __gen_field(values->MaximumNumberofThreads, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Enable, 31, 31) |
+      __gen_field(values->StatisticsEnable, 29, 29) |
+      __gen_field(values->InstanceCount, 0, 3) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[4] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->SingleProgramFlow, 27, 27) |
+      __gen_field(values->VectorMaskEnable, 26, 26) |
+      __gen_field(values->HSaccessesUAV, 25, 25) |
+      __gen_field(values->IncludeVertexHandles, 24, 24) |
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 19, 23) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[6] =
+      __gen_offset(values->SemaphoreHandle, 0, 12) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_INDEX_BUFFER_length_bias 0x00000002
+#define GEN75_3DSTATE_INDEX_BUFFER_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 10,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_INDEX_BUFFER_length 0x00000003
+
+struct GEN75_3DSTATE_INDEX_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     MemoryObjectControlState;
+#define     INDEX_BYTE                                         0
+#define     INDEX_WORD                                         1
+#define     INDEX_DWORD                                        2
+   uint32_t                                     IndexFormat;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BufferStartingAddress;
+   __gen_address_type                           BufferEndingAddress;
+};
+
+static inline void
+GEN75_3DSTATE_INDEX_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_3DSTATE_INDEX_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_MemoryObjectControlState, 12, 15) |
+      __gen_field(values->IndexFormat, 8, 9) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BufferStartingAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->BufferEndingAddress, dw2);
+
+}
+
+#define GEN75_3DSTATE_LINE_STIPPLE_length_bias 0x00000002
+#define GEN75_3DSTATE_LINE_STIPPLE_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  8,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_LINE_STIPPLE_length 0x00000003
+
+struct GEN75_3DSTATE_LINE_STIPPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         ModifyEnableCurrentRepeatCounterCurrentStippleIndex;
+   uint32_t                                     CurrentRepeatCounter;
+   uint32_t                                     CurrentStippleIndex;
+   uint32_t                                     LineStipplePattern;
+   float                                        LineStippleInverseRepeatCount;
+   uint32_t                                     LineStippleRepeatCount;
+};
+
+static inline void
+GEN75_3DSTATE_LINE_STIPPLE_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_3DSTATE_LINE_STIPPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ModifyEnableCurrentRepeatCounterCurrentStippleIndex, 31, 31) |
+      __gen_field(values->CurrentRepeatCounter, 21, 29) |
+      __gen_field(values->CurrentStippleIndex, 16, 19) |
+      __gen_field(values->LineStipplePattern, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->LineStippleInverseRepeatCount * (1 << 16), 15, 31) |
+      __gen_field(values->LineStippleRepeatCount, 0, 8) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_MONOFILTER_SIZE_length_bias 0x00000002
+#define GEN75_3DSTATE_MONOFILTER_SIZE_header    \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 17,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_MONOFILTER_SIZE_length 0x00000002
+
+struct GEN75_3DSTATE_MONOFILTER_SIZE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     MonochromeFilterWidth;
+   uint32_t                                     MonochromeFilterHeight;
+};
+
+static inline void
+GEN75_3DSTATE_MONOFILTER_SIZE_pack(__gen_user_data *data, void * restrict dst,
+                                   const struct GEN75_3DSTATE_MONOFILTER_SIZE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MonochromeFilterWidth, 3, 5) |
+      __gen_field(values->MonochromeFilterHeight, 0, 2) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_MULTISAMPLE_length_bias 0x00000002
+#define GEN75_3DSTATE_MULTISAMPLE_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 13,                  \
+   .DwordLength          =  2
+
+#define GEN75_3DSTATE_MULTISAMPLE_length 0x00000004
+
+struct GEN75_3DSTATE_MULTISAMPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         MultiSampleEnable;
+#define     PIXLOC_CENTER                                      0
+#define     PIXLOC_UL_CORNER                                   1
+   uint32_t                                     PixelLocation;
+#define     NUMSAMPLES_1                                       0
+#define     NUMSAMPLES_4                                       2
+#define     NUMSAMPLES_8                                       3
+   uint32_t                                     NumberofMultisamples;
+   float                                        Sample3XOffset;
+   float                                        Sample3YOffset;
+   float                                        Sample2XOffset;
+   float                                        Sample2YOffset;
+   float                                        Sample1XOffset;
+   float                                        Sample1YOffset;
+   float                                        Sample0XOffset;
+   float                                        Sample0YOffset;
+   float                                        Sample7XOffset;
+   float                                        Sample7YOffset;
+   float                                        Sample6XOffset;
+   float                                        Sample6YOffset;
+   float                                        Sample5XOffset;
+   float                                        Sample5YOffset;
+   float                                        Sample4XOffset;
+   float                                        Sample4YOffset;
+};
+
+static inline void
+GEN75_3DSTATE_MULTISAMPLE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_MULTISAMPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MultiSampleEnable, 5, 5) |
+      __gen_field(values->PixelLocation, 4, 4) |
+      __gen_field(values->NumberofMultisamples, 1, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Sample3XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample3YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample2XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample2YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample1XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample1YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample0XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample0YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Sample7XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample7YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample6XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample6YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample5XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample5YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample4XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample4YOffset * (1 << 4), 0, 3) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_POLY_STIPPLE_OFFSET_length_bias 0x00000002
+#define GEN75_3DSTATE_POLY_STIPPLE_OFFSET_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  6,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_POLY_STIPPLE_OFFSET_length 0x00000002
+
+struct GEN75_3DSTATE_POLY_STIPPLE_OFFSET {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PolygonStippleXOffset;
+   uint32_t                                     PolygonStippleYOffset;
+};
+
+static inline void
+GEN75_3DSTATE_POLY_STIPPLE_OFFSET_pack(__gen_user_data *data, void * restrict dst,
+                                       const struct GEN75_3DSTATE_POLY_STIPPLE_OFFSET * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PolygonStippleXOffset, 8, 12) |
+      __gen_field(values->PolygonStippleYOffset, 0, 4) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_POLY_STIPPLE_PATTERN_length_bias 0x00000002
+#define GEN75_3DSTATE_POLY_STIPPLE_PATTERN_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  7,                  \
+   .DwordLength          = 31
+
+#define GEN75_3DSTATE_POLY_STIPPLE_PATTERN_length 0x00000021
+
+struct GEN75_3DSTATE_POLY_STIPPLE_PATTERN {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PatternRow[32];
+};
+
+static inline void
+GEN75_3DSTATE_POLY_STIPPLE_PATTERN_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN75_3DSTATE_POLY_STIPPLE_PATTERN * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   for (uint32_t i = 0, j = 1; i < 32; i += 1, j++) {
+      dw[j] =
+         __gen_field(values->PatternRow[i + 0], 0, 31) |
+         0;
+   }
+
+}
+
+#define GEN75_3DSTATE_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_PS_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 32,                  \
+   .DwordLength          =  6
+
+#define GEN75_3DSTATE_PS_length 0x00000008
+
+struct GEN75_3DSTATE_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer0;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleProgramFlowSPF;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnableVME;
+   uint32_t                                     SamplerCount;
+#define     FTZ                                                0
+#define     RET                                                1
+   uint32_t                                     DenormalMode;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadPriority;
+#define     IEEE745                                            0
+#define     Alt                                                1
+   uint32_t                                     FloatingPointMode;
+#define     RTNE                                               0
+#define     RU                                                 1
+#define     RD                                                 2
+#define     RTZ                                                3
+   uint32_t                                     RoundingMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     SampleMask;
+   bool                                         PushConstantEnable;
+   bool                                         AttributeEnable;
+   bool                                         oMaskPresenttoRenderTarget;
+   bool                                         RenderTargetFastClearEnable;
+   bool                                         DualSourceBlendEnable;
+   bool                                         RenderTargetResolveEnable;
+   bool                                         PSAccessesUAV;
+#define     POSOFFSET_NONE                                     0
+#define     POSOFFSET_CENTROID                                 2
+#define     POSOFFSET_SAMPLE                                   3
+   uint32_t                                     PositionXYOffsetSelect;
+   bool                                         _32PixelDispatchEnable;
+   bool                                         _16PixelDispatchEnable;
+   bool                                         _8PixelDispatchEnable;
+   uint32_t                                     DispatchGRFStartRegisterforConstantSetupData0;
+   uint32_t                                     DispatchGRFStartRegisterforConstantSetupData1;
+   uint32_t                                     DispatchGRFStartRegisterforConstantSetupData2;
+   uint32_t                                     KernelStartPointer1;
+   uint32_t                                     KernelStartPointer2;
+};
+
+static inline void
+GEN75_3DSTATE_PS_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer0, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleProgramFlowSPF, 31, 31) |
+      __gen_field(values->VectorMaskEnableVME, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->DenormalMode, 26, 26) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->RoundingMode, 14, 15) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->MaximumNumberofThreads, 23, 31) |
+      __gen_field(values->SampleMask, 12, 19) |
+      __gen_field(values->PushConstantEnable, 11, 11) |
+      __gen_field(values->AttributeEnable, 10, 10) |
+      __gen_field(values->oMaskPresenttoRenderTarget, 9, 9) |
+      __gen_field(values->RenderTargetFastClearEnable, 8, 8) |
+      __gen_field(values->DualSourceBlendEnable, 7, 7) |
+      __gen_field(values->RenderTargetResolveEnable, 6, 6) |
+      __gen_field(values->PSAccessesUAV, 5, 5) |
+      __gen_field(values->PositionXYOffsetSelect, 3, 4) |
+      __gen_field(values->_32PixelDispatchEnable, 2, 2) |
+      __gen_field(values->_16PixelDispatchEnable, 1, 1) |
+      __gen_field(values->_8PixelDispatchEnable, 0, 0) |
+      0;
+
+   dw[5] =
+      __gen_field(values->DispatchGRFStartRegisterforConstantSetupData0, 16, 22) |
+      __gen_field(values->DispatchGRFStartRegisterforConstantSetupData1, 8, 14) |
+      __gen_field(values->DispatchGRFStartRegisterforConstantSetupData2, 0, 6) |
+      0;
+
+   dw[6] =
+      __gen_offset(values->KernelStartPointer1, 6, 31) |
+      0;
+
+   dw[7] =
+      __gen_offset(values->KernelStartPointer2, 6, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 20,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_DS_length 0x00000002
+
+struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_DS_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 21,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_GS_length 0x00000002
+
+struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_GS_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 19,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_HS_length 0x00000002
+
+struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_HS_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 22,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_PS_length 0x00000002
+
+struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_PS_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 18,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_VS_length 0x00000002
+
+struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_VS_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN75_3DSTATE_PUSH_CONSTANT_ALLOC_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_RAST_MULTISAMPLE_length_bias 0x00000002
+#define GEN75_3DSTATE_RAST_MULTISAMPLE_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 14,                  \
+   .DwordLength          =  4
+
+#define GEN75_3DSTATE_RAST_MULTISAMPLE_length 0x00000006
+
+struct GEN75_3DSTATE_RAST_MULTISAMPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     NRM_NUMRASTSAMPLES_1                               0
+#define     NRM_NUMRASTSAMPLES_2                               1
+#define     NRM_NUMRASTSAMPLES_4                               2
+#define     NRM_NUMRASTSAMPLES_8                               3
+#define     NRM_NUMRASTSAMPLES_16                              4
+   uint32_t                                     NumberofRasterizationMultisamples;
+   float                                        Sample3XOffset;
+   float                                        Sample3YOffset;
+   float                                        Sample2XOffset;
+   float                                        Sample2YOffset;
+   float                                        Sample1XOffset;
+   float                                        Sample1YOffset;
+   float                                        Sample0XOffset;
+   float                                        Sample0YOffset;
+   float                                        Sample7XOffset;
+   float                                        Sample7YOffset;
+   float                                        Sample6XOffset;
+   float                                        Sample6YOffset;
+   float                                        Sample5XOffset;
+   float                                        Sample5YOffset;
+   float                                        Sample4XOffset;
+   float                                        Sample4YOffset;
+   float                                        Sample11XOffset;
+   float                                        Sample11YOffset;
+   float                                        Sample10XOffset;
+   float                                        Sample10YOffset;
+   float                                        Sample9XOffset;
+   float                                        Sample9YOffset;
+   float                                        Sample8XOffset;
+   float                                        Sample8YOffset;
+   float                                        Sample15XOffset;
+   float                                        Sample15YOffset;
+   float                                        Sample14XOffset;
+   float                                        Sample14YOffset;
+   float                                        Sample13XOffset;
+   float                                        Sample13YOffset;
+   float                                        Sample12XOffset;
+   float                                        Sample12YOffset;
+};
+
+static inline void
+GEN75_3DSTATE_RAST_MULTISAMPLE_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN75_3DSTATE_RAST_MULTISAMPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->NumberofRasterizationMultisamples, 1, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Sample3XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample3YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample2XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample2YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample1XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample1YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample0XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample0YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Sample7XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample7YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample6XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample6YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample5XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample5YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample4XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample4YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->Sample11XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample11YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample10XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample10YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample9XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample9YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample8XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample8YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->Sample15XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample15YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample14XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample14YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample13XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample13YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample12XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample12YOffset * (1 << 4), 0, 3) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SAMPLER_PALETTE_LOAD0_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_PALETTE_LOAD0_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  2
+
+#define GEN75_3DSTATE_SAMPLER_PALETTE_LOAD0_length 0x00000000
+
+#define GEN75_PALETTE_ENTRY_length 0x00000001
+
+struct GEN75_PALETTE_ENTRY {
+   uint32_t                                     Alpha;
+   uint32_t                                     Red;
+   uint32_t                                     Green;
+   uint32_t                                     Blue;
+};
+
+static inline void
+GEN75_PALETTE_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_PALETTE_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->Alpha, 24, 31) |
+      __gen_field(values->Red, 16, 23) |
+      __gen_field(values->Green, 8, 15) |
+      __gen_field(values->Blue, 0, 7) |
+      0;
+
+}
+
+struct GEN75_3DSTATE_SAMPLER_PALETTE_LOAD0 {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_PALETTE_LOAD0_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_SAMPLER_PALETTE_LOAD0 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_SAMPLER_PALETTE_LOAD1_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_PALETTE_LOAD1_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 12
+
+#define GEN75_3DSTATE_SAMPLER_PALETTE_LOAD1_length 0x00000000
+
+struct GEN75_3DSTATE_SAMPLER_PALETTE_LOAD1 {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_PALETTE_LOAD1_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN75_3DSTATE_SAMPLER_PALETTE_LOAD1 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 45,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_DS_length 0x00000002
+
+struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDSSamplerState;
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_STATE_POINTERS_DS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 46,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_GS_length 0x00000002
+
+struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoGSSamplerState;
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_STATE_POINTERS_GS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoGSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 44,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_HS_length 0x00000002
+
+struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoHSSamplerState;
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_STATE_POINTERS_HS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoHSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_PS_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 47,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_PS_length 0x00000002
+
+struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoPSSamplerState;
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_STATE_POINTERS_PS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoPSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 43,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SAMPLER_STATE_POINTERS_VS_length 0x00000002
+
+struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoVSSamplerState;
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLER_STATE_POINTERS_VS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN75_3DSTATE_SAMPLER_STATE_POINTERS_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoVSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SAMPLE_MASK_length_bias 0x00000002
+#define GEN75_3DSTATE_SAMPLE_MASK_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 24,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SAMPLE_MASK_length 0x00000002
+
+struct GEN75_3DSTATE_SAMPLE_MASK {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SampleMask;
+};
+
+static inline void
+GEN75_3DSTATE_SAMPLE_MASK_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_3DSTATE_SAMPLE_MASK * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SampleMask, 0, 7) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SBE_length_bias 0x00000002
+#define GEN75_3DSTATE_SBE_header                \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 31,                  \
+   .DwordLength          = 12
+
+#define GEN75_3DSTATE_SBE_length 0x0000000e
+
+struct GEN75_3DSTATE_SBE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     AttributeSwizzleControlMode;
+   uint32_t                                     NumberofSFOutputAttributes;
+   bool                                         AttributeSwizzleEnable;
+#define     UPPERLEFT                                          0
+#define     LOWERLEFT                                          1
+   uint32_t                                     PointSpriteTextureCoordinateOrigin;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   bool                                         Attribute2n1ComponentOverrideW;
+   bool                                         Attribute2n1ComponentOverrideZ;
+   bool                                         Attribute2n1ComponentOverrideY;
+   bool                                         Attribute2n1ComponentOverrideX;
+#define     CONST_0000                                         0
+#define     CONST_0001_FLOAT                                   1
+#define     CONST_1111_FLOAT                                   2
+#define     PRIM_ID                                            3
+   uint32_t                                     Attribute2n1ConstantSource;
+#define     INPUTATTR                                          0
+#define     INPUTATTR_FACING                                   1
+#define     INPUTATTR_W                                        2
+#define     INPUTATTR_FACING_W                                 3
+   uint32_t                                     Attribute2n1SwizzleSelect;
+   uint32_t                                     Attribute2n1SourceAttribute;
+   bool                                         Attribute2nComponentOverrideW;
+   bool                                         Attribute2nComponentOverrideZ;
+   bool                                         Attribute2nComponentOverrideY;
+   bool                                         Attribute2nComponentOverrideX;
+#define     CONST_0000                                         0
+#define     CONST_0001_FLOAT                                   1
+#define     CONST_1111_FLOAT                                   2
+#define     PRIM_ID                                            3
+   uint32_t                                     Attribute2nConstantSource;
+#define     INPUTATTR                                          0
+#define     INPUTATTR_FACING                                   1
+#define     INPUTATTR_W                                        2
+#define     INPUTATTR_FACING_W                                 3
+   uint32_t                                     Attribute2nSwizzleSelect;
+   uint32_t                                     Attribute2nSourceAttribute;
+   uint32_t                                     PointSpriteTextureCoordinateEnable;
+   uint32_t                                     ConstantInterpolationEnable310;
+   uint32_t                                     Attribute7WrapShortestEnables;
+   uint32_t                                     Attribute6WrapShortestEnables;
+   uint32_t                                     Attribute5WrapShortestEnables;
+   uint32_t                                     Attribute4WrapShortestEnables;
+   uint32_t                                     Attribute3WrapShortestEnables;
+   uint32_t                                     Attribute2WrapShortestEnables;
+   uint32_t                                     Attribute1WrapShortestEnables;
+   uint32_t                                     Attribute0WrapShortestEnables;
+   uint32_t                                     Attribute15WrapShortestEnables;
+   uint32_t                                     Attribute14WrapShortestEnables;
+   uint32_t                                     Attribute13WrapShortestEnables;
+   uint32_t                                     Attribute12WrapShortestEnables;
+   uint32_t                                     Attribute11WrapShortestEnables;
+   uint32_t                                     Attribute10WrapShortestEnables;
+   uint32_t                                     Attribute9WrapShortestEnables;
+   uint32_t                                     Attribute8WrapShortestEnables;
+};
+
+static inline void
+GEN75_3DSTATE_SBE_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN75_3DSTATE_SBE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AttributeSwizzleControlMode, 28, 28) |
+      __gen_field(values->NumberofSFOutputAttributes, 22, 27) |
+      __gen_field(values->AttributeSwizzleEnable, 21, 21) |
+      __gen_field(values->PointSpriteTextureCoordinateOrigin, 20, 20) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 15) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Attribute2n1ComponentOverrideW, 31, 31) |
+      __gen_field(values->Attribute2n1ComponentOverrideZ, 30, 30) |
+      __gen_field(values->Attribute2n1ComponentOverrideY, 29, 29) |
+      __gen_field(values->Attribute2n1ComponentOverrideX, 28, 28) |
+      __gen_field(values->Attribute2n1ConstantSource, 25, 26) |
+      __gen_field(values->Attribute2n1SwizzleSelect, 22, 23) |
+      __gen_field(values->Attribute2n1SourceAttribute, 16, 20) |
+      __gen_field(values->Attribute2nComponentOverrideW, 15, 15) |
+      __gen_field(values->Attribute2nComponentOverrideZ, 14, 14) |
+      __gen_field(values->Attribute2nComponentOverrideY, 13, 13) |
+      __gen_field(values->Attribute2nComponentOverrideX, 12, 12) |
+      __gen_field(values->Attribute2nConstantSource, 9, 10) |
+      __gen_field(values->Attribute2nSwizzleSelect, 6, 7) |
+      __gen_field(values->Attribute2nSourceAttribute, 0, 4) |
+      0;
+
+   dw[10] =
+      __gen_field(values->PointSpriteTextureCoordinateEnable, 0, 31) |
+      0;
+
+   dw[11] =
+      __gen_field(values->ConstantInterpolationEnable310, 0, 31) |
+      0;
+
+   dw[12] =
+      __gen_field(values->Attribute7WrapShortestEnables, 28, 31) |
+      __gen_field(values->Attribute6WrapShortestEnables, 24, 27) |
+      __gen_field(values->Attribute5WrapShortestEnables, 20, 23) |
+      __gen_field(values->Attribute4WrapShortestEnables, 16, 19) |
+      __gen_field(values->Attribute3WrapShortestEnables, 12, 15) |
+      __gen_field(values->Attribute2WrapShortestEnables, 8, 11) |
+      __gen_field(values->Attribute1WrapShortestEnables, 4, 7) |
+      __gen_field(values->Attribute0WrapShortestEnables, 0, 3) |
+      0;
+
+   dw[13] =
+      __gen_field(values->Attribute15WrapShortestEnables, 28, 31) |
+      __gen_field(values->Attribute14WrapShortestEnables, 24, 27) |
+      __gen_field(values->Attribute13WrapShortestEnables, 20, 23) |
+      __gen_field(values->Attribute12WrapShortestEnables, 16, 19) |
+      __gen_field(values->Attribute11WrapShortestEnables, 12, 15) |
+      __gen_field(values->Attribute10WrapShortestEnables, 8, 11) |
+      __gen_field(values->Attribute9WrapShortestEnables, 4, 7) |
+      __gen_field(values->Attribute8WrapShortestEnables, 0, 3) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SCISSOR_STATE_POINTERS_length_bias 0x00000002
+#define GEN75_3DSTATE_SCISSOR_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 15,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_SCISSOR_STATE_POINTERS_length 0x00000002
+
+struct GEN75_3DSTATE_SCISSOR_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ScissorRectPointer;
+};
+
+static inline void
+GEN75_3DSTATE_SCISSOR_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN75_3DSTATE_SCISSOR_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ScissorRectPointer, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SF_length_bias 0x00000002
+#define GEN75_3DSTATE_SF_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 19,                  \
+   .DwordLength          =  5
+
+#define GEN75_3DSTATE_SF_length 0x00000007
+
+struct GEN75_3DSTATE_SF {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     D32_FLOAT_S8X24_UINT                               0
+#define     D32_FLOAT                                          1
+#define     D24_UNORM_S8_UINT                                  2
+#define     D24_UNORM_X8_UINT                                  3
+#define     D16_UNORM                                          5
+   uint32_t                                     DepthBufferSurfaceFormat;
+   bool                                         LegacyGlobalDepthBiasEnable;
+   bool                                         StatisticsEnable;
+   bool                                         GlobalDepthOffsetEnableSolid;
+   bool                                         GlobalDepthOffsetEnableWireframe;
+   bool                                         GlobalDepthOffsetEnablePoint;
+#define     RASTER_SOLID                                       0
+#define     RASTER_WIREFRAME                                   1
+#define     RASTER_POINT                                       2
+   uint32_t                                     FrontFaceFillMode;
+#define     RASTER_SOLID                                       0
+#define     RASTER_WIREFRAME                                   1
+#define     RASTER_POINT                                       2
+   uint32_t                                     BackFaceFillMode;
+   bool                                         ViewTransformEnable;
+   uint32_t                                     FrontWinding;
+   bool                                         AntiAliasingEnable;
+#define     CULLMODE_BOTH                                      0
+#define     CULLMODE_NONE                                      1
+#define     CULLMODE_FRONT                                     2
+#define     CULLMODE_BACK                                      3
+   uint32_t                                     CullMode;
+   float                                        LineWidth;
+   uint32_t                                     LineEndCapAntialiasingRegionWidth;
+   bool                                         LineStippleEnable;
+   bool                                         ScissorRectangleEnable;
+   bool                                         RTIndependentRasterizationEnable;
+   uint32_t                                     MultisampleRasterizationMode;
+   bool                                         LastPixelEnable;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleStripListProvokingVertexSelect;
+   uint32_t                                     LineStripListProvokingVertexSelect;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleFanProvokingVertexSelect;
+#define     AALINEDISTANCE_TRUE                                1
+   uint32_t                                     AALineDistanceMode;
+   uint32_t                                     VertexSubPixelPrecisionSelect;
+   uint32_t                                     UsePointWidthState;
+   float                                        PointWidth;
+   float                                        GlobalDepthOffsetConstant;
+   float                                        GlobalDepthOffsetScale;
+   float                                        GlobalDepthOffsetClamp;
+};
+
+static inline void
+GEN75_3DSTATE_SF_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_SF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DepthBufferSurfaceFormat, 12, 14) |
+      __gen_field(values->LegacyGlobalDepthBiasEnable, 11, 11) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->GlobalDepthOffsetEnableSolid, 9, 9) |
+      __gen_field(values->GlobalDepthOffsetEnableWireframe, 8, 8) |
+      __gen_field(values->GlobalDepthOffsetEnablePoint, 7, 7) |
+      __gen_field(values->FrontFaceFillMode, 5, 6) |
+      __gen_field(values->BackFaceFillMode, 3, 4) |
+      __gen_field(values->ViewTransformEnable, 1, 1) |
+      __gen_field(values->FrontWinding, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_field(values->AntiAliasingEnable, 31, 31) |
+      __gen_field(values->CullMode, 29, 30) |
+      __gen_field(values->LineWidth * (1 << 7), 18, 27) |
+      __gen_field(values->LineEndCapAntialiasingRegionWidth, 16, 17) |
+      __gen_field(values->LineStippleEnable, 14, 14) |
+      __gen_field(values->ScissorRectangleEnable, 11, 11) |
+      __gen_field(values->RTIndependentRasterizationEnable, 10, 10) |
+      __gen_field(values->MultisampleRasterizationMode, 8, 9) |
+      0;
+
+   dw[3] =
+      __gen_field(values->LastPixelEnable, 31, 31) |
+      __gen_field(values->TriangleStripListProvokingVertexSelect, 29, 30) |
+      __gen_field(values->LineStripListProvokingVertexSelect, 27, 28) |
+      __gen_field(values->TriangleFanProvokingVertexSelect, 25, 26) |
+      __gen_field(values->AALineDistanceMode, 14, 14) |
+      __gen_field(values->VertexSubPixelPrecisionSelect, 12, 12) |
+      __gen_field(values->UsePointWidthState, 11, 11) |
+      __gen_field(values->PointWidth * (1 << 3), 0, 10) |
+      0;
+
+   dw[4] =
+      __gen_float(values->GlobalDepthOffsetConstant) |
+      0;
+
+   dw[5] =
+      __gen_float(values->GlobalDepthOffsetScale) |
+      0;
+
+   dw[6] =
+      __gen_float(values->GlobalDepthOffsetClamp) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_SO_BUFFER_length_bias 0x00000002
+#define GEN75_3DSTATE_SO_BUFFER_header          \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 24,                  \
+   .DwordLength          =  2
+
+#define GEN75_3DSTATE_SO_BUFFER_length 0x00000004
+
+struct GEN75_3DSTATE_SO_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SOBufferIndex;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     SOBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   __gen_address_type                           SurfaceEndAddress;
+};
+
+static inline void
+GEN75_3DSTATE_SO_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_3DSTATE_SO_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SOBufferObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SOBufferObjectControlState, &values->SOBufferObjectControlState);
+   dw[1] =
+      __gen_field(values->SOBufferIndex, 29, 30) |
+      __gen_field(dw_SOBufferObjectControlState, 25, 28) |
+      __gen_field(values->SurfacePitch, 0, 11) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->SurfaceEndAddress, dw3);
+
+}
+
+#define GEN75_3DSTATE_SO_DECL_LIST_length_bias 0x00000002
+#define GEN75_3DSTATE_SO_DECL_LIST_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 23
+
+#define GEN75_3DSTATE_SO_DECL_LIST_length 0x00000000
+
+#define GEN75_SO_DECL_ENTRY_length 0x00000002
+
+#define GEN75_SO_DECL_length 0x00000001
+
+struct GEN75_SO_DECL {
+   uint32_t                                     OutputBufferSlot;
+   uint32_t                                     HoleFlag;
+   uint32_t                                     RegisterIndex;
+   uint32_t                                     ComponentMask;
+};
+
+static inline void
+GEN75_SO_DECL_pack(__gen_user_data *data, void * restrict dst,
+                   const struct GEN75_SO_DECL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->OutputBufferSlot, 12, 13) |
+      __gen_field(values->HoleFlag, 11, 11) |
+      __gen_field(values->RegisterIndex, 4, 9) |
+      __gen_field(values->ComponentMask, 0, 3) |
+      0;
+
+}
+
+struct GEN75_SO_DECL_ENTRY {
+   struct GEN75_SO_DECL                         Stream3Decl;
+   struct GEN75_SO_DECL                         Stream2Decl;
+   struct GEN75_SO_DECL                         Stream1Decl;
+   struct GEN75_SO_DECL                         Stream0Decl;
+};
+
+static inline void
+GEN75_SO_DECL_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_SO_DECL_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_Stream3Decl;
+   GEN75_SO_DECL_pack(data, &dw_Stream3Decl, &values->Stream3Decl);
+   uint32_t dw_Stream2Decl;
+   GEN75_SO_DECL_pack(data, &dw_Stream2Decl, &values->Stream2Decl);
+   uint32_t dw_Stream1Decl;
+   GEN75_SO_DECL_pack(data, &dw_Stream1Decl, &values->Stream1Decl);
+   uint32_t dw_Stream0Decl;
+   GEN75_SO_DECL_pack(data, &dw_Stream0Decl, &values->Stream0Decl);
+   uint64_t qw0 =
+      __gen_field(dw_Stream3Decl, 48, 63) |
+      __gen_field(dw_Stream2Decl, 32, 47) |
+      __gen_field(dw_Stream1Decl, 16, 31) |
+      __gen_field(dw_Stream0Decl, 0, 15) |
+      0;
+
+   dw[0] = qw0;
+   dw[1] = qw0 >> 32;
+
+}
+
+struct GEN75_3DSTATE_SO_DECL_LIST {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StreamtoBufferSelects3;
+   uint32_t                                     StreamtoBufferSelects2;
+   uint32_t                                     StreamtoBufferSelects1;
+   uint32_t                                     StreamtoBufferSelects0;
+   uint32_t                                     NumEntries3;
+   uint32_t                                     NumEntries2;
+   uint32_t                                     NumEntries1;
+   uint32_t                                     NumEntries0;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_SO_DECL_LIST_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_3DSTATE_SO_DECL_LIST * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StreamtoBufferSelects3, 12, 15) |
+      __gen_field(values->StreamtoBufferSelects2, 8, 11) |
+      __gen_field(values->StreamtoBufferSelects1, 4, 7) |
+      __gen_field(values->StreamtoBufferSelects0, 0, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->NumEntries3, 24, 31) |
+      __gen_field(values->NumEntries2, 16, 23) |
+      __gen_field(values->NumEntries1, 8, 15) |
+      __gen_field(values->NumEntries0, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_STENCIL_BUFFER_length_bias 0x00000002
+#define GEN75_3DSTATE_STENCIL_BUFFER_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  6,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_STENCIL_BUFFER_length 0x00000003
+
+struct GEN75_3DSTATE_STENCIL_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StencilBufferEnable;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     StencilBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+};
+
+static inline void
+GEN75_3DSTATE_STENCIL_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN75_3DSTATE_STENCIL_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_StencilBufferObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_StencilBufferObjectControlState, &values->StencilBufferObjectControlState);
+   dw[1] =
+      __gen_field(values->StencilBufferEnable, 31, 31) |
+      __gen_field(dw_StencilBufferObjectControlState, 25, 28) |
+      __gen_field(values->SurfacePitch, 0, 16) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+}
+
+#define GEN75_3DSTATE_STREAMOUT_length_bias 0x00000002
+#define GEN75_3DSTATE_STREAMOUT_header          \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 30,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_STREAMOUT_length 0x00000003
+
+struct GEN75_3DSTATE_STREAMOUT {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SOFunctionEnable;
+   uint32_t                                     RenderingDisable;
+   uint32_t                                     RenderStreamSelect;
+#define     LEADING                                            0
+#define     TRAILING                                           1
+   uint32_t                                     ReorderMode;
+   bool                                         SOStatisticsEnable;
+   uint32_t                                     SOBufferEnable3;
+   uint32_t                                     SOBufferEnable2;
+   uint32_t                                     SOBufferEnable1;
+   uint32_t                                     SOBufferEnable0;
+   uint32_t                                     Stream3VertexReadOffset;
+   uint32_t                                     Stream3VertexReadLength;
+   uint32_t                                     Stream2VertexReadOffset;
+   uint32_t                                     Stream2VertexReadLength;
+   uint32_t                                     Stream1VertexReadOffset;
+   uint32_t                                     Stream1VertexReadLength;
+   uint32_t                                     Stream0VertexReadOffset;
+   uint32_t                                     Stream0VertexReadLength;
+};
+
+static inline void
+GEN75_3DSTATE_STREAMOUT_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_3DSTATE_STREAMOUT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SOFunctionEnable, 31, 31) |
+      __gen_field(values->RenderingDisable, 30, 30) |
+      __gen_field(values->RenderStreamSelect, 27, 28) |
+      __gen_field(values->ReorderMode, 26, 26) |
+      __gen_field(values->SOStatisticsEnable, 25, 25) |
+      __gen_field(values->SOBufferEnable3, 11, 11) |
+      __gen_field(values->SOBufferEnable2, 10, 10) |
+      __gen_field(values->SOBufferEnable1, 9, 9) |
+      __gen_field(values->SOBufferEnable0, 8, 8) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Stream3VertexReadOffset, 29, 29) |
+      __gen_field(values->Stream3VertexReadLength, 24, 28) |
+      __gen_field(values->Stream2VertexReadOffset, 21, 21) |
+      __gen_field(values->Stream2VertexReadLength, 16, 20) |
+      __gen_field(values->Stream1VertexReadOffset, 13, 13) |
+      __gen_field(values->Stream1VertexReadLength, 8, 12) |
+      __gen_field(values->Stream0VertexReadOffset, 5, 5) |
+      __gen_field(values->Stream0VertexReadLength, 0, 4) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_TE_length_bias 0x00000002
+#define GEN75_3DSTATE_TE_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 28,                  \
+   .DwordLength          =  2
+
+#define GEN75_3DSTATE_TE_length 0x00000004
+
+struct GEN75_3DSTATE_TE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     INTEGER                                            0
+#define     ODD_FRACTIONAL                                     1
+#define     EVEN_FRACTIONAL                                    2
+   uint32_t                                     Partitioning;
+#define     POINT                                              0
+#define     OUTPUT_LINE                                        1
+#define     OUTPUT_TRI_CW                                      2
+#define     OUTPUT_TRI_CCW                                     3
+   uint32_t                                     OutputTopology;
+#define     QUAD                                               0
+#define     TRI                                                1
+#define     ISOLINE                                            2
+   uint32_t                                     TEDomain;
+#define     HW_TESS                                            0
+#define     SW_TESS                                            1
+   uint32_t                                     TEMode;
+   bool                                         TEEnable;
+   float                                        MaximumTessellationFactorOdd;
+   float                                        MaximumTessellationFactorNotOdd;
+};
+
+static inline void
+GEN75_3DSTATE_TE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_TE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Partitioning, 12, 13) |
+      __gen_field(values->OutputTopology, 8, 9) |
+      __gen_field(values->TEDomain, 4, 5) |
+      __gen_field(values->TEMode, 1, 2) |
+      __gen_field(values->TEEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_float(values->MaximumTessellationFactorOdd) |
+      0;
+
+   dw[3] =
+      __gen_float(values->MaximumTessellationFactorNotOdd) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_URB_DS_length_bias 0x00000002
+#define GEN75_3DSTATE_URB_DS_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 50,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_URB_DS_length 0x00000002
+
+struct GEN75_3DSTATE_URB_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     DSURBStartingAddress;
+   uint32_t                                     DSURBEntryAllocationSize;
+   uint32_t                                     DSNumberofURBEntries;
+};
+
+static inline void
+GEN75_3DSTATE_URB_DS_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_3DSTATE_URB_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DSURBStartingAddress, 25, 30) |
+      __gen_field(values->DSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->DSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_URB_GS_length_bias 0x00000002
+#define GEN75_3DSTATE_URB_GS_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 51,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_URB_GS_length 0x00000002
+
+struct GEN75_3DSTATE_URB_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     GSURBStartingAddress;
+   uint32_t                                     GSURBEntryAllocationSize;
+   uint32_t                                     GSNumberofURBEntries;
+};
+
+static inline void
+GEN75_3DSTATE_URB_GS_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_3DSTATE_URB_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->GSURBStartingAddress, 25, 30) |
+      __gen_field(values->GSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->GSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_URB_HS_length_bias 0x00000002
+#define GEN75_3DSTATE_URB_HS_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 49,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_URB_HS_length 0x00000002
+
+struct GEN75_3DSTATE_URB_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     HSURBStartingAddress;
+   uint32_t                                     HSURBEntryAllocationSize;
+   uint32_t                                     HSNumberofURBEntries;
+};
+
+static inline void
+GEN75_3DSTATE_URB_HS_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_3DSTATE_URB_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->HSURBStartingAddress, 25, 30) |
+      __gen_field(values->HSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->HSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_VERTEX_BUFFERS_length_bias 0x00000002
+#define GEN75_3DSTATE_VERTEX_BUFFERS_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  8
+
+#define GEN75_3DSTATE_VERTEX_BUFFERS_length 0x00000000
+
+#define GEN75_VERTEX_BUFFER_STATE_length 0x00000004
+
+struct GEN75_VERTEX_BUFFER_STATE {
+   uint32_t                                     VertexBufferIndex;
+#define     VERTEXDATA                                         0
+#define     INSTANCEDATA                                       1
+   uint32_t                                     BufferAccessType;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     VertexBufferMemoryObjectControlState;
+   uint32_t                                     AddressModifyEnable;
+   bool                                         NullVertexBuffer;
+   uint32_t                                     VertexFetchInvalidate;
+   uint32_t                                     BufferPitch;
+   __gen_address_type                           BufferStartingAddress;
+   __gen_address_type                           EndAddress;
+   uint32_t                                     InstanceDataStepRate;
+};
+
+static inline void
+GEN75_VERTEX_BUFFER_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_VERTEX_BUFFER_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_VertexBufferMemoryObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_VertexBufferMemoryObjectControlState, &values->VertexBufferMemoryObjectControlState);
+   dw[0] =
+      __gen_field(values->VertexBufferIndex, 26, 31) |
+      __gen_field(values->BufferAccessType, 20, 20) |
+      __gen_field(dw_VertexBufferMemoryObjectControlState, 16, 19) |
+      __gen_field(values->AddressModifyEnable, 14, 14) |
+      __gen_field(values->NullVertexBuffer, 13, 13) |
+      __gen_field(values->VertexFetchInvalidate, 12, 12) |
+      __gen_field(values->BufferPitch, 0, 11) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BufferStartingAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->EndAddress, dw2);
+
+   dw[3] =
+      __gen_field(values->InstanceDataStepRate, 0, 31) |
+      0;
+
+}
+
+struct GEN75_3DSTATE_VERTEX_BUFFERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_VERTEX_BUFFERS_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN75_3DSTATE_VERTEX_BUFFERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_VERTEX_ELEMENTS_length_bias 0x00000002
+#define GEN75_3DSTATE_VERTEX_ELEMENTS_header    \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  9
+
+#define GEN75_3DSTATE_VERTEX_ELEMENTS_length 0x00000000
+
+#define GEN75_VERTEX_ELEMENT_STATE_length 0x00000002
+
+struct GEN75_VERTEX_ELEMENT_STATE {
+   uint32_t                                     VertexBufferIndex;
+   bool                                         Valid;
+   uint32_t                                     SourceElementFormat;
+   bool                                         EdgeFlagEnable;
+   uint32_t                                     SourceElementOffset;
+   uint32_t                                     Component0Control;
+   uint32_t                                     Component1Control;
+   uint32_t                                     Component2Control;
+   uint32_t                                     Component3Control;
+};
+
+static inline void
+GEN75_VERTEX_ELEMENT_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_VERTEX_ELEMENT_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->VertexBufferIndex, 26, 31) |
+      __gen_field(values->Valid, 25, 25) |
+      __gen_field(values->SourceElementFormat, 16, 24) |
+      __gen_field(values->EdgeFlagEnable, 15, 15) |
+      __gen_field(values->SourceElementOffset, 0, 11) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Component0Control, 28, 30) |
+      __gen_field(values->Component1Control, 24, 26) |
+      __gen_field(values->Component2Control, 20, 22) |
+      __gen_field(values->Component3Control, 16, 18) |
+      0;
+
+}
+
+struct GEN75_3DSTATE_VERTEX_ELEMENTS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_3DSTATE_VERTEX_ELEMENTS_pack(__gen_user_data *data, void * restrict dst,
+                                   const struct GEN75_3DSTATE_VERTEX_ELEMENTS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_3DSTATE_VF_length_bias 0x00000002
+#define GEN75_3DSTATE_VF_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 12,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_VF_length 0x00000002
+
+struct GEN75_3DSTATE_VF {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         IndexedDrawCutIndexEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CutIndex;
+};
+
+static inline void
+GEN75_3DSTATE_VF_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_VF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->IndexedDrawCutIndexEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->CutIndex, 0, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_VF_STATISTICS_length_bias 0x00000001
+#define GEN75_3DSTATE_VF_STATISTICS_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  1,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 11
+
+#define GEN75_3DSTATE_VF_STATISTICS_length 0x00000001
+
+struct GEN75_3DSTATE_VF_STATISTICS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         StatisticsEnable;
+};
+
+static inline void
+GEN75_3DSTATE_VF_STATISTICS_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN75_3DSTATE_VF_STATISTICS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->StatisticsEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_CC_length_bias 0x00000002
+#define GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_CC_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 35,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_CC_length 0x00000002
+
+struct GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_CC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CCViewportPointer;
+};
+
+static inline void
+GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_CC_pack(__gen_user_data *data, void * restrict dst,
+                                              const struct GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_CC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->CCViewportPointer, 5, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_length_bias 0x00000002
+#define GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 33,                  \
+   .DwordLength          =  0
+
+#define GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_length 0x00000002
+
+struct GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SFClipViewportPointer;
+};
+
+static inline void
+GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_pack(__gen_user_data *data, void * restrict dst,
+                                                   const struct GEN75_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SFClipViewportPointer, 6, 31) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_VS_length_bias 0x00000002
+#define GEN75_3DSTATE_VS_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 16,                  \
+   .DwordLength          =  4
+
+#define GEN75_3DSTATE_VS_length 0x00000006
+
+struct GEN75_3DSTATE_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleVertexDispatch;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnableVME;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     NormalPriority                                     0
+#define     HighPriority                                       1
+   uint32_t                                     ThreadPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         VSaccessesUAV;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBaseOffset;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     DispatchGRFStartRegisterforURBData;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         StatisticsEnable;
+   bool                                         VertexCacheDisable;
+   bool                                         VSFunctionEnable;
+};
+
+static inline void
+GEN75_3DSTATE_VS_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleVertexDispatch, 31, 31) |
+      __gen_field(values->VectorMaskEnableVME, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->VSaccessesUAV, 12, 12) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBaseOffset, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DispatchGRFStartRegisterforURBData, 20, 24) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[5] =
+      __gen_field(values->MaximumNumberofThreads, 23, 31) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->VertexCacheDisable, 1, 1) |
+      __gen_field(values->VSFunctionEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN75_3DSTATE_WM_length_bias 0x00000002
+#define GEN75_3DSTATE_WM_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 20,                  \
+   .DwordLength          =  1
+
+#define GEN75_3DSTATE_WM_length 0x00000003
+
+struct GEN75_3DSTATE_WM {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         StatisticsEnable;
+   bool                                         DepthBufferClear;
+   bool                                         ThreadDispatchEnable;
+   bool                                         DepthBufferResolveEnable;
+   bool                                         HierarchicalDepthBufferResolveEnable;
+   bool                                         LegacyDiamondLineRasterization;
+   bool                                         PixelShaderKillPixel;
+#define     PSCDEPTH_OFF                                       0
+#define     PSCDEPTH_ON                                        1
+#define     PSCDEPTH_ON_GE                                     2
+#define     PSCDEPTH_ON_LE                                     3
+   uint32_t                                     PixelShaderComputedDepthMode;
+#define     EDSC_NORMAL                                        0
+#define     EDSC_PSEXEC                                        1
+#define     EDSC_PREPS                                         2
+   uint32_t                                     EarlyDepthStencilControl;
+   bool                                         PixelShaderUsesSourceDepth;
+   bool                                         PixelShaderUsesSourceW;
+#define     INTERP_PIXEL                                       0
+#define     INTERP_CENTROID                                    2
+#define     INTERP_SAMPLE                                      3
+   uint32_t                                     PositionZWInterpolationMode;
+   uint32_t                                     BarycentricInterpolationMode;
+   bool                                         PixelShaderUsesInputCoverageMask;
+   uint32_t                                     LineEndCapAntialiasingRegionWidth;
+   uint32_t                                     LineAntialiasingRegionWidth;
+   bool                                         RTIndependentRasterizationEnable;
+   bool                                         PolygonStippleEnable;
+   bool                                         LineStippleEnable;
+#define     RASTRULE_UPPER_LEFT                                0
+#define     RASTRULE_UPPER_RIGHT                               1
+   uint32_t                                     PointRasterizationRule;
+#define     MSRASTMODE_OFF_PIXEL                               0
+#define     MSRASTMODE_OFF_PATTERN                             1
+#define     MSRASTMODE_ON_PIXEL                                2
+#define     MSRASTMODE_ON_PATTERN                              3
+   uint32_t                                     MultisampleRasterizationMode;
+#define     MSDISPMODE_PERSAMPLE                               0
+#define     MSDISPMODE_PERPIXEL                                1
+   uint32_t                                     MultisampleDispatchMode;
+#define     OFF                                                0
+#define     ON                                                 1
+   uint32_t                                     PSUAVonly;
+};
+
+static inline void
+GEN75_3DSTATE_WM_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_3DSTATE_WM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StatisticsEnable, 31, 31) |
+      __gen_field(values->DepthBufferClear, 30, 30) |
+      __gen_field(values->ThreadDispatchEnable, 29, 29) |
+      __gen_field(values->DepthBufferResolveEnable, 28, 28) |
+      __gen_field(values->HierarchicalDepthBufferResolveEnable, 27, 27) |
+      __gen_field(values->LegacyDiamondLineRasterization, 26, 26) |
+      __gen_field(values->PixelShaderKillPixel, 25, 25) |
+      __gen_field(values->PixelShaderComputedDepthMode, 23, 24) |
+      __gen_field(values->EarlyDepthStencilControl, 21, 22) |
+      __gen_field(values->PixelShaderUsesSourceDepth, 20, 20) |
+      __gen_field(values->PixelShaderUsesSourceW, 19, 19) |
+      __gen_field(values->PositionZWInterpolationMode, 17, 18) |
+      __gen_field(values->BarycentricInterpolationMode, 11, 16) |
+      __gen_field(values->PixelShaderUsesInputCoverageMask, 10, 10) |
+      __gen_field(values->LineEndCapAntialiasingRegionWidth, 8, 9) |
+      __gen_field(values->LineAntialiasingRegionWidth, 6, 7) |
+      __gen_field(values->RTIndependentRasterizationEnable, 5, 5) |
+      __gen_field(values->PolygonStippleEnable, 4, 4) |
+      __gen_field(values->LineStippleEnable, 3, 3) |
+      __gen_field(values->PointRasterizationRule, 2, 2) |
+      __gen_field(values->MultisampleRasterizationMode, 0, 1) |
+      0;
+
+   dw[2] =
+      __gen_field(values->MultisampleDispatchMode, 31, 31) |
+      __gen_field(values->PSUAVonly, 30, 30) |
+      0;
+
+}
+
+#define GEN75_GPGPU_OBJECT_length_bias 0x00000002
+#define GEN75_GPGPU_OBJECT_header               \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  4,                  \
+   .DwordLength          =  6
+
+#define GEN75_GPGPU_OBJECT_length 0x00000008
+
+struct GEN75_GPGPU_OBJECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SharedLocalMemoryFixedOffset;
+   uint32_t                                     InterfaceDescriptorOffset;
+   uint32_t                                     SharedLocalMemoryOffset;
+   uint32_t                                     EndofThreadGroup;
+#define     Slice0                                             0
+#define     Slice1                                             1
+   uint32_t                                     SliceDestinationSelect;
+#define     HalfSlice1                                         2
+#define     HalfSlice0                                         1
+#define     EitherHalfSlice                                    0
+   uint32_t                                     HalfSliceDestinationSelect;
+   uint32_t                                     IndirectDataLength;
+   uint32_t                                     IndirectDataStartAddress;
+   uint32_t                                     ThreadGroupIDX;
+   uint32_t                                     ThreadGroupIDY;
+   uint32_t                                     ThreadGroupIDZ;
+   uint32_t                                     ExecutionMask;
+};
+
+static inline void
+GEN75_GPGPU_OBJECT_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_GPGPU_OBJECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SharedLocalMemoryFixedOffset, 7, 7) |
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SharedLocalMemoryOffset, 28, 31) |
+      __gen_field(values->EndofThreadGroup, 24, 24) |
+      __gen_field(values->SliceDestinationSelect, 19, 19) |
+      __gen_field(values->HalfSliceDestinationSelect, 17, 18) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->IndirectDataStartAddress, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ThreadGroupIDX, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ThreadGroupIDY, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ThreadGroupIDZ, 0, 31) |
+      0;
+
+   dw[7] =
+      __gen_field(values->ExecutionMask, 0, 31) |
+      0;
+
+}
+
+#define GEN75_GPGPU_WALKER_length_bias 0x00000002
+#define GEN75_GPGPU_WALKER_header               \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcodeA           =  5,                  \
+   .DwordLength          =  9
+
+#define GEN75_GPGPU_WALKER_length 0x0000000b
+
+struct GEN75_GPGPU_WALKER {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcodeA;
+   bool                                         IndirectParameterEnable;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+#define     SIMD8                                              0
+#define     SIMD16                                             1
+#define     SIMD32                                             2
+   uint32_t                                     SIMDSize;
+   uint32_t                                     ThreadDepthCounterMaximum;
+   uint32_t                                     ThreadHeightCounterMaximum;
+   uint32_t                                     ThreadWidthCounterMaximum;
+   uint32_t                                     ThreadGroupIDStartingX;
+   uint32_t                                     ThreadGroupIDXDimension;
+   uint32_t                                     ThreadGroupIDStartingY;
+   uint32_t                                     ThreadGroupIDYDimension;
+   uint32_t                                     ThreadGroupIDStartingZ;
+   uint32_t                                     ThreadGroupIDZDimension;
+   uint32_t                                     RightExecutionMask;
+   uint32_t                                     BottomExecutionMask;
+};
+
+static inline void
+GEN75_GPGPU_WALKER_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_GPGPU_WALKER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcodeA, 16, 23) |
+      __gen_field(values->IndirectParameterEnable, 10, 10) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SIMDSize, 30, 31) |
+      __gen_field(values->ThreadDepthCounterMaximum, 16, 21) |
+      __gen_field(values->ThreadHeightCounterMaximum, 8, 13) |
+      __gen_field(values->ThreadWidthCounterMaximum, 0, 5) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ThreadGroupIDStartingX, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ThreadGroupIDXDimension, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ThreadGroupIDStartingY, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ThreadGroupIDYDimension, 0, 31) |
+      0;
+
+   dw[7] =
+      __gen_field(values->ThreadGroupIDStartingZ, 0, 31) |
+      0;
+
+   dw[8] =
+      __gen_field(values->ThreadGroupIDZDimension, 0, 31) |
+      0;
+
+   dw[9] =
+      __gen_field(values->RightExecutionMask, 0, 31) |
+      0;
+
+   dw[10] =
+      __gen_field(values->BottomExecutionMask, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MEDIA_CURBE_LOAD_length_bias 0x00000002
+#define GEN75_MEDIA_CURBE_LOAD_header           \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  1,                  \
+   .DwordLength          =  2
+
+#define GEN75_MEDIA_CURBE_LOAD_length 0x00000004
+
+struct GEN75_MEDIA_CURBE_LOAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CURBETotalDataLength;
+   uint32_t                                     CURBEDataStartAddress;
+};
+
+static inline void
+GEN75_MEDIA_CURBE_LOAD_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_MEDIA_CURBE_LOAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->CURBETotalDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_field(values->CURBEDataStartAddress, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MEDIA_INTERFACE_DESCRIPTOR_LOAD_length_bias 0x00000002
+#define GEN75_MEDIA_INTERFACE_DESCRIPTOR_LOAD_header\
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  2,                  \
+   .DwordLength          =  2
+
+#define GEN75_MEDIA_INTERFACE_DESCRIPTOR_LOAD_length 0x00000004
+
+struct GEN75_MEDIA_INTERFACE_DESCRIPTOR_LOAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorTotalLength;
+   uint32_t                                     InterfaceDescriptorDataStartAddress;
+};
+
+static inline void
+GEN75_MEDIA_INTERFACE_DESCRIPTOR_LOAD_pack(__gen_user_data *data, void * restrict dst,
+                                           const struct GEN75_MEDIA_INTERFACE_DESCRIPTOR_LOAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->InterfaceDescriptorTotalLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->InterfaceDescriptorDataStartAddress, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MEDIA_OBJECT_length_bias 0x00000002
+#define GEN75_MEDIA_OBJECT_header               \
+   .CommandType          =  3,                  \
+   .MediaCommandPipeline =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .MediaCommandSubOpcode =  0
+
+#define GEN75_MEDIA_OBJECT_length 0x00000000
+
+struct GEN75_MEDIA_OBJECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MediaCommandPipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     MediaCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+#define     Nothreadsynchronization                            0
+#define     Threaddispatchissynchronizedbythespawnrootthreadmessage       1
+   uint32_t                                     ThreadSynchronization;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+#define     Slice0                                             0
+#define     Slice1                                             1
+#define     EitherSlice                                        0
+   uint32_t                                     SliceDestinationSelect;
+#define     HalfSlice1                                         2
+#define     HalfSlice0                                         1
+#define     Eitherhalfslice                                    0
+   uint32_t                                     HalfSliceDestinationSelect;
+   uint32_t                                     IndirectDataLength;
+   __gen_address_type                           IndirectDataStartAddress;
+   uint32_t                                     ScoredboardY;
+   uint32_t                                     ScoreboardX;
+   uint32_t                                     ScoreboardColor;
+   bool                                         ScoreboardMask;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_MEDIA_OBJECT_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_MEDIA_OBJECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MediaCommandPipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->MediaCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->ThreadSynchronization, 24, 24) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->SliceDestinationSelect, 19, 19) |
+      __gen_field(values->HalfSliceDestinationSelect, 17, 18) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->IndirectDataStartAddress, dw3);
+
+   dw[4] =
+      __gen_field(values->ScoredboardY, 16, 24) |
+      __gen_field(values->ScoreboardX, 0, 8) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardColor, 16, 19) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_MEDIA_OBJECT_PRT_length_bias 0x00000002
+#define GEN75_MEDIA_OBJECT_PRT_header           \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  2,                  \
+   .DwordLength          = 14
+
+#define GEN75_MEDIA_OBJECT_PRT_length 0x00000010
+
+struct GEN75_MEDIA_OBJECT_PRT {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+   bool                                         PRT_FenceNeeded;
+#define     Rootthreadqueue                                    0
+#define     VFEstateflush                                      1
+   uint32_t                                     PRT_FenceType;
+   uint32_t                                     InlineData[12];
+};
+
+static inline void
+GEN75_MEDIA_OBJECT_PRT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_MEDIA_OBJECT_PRT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->PRT_FenceNeeded, 23, 23) |
+      __gen_field(values->PRT_FenceType, 22, 22) |
+      0;
+
+   dw[3] =
+      0;
+
+   for (uint32_t i = 0, j = 4; i < 12; i += 1, j++) {
+      dw[j] =
+         __gen_field(values->InlineData[i + 0], 0, 31) |
+         0;
+   }
+
+}
+
+#define GEN75_MEDIA_OBJECT_WALKER_length_bias 0x00000002
+#define GEN75_MEDIA_OBJECT_WALKER_header        \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  3
+
+#define GEN75_MEDIA_OBJECT_WALKER_length 0x00000000
+
+struct GEN75_MEDIA_OBJECT_WALKER {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+#define     Nothreadsynchronization                            0
+#define     Threaddispatchissynchronizedbythespawnrootthreadmessage       1
+   uint32_t                                     ThreadSynchronization;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+   uint32_t                                     IndirectDataLength;
+   uint32_t                                     IndirectDataStartAddress;
+   bool                                         ScoreboardMask;
+   bool                                         DualMode;
+   bool                                         Repel;
+   bool                                         QuadMode;
+   uint32_t                                     ColorCountMinusOne;
+   uint32_t                                     MiddleLoopExtraSteps;
+   uint32_t                                     LocalMidLoopUnitY;
+   uint32_t                                     MidLoopUnitX;
+   uint32_t                                     GlobalLoopExecCount;
+   uint32_t                                     LocalLoopExecCount;
+   uint32_t                                     BlockResolutionY;
+   uint32_t                                     BlockResolutionX;
+   uint32_t                                     LocalStartY;
+   uint32_t                                     LocalStartX;
+   uint32_t                                     LocalOuterLoopStrideY;
+   uint32_t                                     LocalOuterLoopStrideX;
+   uint32_t                                     LocalInnerLoopUnitY;
+   uint32_t                                     LocalInnerLoopUnitX;
+   uint32_t                                     GlobalResolutionY;
+   uint32_t                                     GlobalResolutionX;
+   uint32_t                                     GlobalStartY;
+   uint32_t                                     GlobalStartX;
+   uint32_t                                     GlobalOuterLoopStrideY;
+   uint32_t                                     GlobalOuterLoopStrideX;
+   uint32_t                                     GlobalInnerLoopUnitY;
+   uint32_t                                     GlobalInnerLoopUnitX;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_MEDIA_OBJECT_WALKER_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_MEDIA_OBJECT_WALKER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->ThreadSynchronization, 24, 24) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->IndirectDataStartAddress, 0, 31) |
+      0;
+
+   dw[4] =
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->DualMode, 31, 31) |
+      __gen_field(values->Repel, 30, 30) |
+      __gen_field(values->QuadMode, 29, 29) |
+      __gen_field(values->ColorCountMinusOne, 24, 27) |
+      __gen_field(values->MiddleLoopExtraSteps, 16, 20) |
+      __gen_field(values->LocalMidLoopUnitY, 12, 13) |
+      __gen_field(values->MidLoopUnitX, 8, 9) |
+      0;
+
+   dw[7] =
+      __gen_field(values->GlobalLoopExecCount, 16, 25) |
+      __gen_field(values->LocalLoopExecCount, 0, 9) |
+      0;
+
+   dw[8] =
+      __gen_field(values->BlockResolutionY, 16, 24) |
+      __gen_field(values->BlockResolutionX, 0, 8) |
+      0;
+
+   dw[9] =
+      __gen_field(values->LocalStartY, 16, 24) |
+      __gen_field(values->LocalStartX, 0, 8) |
+      0;
+
+   dw[10] =
+      0;
+
+   dw[11] =
+      __gen_field(values->LocalOuterLoopStrideY, 16, 25) |
+      __gen_field(values->LocalOuterLoopStrideX, 0, 9) |
+      0;
+
+   dw[12] =
+      __gen_field(values->LocalInnerLoopUnitY, 16, 25) |
+      __gen_field(values->LocalInnerLoopUnitX, 0, 9) |
+      0;
+
+   dw[13] =
+      __gen_field(values->GlobalResolutionY, 16, 24) |
+      __gen_field(values->GlobalResolutionX, 0, 8) |
+      0;
+
+   dw[14] =
+      __gen_field(values->GlobalStartY, 16, 25) |
+      __gen_field(values->GlobalStartX, 0, 9) |
+      0;
+
+   dw[15] =
+      __gen_field(values->GlobalOuterLoopStrideY, 16, 25) |
+      __gen_field(values->GlobalOuterLoopStrideX, 0, 9) |
+      0;
+
+   dw[16] =
+      __gen_field(values->GlobalInnerLoopUnitY, 16, 25) |
+      __gen_field(values->GlobalInnerLoopUnitX, 0, 9) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_MEDIA_STATE_FLUSH_length_bias 0x00000002
+#define GEN75_MEDIA_STATE_FLUSH_header          \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  4,                  \
+   .DwordLength          =  0
+
+#define GEN75_MEDIA_STATE_FLUSH_length 0x00000002
+
+struct GEN75_MEDIA_STATE_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         DisablePreemption;
+   bool                                         FlushtoGO;
+   uint32_t                                     WatermarkRequired;
+   uint32_t                                     InterfaceDescriptorOffset;
+};
+
+static inline void
+GEN75_MEDIA_STATE_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_MEDIA_STATE_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DisablePreemption, 8, 8) |
+      __gen_field(values->FlushtoGO, 7, 7) |
+      __gen_field(values->WatermarkRequired, 6, 6) |
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+}
+
+#define GEN75_MEDIA_VFE_STATE_length_bias 0x00000002
+#define GEN75_MEDIA_VFE_STATE_header            \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  0,                  \
+   .DwordLength          =  6
+
+#define GEN75_MEDIA_VFE_STATE_length 0x00000008
+
+struct GEN75_MEDIA_VFE_STATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     StackSize;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     NumberofURBEntries;
+#define     Maintainingtheexistingtimestampstate               0
+#define     Resettingrelativetimerandlatchingtheglobaltimestamp       1
+   uint32_t                                     ResetGatewayTimer;
+#define     MaintainingOpenGatewayForwardMsgCloseGatewayprotocollegacymode       0
+#define     BypassingOpenGatewayCloseGatewayprotocol           1
+   uint32_t                                     BypassGatewayControl;
+   uint32_t                                     GPGPUMode;
+   uint32_t                                     HalfSliceDisable;
+   uint32_t                                     URBEntryAllocationSize;
+   uint32_t                                     CURBEAllocationSize;
+#define     Scoreboarddisabled                                 0
+#define     Scoreboardenabled                                  1
+   uint32_t                                     ScoreboardEnable;
+#define     StallingScoreboard                                 0
+#define     NonStallingScoreboard                              1
+   uint32_t                                     ScoreboardType;
+   uint32_t                                     ScoreboardMask;
+   uint32_t                                     Scoreboard3DeltaY;
+   uint32_t                                     Scoreboard3DeltaX;
+   uint32_t                                     Scoreboard2DeltaY;
+   uint32_t                                     Scoreboard2DeltaX;
+   uint32_t                                     Scoreboard1DeltaY;
+   uint32_t                                     Scoreboard1DeltaX;
+   uint32_t                                     Scoreboard0DeltaY;
+   uint32_t                                     Scoreboard0DeltaX;
+   uint32_t                                     Scoreboard7DeltaY;
+   uint32_t                                     Scoreboard7DeltaX;
+   uint32_t                                     Scoreboard6DeltaY;
+   uint32_t                                     Scoreboard6DeltaX;
+   uint32_t                                     Scoreboard5DeltaY;
+   uint32_t                                     Scoreboard5DeltaX;
+   uint32_t                                     Scoreboard4DeltaY;
+   uint32_t                                     Scoreboard4DeltaX;
+};
+
+static inline void
+GEN75_MEDIA_VFE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN75_MEDIA_VFE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->StackSize, 4, 7) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->MaximumNumberofThreads, 16, 31) |
+      __gen_field(values->NumberofURBEntries, 8, 15) |
+      __gen_field(values->ResetGatewayTimer, 7, 7) |
+      __gen_field(values->BypassGatewayControl, 6, 6) |
+      __gen_field(values->GPGPUMode, 2, 2) |
+      0;
+
+   dw[3] =
+      __gen_field(values->HalfSliceDisable, 0, 1) |
+      0;
+
+   dw[4] =
+      __gen_field(values->URBEntryAllocationSize, 16, 31) |
+      __gen_field(values->CURBEAllocationSize, 0, 15) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardEnable, 31, 31) |
+      __gen_field(values->ScoreboardType, 30, 30) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->Scoreboard3DeltaY, 28, 31) |
+      __gen_field(values->Scoreboard3DeltaX, 24, 27) |
+      __gen_field(values->Scoreboard2DeltaY, 20, 23) |
+      __gen_field(values->Scoreboard2DeltaX, 16, 19) |
+      __gen_field(values->Scoreboard1DeltaY, 12, 15) |
+      __gen_field(values->Scoreboard1DeltaX, 8, 11) |
+      __gen_field(values->Scoreboard0DeltaY, 4, 7) |
+      __gen_field(values->Scoreboard0DeltaX, 0, 3) |
+      0;
+
+   dw[7] =
+      __gen_field(values->Scoreboard7DeltaY, 28, 31) |
+      __gen_field(values->Scoreboard7DeltaX, 24, 27) |
+      __gen_field(values->Scoreboard6DeltaY, 20, 23) |
+      __gen_field(values->Scoreboard6DeltaX, 16, 19) |
+      __gen_field(values->Scoreboard5DeltaY, 12, 15) |
+      __gen_field(values->Scoreboard5DeltaX, 8, 11) |
+      __gen_field(values->Scoreboard4DeltaY, 4, 7) |
+      __gen_field(values->Scoreboard4DeltaX, 0, 3) |
+      0;
+
+}
+
+#define GEN75_MI_ARB_CHECK_length_bias 0x00000001
+#define GEN75_MI_ARB_CHECK_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  5
+
+#define GEN75_MI_ARB_CHECK_length 0x00000001
+
+struct GEN75_MI_ARB_CHECK {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN75_MI_ARB_CHECK_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_MI_ARB_CHECK * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN75_MI_ARB_ON_OFF_length_bias 0x00000001
+#define GEN75_MI_ARB_ON_OFF_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  8
+
+#define GEN75_MI_ARB_ON_OFF_length 0x00000001
+
+struct GEN75_MI_ARB_ON_OFF {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         ArbitrationEnable;
+};
+
+static inline void
+GEN75_MI_ARB_ON_OFF_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_MI_ARB_ON_OFF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ArbitrationEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN75_MI_BATCH_BUFFER_END_length_bias 0x00000001
+#define GEN75_MI_BATCH_BUFFER_END_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 10
+
+#define GEN75_MI_BATCH_BUFFER_END_length 0x00000001
+
+struct GEN75_MI_BATCH_BUFFER_END {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN75_MI_BATCH_BUFFER_END_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_MI_BATCH_BUFFER_END * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN75_MI_BATCH_BUFFER_START_length_bias 0x00000002
+#define GEN75_MI_BATCH_BUFFER_START_header      \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 49,                  \
+   .DwordLength          =  0
+
+#define GEN75_MI_BATCH_BUFFER_START_length 0x00000002
+
+struct GEN75_MI_BATCH_BUFFER_START {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     _1stlevelbatch                                     0
+#define     _2ndlevelbatch                                     1
+   uint32_t                                     _2ndLevelBatchBuffer;
+   bool                                         AddOffsetEnable;
+   bool                                         PredicationEnable;
+   uint32_t                                     NonPrivileged;
+   bool                                         ClearCommandBufferEnable;
+   bool                                         ResourceStreamerEnable;
+#define     ASI_GGTT                                           0
+#define     ASI_PPGTT                                          1
+   uint32_t                                     AddressSpaceIndicator;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BatchBufferStartAddress;
+};
+
+static inline void
+GEN75_MI_BATCH_BUFFER_START_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN75_MI_BATCH_BUFFER_START * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->_2ndLevelBatchBuffer, 22, 22) |
+      __gen_field(values->AddOffsetEnable, 16, 16) |
+      __gen_field(values->PredicationEnable, 15, 15) |
+      __gen_field(values->NonPrivileged, 13, 13) |
+      __gen_field(values->ClearCommandBufferEnable, 11, 11) |
+      __gen_field(values->ResourceStreamerEnable, 10, 10) |
+      __gen_field(values->AddressSpaceIndicator, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BatchBufferStartAddress, dw1);
+
+}
+
+#define GEN75_MI_CLFLUSH_length_bias 0x00000002
+#define GEN75_MI_CLFLUSH_header                 \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 39
+
+#define GEN75_MI_CLFLUSH_length 0x00000000
+
+struct GEN75_MI_CLFLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           PageBaseAddress;
+   uint32_t                                     StartingCachelineOffset;
+   __gen_address_type                           PageBaseAddressHigh;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_MI_CLFLUSH_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN75_MI_CLFLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 9) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->StartingCachelineOffset, 6, 11) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->PageBaseAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->PageBaseAddressHigh, dw2);
+
+   /* variable length fields follow */
+}
+
+#define GEN75_MI_CONDITIONAL_BATCH_BUFFER_END_length_bias 0x00000002
+#define GEN75_MI_CONDITIONAL_BATCH_BUFFER_END_header\
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 54,                  \
+   .UseGlobalGTT         =  0,                  \
+   .CompareSemaphore     =  0,                  \
+   .DwordLength          =  0
+
+#define GEN75_MI_CONDITIONAL_BATCH_BUFFER_END_length 0x00000002
+
+struct GEN75_MI_CONDITIONAL_BATCH_BUFFER_END {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     CompareSemaphore;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CompareDataDword;
+   __gen_address_type                           CompareAddress;
+};
+
+static inline void
+GEN75_MI_CONDITIONAL_BATCH_BUFFER_END_pack(__gen_user_data *data, void * restrict dst,
+                                           const struct GEN75_MI_CONDITIONAL_BATCH_BUFFER_END * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->CompareSemaphore, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->CompareDataDword, 0, 31) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->CompareAddress, dw2);
+
+}
+
+#define GEN75_MI_FLUSH_length_bias 0x00000001
+#define GEN75_MI_FLUSH_header                   \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  4
+
+#define GEN75_MI_FLUSH_length 0x00000001
+
+struct GEN75_MI_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         IndirectStatePointersDisable;
+   bool                                         GenericMediaStateClear;
+#define     DontReset                                          0
+#define     Reset                                              1
+   bool                                         GlobalSnapshotCountReset;
+#define     Flush                                              0
+#define     DontFlush                                          1
+   bool                                         RenderCacheFlushInhibit;
+#define     DontInvalidate                                     0
+#define     Invalidate                                         1
+   bool                                         StateInstructionCacheInvalidate;
+};
+
+static inline void
+GEN75_MI_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                    const struct GEN75_MI_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->IndirectStatePointersDisable, 5, 5) |
+      __gen_field(values->GenericMediaStateClear, 4, 4) |
+      __gen_field(values->GlobalSnapshotCountReset, 3, 3) |
+      __gen_field(values->RenderCacheFlushInhibit, 2, 2) |
+      __gen_field(values->StateInstructionCacheInvalidate, 1, 1) |
+      0;
+
+}
+
+#define GEN75_MI_LOAD_REGISTER_IMM_length_bias 0x00000002
+#define GEN75_MI_LOAD_REGISTER_IMM_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 34,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_LOAD_REGISTER_IMM_length 0x00000003
+
+struct GEN75_MI_LOAD_REGISTER_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     ByteWriteDisables;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterOffset;
+   uint32_t                                     DataDWord;
+};
+
+static inline void
+GEN75_MI_LOAD_REGISTER_IMM_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_MI_LOAD_REGISTER_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ByteWriteDisables, 8, 11) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterOffset, 2, 22) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DataDWord, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MI_LOAD_REGISTER_MEM_length_bias 0x00000002
+#define GEN75_MI_LOAD_REGISTER_MEM_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 41,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_LOAD_REGISTER_MEM_length 0x00000003
+
+struct GEN75_MI_LOAD_REGISTER_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     AsyncModeEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN75_MI_LOAD_REGISTER_MEM_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_MI_LOAD_REGISTER_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->AsyncModeEnable, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterAddress, 2, 22) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+}
+
+#define GEN75_MI_LOAD_REGISTER_REG_length_bias 0x00000002
+#define GEN75_MI_LOAD_REGISTER_REG_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 42,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_LOAD_REGISTER_REG_length 0x00000003
+
+struct GEN75_MI_LOAD_REGISTER_REG {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SourceRegisterAddress;
+   uint32_t                                     DestinationRegisterAddress;
+};
+
+static inline void
+GEN75_MI_LOAD_REGISTER_REG_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_MI_LOAD_REGISTER_REG * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SourceRegisterAddress, 2, 22) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->DestinationRegisterAddress, 2, 22) |
+      0;
+
+}
+
+#define GEN75_MI_LOAD_SCAN_LINES_EXCL_length_bias 0x00000002
+#define GEN75_MI_LOAD_SCAN_LINES_EXCL_header    \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 19,                  \
+   .DwordLength          =  0
+
+#define GEN75_MI_LOAD_SCAN_LINES_EXCL_length 0x00000002
+
+struct GEN75_MI_LOAD_SCAN_LINES_EXCL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     DisplayPlaneA                                      0
+#define     DisplayPlaneB                                      1
+#define     DisplayPlaneC                                      4
+   uint32_t                                     DisplayPlaneSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StartScanLineNumber;
+   uint32_t                                     EndScanLineNumber;
+};
+
+static inline void
+GEN75_MI_LOAD_SCAN_LINES_EXCL_pack(__gen_user_data *data, void * restrict dst,
+                                   const struct GEN75_MI_LOAD_SCAN_LINES_EXCL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPlaneSelect, 19, 21) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StartScanLineNumber, 16, 28) |
+      __gen_field(values->EndScanLineNumber, 0, 12) |
+      0;
+
+}
+
+#define GEN75_MI_LOAD_SCAN_LINES_INCL_length_bias 0x00000002
+#define GEN75_MI_LOAD_SCAN_LINES_INCL_header    \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 18,                  \
+   .DwordLength          =  0
+
+#define GEN75_MI_LOAD_SCAN_LINES_INCL_length 0x00000002
+
+struct GEN75_MI_LOAD_SCAN_LINES_INCL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     DisplayPlaneA                                      0
+#define     DisplayPlaneB                                      1
+#define     DisplayPlaneC                                      4
+   uint32_t                                     DisplayPlaneSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StartScanLineNumber;
+   uint32_t                                     EndScanLineNumber;
+};
+
+static inline void
+GEN75_MI_LOAD_SCAN_LINES_INCL_pack(__gen_user_data *data, void * restrict dst,
+                                   const struct GEN75_MI_LOAD_SCAN_LINES_INCL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPlaneSelect, 19, 21) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StartScanLineNumber, 16, 28) |
+      __gen_field(values->EndScanLineNumber, 0, 12) |
+      0;
+
+}
+
+#define GEN75_MI_LOAD_URB_MEM_length_bias 0x00000002
+#define GEN75_MI_LOAD_URB_MEM_header            \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 44,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_LOAD_URB_MEM_length 0x00000003
+
+struct GEN75_MI_LOAD_URB_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN75_MI_LOAD_URB_MEM_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN75_MI_LOAD_URB_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBAddress, 2, 14) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+}
+
+#define GEN75_MI_MATH_length_bias 0x00000002
+#define GEN75_MI_MATH_header                    \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 26
+
+#define GEN75_MI_MATH_length 0x00000000
+
+struct GEN75_MI_MATH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ALUINSTRUCTION1;
+   uint32_t                                     ALUINSTRUCTION2;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_MI_MATH_pack(__gen_user_data *data, void * restrict dst,
+                   const struct GEN75_MI_MATH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ALUINSTRUCTION1, 0, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ALUINSTRUCTION2, 0, 31) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN75_MI_NOOP_length_bias 0x00000001
+#define GEN75_MI_NOOP_header                    \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  0
+
+#define GEN75_MI_NOOP_length 0x00000001
+
+struct GEN75_MI_NOOP {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         IdentificationNumberRegisterWriteEnable;
+   uint32_t                                     IdentificationNumber;
+};
+
+static inline void
+GEN75_MI_NOOP_pack(__gen_user_data *data, void * restrict dst,
+                   const struct GEN75_MI_NOOP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->IdentificationNumberRegisterWriteEnable, 22, 22) |
+      __gen_field(values->IdentificationNumber, 0, 21) |
+      0;
+
+}
+
+#define GEN75_MI_PREDICATE_length_bias 0x00000001
+#define GEN75_MI_PREDICATE_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 12
+
+#define GEN75_MI_PREDICATE_length 0x00000001
+
+struct GEN75_MI_PREDICATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     LOAD_KEEP                                          0
+#define     LOAD_LOAD                                          2
+#define     LOAD_LOADINV                                       3
+   uint32_t                                     LoadOperation;
+#define     COMBINE_SET                                        0
+#define     COMBINE_AND                                        1
+#define     COMBINE_OR                                         2
+#define     COMBINE_XOR                                        3
+   uint32_t                                     CombineOperation;
+#define     COMPARE_SRCS_EQUAL                                 2
+#define     COMPARE_DELTAS_EQUAL                               3
+   uint32_t                                     CompareOperation;
+};
+
+static inline void
+GEN75_MI_PREDICATE_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_MI_PREDICATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->LoadOperation, 6, 7) |
+      __gen_field(values->CombineOperation, 3, 4) |
+      __gen_field(values->CompareOperation, 0, 1) |
+      0;
+
+}
+
+#define GEN75_MI_REPORT_HEAD_length_bias 0x00000001
+#define GEN75_MI_REPORT_HEAD_header             \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  7
+
+#define GEN75_MI_REPORT_HEAD_length 0x00000001
+
+struct GEN75_MI_REPORT_HEAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN75_MI_REPORT_HEAD_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_MI_REPORT_HEAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN75_MI_RS_CONTEXT_length_bias 0x00000001
+#define GEN75_MI_RS_CONTEXT_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 15
+
+#define GEN75_MI_RS_CONTEXT_length 0x00000001
+
+struct GEN75_MI_RS_CONTEXT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     RS_RESTORE                                         0
+#define     RS_SAVE                                            1
+   uint32_t                                     ResourceStreamerSave;
+};
+
+static inline void
+GEN75_MI_RS_CONTEXT_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_MI_RS_CONTEXT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ResourceStreamerSave, 0, 0) |
+      0;
+
+}
+
+#define GEN75_MI_RS_CONTROL_length_bias 0x00000001
+#define GEN75_MI_RS_CONTROL_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  6
+
+#define GEN75_MI_RS_CONTROL_length 0x00000001
+
+struct GEN75_MI_RS_CONTROL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     RS_STOP                                            0
+#define     RS_START                                           1
+   uint32_t                                     ResourceStreamerControl;
+};
+
+static inline void
+GEN75_MI_RS_CONTROL_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_MI_RS_CONTROL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ResourceStreamerControl, 0, 0) |
+      0;
+
+}
+
+#define GEN75_MI_RS_STORE_DATA_IMM_length_bias 0x00000002
+#define GEN75_MI_RS_STORE_DATA_IMM_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 43,                  \
+   .DwordLength          =  2
+
+#define GEN75_MI_RS_STORE_DATA_IMM_length 0x00000004
+
+struct GEN75_MI_RS_STORE_DATA_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           DestinationAddress;
+   uint32_t                                     CoreModeEnable;
+   uint32_t                                     DataDWord0;
+};
+
+static inline void
+GEN75_MI_RS_STORE_DATA_IMM_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_MI_RS_STORE_DATA_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      0;
+
+   uint32_t dw2 =
+      __gen_field(values->CoreModeEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->DestinationAddress, dw2);
+
+   dw[3] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MI_SEMAPHORE_MBOX_length_bias 0x00000002
+#define GEN75_MI_SEMAPHORE_MBOX_header          \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 22,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_SEMAPHORE_MBOX_length 0x00000003
+
+struct GEN75_MI_SEMAPHORE_MBOX {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     RVSYNC                                             0
+#define     RVESYNC                                            1
+#define     RBSYNC                                             2
+#define     UseGeneralRegisterSelect                           3
+   uint32_t                                     RegisterSelect;
+   uint32_t                                     GeneralRegisterSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SemaphoreDataDword;
+};
+
+static inline void
+GEN75_MI_SEMAPHORE_MBOX_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_MI_SEMAPHORE_MBOX * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->RegisterSelect, 16, 17) |
+      __gen_field(values->GeneralRegisterSelect, 8, 13) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SemaphoreDataDword, 0, 31) |
+      0;
+
+   dw[2] =
+      0;
+
+}
+
+#define GEN75_MI_SET_CONTEXT_length_bias 0x00000002
+#define GEN75_MI_SET_CONTEXT_header             \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 24,                  \
+   .DwordLength          =  0
+
+#define GEN75_MI_SET_CONTEXT_length 0x00000002
+
+struct GEN75_MI_SET_CONTEXT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           LogicalContextAddress;
+   uint32_t                                     ReservedMustbe1;
+   bool                                         CoreModeEnable;
+   bool                                         ResourceStreamerStateSaveEnable;
+   bool                                         ResourceStreamerStateRestoreEnable;
+   uint32_t                                     ForceRestore;
+   uint32_t                                     RestoreInhibit;
+};
+
+static inline void
+GEN75_MI_SET_CONTEXT_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN75_MI_SET_CONTEXT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->ReservedMustbe1, 8, 8) |
+      __gen_field(values->CoreModeEnable, 4, 4) |
+      __gen_field(values->ResourceStreamerStateSaveEnable, 3, 3) |
+      __gen_field(values->ResourceStreamerStateRestoreEnable, 2, 2) |
+      __gen_field(values->ForceRestore, 1, 1) |
+      __gen_field(values->RestoreInhibit, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->LogicalContextAddress, dw1);
+
+}
+
+#define GEN75_MI_SET_PREDICATE_length_bias 0x00000001
+#define GEN75_MI_SET_PREDICATE_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  1,                  \
+   .PREDICATEENABLE      =  6
+
+#define GEN75_MI_SET_PREDICATE_length 0x00000001
+
+struct GEN75_MI_SET_PREDICATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PredicateAlways                                    0
+#define     PredicateonClear                                   1
+#define     PredicateonSet                                     2
+#define     PredicateDisable                                   3
+   bool                                         PREDICATEENABLE;
+};
+
+static inline void
+GEN75_MI_SET_PREDICATE_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_MI_SET_PREDICATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->PREDICATEENABLE, 0, 1) |
+      0;
+
+}
+
+#define GEN75_MI_STORE_DATA_IMM_length_bias 0x00000002
+#define GEN75_MI_STORE_DATA_IMM_header          \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 32,                  \
+   .DwordLength          =  2
+
+#define GEN75_MI_STORE_DATA_IMM_length 0x00000004
+
+struct GEN75_MI_STORE_DATA_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   uint32_t                                     Address;
+   uint32_t                                     CoreModeEnable;
+   uint32_t                                     DataDWord0;
+   uint32_t                                     DataDWord1;
+};
+
+static inline void
+GEN75_MI_STORE_DATA_IMM_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_MI_STORE_DATA_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->Address, 2, 31) |
+      __gen_field(values->CoreModeEnable, 0, 0) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DataDWord1, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MI_STORE_DATA_INDEX_length_bias 0x00000002
+#define GEN75_MI_STORE_DATA_INDEX_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 33,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_STORE_DATA_INDEX_length 0x00000003
+
+struct GEN75_MI_STORE_DATA_INDEX {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     Offset;
+   uint32_t                                     DataDWord0;
+   uint32_t                                     DataDWord1;
+};
+
+static inline void
+GEN75_MI_STORE_DATA_INDEX_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_MI_STORE_DATA_INDEX * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Offset, 2, 11) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DataDWord1, 0, 31) |
+      0;
+
+}
+
+#define GEN75_MI_STORE_URB_MEM_length_bias 0x00000002
+#define GEN75_MI_STORE_URB_MEM_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 45,                  \
+   .DwordLength          =  1
+
+#define GEN75_MI_STORE_URB_MEM_length 0x00000003
+
+struct GEN75_MI_STORE_URB_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN75_MI_STORE_URB_MEM_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_MI_STORE_URB_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBAddress, 2, 14) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+}
+
+#define GEN75_MI_SUSPEND_FLUSH_length_bias 0x00000001
+#define GEN75_MI_SUSPEND_FLUSH_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 11
+
+#define GEN75_MI_SUSPEND_FLUSH_length 0x00000001
+
+struct GEN75_MI_SUSPEND_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         SuspendFlush;
+};
+
+static inline void
+GEN75_MI_SUSPEND_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_MI_SUSPEND_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->SuspendFlush, 0, 0) |
+      0;
+
+}
+
+#define GEN75_MI_TOPOLOGY_FILTER_length_bias 0x00000001
+#define GEN75_MI_TOPOLOGY_FILTER_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 13
+
+#define GEN75_MI_TOPOLOGY_FILTER_length 0x00000001
+
+struct GEN75_MI_TOPOLOGY_FILTER {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     TopologyFilterValue;
+};
+
+static inline void
+GEN75_MI_TOPOLOGY_FILTER_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN75_MI_TOPOLOGY_FILTER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->TopologyFilterValue, 0, 5) |
+      0;
+
+}
+
+#define GEN75_MI_UPDATE_GTT_length_bias 0x00000002
+#define GEN75_MI_UPDATE_GTT_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 35
+
+#define GEN75_MI_UPDATE_GTT_length 0x00000000
+
+struct GEN75_MI_UPDATE_GTT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           EntryAddress;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN75_MI_UPDATE_GTT_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_MI_UPDATE_GTT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->EntryAddress, dw1);
+
+   /* variable length fields follow */
+}
+
+#define GEN75_MI_URB_ATOMIC_ALLOC_length_bias 0x00000001
+#define GEN75_MI_URB_ATOMIC_ALLOC_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  9
+
+#define GEN75_MI_URB_ATOMIC_ALLOC_length 0x00000001
+
+struct GEN75_MI_URB_ATOMIC_ALLOC {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     URBAtomicStorageOffset;
+   uint32_t                                     URBAtomicStorageSize;
+};
+
+static inline void
+GEN75_MI_URB_ATOMIC_ALLOC_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_MI_URB_ATOMIC_ALLOC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->URBAtomicStorageOffset, 12, 19) |
+      __gen_field(values->URBAtomicStorageSize, 0, 8) |
+      0;
+
+}
+
+#define GEN75_MI_URB_CLEAR_length_bias 0x00000002
+#define GEN75_MI_URB_CLEAR_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 25,                  \
+   .DwordLength          =  0
+
+#define GEN75_MI_URB_CLEAR_length 0x00000002
+
+struct GEN75_MI_URB_CLEAR {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBClearLength;
+   uint32_t                                     URBAddress;
+};
+
+static inline void
+GEN75_MI_URB_CLEAR_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_MI_URB_CLEAR * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBClearLength, 16, 29) |
+      __gen_offset(values->URBAddress, 0, 14) |
+      0;
+
+}
+
+#define GEN75_MI_USER_INTERRUPT_length_bias 0x00000001
+#define GEN75_MI_USER_INTERRUPT_header          \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  2
+
+#define GEN75_MI_USER_INTERRUPT_length 0x00000001
+
+struct GEN75_MI_USER_INTERRUPT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN75_MI_USER_INTERRUPT_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_MI_USER_INTERRUPT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN75_MI_WAIT_FOR_EVENT_length_bias 0x00000001
+#define GEN75_MI_WAIT_FOR_EVENT_header          \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  3
+
+#define GEN75_MI_WAIT_FOR_EVENT_length 0x00000001
+
+struct GEN75_MI_WAIT_FOR_EVENT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         DisplayPipeCHorizontalBlankWaitEnable;
+   bool                                         DisplayPipeCVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteCFlipPendingWaitEnable;
+#define     Notenabled                                         0
+   uint32_t                                     ConditionCodeWaitSelect;
+   bool                                         DisplayPlaneCFlipPendingWaitEnable;
+   bool                                         DisplayPipeCScanLineWaitEnable;
+   bool                                         DisplayPipeBHorizontalBlankWaitEnable;
+   bool                                         DisplayPipeBVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteBFlipPendingWaitEnable;
+   bool                                         DisplayPlaneBFlipPendingWaitEnable;
+   bool                                         DisplayPipeBScanLineWaitEnable;
+   bool                                         DisplayPipeAHorizontalBlankWaitEnable;
+   bool                                         DisplayPipeAVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteAFlipPendingWaitEnable;
+   bool                                         DisplayPlaneAFlipPendingWaitEnable;
+   bool                                         DisplayPipeAScanLineWaitEnable;
+};
+
+static inline void
+GEN75_MI_WAIT_FOR_EVENT_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN75_MI_WAIT_FOR_EVENT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPipeCHorizontalBlankWaitEnable, 22, 22) |
+      __gen_field(values->DisplayPipeCVerticalBlankWaitEnable, 21, 21) |
+      __gen_field(values->DisplaySpriteCFlipPendingWaitEnable, 20, 20) |
+      __gen_field(values->ConditionCodeWaitSelect, 16, 19) |
+      __gen_field(values->DisplayPlaneCFlipPendingWaitEnable, 15, 15) |
+      __gen_field(values->DisplayPipeCScanLineWaitEnable, 14, 14) |
+      __gen_field(values->DisplayPipeBHorizontalBlankWaitEnable, 13, 13) |
+      __gen_field(values->DisplayPipeBVerticalBlankWaitEnable, 11, 11) |
+      __gen_field(values->DisplaySpriteBFlipPendingWaitEnable, 10, 10) |
+      __gen_field(values->DisplayPlaneBFlipPendingWaitEnable, 9, 9) |
+      __gen_field(values->DisplayPipeBScanLineWaitEnable, 8, 8) |
+      __gen_field(values->DisplayPipeAHorizontalBlankWaitEnable, 5, 5) |
+      __gen_field(values->DisplayPipeAVerticalBlankWaitEnable, 3, 3) |
+      __gen_field(values->DisplaySpriteAFlipPendingWaitEnable, 2, 2) |
+      __gen_field(values->DisplayPlaneAFlipPendingWaitEnable, 1, 1) |
+      __gen_field(values->DisplayPipeAScanLineWaitEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN75_PIPE_CONTROL_length_bias 0x00000002
+#define GEN75_PIPE_CONTROL_header               \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  2,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  3
+
+#define GEN75_PIPE_CONTROL_length 0x00000005
+
+struct GEN75_PIPE_CONTROL {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     DAT_PPGTT                                          0
+#define     DAT_GGTT                                           1
+   uint32_t                                     DestinationAddressType;
+#define     NoLRIOperation                                     0
+#define     MMIOWriteImmediateData                             1
+   uint32_t                                     LRIPostSyncOperation;
+   uint32_t                                     StoreDataIndex;
+   uint32_t                                     CommandStreamerStallEnable;
+#define     DontReset                                          0
+#define     Reset                                              1
+   uint32_t                                     GlobalSnapshotCountReset;
+   uint32_t                                     TLBInvalidate;
+   bool                                         GenericMediaStateClear;
+#define     NoWrite                                            0
+#define     WriteImmediateData                                 1
+#define     WritePSDepthCount                                  2
+#define     WriteTimestamp                                     3
+   uint32_t                                     PostSyncOperation;
+   bool                                         DepthStallEnable;
+#define     DisableFlush                                       0
+#define     EnableFlush                                        1
+   bool                                         RenderTargetCacheFlushEnable;
+   bool                                         InstructionCacheInvalidateEnable;
+   bool                                         TextureCacheInvalidationEnable;
+   bool                                         IndirectStatePointersDisable;
+   bool                                         NotifyEnable;
+   bool                                         PipeControlFlushEnable;
+   bool                                         DCFlushEnable;
+   bool                                         VFCacheInvalidationEnable;
+   bool                                         ConstantCacheInvalidationEnable;
+   bool                                         StateCacheInvalidationEnable;
+   bool                                         StallAtPixelScoreboard;
+#define     FlushDisabled                                      0
+#define     FlushEnabled                                       1
+   bool                                         DepthCacheFlushEnable;
+   __gen_address_type                           Address;
+   uint32_t                                     ImmediateData;
+   uint32_t                                     ImmediateData0;
+};
+
+static inline void
+GEN75_PIPE_CONTROL_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_PIPE_CONTROL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DestinationAddressType, 24, 24) |
+      __gen_field(values->LRIPostSyncOperation, 23, 23) |
+      __gen_field(values->StoreDataIndex, 21, 21) |
+      __gen_field(values->CommandStreamerStallEnable, 20, 20) |
+      __gen_field(values->GlobalSnapshotCountReset, 19, 19) |
+      __gen_field(values->TLBInvalidate, 18, 18) |
+      __gen_field(values->GenericMediaStateClear, 16, 16) |
+      __gen_field(values->PostSyncOperation, 14, 15) |
+      __gen_field(values->DepthStallEnable, 13, 13) |
+      __gen_field(values->RenderTargetCacheFlushEnable, 12, 12) |
+      __gen_field(values->InstructionCacheInvalidateEnable, 11, 11) |
+      __gen_field(values->TextureCacheInvalidationEnable, 10, 10) |
+      __gen_field(values->IndirectStatePointersDisable, 9, 9) |
+      __gen_field(values->NotifyEnable, 8, 8) |
+      __gen_field(values->PipeControlFlushEnable, 7, 7) |
+      __gen_field(values->DCFlushEnable, 5, 5) |
+      __gen_field(values->VFCacheInvalidationEnable, 4, 4) |
+      __gen_field(values->ConstantCacheInvalidationEnable, 3, 3) |
+      __gen_field(values->StateCacheInvalidationEnable, 2, 2) |
+      __gen_field(values->StallAtPixelScoreboard, 1, 1) |
+      __gen_field(values->DepthCacheFlushEnable, 0, 0) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->Address, dw2);
+
+   dw[3] =
+      __gen_field(values->ImmediateData, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ImmediateData, 0, 31) |
+      0;
+
+}
+
+#define GEN75_SCISSOR_RECT_length 0x00000002
+
+struct GEN75_SCISSOR_RECT {
+   uint32_t                                     ScissorRectangleYMin;
+   uint32_t                                     ScissorRectangleXMin;
+   uint32_t                                     ScissorRectangleYMax;
+   uint32_t                                     ScissorRectangleXMax;
+};
+
+static inline void
+GEN75_SCISSOR_RECT_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN75_SCISSOR_RECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ScissorRectangleYMin, 16, 31) |
+      __gen_field(values->ScissorRectangleXMin, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ScissorRectangleYMax, 16, 31) |
+      __gen_field(values->ScissorRectangleXMax, 0, 15) |
+      0;
+
+}
+
+#define GEN75_SF_CLIP_VIEWPORT_length 0x00000010
+
+struct GEN75_SF_CLIP_VIEWPORT {
+   float                                        ViewportMatrixElementm00;
+   float                                        ViewportMatrixElementm11;
+   float                                        ViewportMatrixElementm22;
+   float                                        ViewportMatrixElementm30;
+   float                                        ViewportMatrixElementm31;
+   float                                        ViewportMatrixElementm32;
+   float                                        XMinClipGuardband;
+   float                                        XMaxClipGuardband;
+   float                                        YMinClipGuardband;
+   float                                        YMaxClipGuardband;
+};
+
+static inline void
+GEN75_SF_CLIP_VIEWPORT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_SF_CLIP_VIEWPORT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->ViewportMatrixElementm00) |
+      0;
+
+   dw[1] =
+      __gen_float(values->ViewportMatrixElementm11) |
+      0;
+
+   dw[2] =
+      __gen_float(values->ViewportMatrixElementm22) |
+      0;
+
+   dw[3] =
+      __gen_float(values->ViewportMatrixElementm30) |
+      0;
+
+   dw[4] =
+      __gen_float(values->ViewportMatrixElementm31) |
+      0;
+
+   dw[5] =
+      __gen_float(values->ViewportMatrixElementm32) |
+      0;
+
+   dw[6] =
+      0;
+
+   dw[7] =
+      0;
+
+   dw[8] =
+      __gen_float(values->XMinClipGuardband) |
+      0;
+
+   dw[9] =
+      __gen_float(values->XMaxClipGuardband) |
+      0;
+
+   dw[10] =
+      __gen_float(values->YMinClipGuardband) |
+      0;
+
+   dw[11] =
+      __gen_float(values->YMaxClipGuardband) |
+      0;
+
+   for (uint32_t i = 0, j = 12; i < 4; i += 1, j++) {
+      dw[j] =
+         0;
+   }
+
+}
+
+#define GEN75_BLEND_STATE_length 0x00000002
+
+struct GEN75_BLEND_STATE {
+   bool                                         ColorBufferBlendEnable;
+   bool                                         IndependentAlphaBlendEnable;
+#define     BLENDFUNCTION_ADD                                  0
+#define     BLENDFUNCTION_SUBTRACT                             1
+#define     BLENDFUNCTION_REVERSE_SUBTRACT                     2
+#define     BLENDFUNCTION_MIN                                  3
+#define     BLENDFUNCTION_MAX                                  4
+   uint32_t                                     AlphaBlendFunction;
+#define     BLENDFACTOR_ONE                                    1
+#define     BLENDFACTOR_SRC_COLOR                              2
+#define     BLENDFACTOR_SRC_ALPHA                              3
+#define     BLENDFACTOR_DST_ALPHA                              4
+#define     BLENDFACTOR_DST_COLOR                              5
+#define     BLENDFACTOR_SRC_ALPHA_SATURATE                     6
+#define     BLENDFACTOR_CONST_COLOR                            7
+#define     BLENDFACTOR_CONST_ALPHA                            8
+#define     BLENDFACTOR_SRC1_COLOR                             9
+#define     BLENDFACTOR_SRC1_ALPHA                            10
+#define     BLENDFACTOR_ZERO                                  17
+#define     BLENDFACTOR_INV_SRC_COLOR                         18
+#define     BLENDFACTOR_INV_SRC_ALPHA                         19
+#define     BLENDFACTOR_INV_DST_ALPHA                         20
+#define     BLENDFACTOR_INV_DST_COLOR                         21
+#define     BLENDFACTOR_INV_CONST_COLOR                       23
+#define     BLENDFACTOR_INV_CONST_ALPHA                       24
+#define     BLENDFACTOR_INV_SRC1_COLOR                        25
+#define     BLENDFACTOR_INV_SRC1_ALPHA                        26
+   uint32_t                                     SourceAlphaBlendFactor;
+   uint32_t                                     DestinationAlphaBlendFactor;
+#define     BLENDFUNCTION_ADD                                  0
+#define     BLENDFUNCTION_SUBTRACT                             1
+#define     BLENDFUNCTION_REVERSE_SUBTRACT                     2
+#define     BLENDFUNCTION_MIN                                  3
+#define     BLENDFUNCTION_MAX                                  4
+   uint32_t                                     ColorBlendFunction;
+   uint32_t                                     SourceBlendFactor;
+   uint32_t                                     DestinationBlendFactor;
+   bool                                         AlphaToCoverageEnable;
+   bool                                         AlphaToOneEnable;
+   bool                                         AlphaToCoverageDitherEnable;
+   bool                                         WriteDisableAlpha;
+   bool                                         WriteDisableRed;
+   bool                                         WriteDisableGreen;
+   bool                                         WriteDisableBlue;
+   bool                                         LogicOpEnable;
+#define     LOGICOP_CLEAR                                      0
+#define     LOGICOP_NOR                                        1
+#define     LOGICOP_AND_INVERTED                               2
+#define     LOGICOP_COPY_INVERTED                              3
+#define     LOGICOP_AND_REVERSE                                4
+#define     LOGICOP_INVERT                                     5
+#define     LOGICOP_XOR                                        6
+#define     LOGICOP_NAND                                       7
+#define     LOGICOP_AND                                        8
+#define     LOGICOP_EQUIV                                      9
+#define     LOGICOP_NOOP                                      10
+#define     LOGICOP_OR_INVERTED                               11
+#define     LOGICOP_COPY                                      12
+#define     LOGICOP_OR_REVERSE                                13
+#define     LOGICOP_OR                                        14
+#define     LOGICOP_SET                                       15
+   uint32_t                                     LogicOpFunction;
+   bool                                         AlphaTestEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     AlphaTestFunction;
+   bool                                         ColorDitherEnable;
+   uint32_t                                     XDitherOffset;
+   uint32_t                                     YDitherOffset;
+#define     COLORCLAMP_UNORM                                   0
+#define     COLORCLAMP_SNORM                                   1
+#define     COLORCLAMP_RTFORMAT                                2
+   uint32_t                                     ColorClampRange;
+   bool                                         PreBlendColorClampEnable;
+   bool                                         PostBlendColorClampEnable;
+};
+
+static inline void
+GEN75_BLEND_STATE_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN75_BLEND_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ColorBufferBlendEnable, 31, 31) |
+      __gen_field(values->IndependentAlphaBlendEnable, 30, 30) |
+      __gen_field(values->AlphaBlendFunction, 26, 28) |
+      __gen_field(values->SourceAlphaBlendFactor, 20, 24) |
+      __gen_field(values->DestinationAlphaBlendFactor, 15, 19) |
+      __gen_field(values->ColorBlendFunction, 11, 13) |
+      __gen_field(values->SourceBlendFactor, 5, 9) |
+      __gen_field(values->DestinationBlendFactor, 0, 4) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AlphaToCoverageEnable, 31, 31) |
+      __gen_field(values->AlphaToOneEnable, 30, 30) |
+      __gen_field(values->AlphaToCoverageDitherEnable, 29, 29) |
+      __gen_field(values->WriteDisableAlpha, 27, 27) |
+      __gen_field(values->WriteDisableRed, 26, 26) |
+      __gen_field(values->WriteDisableGreen, 25, 25) |
+      __gen_field(values->WriteDisableBlue, 24, 24) |
+      __gen_field(values->LogicOpEnable, 22, 22) |
+      __gen_field(values->LogicOpFunction, 18, 21) |
+      __gen_field(values->AlphaTestEnable, 16, 16) |
+      __gen_field(values->AlphaTestFunction, 13, 15) |
+      __gen_field(values->ColorDitherEnable, 12, 12) |
+      __gen_field(values->XDitherOffset, 10, 11) |
+      __gen_field(values->YDitherOffset, 8, 9) |
+      __gen_field(values->ColorClampRange, 2, 3) |
+      __gen_field(values->PreBlendColorClampEnable, 1, 1) |
+      __gen_field(values->PostBlendColorClampEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN75_CC_VIEWPORT_length 0x00000002
+
+struct GEN75_CC_VIEWPORT {
+   float                                        MinimumDepth;
+   float                                        MaximumDepth;
+};
+
+static inline void
+GEN75_CC_VIEWPORT_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN75_CC_VIEWPORT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->MinimumDepth) |
+      0;
+
+   dw[1] =
+      __gen_float(values->MaximumDepth) |
+      0;
+
+}
+
+#define GEN75_COLOR_CALC_STATE_length 0x00000006
+
+struct GEN75_COLOR_CALC_STATE {
+   uint32_t                                     StencilReferenceValue;
+   uint32_t                                     BackFaceStencilReferenceValue;
+#define     Cancelled                                          0
+#define     NotCancelled                                       1
+   uint32_t                                     RoundDisableFunctionDisable;
+#define     ALPHATEST_UNORM8                                   0
+#define     ALPHATEST_FLOAT32                                  1
+   uint32_t                                     AlphaTestFormat;
+   uint32_t                                     AlphaReferenceValueAsUNORM8;
+   float                                        AlphaReferenceValueAsFLOAT32;
+   float                                        BlendConstantColorRed;
+   float                                        BlendConstantColorGreen;
+   float                                        BlendConstantColorBlue;
+   float                                        BlendConstantColorAlpha;
+};
+
+static inline void
+GEN75_COLOR_CALC_STATE_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN75_COLOR_CALC_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->StencilReferenceValue, 24, 31) |
+      __gen_field(values->BackFaceStencilReferenceValue, 16, 23) |
+      __gen_field(values->RoundDisableFunctionDisable, 15, 15) |
+      __gen_field(values->AlphaTestFormat, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AlphaReferenceValueAsUNORM8, 0, 31) |
+      __gen_float(values->AlphaReferenceValueAsFLOAT32) |
+      0;
+
+   dw[2] =
+      __gen_float(values->BlendConstantColorRed) |
+      0;
+
+   dw[3] =
+      __gen_float(values->BlendConstantColorGreen) |
+      0;
+
+   dw[4] =
+      __gen_float(values->BlendConstantColorBlue) |
+      0;
+
+   dw[5] =
+      __gen_float(values->BlendConstantColorAlpha) |
+      0;
+
+}
+
+#define GEN75_DEPTH_STENCIL_STATE_length 0x00000003
+
+struct GEN75_DEPTH_STENCIL_STATE {
+   bool                                         StencilTestEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     StencilTestFunction;
+#define     STENCILOP_KEEP                                     0
+#define     STENCILOP_ZERO                                     1
+#define     STENCILOP_REPLACE                                  2
+#define     STENCILOP_INCRSAT                                  3
+#define     STENCILOP_DECRSAT                                  4
+#define     STENCILOP_INCR                                     5
+#define     STENCILOP_DECR                                     6
+#define     STENCILOP_INVERT                                   7
+   uint32_t                                     StencilFailOp;
+   uint32_t                                     StencilPassDepthFailOp;
+   uint32_t                                     StencilPassDepthPassOp;
+   bool                                         StencilBufferWriteEnable;
+   bool                                         DoubleSidedStencilEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     BackFaceStencilTestFunction;
+#define     STENCILOP_KEEP                                     0
+#define     STENCILOP_ZERO                                     1
+#define     STENCILOP_REPLACE                                  2
+#define     STENCILOP_INCRSAT                                  3
+#define     STENCILOP_DECRSAT                                  4
+#define     STENCILOP_INCR                                     5
+#define     STENCILOP_DECR                                     6
+#define     STENCILOP_INVERT                                   7
+   uint32_t                                     BackfaceStencilFailOp;
+   uint32_t                                     BackfaceStencilPassDepthFailOp;
+   uint32_t                                     BackfaceStencilPassDepthPassOp;
+   uint32_t                                     StencilTestMask;
+   uint32_t                                     StencilWriteMask;
+   uint32_t                                     BackfaceStencilTestMask;
+   uint32_t                                     BackfaceStencilWriteMask;
+   bool                                         DepthTestEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     DepthTestFunction;
+   bool                                         DepthBufferWriteEnable;
+};
+
+static inline void
+GEN75_DEPTH_STENCIL_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_DEPTH_STENCIL_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->StencilTestEnable, 31, 31) |
+      __gen_field(values->StencilTestFunction, 28, 30) |
+      __gen_field(values->StencilFailOp, 25, 27) |
+      __gen_field(values->StencilPassDepthFailOp, 22, 24) |
+      __gen_field(values->StencilPassDepthPassOp, 19, 21) |
+      __gen_field(values->StencilBufferWriteEnable, 18, 18) |
+      __gen_field(values->DoubleSidedStencilEnable, 15, 15) |
+      __gen_field(values->BackFaceStencilTestFunction, 12, 14) |
+      __gen_field(values->BackfaceStencilFailOp, 9, 11) |
+      __gen_field(values->BackfaceStencilPassDepthFailOp, 6, 8) |
+      __gen_field(values->BackfaceStencilPassDepthPassOp, 3, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StencilTestMask, 24, 31) |
+      __gen_field(values->StencilWriteMask, 16, 23) |
+      __gen_field(values->BackfaceStencilTestMask, 8, 15) |
+      __gen_field(values->BackfaceStencilWriteMask, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DepthTestEnable, 31, 31) |
+      __gen_field(values->DepthTestFunction, 27, 29) |
+      __gen_field(values->DepthBufferWriteEnable, 26, 26) |
+      0;
+
+}
+
+#define GEN75_INTERFACE_DESCRIPTOR_DATA_length 0x00000008
+
+struct GEN75_INTERFACE_DESCRIPTOR_DATA {
+   uint32_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleProgramFlow;
+#define     NormalPriority                                     0
+#define     HighPriority                                       1
+   uint32_t                                     ThreadPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     SamplerStatePointer;
+#define     Nosamplersused                                     0
+#define     Between1and4samplersused                           1
+#define     Between5and8samplersused                           2
+#define     Between9and12samplersused                          3
+#define     Between13and16samplersused                         4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTablePointer;
+   uint32_t                                     BindingTableEntryCount;
+   uint32_t                                     ConstantURBEntryReadLength;
+#define     RTNE                                               0
+#define     RU                                                 1
+#define     RD                                                 2
+#define     RTZ                                                3
+   uint32_t                                     RoundingMode;
+   bool                                         BarrierEnable;
+   uint32_t                                     SharedLocalMemorySize;
+   uint32_t                                     NumberofThreadsinGPGPUThreadGroup;
+   uint32_t                                     CrossThreadConstantDataReadLength;
+};
+
+static inline void
+GEN75_INTERFACE_DESCRIPTOR_DATA_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN75_INTERFACE_DESCRIPTOR_DATA * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SingleProgramFlow, 18, 18) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->SamplerStatePointer, 5, 31) |
+      __gen_field(values->SamplerCount, 2, 4) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->BindingTablePointer, 5, 15) |
+      __gen_field(values->BindingTableEntryCount, 0, 4) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ConstantURBEntryReadLength, 16, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->RoundingMode, 22, 23) |
+      __gen_field(values->BarrierEnable, 21, 21) |
+      __gen_field(values->SharedLocalMemorySize, 16, 20) |
+      __gen_field(values->NumberofThreadsinGPGPUThreadGroup, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->CrossThreadConstantDataReadLength, 0, 7) |
+      0;
+
+   dw[7] =
+      0;
+
+}
+
+#define GEN75_BINDING_TABLE_STATE_length 0x00000001
+
+struct GEN75_BINDING_TABLE_STATE {
+   uint32_t                                     SurfaceStatePointer;
+};
+
+static inline void
+GEN75_BINDING_TABLE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN75_BINDING_TABLE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->SurfaceStatePointer, 5, 31) |
+      0;
+
+}
+
+#define GEN75_RENDER_SURFACE_STATE_length 0x00000008
+
+struct GEN75_RENDER_SURFACE_STATE {
+#define     SURFTYPE_1D                                        0
+#define     SURFTYPE_2D                                        1
+#define     SURFTYPE_3D                                        2
+#define     SURFTYPE_CUBE                                      3
+#define     SURFTYPE_BUFFER                                    4
+#define     SURFTYPE_STRBUF                                    5
+#define     SURFTYPE_NULL                                      7
+   uint32_t                                     SurfaceType;
+   bool                                         SurfaceArray;
+   uint32_t                                     SurfaceFormat;
+#define     VALIGN_2                                           0
+#define     VALIGN_4                                           1
+   uint32_t                                     SurfaceVerticalAlignment;
+#define     HALIGN_4                                           0
+#define     HALIGN_8                                           1
+   uint32_t                                     SurfaceHorizontalAlignment;
+   uint32_t                                     TiledSurface;
+#define     TILEWALK_XMAJOR                                    0
+#define     TILEWALK_YMAJOR                                    1
+   uint32_t                                     TileWalk;
+   uint32_t                                     VerticalLineStride;
+   uint32_t                                     VerticalLineStrideOffset;
+#define     ARYSPC_FULL                                        0
+#define     ARYSPC_LOD0                                        1
+   uint32_t                                     SurfaceArraySpacing;
+   uint32_t                                     RenderCacheReadWriteMode;
+#define     NORMAL_MODE                                        0
+#define     PROGRESSIVE_FRAME                                  2
+#define     INTERLACED_FRAME                                   3
+   uint32_t                                     MediaBoundaryPixelMode;
+   uint32_t                                     CubeFaceEnables;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     Height;
+   uint32_t                                     Width;
+   uint32_t                                     Depth;
+   uint32_t                                     IntegerSurfaceFormat;
+   uint32_t                                     SurfacePitch;
+#define     RTROTATE_0DEG                                      0
+#define     RTROTATE_90DEG                                     1
+#define     RTROTATE_270DEG                                    3
+   uint32_t                                     RenderTargetRotation;
+   uint32_t                                     MinimumArrayElement;
+   uint32_t                                     RenderTargetViewExtent;
+#define     MSFMT_MSS                                          0
+#define     MSFMT_DEPTH_STENCIL                                1
+   uint32_t                                     MultisampledSurfaceStorageFormat;
+#define     MULTISAMPLECOUNT_1                                 0
+#define     MULTISAMPLECOUNT_4                                 2
+#define     MULTISAMPLECOUNT_8                                 3
+   uint32_t                                     NumberofMultisamples;
+   uint32_t                                     MultisamplePositionPaletteIndex;
+   uint32_t                                     MinimumArrayElement0;
+   uint32_t                                     XOffset;
+   uint32_t                                     YOffset;
+   struct GEN75_MEMORY_OBJECT_CONTROL_STATE     SurfaceObjectControlState;
+   uint32_t                                     SurfaceMinLOD;
+   uint32_t                                     MIPCountLOD;
+   __gen_address_type                           MCSBaseAddress;
+   uint32_t                                     MCSSurfacePitch;
+   __gen_address_type                           AppendCounterAddress;
+   bool                                         AppendCounterEnable;
+   bool                                         MCSEnable;
+   uint32_t                                     XOffsetforUVPlane;
+   uint32_t                                     YOffsetforUVPlane;
+#define     SCS_ZERO                                           0
+#define     SCS_ONE                                            1
+#define     SCS_RED                                            4
+#define     SCS_GREEN                                          5
+#define     SCS_BLUE                                           6
+#define     SCS_ALPHA                                          7
+   uint32_t                                     ShaderChannelSelectR;
+   uint32_t                                     ShaderChannelSelectG;
+   uint32_t                                     ShaderChannelSelectB;
+   uint32_t                                     ShaderChannelSelectA;
+   float                                        ResourceMinLOD;
+};
+
+static inline void
+GEN75_RENDER_SURFACE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN75_RENDER_SURFACE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->SurfaceType, 29, 31) |
+      __gen_field(values->SurfaceArray, 28, 28) |
+      __gen_field(values->SurfaceFormat, 18, 26) |
+      __gen_field(values->SurfaceVerticalAlignment, 16, 17) |
+      __gen_field(values->SurfaceHorizontalAlignment, 15, 15) |
+      __gen_field(values->TiledSurface, 14, 14) |
+      __gen_field(values->TileWalk, 13, 13) |
+      __gen_field(values->VerticalLineStride, 12, 12) |
+      __gen_field(values->VerticalLineStrideOffset, 11, 11) |
+      __gen_field(values->SurfaceArraySpacing, 10, 10) |
+      __gen_field(values->RenderCacheReadWriteMode, 8, 8) |
+      __gen_field(values->MediaBoundaryPixelMode, 6, 7) |
+      __gen_field(values->CubeFaceEnables, 0, 5) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->SurfaceBaseAddress, dw1);
+
+   dw[2] =
+      __gen_field(values->Height, 16, 29) |
+      __gen_field(values->Width, 0, 13) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Depth, 21, 31) |
+      __gen_field(values->IntegerSurfaceFormat, 18, 20) |
+      __gen_field(values->SurfacePitch, 0, 17) |
+      0;
+
+   dw[4] =
+      __gen_field(values->RenderTargetRotation, 29, 30) |
+      __gen_field(values->MinimumArrayElement, 18, 28) |
+      __gen_field(values->RenderTargetViewExtent, 7, 17) |
+      __gen_field(values->MultisampledSurfaceStorageFormat, 6, 6) |
+      __gen_field(values->NumberofMultisamples, 3, 5) |
+      __gen_field(values->MultisamplePositionPaletteIndex, 0, 2) |
+      __gen_field(values->MinimumArrayElement, 0, 26) |
+      0;
+
+   uint32_t dw_SurfaceObjectControlState;
+   GEN75_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceObjectControlState, &values->SurfaceObjectControlState);
+   dw[5] =
+      __gen_offset(values->XOffset, 25, 31) |
+      __gen_offset(values->YOffset, 20, 23) |
+      __gen_field(dw_SurfaceObjectControlState, 16, 19) |
+      __gen_field(values->SurfaceMinLOD, 4, 7) |
+      __gen_field(values->MIPCountLOD, 0, 3) |
+      0;
+
+   uint32_t dw6 =
+      __gen_field(values->MCSSurfacePitch, 3, 11) |
+      __gen_field(values->AppendCounterEnable, 1, 1) |
+      __gen_field(values->MCSEnable, 0, 0) |
+      __gen_field(values->XOffsetforUVPlane, 16, 29) |
+      __gen_field(values->YOffsetforUVPlane, 0, 13) |
+      0;
+
+   dw[6] =
+      __gen_combine_address(data, &dw[6], values->AppendCounterAddress, dw6);
+
+   dw[7] =
+      __gen_field(values->ShaderChannelSelectR, 25, 27) |
+      __gen_field(values->ShaderChannelSelectG, 22, 24) |
+      __gen_field(values->ShaderChannelSelectB, 19, 21) |
+      __gen_field(values->ShaderChannelSelectA, 16, 18) |
+      __gen_field(values->ResourceMinLOD * (1 << 8), 0, 11) |
+      0;
+
+}
+
+#define GEN75_SAMPLER_BORDER_COLOR_STATE_length 0x00000014
+
+#define GEN75_BORDER_COLOR_UINT32_SINT32_length 0x00000004
+
+struct GEN75_BORDER_COLOR_UINT32_SINT32 {
+   uint32_t                                     BorderColorRedui32integerunclamp;
+   uint32_t                                     BorderColorRedsi32integerunclamp;
+   uint32_t                                     BorderColorGreenui32integerunclamp;
+   uint32_t                                     BorderColorGreensi32integerunclamp;
+   uint32_t                                     BorderColorBlueui32integerunclamp;
+   uint32_t                                     BorderColorBluesi32integerunclamp;
+   uint32_t                                     BorderColorGreenui32integerunclamp0;
+   uint32_t                                     BorderColorGreensi32integerunclamp0;
+   uint32_t                                     BorderColorAlphaui32integerunclamp;
+   uint32_t                                     BorderColorAlphasi32integerunclamp;
+};
+
+static inline void
+GEN75_BORDER_COLOR_UINT32_SINT32_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_BORDER_COLOR_UINT32_SINT32 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->BorderColorRedui32integerunclamp, 0, 31) |
+      __gen_field(values->BorderColorRedsi32integerunclamp, 0, 31) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BorderColorGreenui32integerunclamp, 0, 31) |
+      __gen_field(values->BorderColorGreensi32integerunclamp, 0, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->BorderColorBlueui32integerunclamp, 0, 31) |
+      __gen_field(values->BorderColorBluesi32integerunclamp, 0, 31) |
+      __gen_field(values->BorderColorGreenui32integerunclamp, 0, 31) |
+      __gen_field(values->BorderColorGreensi32integerunclamp, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->BorderColorAlphaui32integerunclamp, 0, 31) |
+      __gen_field(values->BorderColorAlphasi32integerunclamp, 0, 31) |
+      0;
+
+}
+
+#define GEN75_BORDER_COLOR_UINT16_SINT16_length 0x00000004
+
+struct GEN75_BORDER_COLOR_UINT16_SINT16 {
+   uint32_t                                     BorderColorGreenclamptouint16;
+   uint32_t                                     BorderColorGreenclamptosint16;
+   uint32_t                                     BorderColorRedclamptouint16;
+   uint32_t                                     BorderColorRedclamptosint16;
+   uint32_t                                     BorderColorAlphaclamptouint16;
+   uint32_t                                     BorderColorAlphaclamptosint16;
+   uint32_t                                     BorderColorBlueclamptouint16;
+   uint32_t                                     BorderColorBlueclamptosint16;
+};
+
+static inline void
+GEN75_BORDER_COLOR_UINT16_SINT16_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_BORDER_COLOR_UINT16_SINT16 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->BorderColorGreenclamptouint16, 16, 31) |
+      __gen_field(values->BorderColorGreenclamptosint16, 16, 31) |
+      __gen_field(values->BorderColorRedclamptouint16, 0, 15) |
+      __gen_field(values->BorderColorRedclamptosint16, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->BorderColorAlphaclamptouint16, 16, 31) |
+      __gen_field(values->BorderColorAlphaclamptosint16, 16, 31) |
+      __gen_field(values->BorderColorBlueclamptouint16, 0, 15) |
+      __gen_field(values->BorderColorBlueclamptosint16, 0, 15) |
+      0;
+
+   dw[3] =
+      0;
+
+}
+
+#define GEN75_BORDER_COLOR_UINT8_SINT8_length 0x00000004
+
+struct GEN75_BORDER_COLOR_UINT8_SINT8 {
+   uint32_t                                     BorderColorAlphaclamptouint8;
+   uint32_t                                     BorderColorAlphaclamptosint8;
+   uint32_t                                     BorderColorBlueclamptouint8;
+   uint32_t                                     BorderColorBlueclamptosint8;
+   uint32_t                                     BorderColorGreenclamptouint8;
+   uint32_t                                     BorderColorGreenclamptosint8;
+   uint32_t                                     BorderRedAlphaclamptouint8;
+   uint32_t                                     BorderRedAlphaclamptosint8;
+};
+
+static inline void
+GEN75_BORDER_COLOR_UINT8_SINT8_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN75_BORDER_COLOR_UINT8_SINT8 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->BorderColorAlphaclamptouint8, 24, 31) |
+      __gen_field(values->BorderColorAlphaclamptosint8, 24, 31) |
+      __gen_field(values->BorderColorBlueclamptouint8, 16, 23) |
+      __gen_field(values->BorderColorBlueclamptosint8, 16, 23) |
+      __gen_field(values->BorderColorGreenclamptouint8, 8, 15) |
+      __gen_field(values->BorderColorGreenclamptosint8, 8, 15) |
+      __gen_field(values->BorderRedAlphaclamptouint8, 0, 7) |
+      __gen_field(values->BorderRedAlphaclamptosint8, 0, 7) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      0;
+
+   dw[3] =
+      0;
+
+}
+
+struct GEN75_SAMPLER_BORDER_COLOR_STATE {
+   float                                        BorderColorRedDX100GL;
+   uint32_t                                     BorderColorAlpha;
+   uint32_t                                     BorderColorBlue;
+   uint32_t                                     BorderColorGreen;
+   uint32_t                                     BorderColorRedDX9;
+   float                                        BorderColorGreen0;
+   float                                        BorderColorBlue0;
+   float                                        BorderColorAlpha0;
+   struct GEN75_BORDER_COLOR_UINT32_SINT32      BorderColor;
+   struct GEN75_BORDER_COLOR_UINT16_SINT16      BorderColor0;
+   struct GEN75_BORDER_COLOR_UINT8_SINT8        BorderColor1;
+};
+
+static inline void
+GEN75_SAMPLER_BORDER_COLOR_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN75_SAMPLER_BORDER_COLOR_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->BorderColorRedDX100GL) |
+      __gen_field(values->BorderColorAlpha, 24, 31) |
+      __gen_field(values->BorderColorBlue, 16, 23) |
+      __gen_field(values->BorderColorGreen, 8, 15) |
+      __gen_field(values->BorderColorRedDX9, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_float(values->BorderColorGreen) |
+      0;
+
+   dw[2] =
+      __gen_float(values->BorderColorBlue) |
+      0;
+
+   dw[3] =
+      __gen_float(values->BorderColorAlpha) |
+      0;
+
+   for (uint32_t i = 0, j = 4; i < 12; i += 1, j++) {
+      dw[j] =
+         0;
+   }
+
+   GEN75_BORDER_COLOR_UINT32_SINT32_pack(data, &dw[16], &values->BorderColor);
+}
+
+#define GEN75_SAMPLER_STATE_length 0x00000004
+
+struct GEN75_SAMPLER_STATE {
+   bool                                         SamplerDisable;
+#define     DX10OGL                                            0
+#define     DX9                                                1
+   uint32_t                                     TextureBorderColorMode;
+#define     OGL                                                1
+   uint32_t                                     LODPreClampEnable;
+   float                                        BaseMipLevel;
+#define     MIPFILTER_NONE                                     0
+#define     MIPFILTER_NEAREST                                  1
+#define     MIPFILTER_LINEAR                                   3
+   uint32_t                                     MipModeFilter;
+#define     MAPFILTER_NEAREST                                  0
+#define     MAPFILTER_LINEAR                                   1
+#define     MAPFILTER_ANISOTROPIC                              2
+#define     MAPFILTER_MONO                                     6
+   uint32_t                                     MagModeFilter;
+#define     MAPFILTER_NEAREST                                  0
+#define     MAPFILTER_LINEAR                                   1
+#define     MAPFILTER_ANISOTROPIC                              2
+#define     MAPFILTER_MONO                                     6
+   uint32_t                                     MinModeFilter;
+   uint32_t                                     TextureLODBias;
+#define     LEGACY                                             0
+#define     EWAApproximation                                   1
+   uint32_t                                     AnisotropicAlgorithm;
+   float                                        MinLOD;
+   float                                        MaxLOD;
+#define     PREFILTEROPALWAYS                                  0
+#define     PREFILTEROPNEVER                                   1
+#define     PREFILTEROPLESS                                    2
+#define     PREFILTEROPEQUAL                                   3
+#define     PREFILTEROPLEQUAL                                  4
+#define     PREFILTEROPGREATER                                 5
+#define     PREFILTEROPNOTEQUAL                                6
+#define     PREFILTEROPGEQUAL                                  7
+   uint32_t                                     ShadowFunction;
+#define     PROGRAMMED                                         0
+#define     OVERRIDE                                           1
+   uint32_t                                     CubeSurfaceControlMode;
+   uint32_t                                     BorderColorPointer;
+   bool                                         ChromaKeyEnable;
+   uint32_t                                     ChromaKeyIndex;
+#define     KEYFILTER_KILL_ON_ANY_MATCH                        0
+#define     KEYFILTER_REPLACE_BLACK                            1
+   uint32_t                                     ChromaKeyMode;
+#define     RATIO21                                            0
+#define     RATIO41                                            1
+#define     RATIO61                                            2
+#define     RATIO81                                            3
+#define     RATIO101                                           4
+#define     RATIO121                                           5
+#define     RATIO141                                           6
+#define     RATIO161                                           7
+   uint32_t                                     MaximumAnisotropy;
+   bool                                         RAddressMinFilterRoundingEnable;
+   bool                                         RAddressMagFilterRoundingEnable;
+   bool                                         VAddressMinFilterRoundingEnable;
+   bool                                         VAddressMagFilterRoundingEnable;
+   bool                                         UAddressMinFilterRoundingEnable;
+   bool                                         UAddressMagFilterRoundingEnable;
+#define     FULL                                               0
+#define     TRIQUAL_HIGHMAG_CLAMP_MIPFILTER                    1
+#define     MED                                                2
+#define     LOW                                                3
+   uint32_t                                     TrilinearFilterQuality;
+   bool                                         NonnormalizedCoordinateEnable;
+   uint32_t                                     TCXAddressControlMode;
+   uint32_t                                     TCYAddressControlMode;
+   uint32_t                                     TCZAddressControlMode;
+};
+
+static inline void
+GEN75_SAMPLER_STATE_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN75_SAMPLER_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->SamplerDisable, 31, 31) |
+      __gen_field(values->TextureBorderColorMode, 29, 29) |
+      __gen_field(values->LODPreClampEnable, 28, 28) |
+      __gen_field(values->BaseMipLevel * (1 << 1), 22, 26) |
+      __gen_field(values->MipModeFilter, 20, 21) |
+      __gen_field(values->MagModeFilter, 17, 19) |
+      __gen_field(values->MinModeFilter, 14, 16) |
+      __gen_field(values->TextureLODBias, 1, 13) |
+      __gen_field(values->AnisotropicAlgorithm, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MinLOD * (1 << 8), 20, 31) |
+      __gen_field(values->MaxLOD * (1 << 8), 8, 19) |
+      __gen_field(values->ShadowFunction, 1, 3) |
+      __gen_field(values->CubeSurfaceControlMode, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->BorderColorPointer, 5, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ChromaKeyEnable, 25, 25) |
+      __gen_field(values->ChromaKeyIndex, 23, 24) |
+      __gen_field(values->ChromaKeyMode, 22, 22) |
+      __gen_field(values->MaximumAnisotropy, 19, 21) |
+      __gen_field(values->RAddressMinFilterRoundingEnable, 13, 13) |
+      __gen_field(values->RAddressMagFilterRoundingEnable, 14, 14) |
+      __gen_field(values->VAddressMinFilterRoundingEnable, 15, 15) |
+      __gen_field(values->VAddressMagFilterRoundingEnable, 16, 16) |
+      __gen_field(values->UAddressMinFilterRoundingEnable, 17, 17) |
+      __gen_field(values->UAddressMagFilterRoundingEnable, 18, 18) |
+      __gen_field(values->TrilinearFilterQuality, 11, 12) |
+      __gen_field(values->NonnormalizedCoordinateEnable, 10, 10) |
+      __gen_field(values->TCXAddressControlMode, 6, 8) |
+      __gen_field(values->TCYAddressControlMode, 3, 5) |
+      __gen_field(values->TCZAddressControlMode, 0, 2) |
+      0;
+
+}
+
+/* Enum 3D_Prim_Topo_Type */
+#define     _3DPRIM_POINTLIST                                  1
+#define     _3DPRIM_LINELIST                                   2
+#define     _3DPRIM_LINESTRIP                                  3
+#define     _3DPRIM_TRILIST                                    4
+#define     _3DPRIM_TRISTRIP                                   5
+#define     _3DPRIM_TRIFAN                                     6
+#define     _3DPRIM_QUADLIST                                   7
+#define     _3DPRIM_QUADSTRIP                                  8
+#define     _3DPRIM_LINELIST_ADJ                               9
+#define     _3DPRIM_LINESTRIP_ADJ                             10
+#define     _3DPRIM_TRILIST_ADJ                               11
+#define     _3DPRIM_TRISTRIP_ADJ                              12
+#define     _3DPRIM_TRISTRIP_REVERSE                          13
+#define     _3DPRIM_POLYGON                                   14
+#define     _3DPRIM_RECTLIST                                  15
+#define     _3DPRIM_LINELOOP                                  16
+#define     _3DPRIM_POINTLIST_BF                              17
+#define     _3DPRIM_LINESTRIP_CONT                            18
+#define     _3DPRIM_LINESTRIP_BF                              19
+#define     _3DPRIM_LINESTRIP_CONT_BF                         20
+#define     _3DPRIM_TRIFAN_NOSTIPPLE                          22
+#define     _3DPRIM_PATCHLIST_1                               32
+#define     _3DPRIM_PATCHLIST_2                               33
+#define     _3DPRIM_PATCHLIST_3                               34
+#define     _3DPRIM_PATCHLIST_4                               35
+#define     _3DPRIM_PATCHLIST_5                               36
+#define     _3DPRIM_PATCHLIST_6                               37
+#define     _3DPRIM_PATCHLIST_7                               38
+#define     _3DPRIM_PATCHLIST_8                               39
+#define     _3DPRIM_PATCHLIST_9                               40
+#define     _3DPRIM_PATCHLIST_10                              41
+#define     _3DPRIM_PATCHLIST_11                              42
+#define     _3DPRIM_PATCHLIST_12                              43
+#define     _3DPRIM_PATCHLIST_13                              44
+#define     _3DPRIM_PATCHLIST_14                              45
+#define     _3DPRIM_PATCHLIST_15                              46
+#define     _3DPRIM_PATCHLIST_16                              47
+#define     _3DPRIM_PATCHLIST_17                              48
+#define     _3DPRIM_PATCHLIST_18                              49
+#define     _3DPRIM_PATCHLIST_19                              50
+#define     _3DPRIM_PATCHLIST_20                              51
+#define     _3DPRIM_PATCHLIST_21                              52
+#define     _3DPRIM_PATCHLIST_22                              53
+#define     _3DPRIM_PATCHLIST_23                              54
+#define     _3DPRIM_PATCHLIST_24                              55
+#define     _3DPRIM_PATCHLIST_25                              56
+#define     _3DPRIM_PATCHLIST_26                              57
+#define     _3DPRIM_PATCHLIST_27                              58
+#define     _3DPRIM_PATCHLIST_28                              59
+#define     _3DPRIM_PATCHLIST_29                              60
+#define     _3DPRIM_PATCHLIST_30                              61
+#define     _3DPRIM_PATCHLIST_31                              62
+#define     _3DPRIM_PATCHLIST_32                              63
+
+/* Enum 3D_Vertex_Component_Control */
+#define     VFCOMP_NOSTORE                                     0
+#define     VFCOMP_STORE_SRC                                   1
+#define     VFCOMP_STORE_0                                     2
+#define     VFCOMP_STORE_1_FP                                  3
+#define     VFCOMP_STORE_1_INT                                 4
+#define     VFCOMP_STORE_VID                                   5
+#define     VFCOMP_STORE_IID                                   6
+#define     VFCOMP_STORE_PID                                   7
+
+/* Enum 3D_Compare_Function */
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+
+/* Enum SURFACE_FORMAT */
+#define     R32G32B32A32_FLOAT                                 0
+#define     R32G32B32A32_SINT                                  1
+#define     R32G32B32A32_UINT                                  2
+#define     R32G32B32A32_UNORM                                 3
+#define     R32G32B32A32_SNORM                                 4
+#define     R64G64_FLOAT                                       5
+#define     R32G32B32X32_FLOAT                                 6
+#define     R32G32B32A32_SSCALED                               7
+#define     R32G32B32A32_USCALED                               8
+#define     R32G32B32A32_SFIXED                               32
+#define     R64G64_PASSTHRU                                   33
+#define     R32G32B32_FLOAT                                   64
+#define     R32G32B32_SINT                                    65
+#define     R32G32B32_UINT                                    66
+#define     R32G32B32_UNORM                                   67
+#define     R32G32B32_SNORM                                   68
+#define     R32G32B32_SSCALED                                 69
+#define     R32G32B32_USCALED                                 70
+#define     R32G32B32_SFIXED                                  80
+#define     R16G16B16A16_UNORM                               128
+#define     R16G16B16A16_SNORM                               129
+#define     R16G16B16A16_SINT                                130
+#define     R16G16B16A16_UINT                                131
+#define     R16G16B16A16_FLOAT                               132
+#define     R32G32_FLOAT                                     133
+#define     R32G32_SINT                                      134
+#define     R32G32_UINT                                      135
+#define     R32_FLOAT_X8X24_TYPELESS                         136
+#define     X32_TYPELESS_G8X24_UINT                          137
+#define     L32A32_FLOAT                                     138
+#define     R32G32_UNORM                                     139
+#define     R32G32_SNORM                                     140
+#define     R64_FLOAT                                        141
+#define     R16G16B16X16_UNORM                               142
+#define     R16G16B16X16_FLOAT                               143
+#define     A32X32_FLOAT                                     144
+#define     L32X32_FLOAT                                     145
+#define     I32X32_FLOAT                                     146
+#define     R16G16B16A16_SSCALED                             147
+#define     R16G16B16A16_USCALED                             148
+#define     R32G32_SSCALED                                   149
+#define     R32G32_USCALED                                   150
+#define     R32G32_SFIXED                                    160
+#define     R64_PASSTHRU                                     161
+#define     B8G8R8A8_UNORM                                   192
+#define     B8G8R8A8_UNORM_SRGB                              193
+#define     R10G10B10A2_UNORM                                194
+#define     R10G10B10A2_UNORM_SRGB                           195
+#define     R10G10B10A2_UINT                                 196
+#define     R10G10B10_SNORM_A2_UNORM                         197
+#define     R8G8B8A8_UNORM                                   199
+#define     R8G8B8A8_UNORM_SRGB                              200
+#define     R8G8B8A8_SNORM                                   201
+#define     R8G8B8A8_SINT                                    202
+#define     R8G8B8A8_UINT                                    203
+#define     R16G16_UNORM                                     204
+#define     R16G16_SNORM                                     205
+#define     R16G16_SINT                                      206
+#define     R16G16_UINT                                      207
+#define     R16G16_FLOAT                                     208
+#define     B10G10R10A2_UNORM                                209
+#define     B10G10R10A2_UNORM_SRGB                           210
+#define     R11G11B10_FLOAT                                  211
+#define     R32_SINT                                         214
+#define     R32_UINT                                         215
+#define     R32_FLOAT                                        216
+#define     R24_UNORM_X8_TYPELESS                            217
+#define     X24_TYPELESS_G8_UINT                             218
+#define     L32_UNORM                                        221
+#define     A32_UNORM                                        222
+#define     L16A16_UNORM                                     223
+#define     I24X8_UNORM                                      224
+#define     L24X8_UNORM                                      225
+#define     A24X8_UNORM                                      226
+#define     I32_FLOAT                                        227
+#define     L32_FLOAT                                        228
+#define     A32_FLOAT                                        229
+#define     X8B8_UNORM_G8R8_SNORM                            230
+#define     A8X8_UNORM_G8R8_SNORM                            231
+#define     B8X8_UNORM_G8R8_SNORM                            232
+#define     B8G8R8X8_UNORM                                   233
+#define     B8G8R8X8_UNORM_SRGB                              234
+#define     R8G8B8X8_UNORM                                   235
+#define     R8G8B8X8_UNORM_SRGB                              236
+#define     R9G9B9E5_SHAREDEXP                               237
+#define     B10G10R10X2_UNORM                                238
+#define     L16A16_FLOAT                                     240
+#define     R32_UNORM                                        241
+#define     R32_SNORM                                        242
+#define     R10G10B10X2_USCALED                              243
+#define     R8G8B8A8_SSCALED                                 244
+#define     R8G8B8A8_USCALED                                 245
+#define     R16G16_SSCALED                                   246
+#define     R16G16_USCALED                                   247
+#define     R32_SSCALED                                      248
+#define     R32_USCALED                                      249
+#define     B5G6R5_UNORM                                     256
+#define     B5G6R5_UNORM_SRGB                                257
+#define     B5G5R5A1_UNORM                                   258
+#define     B5G5R5A1_UNORM_SRGB                              259
+#define     B4G4R4A4_UNORM                                   260
+#define     B4G4R4A4_UNORM_SRGB                              261
+#define     R8G8_UNORM                                       262
+#define     R8G8_SNORM                                       263
+#define     R8G8_SINT                                        264
+#define     R8G8_UINT                                        265
+#define     R16_UNORM                                        266
+#define     R16_SNORM                                        267
+#define     R16_SINT                                         268
+#define     R16_UINT                                         269
+#define     R16_FLOAT                                        270
+#define     A8P8_UNORM_PALETTE0                              271
+#define     A8P8_UNORM_PALETTE1                              272
+#define     I16_UNORM                                        273
+#define     L16_UNORM                                        274
+#define     A16_UNORM                                        275
+#define     L8A8_UNORM                                       276
+#define     I16_FLOAT                                        277
+#define     L16_FLOAT                                        278
+#define     A16_FLOAT                                        279
+#define     L8A8_UNORM_SRGB                                  280
+#define     R5G5_SNORM_B6_UNORM                              281
+#define     B5G5R5X1_UNORM                                   282
+#define     B5G5R5X1_UNORM_SRGB                              283
+#define     R8G8_SSCALED                                     284
+#define     R8G8_USCALED                                     285
+#define     R16_SSCALED                                      286
+#define     R16_USCALED                                      287
+#define     P8A8_UNORM_PALETTE0                              290
+#define     P8A8_UNORM_PALETTE1                              291
+#define     A1B5G5R5_UNORM                                   292
+#define     A4B4G4R4_UNORM                                   293
+#define     L8A8_UINT                                        294
+#define     L8A8_SINT                                        295
+#define     R8_UNORM                                         320
+#define     R8_SNORM                                         321
+#define     R8_SINT                                          322
+#define     R8_UINT                                          323
+#define     A8_UNORM                                         324
+#define     I8_UNORM                                         325
+#define     L8_UNORM                                         326
+#define     P4A4_UNORM_PALETTE0                              327
+#define     A4P4_UNORM_PALETTE0                              328
+#define     R8_SSCALED                                       329
+#define     R8_USCALED                                       330
+#define     P8_UNORM_PALETTE0                                331
+#define     L8_UNORM_SRGB                                    332
+#define     P8_UNORM_PALETTE1                                333
+#define     P4A4_UNORM_PALETTE1                              334
+#define     A4P4_UNORM_PALETTE1                              335
+#define     Y8_UNORM                                         336
+#define     L8_UINT                                          338
+#define     L8_SINT                                          339
+#define     I8_UINT                                          340
+#define     I8_SINT                                          341
+#define     DXT1_RGB_SRGB                                    384
+#define     R1_UNORM                                         385
+#define     YCRCB_NORMAL                                     386
+#define     YCRCB_SWAPUVY                                    387
+#define     P2_UNORM_PALETTE0                                388
+#define     P2_UNORM_PALETTE1                                389
+#define     BC1_UNORM                                        390
+#define     BC2_UNORM                                        391
+#define     BC3_UNORM                                        392
+#define     BC4_UNORM                                        393
+#define     BC5_UNORM                                        394
+#define     BC1_UNORM_SRGB                                   395
+#define     BC2_UNORM_SRGB                                   396
+#define     BC3_UNORM_SRGB                                   397
+#define     MONO8                                            398
+#define     YCRCB_SWAPUV                                     399
+#define     YCRCB_SWAPY                                      400
+#define     DXT1_RGB                                         401
+#define     FXT1                                             402
+#define     R8G8B8_UNORM                                     403
+#define     R8G8B8_SNORM                                     404
+#define     R8G8B8_SSCALED                                   405
+#define     R8G8B8_USCALED                                   406
+#define     R64G64B64A64_FLOAT                               407
+#define     R64G64B64_FLOAT                                  408
+#define     BC4_SNORM                                        409
+#define     BC5_SNORM                                        410
+#define     R16G16B16_FLOAT                                  411
+#define     R16G16B16_UNORM                                  412
+#define     R16G16B16_SNORM                                  413
+#define     R16G16B16_SSCALED                                414
+#define     R16G16B16_USCALED                                415
+#define     BC6H_SF16                                        417
+#define     BC7_UNORM                                        418
+#define     BC7_UNORM_SRGB                                   419
+#define     BC6H_UF16                                        420
+#define     PLANAR_420_8                                     421
+#define     R8G8B8_UNORM_SRGB                                424
+#define     ETC1_RGB8                                        425
+#define     ETC2_RGB8                                        426
+#define     EAC_R11                                          427
+#define     EAC_RG11                                         428
+#define     EAC_SIGNED_R11                                   429
+#define     EAC_SIGNED_RG11                                  430
+#define     ETC2_SRGB8                                       431
+#define     R16G16B16_UINT                                   432
+#define     R16G16B16_SINT                                   433
+#define     R32_SFIXED                                       434
+#define     R10G10B10A2_SNORM                                435
+#define     R10G10B10A2_USCALED                              436
+#define     R10G10B10A2_SSCALED                              437
+#define     R10G10B10A2_SINT                                 438
+#define     B10G10R10A2_SNORM                                439
+#define     B10G10R10A2_USCALED                              440
+#define     B10G10R10A2_SSCALED                              441
+#define     B10G10R10A2_UINT                                 442
+#define     B10G10R10A2_SINT                                 443
+#define     R64G64B64A64_PASSTHRU                            444
+#define     R64G64B64_PASSTHRU                               445
+#define     ETC2_RGB8_PTA                                    448
+#define     ETC2_SRGB8_PTA                                   449
+#define     ETC2_EAC_RGBA8                                   450
+#define     ETC2_EAC_SRGB8_A8                                451
+#define     R8G8B8_UINT                                      456
+#define     R8G8B8_SINT                                      457
+#define     RAW                                              511
+
+/* Enum Texture Coordinate Mode */
+#define     TCM_WRAP                                           0
+#define     TCM_MIRROR                                         1
+#define     TCM_CLAMP                                          2
+#define     TCM_CUBE                                           3
+#define     TCM_CLAMP_BORDER                                   4
+#define     TCM_MIRROR_ONCE                                    5
+
diff --git a/src/vulkan/gen7_cmd_buffer.c b/src/vulkan/gen7_cmd_buffer.c
new file mode 100644 (file)
index 0000000..5ebf129
--- /dev/null
@@ -0,0 +1,771 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static void
+gen7_cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer)
+{
+   static const uint32_t push_constant_opcodes[] = {
+      [VK_SHADER_STAGE_VERTEX]                  = 21,
+      [VK_SHADER_STAGE_TESS_CONTROL]            = 25, /* HS */
+      [VK_SHADER_STAGE_TESS_EVALUATION]         = 26, /* DS */
+      [VK_SHADER_STAGE_GEOMETRY]                = 22,
+      [VK_SHADER_STAGE_FRAGMENT]                = 23,
+      [VK_SHADER_STAGE_COMPUTE]                 = 0,
+   };
+
+   VkShaderStage stage;
+   VkShaderStageFlags flushed = 0;
+
+   for_each_bit(stage, cmd_buffer->state.push_constants_dirty) {
+      struct anv_state state = anv_cmd_buffer_push_constants(cmd_buffer, stage);
+
+      if (state.offset == 0)
+         continue;
+
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_CONSTANT_VS,
+                     ._3DCommandSubOpcode = push_constant_opcodes[stage],
+                     .ConstantBody = {
+                        .PointerToConstantBuffer0 = { .offset = state.offset },
+                        .ConstantBuffer0ReadLength = DIV_ROUND_UP(state.alloc_size, 32),
+                     });
+
+      flushed |= 1 << stage;
+   }
+
+   cmd_buffer->state.push_constants_dirty &= ~flushed;
+}
+
+
+void
+gen7_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_bo *scratch_bo = NULL;
+
+   cmd_buffer->state.scratch_size =
+      anv_block_pool_size(&device->scratch_block_pool);
+   if (cmd_buffer->state.scratch_size > 0)
+      scratch_bo = &device->scratch_block_pool.bo;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_STATE_BASE_ADDRESS,
+      .GeneralStateBaseAddress                  = { scratch_bo, 0 },
+      .GeneralStateMemoryObjectControlState     = GEN7_MOCS,
+      .GeneralStateBaseAddressModifyEnable      = true,
+      .GeneralStateAccessUpperBound             = { scratch_bo, scratch_bo->size },
+      .GeneralStateAccessUpperBoundModifyEnable = true,
+
+      .SurfaceStateBaseAddress                  = anv_cmd_buffer_surface_base_address(cmd_buffer),
+      .SurfaceStateMemoryObjectControlState     = GEN7_MOCS,
+      .SurfaceStateBaseAddressModifyEnable      = true,
+
+      .DynamicStateBaseAddress                  = { &device->dynamic_state_block_pool.bo, 0 },
+      .DynamicStateMemoryObjectControlState     = GEN7_MOCS,
+      .DynamicStateBaseAddressModifyEnable      = true,
+      .DynamicStateAccessUpperBound             = { &device->dynamic_state_block_pool.bo,
+                                                    device->dynamic_state_block_pool.bo.size },
+      .DynamicStateAccessUpperBoundModifyEnable = true,
+
+      .IndirectObjectBaseAddress                = { NULL, 0 },
+      .IndirectObjectMemoryObjectControlState   = GEN7_MOCS,
+      .IndirectObjectBaseAddressModifyEnable    = true,
+
+      .IndirectObjectAccessUpperBound           = { NULL, 0xffffffff },
+      .IndirectObjectAccessUpperBoundModifyEnable = true,
+
+      .InstructionBaseAddress                   = { &device->instruction_block_pool.bo, 0 },
+      .InstructionMemoryObjectControlState      = GEN7_MOCS,
+      .InstructionBaseAddressModifyEnable       = true,
+      .InstructionAccessUpperBound              =  { &device->instruction_block_pool.bo,
+                                                     device->instruction_block_pool.bo.size },
+      .InstructionAccessUpperBoundModifyEnable  = true);
+
+   /* After re-setting the surface state base address, we have to do some
+    * cache flusing so that the sampler engine will pick up the new
+    * SURFACE_STATE objects and binding tables. From the Broadwell PRM,
+    * Shared Function > 3D Sampler > State > State Caching (page 96):
+    *
+    *    Coherency with system memory in the state cache, like the texture
+    *    cache is handled partially by software. It is expected that the
+    *    command stream or shader will issue Cache Flush operation or
+    *    Cache_Flush sampler message to ensure that the L1 cache remains
+    *    coherent with system memory.
+    *
+    *    [...]
+    *
+    *    Whenever the value of the Dynamic_State_Base_Addr,
+    *    Surface_State_Base_Addr are altered, the L1 state cache must be
+    *    invalidated to ensure the new surface or sampler state is fetched
+    *    from system memory.
+    *
+    * The PIPE_CONTROL command has a "State Cache Invalidation Enable" bit
+    * which, according the PIPE_CONTROL instruction documentation in the
+    * Broadwell PRM:
+    *
+    *    Setting this bit is independent of any other bit in this packet.
+    *    This bit controls the invalidation of the L1 and L2 state caches
+    *    at the top of the pipe i.e. at the parsing time.
+    *
+    * Unfortunately, experimentation seems to indicate that state cache
+    * invalidation through a PIPE_CONTROL does nothing whatsoever in
+    * regards to surface state and binding tables.  In stead, it seems that
+    * invalidating the texture cache is what is actually needed.
+    *
+    * XXX:  As far as we have been able to determine through
+    * experimentation, shows that flush the texture cache appears to be
+    * sufficient.  The theory here is that all of the sampling/rendering
+    * units cache the binding table in the texture cache.  However, we have
+    * yet to be able to actually confirm this.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN7_PIPE_CONTROL,
+                  .TextureCacheInvalidationEnable = true);
+}
+
+static const uint32_t vk_to_gen_index_type[] = {
+   [VK_INDEX_TYPE_UINT16]                       = INDEX_WORD,
+   [VK_INDEX_TYPE_UINT32]                       = INDEX_DWORD,
+};
+
+void gen7_CmdBindIndexBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    VkIndexType                                 indexType)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
+   cmd_buffer->state.gen7.index_buffer = buffer;
+   cmd_buffer->state.gen7.index_type = vk_to_gen_index_type[indexType];
+   cmd_buffer->state.gen7.index_offset = offset;
+}
+
+static VkResult
+gen7_flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct anv_state surfaces = { 0, }, samplers = { 0, };
+   VkResult result;
+
+   result = anv_cmd_buffer_emit_samplers(cmd_buffer,
+                                         VK_SHADER_STAGE_COMPUTE, &samplers);
+   if (result != VK_SUCCESS)
+      return result;
+   result = anv_cmd_buffer_emit_binding_table(cmd_buffer,
+                                               VK_SHADER_STAGE_COMPUTE, &surfaces);
+   if (result != VK_SUCCESS)
+      return result;
+
+   struct GEN7_INTERFACE_DESCRIPTOR_DATA desc = {
+      .KernelStartPointer = pipeline->cs_simd,
+      .BindingTablePointer = surfaces.offset,
+      .SamplerStatePointer = samplers.offset,
+      .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
+   };
+
+   uint32_t size = GEN7_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
+   struct anv_state state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
+
+   GEN7_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
+                  .InterfaceDescriptorTotalLength = size,
+                  .InterfaceDescriptorDataStartAddress = state.offset);
+
+   return VK_SUCCESS;
+}
+
+static void
+gen7_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   VkResult result;
+
+   assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
+
+   if (cmd_buffer->state.current_pipeline != GPGPU) {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_PIPELINE_SELECT,
+                     .PipelineSelection = GPGPU);
+      cmd_buffer->state.current_pipeline = GPGPU;
+   }
+
+   if (cmd_buffer->state.compute_dirty & ANV_CMD_DIRTY_PIPELINE)
+      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+
+   if ((cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
+       (cmd_buffer->state.compute_dirty & ANV_CMD_DIRTY_PIPELINE)) {
+      /* FIXME: figure out descriptors for gen7 */
+      result = gen7_flush_compute_descriptor_set(cmd_buffer);
+      assert(result == VK_SUCCESS);
+      cmd_buffer->state.descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
+   }
+
+   cmd_buffer->state.compute_dirty = 0;
+}
+
+static void
+gen7_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   uint32_t *p;
+
+   uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
+
+   assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
+
+   if (cmd_buffer->state.current_pipeline != _3D) {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_PIPELINE_SELECT,
+                     .PipelineSelection = _3D);
+      cmd_buffer->state.current_pipeline = _3D;
+   }
+
+   if (vb_emit) {
+      const uint32_t num_buffers = __builtin_popcount(vb_emit);
+      const uint32_t num_dwords = 1 + num_buffers * 4;
+
+      p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
+                          GEN7_3DSTATE_VERTEX_BUFFERS);
+      uint32_t vb, i = 0;
+      for_each_bit(vb, vb_emit) {
+         struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
+         uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
+
+         struct GEN7_VERTEX_BUFFER_STATE state = {
+            .VertexBufferIndex = vb,
+            .BufferAccessType = pipeline->instancing_enable[vb] ? INSTANCEDATA : VERTEXDATA,
+            .VertexBufferMemoryObjectControlState = GEN7_MOCS,
+            .AddressModifyEnable = true,
+            .BufferPitch = pipeline->binding_stride[vb],
+            .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
+            .EndAddress = { buffer->bo, buffer->offset + buffer->size - 1},
+            .InstanceDataStepRate = 1
+         };
+
+         GEN7_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
+         i++;
+      }
+   }
+
+   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_PIPELINE) {
+      /* If somebody compiled a pipeline after starting a command buffer the
+       * scratch bo may have grown since we started this cmd buffer (and
+       * emitted STATE_BASE_ADDRESS).  If we're binding that pipeline now,
+       * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
+      if (cmd_buffer->state.scratch_size < pipeline->total_scratch)
+         gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
+
+      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+   }
+
+   if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT ||
+       cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) {
+      /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
+       *
+       *    "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth
+       *    stall needs to be sent just prior to any 3DSTATE_VS,
+       *    3DSTATE_URB_VS, 3DSTATE_CONSTANT_VS,
+       *    3DSTATE_BINDING_TABLE_POINTER_VS,
+       *    3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one
+       *    PIPE_CONTROL needs to be sent before any combination of VS
+       *    associated 3DSTATE."
+       */
+      anv_batch_emit(&cmd_buffer->batch, GEN7_PIPE_CONTROL,
+                     .DepthStallEnable = true,
+                     .PostSyncOperation = WriteImmediateData,
+                     .Address = { &cmd_buffer->device->workaround_bo, 0 });
+   }
+
+   if (cmd_buffer->state.descriptors_dirty)
+      anv_flush_descriptor_sets(cmd_buffer);
+
+   if (cmd_buffer->state.push_constants_dirty)
+      gen7_cmd_buffer_flush_push_constants(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)
+      anv_cmd_buffer_emit_viewport(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_SCISSOR)
+      anv_cmd_buffer_emit_scissor(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH |
+                                  ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)) {
+
+      bool enable_bias = cmd_buffer->state.dynamic.depth_bias.bias != 0.0f ||
+         cmd_buffer->state.dynamic.depth_bias.slope_scaled != 0.0f;
+
+      uint32_t sf_dw[GEN7_3DSTATE_SF_length];
+      struct GEN7_3DSTATE_SF sf = {
+         GEN7_3DSTATE_SF_header,
+         .LineWidth = cmd_buffer->state.dynamic.line_width,
+         .GlobalDepthOffsetEnableSolid = enable_bias,
+         .GlobalDepthOffsetEnableWireframe = enable_bias,
+         .GlobalDepthOffsetEnablePoint = enable_bias,
+         .GlobalDepthOffsetConstant = cmd_buffer->state.dynamic.depth_bias.bias,
+         .GlobalDepthOffsetScale = cmd_buffer->state.dynamic.depth_bias.slope_scaled,
+         .GlobalDepthOffsetClamp = cmd_buffer->state.dynamic.depth_bias.clamp
+      };
+      GEN7_3DSTATE_SF_pack(NULL, sf_dw, &sf);
+
+      anv_batch_emit_merge(&cmd_buffer->batch, sf_dw, pipeline->gen7.sf);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |
+                                  ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
+      struct anv_state cc_state =
+         anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+                                            GEN7_COLOR_CALC_STATE_length, 64);
+      struct GEN7_COLOR_CALC_STATE cc = {
+         .BlendConstantColorRed = cmd_buffer->state.dynamic.blend_constants[0],
+         .BlendConstantColorGreen = cmd_buffer->state.dynamic.blend_constants[1],
+         .BlendConstantColorBlue = cmd_buffer->state.dynamic.blend_constants[2],
+         .BlendConstantColorAlpha = cmd_buffer->state.dynamic.blend_constants[3],
+         .StencilReferenceValue =
+            cmd_buffer->state.dynamic.stencil_reference.front,
+         .BackFaceStencilReferenceValue =
+            cmd_buffer->state.dynamic.stencil_reference.back,
+      };
+      GEN7_COLOR_CALC_STATE_pack(NULL, cc_state.map, &cc);
+
+      anv_batch_emit(&cmd_buffer->batch,
+                     GEN7_3DSTATE_CC_STATE_POINTERS,
+                     .ColorCalcStatePointer = cc_state.offset);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
+                                  ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK)) {
+      uint32_t depth_stencil_dw[GEN7_DEPTH_STENCIL_STATE_length];
+
+      struct GEN7_DEPTH_STENCIL_STATE depth_stencil = {
+         /* Is this what we need to do? */
+         .StencilBufferWriteEnable =
+            cmd_buffer->state.dynamic.stencil_write_mask.front != 0,
+
+         .StencilTestMask =
+            cmd_buffer->state.dynamic.stencil_compare_mask.front & 0xff,
+         .StencilWriteMask =
+            cmd_buffer->state.dynamic.stencil_write_mask.front & 0xff,
+
+         .BackfaceStencilTestMask =
+            cmd_buffer->state.dynamic.stencil_compare_mask.back & 0xff,
+         .BackfaceStencilWriteMask =
+            cmd_buffer->state.dynamic.stencil_write_mask.back & 0xff,
+      };
+      GEN7_DEPTH_STENCIL_STATE_pack(NULL, depth_stencil_dw, &depth_stencil);
+
+      struct anv_state ds_state =
+         anv_cmd_buffer_merge_dynamic(cmd_buffer, depth_stencil_dw,
+                                      pipeline->gen7.depth_stencil_state,
+                                      GEN7_DEPTH_STENCIL_STATE_length, 64);
+
+      anv_batch_emit(&cmd_buffer->batch,
+                     GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS,
+                     .PointertoDEPTH_STENCIL_STATE = ds_state.offset);
+   }
+
+   if (cmd_buffer->state.gen7.index_buffer &&
+       cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_INDEX_BUFFER)) {
+      struct anv_buffer *buffer = cmd_buffer->state.gen7.index_buffer;
+      uint32_t offset = cmd_buffer->state.gen7.index_offset;
+
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_INDEX_BUFFER,
+                     .CutIndexEnable = pipeline->primitive_restart,
+                     .IndexFormat = cmd_buffer->state.gen7.index_type,
+                     .MemoryObjectControlState = GEN7_MOCS,
+                     .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
+                     .BufferEndingAddress = { buffer->bo, buffer->offset + buffer->size });
+   }
+
+   cmd_buffer->state.vb_dirty &= ~vb_emit;
+   cmd_buffer->state.dirty = 0;
+}
+
+void gen7_CmdDraw(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    vertexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstVertex,
+    uint32_t                                    firstInstance)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+
+   gen7_cmd_buffer_flush_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
+                  .VertexAccessType = SEQUENTIAL,
+                  .PrimitiveTopologyType = pipeline->topology,
+                  .VertexCountPerInstance = vertexCount,
+                  .StartVertexLocation = firstVertex,
+                  .InstanceCount = instanceCount,
+                  .StartInstanceLocation = firstInstance,
+                  .BaseVertexLocation = 0);
+}
+
+void gen7_CmdDrawIndexed(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    indexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstIndex,
+    int32_t                                     vertexOffset,
+    uint32_t                                    firstInstance)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+
+   gen7_cmd_buffer_flush_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
+                  .VertexAccessType = RANDOM,
+                  .PrimitiveTopologyType = pipeline->topology,
+                  .VertexCountPerInstance = indexCount,
+                  .StartVertexLocation = firstIndex,
+                  .InstanceCount = instanceCount,
+                  .StartInstanceLocation = firstInstance,
+                  .BaseVertexLocation = vertexOffset);
+}
+
+static void
+gen7_batch_lrm(struct anv_batch *batch,
+              uint32_t reg, struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN7_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg,
+                  .MemoryAddress = { bo, offset });
+}
+
+static void
+gen7_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
+{
+   anv_batch_emit(batch, GEN7_MI_LOAD_REGISTER_IMM,
+                  .RegisterOffset = reg,
+                  .DataDWord = imm);
+}
+
+/* Auto-Draw / Indirect Registers */
+#define GEN7_3DPRIM_END_OFFSET          0x2420
+#define GEN7_3DPRIM_START_VERTEX        0x2430
+#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
+#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
+#define GEN7_3DPRIM_START_INSTANCE      0x243C
+#define GEN7_3DPRIM_BASE_VERTEX         0x2440
+
+void gen7_CmdDrawIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen7_cmd_buffer_flush_state(cmd_buffer);
+
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
+   gen7_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
+                  .IndirectParameterEnable = true,
+                  .VertexAccessType = SEQUENTIAL,
+                  .PrimitiveTopologyType = pipeline->topology);
+}
+
+void gen7_CmdDrawIndexedIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen7_cmd_buffer_flush_state(cmd_buffer);
+
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
+   gen7_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DPRIMITIVE,
+                  .IndirectParameterEnable = true,
+                  .VertexAccessType = RANDOM,
+                  .PrimitiveTopologyType = pipeline->topology);
+}
+
+void gen7_CmdDispatch(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    x,
+    uint32_t                                    y,
+    uint32_t                                    z)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+
+   gen7_cmd_buffer_flush_compute_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_GPGPU_WALKER,
+                  .SIMDSize = prog_data->simd_size / 16,
+                  .ThreadDepthCounterMaximum = 0,
+                  .ThreadHeightCounterMaximum = 0,
+                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
+                  .ThreadGroupIDXDimension = x,
+                  .ThreadGroupIDYDimension = y,
+                  .ThreadGroupIDZDimension = z,
+                  .RightExecutionMask = pipeline->cs_right_mask,
+                  .BottomExecutionMask = 0xffffffff);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_MEDIA_STATE_FLUSH);
+}
+
+#define GPGPU_DISPATCHDIMX 0x2500
+#define GPGPU_DISPATCHDIMY 0x2504
+#define GPGPU_DISPATCHDIMZ 0x2508
+
+void gen7_CmdDispatchIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen7_cmd_buffer_flush_compute_state(cmd_buffer);
+
+   gen7_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
+   gen7_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
+   gen7_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_GPGPU_WALKER,
+                  .IndirectParameterEnable = true,
+                  .SIMDSize = prog_data->simd_size / 16,
+                  .ThreadDepthCounterMaximum = 0,
+                  .ThreadHeightCounterMaximum = 0,
+                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
+                  .RightExecutionMask = pipeline->cs_right_mask,
+                  .BottomExecutionMask = 0xffffffff);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_MEDIA_STATE_FLUSH);
+}
+
+void gen7_CmdPipelineBarrier(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineStageFlags                        srcStageMask,
+    VkPipelineStageFlags                        destStageMask,
+    VkBool32                                    byRegion,
+    uint32_t                                    memBarrierCount,
+    const void* const*                          ppMemBarriers)
+{
+   stub();
+}
+
+static void
+gen7_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
+{
+   const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   const struct anv_image_view *iview =
+      anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
+   const struct anv_image *image = iview ? iview->image : NULL;
+   const bool has_depth = iview && iview->format->depth_format;
+   const bool has_stencil = iview && iview->format->has_stencil;
+
+   /* Emit 3DSTATE_DEPTH_BUFFER */
+   if (has_depth) {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER,
+         .SurfaceType = SURFTYPE_2D,
+         .DepthWriteEnable = iview->format->depth_format,
+         .StencilWriteEnable = has_stencil,
+         .HierarchicalDepthBufferEnable = false,
+         .SurfaceFormat = iview->format->depth_format,
+         .SurfacePitch = image->depth_surface.stride - 1,
+         .SurfaceBaseAddress = {
+            .bo = image->bo,
+            .offset = image->depth_surface.offset,
+         },
+         .Height = fb->height - 1,
+         .Width = fb->width - 1,
+         .LOD = 0,
+         .Depth = 1 - 1,
+         .MinimumArrayElement = 0,
+         .DepthBufferObjectControlState = GEN7_MOCS,
+         .RenderTargetViewExtent = 1 - 1);
+   } else {
+      /* Even when no depth buffer is present, the hardware requires that
+       * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
+       *
+       *    If a null depth buffer is bound, the driver must instead bind depth as:
+       *       3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D
+       *       3DSTATE_DEPTH.Width = 1
+       *       3DSTATE_DEPTH.Height = 1
+       *       3DSTATE_DEPTH.SuraceFormat = D16_UNORM
+       *       3DSTATE_DEPTH.SurfaceBaseAddress = 0
+       *       3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0
+       *       3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0
+       *       3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
+       *
+       * The PRM is wrong, though. The width and height must be programmed to
+       * actual framebuffer's width and height, even when neither depth buffer
+       * nor stencil buffer is present.
+       */
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DEPTH_BUFFER,
+         .SurfaceType = SURFTYPE_2D,
+         .SurfaceFormat = D16_UNORM,
+         .Width = fb->width - 1,
+         .Height = fb->height - 1,
+         .StencilWriteEnable = has_stencil);
+   }
+
+   /* Emit 3DSTATE_STENCIL_BUFFER */
+   if (has_stencil) {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER,
+         .StencilBufferObjectControlState = GEN7_MOCS,
+
+         /* Stencil buffers have strange pitch. The PRM says:
+          *
+          *    The pitch must be set to 2x the value computed based on width,
+          *    as the stencil buffer is stored with two rows interleaved.
+          */
+         .SurfacePitch = 2 * image->stencil_surface.stride - 1,
+
+         .SurfaceBaseAddress = {
+            .bo = image->bo,
+            .offset = image->offset + image->stencil_surface.offset,
+         });
+   } else {
+      anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_STENCIL_BUFFER);
+   }
+
+   /* Disable hierarchial depth buffers. */
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_HIER_DEPTH_BUFFER);
+
+   /* Clear the clear params. */
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_CLEAR_PARAMS);
+}
+
+void
+gen7_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_subpass *subpass)
+{
+   cmd_buffer->state.subpass = subpass;
+   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
+
+   gen7_cmd_buffer_emit_depth_stencil(cmd_buffer);
+}
+
+static void
+begin_render_pass(struct anv_cmd_buffer *cmd_buffer,
+                  const VkRenderPassBeginInfo* pRenderPassBegin)
+{
+   ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
+   ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
+
+   cmd_buffer->state.framebuffer = framebuffer;
+   cmd_buffer->state.pass = pass;
+
+   const VkRect2D *render_area = &pRenderPassBegin->renderArea;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN7_3DSTATE_DRAWING_RECTANGLE,
+                  .ClippedDrawingRectangleYMin = render_area->offset.y,
+                  .ClippedDrawingRectangleXMin = render_area->offset.x,
+                  .ClippedDrawingRectangleYMax =
+                     render_area->offset.y + render_area->extent.height - 1,
+                  .ClippedDrawingRectangleXMax =
+                     render_area->offset.x + render_area->extent.width - 1,
+                  .DrawingRectangleOriginY = 0,
+                  .DrawingRectangleOriginX = 0);
+
+   anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
+                                    pRenderPassBegin->pClearValues);
+}
+
+void gen7_CmdBeginRenderPass(
+    VkCmdBuffer                                 cmdBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    VkRenderPassContents                        contents)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
+
+   begin_render_pass(cmd_buffer, pRenderPassBegin);
+
+   gen7_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
+}
+
+void gen7_CmdNextSubpass(
+    VkCmdBuffer                                 cmdBuffer,
+    VkRenderPassContents                        contents)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+
+   gen7_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
+}
+
+void gen7_CmdEndRenderPass(
+    VkCmdBuffer                                 cmdBuffer)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   /* Emit a flushing pipe control at the end of a pass.  This is kind of a
+    * hack but it ensures that render targets always actually get written.
+    * Eventually, we should do flushing based on image format transitions
+    * or something of that nature.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN7_PIPE_CONTROL,
+                  .PostSyncOperation = NoWrite,
+                  .RenderTargetCacheFlushEnable = true,
+                  .InstructionCacheInvalidateEnable = true,
+                  .DepthCacheFlushEnable = true,
+                  .VFCacheInvalidationEnable = true,
+                  .TextureCacheInvalidationEnable = true,
+                  .CommandStreamerStallEnable = true);
+}
diff --git a/src/vulkan/gen7_pack.h b/src/vulkan/gen7_pack.h
new file mode 100644 (file)
index 0000000..5f2dbc4
--- /dev/null
@@ -0,0 +1,6973 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+
+/* Instructions, enums and structures for IVB.
+ *
+ * This file has been generated, do not hand edit.
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef __gen_validate_value
+#define __gen_validate_value(x)
+#endif
+
+#ifndef __gen_field_functions
+#define __gen_field_functions
+
+union __gen_value {
+   float f;
+   uint32_t dw;
+};
+
+static inline uint64_t
+__gen_mbo(uint32_t start, uint32_t end)
+{
+   return (~0ul >> (64 - (end - start + 1))) << start;
+}
+
+static inline uint64_t
+__gen_field(uint64_t v, uint32_t start, uint32_t end)
+{
+   __gen_validate_value(v);
+#if DEBUG
+   if (end - start + 1 < 64)
+      assert(v < 1ul << (end - start + 1));
+#endif
+
+   return v << start;
+}
+
+static inline uint64_t
+__gen_offset(uint64_t v, uint32_t start, uint32_t end)
+{
+   __gen_validate_value(v);
+#if DEBUG
+   uint64_t mask = (~0ul >> (64 - (end - start + 1))) << start;
+
+   assert((v & ~mask) == 0);
+#endif
+
+   return v;
+}
+
+static inline uint32_t
+__gen_float(float v)
+{
+   __gen_validate_value(v);
+   return ((union __gen_value) { .f = (v) }).dw;
+}
+
+#ifndef __gen_address_type
+#error #define __gen_address_type before including this file
+#endif
+
+#ifndef __gen_user_data
+#error #define __gen_combine_address before including this file
+#endif
+
+#endif
+
+#define GEN7_3DSTATE_URB_VS_length_bias 0x00000002
+#define GEN7_3DSTATE_URB_VS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 48,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_URB_VS_length 0x00000002
+
+struct GEN7_3DSTATE_URB_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     VSURBStartingAddress;
+   uint32_t                                     VSURBEntryAllocationSize;
+   uint32_t                                     VSNumberofURBEntries;
+};
+
+static inline void
+GEN7_3DSTATE_URB_VS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_3DSTATE_URB_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->VSURBStartingAddress, 25, 29) |
+      __gen_field(values->VSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->VSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN7_MI_STORE_REGISTER_MEM_length_bias 0x00000002
+#define GEN7_MI_STORE_REGISTER_MEM_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 36,                  \
+   .DwordLength          =  1
+
+#define GEN7_MI_STORE_REGISTER_MEM_length 0x00000003
+
+struct GEN7_MI_STORE_REGISTER_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN7_MI_STORE_REGISTER_MEM_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN7_MI_STORE_REGISTER_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterAddress, 2, 22) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+}
+
+#define GEN7_PIPELINE_SELECT_length_bias 0x00000001
+#define GEN7_PIPELINE_SELECT_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  1,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4
+
+#define GEN7_PIPELINE_SELECT_length 0x00000001
+
+struct GEN7_PIPELINE_SELECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+#define     _3D                                                0
+#define     Media                                              1
+#define     GPGPU                                              2
+   uint32_t                                     PipelineSelection;
+};
+
+static inline void
+GEN7_PIPELINE_SELECT_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN7_PIPELINE_SELECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->PipelineSelection, 0, 1) |
+      0;
+
+}
+
+#define GEN7_STATE_BASE_ADDRESS_length_bias 0x00000002
+#define GEN7_STATE_BASE_ADDRESS_header          \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  1,                  \
+   .DwordLength          =  8
+
+#define GEN7_STATE_BASE_ADDRESS_length 0x0000000a
+
+#define GEN7_MEMORY_OBJECT_CONTROL_STATE_length 0x00000001
+
+struct GEN7_MEMORY_OBJECT_CONTROL_STATE {
+   uint32_t                                     GraphicsDataTypeGFDT;
+   uint32_t                                     LLCCacheabilityControlLLCCC;
+   uint32_t                                     L3CacheabilityControlL3CC;
+};
+
+static inline void
+GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN7_MEMORY_OBJECT_CONTROL_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->GraphicsDataTypeGFDT, 2, 2) |
+      __gen_field(values->LLCCacheabilityControlLLCCC, 1, 1) |
+      __gen_field(values->L3CacheabilityControlL3CC, 0, 0) |
+      0;
+
+}
+
+struct GEN7_STATE_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GeneralStateBaseAddress;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      GeneralStateMemoryObjectControlState;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      StatelessDataPortAccessMemoryObjectControlState;
+   uint32_t                                     StatelessDataPortAccessForceWriteThru;
+   bool                                         GeneralStateBaseAddressModifyEnable;
+   __gen_address_type                           SurfaceStateBaseAddress;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      SurfaceStateMemoryObjectControlState;
+   bool                                         SurfaceStateBaseAddressModifyEnable;
+   __gen_address_type                           DynamicStateBaseAddress;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      DynamicStateMemoryObjectControlState;
+   bool                                         DynamicStateBaseAddressModifyEnable;
+   __gen_address_type                           IndirectObjectBaseAddress;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      IndirectObjectMemoryObjectControlState;
+   bool                                         IndirectObjectBaseAddressModifyEnable;
+   __gen_address_type                           InstructionBaseAddress;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      InstructionMemoryObjectControlState;
+   bool                                         InstructionBaseAddressModifyEnable;
+   __gen_address_type                           GeneralStateAccessUpperBound;
+   bool                                         GeneralStateAccessUpperBoundModifyEnable;
+   __gen_address_type                           DynamicStateAccessUpperBound;
+   bool                                         DynamicStateAccessUpperBoundModifyEnable;
+   __gen_address_type                           IndirectObjectAccessUpperBound;
+   bool                                         IndirectObjectAccessUpperBoundModifyEnable;
+   __gen_address_type                           InstructionAccessUpperBound;
+   bool                                         InstructionAccessUpperBoundModifyEnable;
+};
+
+static inline void
+GEN7_STATE_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN7_STATE_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_GeneralStateMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_GeneralStateMemoryObjectControlState, &values->GeneralStateMemoryObjectControlState);
+   uint32_t dw_StatelessDataPortAccessMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_StatelessDataPortAccessMemoryObjectControlState, &values->StatelessDataPortAccessMemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(dw_GeneralStateMemoryObjectControlState, 8, 11) |
+      __gen_field(dw_StatelessDataPortAccessMemoryObjectControlState, 4, 7) |
+      __gen_field(values->StatelessDataPortAccessForceWriteThru, 3, 3) |
+      __gen_field(values->GeneralStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->GeneralStateBaseAddress, dw1);
+
+   uint32_t dw_SurfaceStateMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceStateMemoryObjectControlState, &values->SurfaceStateMemoryObjectControlState);
+   uint32_t dw2 =
+      __gen_field(dw_SurfaceStateMemoryObjectControlState, 8, 11) |
+      __gen_field(values->SurfaceStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceStateBaseAddress, dw2);
+
+   uint32_t dw_DynamicStateMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_DynamicStateMemoryObjectControlState, &values->DynamicStateMemoryObjectControlState);
+   uint32_t dw3 =
+      __gen_field(dw_DynamicStateMemoryObjectControlState, 8, 11) |
+      __gen_field(values->DynamicStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->DynamicStateBaseAddress, dw3);
+
+   uint32_t dw_IndirectObjectMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_IndirectObjectMemoryObjectControlState, &values->IndirectObjectMemoryObjectControlState);
+   uint32_t dw4 =
+      __gen_field(dw_IndirectObjectMemoryObjectControlState, 8, 11) |
+      __gen_field(values->IndirectObjectBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[4] =
+      __gen_combine_address(data, &dw[4], values->IndirectObjectBaseAddress, dw4);
+
+   uint32_t dw_InstructionMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_InstructionMemoryObjectControlState, &values->InstructionMemoryObjectControlState);
+   uint32_t dw5 =
+      __gen_field(dw_InstructionMemoryObjectControlState, 8, 11) |
+      __gen_field(values->InstructionBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   dw[5] =
+      __gen_combine_address(data, &dw[5], values->InstructionBaseAddress, dw5);
+
+   uint32_t dw6 =
+      __gen_field(values->GeneralStateAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[6] =
+      __gen_combine_address(data, &dw[6], values->GeneralStateAccessUpperBound, dw6);
+
+   uint32_t dw7 =
+      __gen_field(values->DynamicStateAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[7] =
+      __gen_combine_address(data, &dw[7], values->DynamicStateAccessUpperBound, dw7);
+
+   uint32_t dw8 =
+      __gen_field(values->IndirectObjectAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[8] =
+      __gen_combine_address(data, &dw[8], values->IndirectObjectAccessUpperBound, dw8);
+
+   uint32_t dw9 =
+      __gen_field(values->InstructionAccessUpperBoundModifyEnable, 0, 0) |
+      0;
+
+   dw[9] =
+      __gen_combine_address(data, &dw[9], values->InstructionAccessUpperBound, dw9);
+
+}
+
+#define GEN7_STATE_PREFETCH_length_bias 0x00000002
+#define GEN7_STATE_PREFETCH_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  3,                  \
+   .DwordLength          =  0
+
+#define GEN7_STATE_PREFETCH_length 0x00000002
+
+struct GEN7_STATE_PREFETCH {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           PrefetchPointer;
+   uint32_t                                     PrefetchCount;
+};
+
+static inline void
+GEN7_STATE_PREFETCH_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_STATE_PREFETCH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->PrefetchCount, 0, 2) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->PrefetchPointer, dw1);
+
+}
+
+#define GEN7_STATE_SIP_length_bias 0x00000002
+#define GEN7_STATE_SIP_header                   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  2,                  \
+   .DwordLength          =  0
+
+#define GEN7_STATE_SIP_length 0x00000002
+
+struct GEN7_STATE_SIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SystemInstructionPointer;
+};
+
+static inline void
+GEN7_STATE_SIP_pack(__gen_user_data *data, void * restrict dst,
+                    const struct GEN7_STATE_SIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SystemInstructionPointer, 4, 31) |
+      0;
+
+}
+
+#define GEN7_SWTESS_BASE_ADDRESS_length_bias 0x00000002
+#define GEN7_SWTESS_BASE_ADDRESS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  3,                  \
+   .DwordLength          =  0
+
+#define GEN7_SWTESS_BASE_ADDRESS_length 0x00000002
+
+struct GEN7_SWTESS_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           SWTessellationBaseAddress;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      SWTessellationMemoryObjectControlState;
+};
+
+static inline void
+GEN7_SWTESS_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_SWTESS_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SWTessellationMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SWTessellationMemoryObjectControlState, &values->SWTessellationMemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(dw_SWTessellationMemoryObjectControlState, 8, 11) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->SWTessellationBaseAddress, dw1);
+
+}
+
+#define GEN7_3DPRIMITIVE_length_bias 0x00000002
+#define GEN7_3DPRIMITIVE_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  3,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DPRIMITIVE_length 0x00000007
+
+struct GEN7_3DPRIMITIVE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         IndirectParameterEnable;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   bool                                         EndOffsetEnable;
+#define     SEQUENTIAL                                         0
+#define     RANDOM                                             1
+   uint32_t                                     VertexAccessType;
+   uint32_t                                     PrimitiveTopologyType;
+   uint32_t                                     VertexCountPerInstance;
+   uint32_t                                     StartVertexLocation;
+   uint32_t                                     InstanceCount;
+   uint32_t                                     StartInstanceLocation;
+   uint32_t                                     BaseVertexLocation;
+};
+
+static inline void
+GEN7_3DPRIMITIVE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN7_3DPRIMITIVE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->IndirectParameterEnable, 10, 10) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->EndOffsetEnable, 9, 9) |
+      __gen_field(values->VertexAccessType, 8, 8) |
+      __gen_field(values->PrimitiveTopologyType, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->VertexCountPerInstance, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->StartVertexLocation, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->InstanceCount, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->StartInstanceLocation, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->BaseVertexLocation, 0, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_AA_LINE_PARAMETERS_length_bias 0x00000002
+#define GEN7_3DSTATE_AA_LINE_PARAMETERS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 10,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_AA_LINE_PARAMETERS_length 0x00000003
+
+struct GEN7_3DSTATE_AA_LINE_PARAMETERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   float                                        AACoverageBias;
+   float                                        AACoverageSlope;
+   float                                        AACoverageEndCapBias;
+   float                                        AACoverageEndCapSlope;
+};
+
+static inline void
+GEN7_3DSTATE_AA_LINE_PARAMETERS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN7_3DSTATE_AA_LINE_PARAMETERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AACoverageBias * (1 << 8), 16, 23) |
+      __gen_field(values->AACoverageSlope * (1 << 8), 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->AACoverageEndCapBias * (1 << 8), 16, 23) |
+      __gen_field(values->AACoverageEndCapSlope * (1 << 8), 0, 7) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS_length_bias 0x00000002
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 40,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS_length 0x00000002
+
+struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDSBindingTable;
+};
+
+static inline void
+GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS_length_bias 0x00000002
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 41,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS_length 0x00000002
+
+struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoGSBindingTable;
+};
+
+static inline void
+GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoGSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS_length_bias 0x00000002
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 39,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS_length 0x00000002
+
+struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoHSBindingTable;
+};
+
+static inline void
+GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoHSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS_length_bias 0x00000002
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 42,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS_length 0x00000002
+
+struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoPSBindingTable;
+};
+
+static inline void
+GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoPSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS_length_bias 0x00000002
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 38,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS_length 0x00000002
+
+struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoVSBindingTable;
+};
+
+static inline void
+GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoVSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_BLEND_STATE_POINTERS_length_bias 0x00000002
+#define GEN7_3DSTATE_BLEND_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 36,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_BLEND_STATE_POINTERS_length 0x00000002
+
+struct GEN7_3DSTATE_BLEND_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BlendStatePointer;
+};
+
+static inline void
+GEN7_3DSTATE_BLEND_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                       const struct GEN7_3DSTATE_BLEND_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->BlendStatePointer, 6, 31) |
+      __gen_mbo(0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_CC_STATE_POINTERS_length_bias 0x00000002
+#define GEN7_3DSTATE_CC_STATE_POINTERS_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 14,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_CC_STATE_POINTERS_length 0x00000002
+
+struct GEN7_3DSTATE_CC_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ColorCalcStatePointer;
+};
+
+static inline void
+GEN7_3DSTATE_CC_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN7_3DSTATE_CC_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ColorCalcStatePointer, 6, 31) |
+      __gen_mbo(0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_CHROMA_KEY_length_bias 0x00000002
+#define GEN7_3DSTATE_CHROMA_KEY_header          \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  2
+
+#define GEN7_3DSTATE_CHROMA_KEY_length 0x00000004
+
+struct GEN7_3DSTATE_CHROMA_KEY {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ChromaKeyTableIndex;
+   uint32_t                                     ChromaKeyLowValue;
+   uint32_t                                     ChromaKeyHighValue;
+};
+
+static inline void
+GEN7_3DSTATE_CHROMA_KEY_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN7_3DSTATE_CHROMA_KEY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ChromaKeyTableIndex, 30, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChromaKeyLowValue, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ChromaKeyHighValue, 0, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_CLEAR_PARAMS_length_bias 0x00000002
+#define GEN7_3DSTATE_CLEAR_PARAMS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_CLEAR_PARAMS_length 0x00000003
+
+struct GEN7_3DSTATE_CLEAR_PARAMS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     DepthClearValue;
+   bool                                         DepthClearValueValid;
+};
+
+static inline void
+GEN7_3DSTATE_CLEAR_PARAMS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_3DSTATE_CLEAR_PARAMS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DepthClearValue, 0, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DepthClearValueValid, 0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_CLIP_length_bias 0x00000002
+#define GEN7_3DSTATE_CLIP_header                \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 18,                  \
+   .DwordLength          =  2
+
+#define GEN7_3DSTATE_CLIP_length 0x00000004
+
+struct GEN7_3DSTATE_CLIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     FrontWinding;
+   uint32_t                                     VertexSubPixelPrecisionSelect;
+   bool                                         EarlyCullEnable;
+#define     CULLMODE_BOTH                                      0
+#define     CULLMODE_NONE                                      1
+#define     CULLMODE_FRONT                                     2
+#define     CULLMODE_BACK                                      3
+   uint32_t                                     CullMode;
+   bool                                         ClipperStatisticsEnable;
+   uint32_t                                     UserClipDistanceCullTestEnableBitmask;
+   bool                                         ClipEnable;
+#define     APIMODE_OGL                                        0
+   uint32_t                                     APIMode;
+   bool                                         ViewportXYClipTestEnable;
+   bool                                         ViewportZClipTestEnable;
+   bool                                         GuardbandClipTestEnable;
+   uint32_t                                     UserClipDistanceClipTestEnableBitmask;
+#define     CLIPMODE_NORMAL                                    0
+#define     CLIPMODE_REJECT_ALL                                3
+#define     CLIPMODE_ACCEPT_ALL                                4
+   uint32_t                                     ClipMode;
+   bool                                         PerspectiveDivideDisable;
+   bool                                         NonPerspectiveBarycentricEnable;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleStripListProvokingVertexSelect;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+   uint32_t                                     LineStripListProvokingVertexSelect;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleFanProvokingVertexSelect;
+   float                                        MinimumPointWidth;
+   float                                        MaximumPointWidth;
+   bool                                         ForceZeroRTAIndexEnable;
+   uint32_t                                     MaximumVPIndex;
+};
+
+static inline void
+GEN7_3DSTATE_CLIP_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_3DSTATE_CLIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->FrontWinding, 20, 20) |
+      __gen_field(values->VertexSubPixelPrecisionSelect, 19, 19) |
+      __gen_field(values->EarlyCullEnable, 18, 18) |
+      __gen_field(values->CullMode, 16, 17) |
+      __gen_field(values->ClipperStatisticsEnable, 10, 10) |
+      __gen_field(values->UserClipDistanceCullTestEnableBitmask, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClipEnable, 31, 31) |
+      __gen_field(values->APIMode, 30, 30) |
+      __gen_field(values->ViewportXYClipTestEnable, 28, 28) |
+      __gen_field(values->ViewportZClipTestEnable, 27, 27) |
+      __gen_field(values->GuardbandClipTestEnable, 26, 26) |
+      __gen_field(values->UserClipDistanceClipTestEnableBitmask, 16, 23) |
+      __gen_field(values->ClipMode, 13, 15) |
+      __gen_field(values->PerspectiveDivideDisable, 9, 9) |
+      __gen_field(values->NonPerspectiveBarycentricEnable, 8, 8) |
+      __gen_field(values->TriangleStripListProvokingVertexSelect, 4, 5) |
+      __gen_field(values->LineStripListProvokingVertexSelect, 2, 3) |
+      __gen_field(values->TriangleFanProvokingVertexSelect, 0, 1) |
+      0;
+
+   dw[3] =
+      __gen_field(values->MinimumPointWidth * (1 << 3), 17, 27) |
+      __gen_field(values->MaximumPointWidth * (1 << 3), 6, 16) |
+      __gen_field(values->ForceZeroRTAIndexEnable, 5, 5) |
+      __gen_field(values->MaximumVPIndex, 0, 3) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_CONSTANT_DS_length_bias 0x00000002
+#define GEN7_3DSTATE_CONSTANT_DS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 26,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_CONSTANT_DS_length 0x00000007
+
+#define GEN7_3DSTATE_CONSTANT_BODY_length 0x00000006
+
+struct GEN7_3DSTATE_CONSTANT_BODY {
+   uint32_t                                     ConstantBuffer1ReadLength;
+   uint32_t                                     ConstantBuffer0ReadLength;
+   uint32_t                                     ConstantBuffer3ReadLength;
+   uint32_t                                     ConstantBuffer2ReadLength;
+   __gen_address_type                           PointerToConstantBuffer0;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      ConstantBufferObjectControlState;
+   __gen_address_type                           PointerToConstantBuffer1;
+   __gen_address_type                           PointerToConstantBuffer2;
+   __gen_address_type                           PointerToConstantBuffer3;
+};
+
+static inline void
+GEN7_3DSTATE_CONSTANT_BODY_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN7_3DSTATE_CONSTANT_BODY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ConstantBuffer1ReadLength, 16, 31) |
+      __gen_field(values->ConstantBuffer0ReadLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBuffer3ReadLength, 16, 31) |
+      __gen_field(values->ConstantBuffer2ReadLength, 0, 15) |
+      0;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   uint32_t dw2 =
+      __gen_field(dw_ConstantBufferObjectControlState, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->PointerToConstantBuffer0, dw2);
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->PointerToConstantBuffer1, dw3);
+
+   uint32_t dw4 =
+      0;
+
+   dw[4] =
+      __gen_combine_address(data, &dw[4], values->PointerToConstantBuffer2, dw4);
+
+   uint32_t dw5 =
+      0;
+
+   dw[5] =
+      __gen_combine_address(data, &dw[5], values->PointerToConstantBuffer3, dw5);
+
+}
+
+struct GEN7_3DSTATE_CONSTANT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN7_3DSTATE_CONSTANT_DS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_CONSTANT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN7_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN7_3DSTATE_CONSTANT_GS_length_bias 0x00000002
+#define GEN7_3DSTATE_CONSTANT_GS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 22,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_CONSTANT_GS_length 0x00000007
+
+struct GEN7_3DSTATE_CONSTANT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN7_3DSTATE_CONSTANT_GS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_CONSTANT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN7_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN7_3DSTATE_CONSTANT_HS_length_bias 0x00000002
+#define GEN7_3DSTATE_CONSTANT_HS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 25,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_CONSTANT_HS_length 0x00000007
+
+struct GEN7_3DSTATE_CONSTANT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN7_3DSTATE_CONSTANT_HS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_CONSTANT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN7_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN7_3DSTATE_CONSTANT_PS_length_bias 0x00000002
+#define GEN7_3DSTATE_CONSTANT_PS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 23,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_CONSTANT_PS_length 0x00000007
+
+struct GEN7_3DSTATE_CONSTANT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN7_3DSTATE_CONSTANT_PS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_CONSTANT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN7_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN7_3DSTATE_CONSTANT_VS_length_bias 0x00000002
+#define GEN7_3DSTATE_CONSTANT_VS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 21,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_CONSTANT_VS_length 0x00000007
+
+struct GEN7_3DSTATE_CONSTANT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN7_3DSTATE_CONSTANT_VS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_CONSTANT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN7_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN7_3DSTATE_DEPTH_BUFFER_length_bias 0x00000002
+#define GEN7_3DSTATE_DEPTH_BUFFER_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  5,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_DEPTH_BUFFER_length 0x00000007
+
+struct GEN7_3DSTATE_DEPTH_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     SURFTYPE_1D                                        0
+#define     SURFTYPE_2D                                        1
+#define     SURFTYPE_3D                                        2
+#define     SURFTYPE_CUBE                                      3
+#define     SURFTYPE_NULL                                      7
+   uint32_t                                     SurfaceType;
+   bool                                         DepthWriteEnable;
+   bool                                         StencilWriteEnable;
+   bool                                         HierarchicalDepthBufferEnable;
+#define     D32_FLOAT                                          1
+#define     D24_UNORM_X8_UINT                                  3
+#define     D16_UNORM                                          5
+   uint32_t                                     SurfaceFormat;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     Height;
+   uint32_t                                     Width;
+   uint32_t                                     LOD;
+#define     SURFTYPE_CUBEmustbezero                            0
+   uint32_t                                     Depth;
+   uint32_t                                     MinimumArrayElement;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      DepthBufferObjectControlState;
+   uint32_t                                     DepthCoordinateOffsetY;
+   uint32_t                                     DepthCoordinateOffsetX;
+   uint32_t                                     RenderTargetViewExtent;
+};
+
+static inline void
+GEN7_3DSTATE_DEPTH_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_3DSTATE_DEPTH_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SurfaceType, 29, 31) |
+      __gen_field(values->DepthWriteEnable, 28, 28) |
+      __gen_field(values->StencilWriteEnable, 27, 27) |
+      __gen_field(values->HierarchicalDepthBufferEnable, 22, 22) |
+      __gen_field(values->SurfaceFormat, 18, 20) |
+      __gen_field(values->SurfacePitch, 0, 17) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   dw[3] =
+      __gen_field(values->Height, 18, 31) |
+      __gen_field(values->Width, 4, 17) |
+      __gen_field(values->LOD, 0, 3) |
+      0;
+
+   uint32_t dw_DepthBufferObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_DepthBufferObjectControlState, &values->DepthBufferObjectControlState);
+   dw[4] =
+      __gen_field(values->Depth, 21, 31) |
+      __gen_field(values->MinimumArrayElement, 10, 20) |
+      __gen_field(dw_DepthBufferObjectControlState, 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->DepthCoordinateOffsetY, 16, 31) |
+      __gen_field(values->DepthCoordinateOffsetX, 0, 15) |
+      0;
+
+   dw[6] =
+      __gen_field(values->RenderTargetViewExtent, 21, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_length_bias 0x00000002
+#define GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 37,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_length 0x00000002
+
+struct GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDEPTH_STENCIL_STATE;
+};
+
+static inline void
+GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                               const struct GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDEPTH_STENCIL_STATE, 6, 31) |
+      __gen_mbo(0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_DRAWING_RECTANGLE_length_bias 0x00000002
+#define GEN7_3DSTATE_DRAWING_RECTANGLE_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  2
+
+#define GEN7_3DSTATE_DRAWING_RECTANGLE_length 0x00000004
+
+struct GEN7_3DSTATE_DRAWING_RECTANGLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ClippedDrawingRectangleYMin;
+   uint32_t                                     ClippedDrawingRectangleXMin;
+   uint32_t                                     ClippedDrawingRectangleYMax;
+   uint32_t                                     ClippedDrawingRectangleXMax;
+   uint32_t                                     DrawingRectangleOriginY;
+   uint32_t                                     DrawingRectangleOriginX;
+};
+
+static inline void
+GEN7_3DSTATE_DRAWING_RECTANGLE_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN7_3DSTATE_DRAWING_RECTANGLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ClippedDrawingRectangleYMin, 16, 31) |
+      __gen_field(values->ClippedDrawingRectangleXMin, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClippedDrawingRectangleYMax, 16, 31) |
+      __gen_field(values->ClippedDrawingRectangleXMax, 0, 15) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DrawingRectangleOriginY, 16, 31) |
+      __gen_field(values->DrawingRectangleOriginX, 0, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_DS_length_bias 0x00000002
+#define GEN7_3DSTATE_DS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 29,                  \
+   .DwordLength          =  4
+
+#define GEN7_3DSTATE_DS_length 0x00000006
+
+struct GEN7_3DSTATE_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleDomainPointDispatch;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     PatchURBEntryReadLength;
+   uint32_t                                     PatchURBEntryReadOffset;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         StatisticsEnable;
+   bool                                         ComputeWCoordinateEnable;
+   bool                                         DSCacheDisable;
+   bool                                         DSFunctionEnable;
+};
+
+static inline void
+GEN7_3DSTATE_DS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleDomainPointDispatch, 31, 31) |
+      __gen_field(values->VectorMaskEnable, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 20, 24) |
+      __gen_field(values->PatchURBEntryReadLength, 11, 17) |
+      __gen_field(values->PatchURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[5] =
+      __gen_field(values->MaximumNumberofThreads, 25, 31) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->ComputeWCoordinateEnable, 2, 2) |
+      __gen_field(values->DSCacheDisable, 1, 1) |
+      __gen_field(values->DSFunctionEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_GS_length_bias 0x00000002
+#define GEN7_3DSTATE_GS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 17,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_GS_length 0x00000007
+
+struct GEN7_3DSTATE_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer;
+   uint32_t                                     SingleProgramFlowSPF;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnableVME;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     NormalPriority                                     0
+#define     HighPriority                                       1
+   uint32_t                                     ThreadPriority;
+#define     IEEE754                                            0
+#define     alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     OutputVertexSize;
+   uint32_t                                     OutputTopology;
+   uint32_t                                     VertexURBEntryReadLength;
+   bool                                         IncludeVertexHandles;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     DispatchGRFStartRegisterforURBData;
+   uint32_t                                     MaximumNumberofThreads;
+#define     GSCTL_CUT                                          0
+#define     GSCTL_SID                                          1
+   uint32_t                                     ControlDataFormat;
+   uint32_t                                     ControlDataHeaderSize;
+   uint32_t                                     InstanceControl;
+   uint32_t                                     DefaultStreamID;
+#define     SINGLE                                             0
+#define     DUAL_INSTANCE                                      1
+#define     DUAL_OBJECT                                        2
+   uint32_t                                     DispatchMode;
+   uint32_t                                     GSStatisticsEnable;
+   uint32_t                                     GSInvocationsIncrementValue;
+   bool                                         IncludePrimitiveID;
+   uint32_t                                     Hint;
+   bool                                         ReorderEnable;
+   bool                                         DiscardAdjacency;
+   bool                                         GSEnable;
+   uint32_t                                     SemaphoreHandle;
+};
+
+static inline void
+GEN7_3DSTATE_GS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleProgramFlowSPF, 31, 31) |
+      __gen_field(values->VectorMaskEnableVME, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->OutputVertexSize, 23, 28) |
+      __gen_field(values->OutputTopology, 17, 22) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->IncludeVertexHandles, 10, 10) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      __gen_field(values->DispatchGRFStartRegisterforURBData, 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->MaximumNumberofThreads, 25, 31) |
+      __gen_field(values->ControlDataFormat, 24, 24) |
+      __gen_field(values->ControlDataHeaderSize, 20, 23) |
+      __gen_field(values->InstanceControl, 15, 19) |
+      __gen_field(values->DefaultStreamID, 13, 14) |
+      __gen_field(values->DispatchMode, 11, 12) |
+      __gen_field(values->GSStatisticsEnable, 10, 10) |
+      __gen_field(values->GSInvocationsIncrementValue, 5, 9) |
+      __gen_field(values->IncludePrimitiveID, 4, 4) |
+      __gen_field(values->Hint, 3, 3) |
+      __gen_field(values->ReorderEnable, 2, 2) |
+      __gen_field(values->DiscardAdjacency, 1, 1) |
+      __gen_field(values->GSEnable, 0, 0) |
+      0;
+
+   dw[6] =
+      __gen_offset(values->SemaphoreHandle, 0, 11) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_HIER_DEPTH_BUFFER_length_bias 0x00000002
+#define GEN7_3DSTATE_HIER_DEPTH_BUFFER_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  7,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_HIER_DEPTH_BUFFER_length 0x00000003
+
+struct GEN7_3DSTATE_HIER_DEPTH_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      HierarchicalDepthBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+};
+
+static inline void
+GEN7_3DSTATE_HIER_DEPTH_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN7_3DSTATE_HIER_DEPTH_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_HierarchicalDepthBufferObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_HierarchicalDepthBufferObjectControlState, &values->HierarchicalDepthBufferObjectControlState);
+   dw[1] =
+      __gen_field(dw_HierarchicalDepthBufferObjectControlState, 25, 28) |
+      __gen_field(values->SurfacePitch, 0, 16) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+}
+
+#define GEN7_3DSTATE_HS_length_bias 0x00000002
+#define GEN7_3DSTATE_HS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 27,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_HS_length 0x00000007
+
+struct GEN7_3DSTATE_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     IEEE754                                            0
+#define     alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         Enable;
+   bool                                         StatisticsEnable;
+   uint32_t                                     InstanceCount;
+   uint32_t                                     KernelStartPointer;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     SingleProgramFlow;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+   bool                                         IncludeVertexHandles;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     SemaphoreHandle;
+};
+
+static inline void
+GEN7_3DSTATE_HS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      __gen_field(values->MaximumNumberofThreads, 0, 6) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Enable, 31, 31) |
+      __gen_field(values->StatisticsEnable, 29, 29) |
+      __gen_field(values->InstanceCount, 0, 3) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[4] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[5] =
+      __gen_field(values->SingleProgramFlow, 27, 27) |
+      __gen_field(values->VectorMaskEnable, 26, 26) |
+      __gen_field(values->IncludeVertexHandles, 24, 24) |
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 19, 23) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[6] =
+      __gen_offset(values->SemaphoreHandle, 0, 11) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_INDEX_BUFFER_length_bias 0x00000002
+#define GEN7_3DSTATE_INDEX_BUFFER_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 10,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_INDEX_BUFFER_length 0x00000003
+
+struct GEN7_3DSTATE_INDEX_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      MemoryObjectControlState;
+   bool                                         CutIndexEnable;
+#define     INDEX_BYTE                                         0
+#define     INDEX_WORD                                         1
+#define     INDEX_DWORD                                        2
+   uint32_t                                     IndexFormat;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BufferStartingAddress;
+   __gen_address_type                           BufferEndingAddress;
+};
+
+static inline void
+GEN7_3DSTATE_INDEX_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_3DSTATE_INDEX_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_MemoryObjectControlState, 12, 15) |
+      __gen_field(values->CutIndexEnable, 10, 10) |
+      __gen_field(values->IndexFormat, 8, 9) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BufferStartingAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->BufferEndingAddress, dw2);
+
+}
+
+#define GEN7_3DSTATE_LINE_STIPPLE_length_bias 0x00000002
+#define GEN7_3DSTATE_LINE_STIPPLE_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  8,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_LINE_STIPPLE_length 0x00000003
+
+struct GEN7_3DSTATE_LINE_STIPPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         ModifyEnableCurrentRepeatCounterCurrentStippleIndex;
+   uint32_t                                     CurrentRepeatCounter;
+   uint32_t                                     CurrentStippleIndex;
+   uint32_t                                     LineStipplePattern;
+   float                                        LineStippleInverseRepeatCount;
+   uint32_t                                     LineStippleRepeatCount;
+};
+
+static inline void
+GEN7_3DSTATE_LINE_STIPPLE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_3DSTATE_LINE_STIPPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ModifyEnableCurrentRepeatCounterCurrentStippleIndex, 31, 31) |
+      __gen_field(values->CurrentRepeatCounter, 21, 29) |
+      __gen_field(values->CurrentStippleIndex, 16, 19) |
+      __gen_field(values->LineStipplePattern, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->LineStippleInverseRepeatCount * (1 << 16), 15, 31) |
+      __gen_field(values->LineStippleRepeatCount, 0, 8) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_MONOFILTER_SIZE_length_bias 0x00000002
+#define GEN7_3DSTATE_MONOFILTER_SIZE_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 17,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_MONOFILTER_SIZE_length 0x00000002
+
+struct GEN7_3DSTATE_MONOFILTER_SIZE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     MonochromeFilterWidth;
+   uint32_t                                     MonochromeFilterHeight;
+};
+
+static inline void
+GEN7_3DSTATE_MONOFILTER_SIZE_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN7_3DSTATE_MONOFILTER_SIZE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MonochromeFilterWidth, 3, 5) |
+      __gen_field(values->MonochromeFilterHeight, 0, 2) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_MULTISAMPLE_length_bias 0x00000002
+#define GEN7_3DSTATE_MULTISAMPLE_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 13,                  \
+   .DwordLength          =  2
+
+#define GEN7_3DSTATE_MULTISAMPLE_length 0x00000004
+
+struct GEN7_3DSTATE_MULTISAMPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     PIXLOC_CENTER                                      0
+#define     PIXLOC_UL_CORNER                                   1
+   uint32_t                                     PixelLocation;
+#define     NUMSAMPLES_1                                       0
+#define     NUMSAMPLES_4                                       2
+#define     NUMSAMPLES_8                                       3
+   uint32_t                                     NumberofMultisamples;
+   float                                        Sample3XOffset;
+   float                                        Sample3YOffset;
+   float                                        Sample2XOffset;
+   float                                        Sample2YOffset;
+   float                                        Sample1XOffset;
+   float                                        Sample1YOffset;
+   float                                        Sample0XOffset;
+   float                                        Sample0YOffset;
+   float                                        Sample7XOffset;
+   float                                        Sample7YOffset;
+   float                                        Sample6XOffset;
+   float                                        Sample6YOffset;
+   float                                        Sample5XOffset;
+   float                                        Sample5YOffset;
+   float                                        Sample4XOffset;
+   float                                        Sample4YOffset;
+};
+
+static inline void
+GEN7_3DSTATE_MULTISAMPLE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_MULTISAMPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PixelLocation, 4, 4) |
+      __gen_field(values->NumberofMultisamples, 1, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Sample3XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample3YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample2XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample2YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample1XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample1YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample0XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample0YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Sample7XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->Sample7YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->Sample6XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->Sample6YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->Sample5XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->Sample5YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->Sample4XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->Sample4YOffset * (1 << 4), 0, 3) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_POLY_STIPPLE_OFFSET_length_bias 0x00000002
+#define GEN7_3DSTATE_POLY_STIPPLE_OFFSET_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  6,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_POLY_STIPPLE_OFFSET_length 0x00000002
+
+struct GEN7_3DSTATE_POLY_STIPPLE_OFFSET {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PolygonStippleXOffset;
+   uint32_t                                     PolygonStippleYOffset;
+};
+
+static inline void
+GEN7_3DSTATE_POLY_STIPPLE_OFFSET_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN7_3DSTATE_POLY_STIPPLE_OFFSET * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PolygonStippleXOffset, 8, 12) |
+      __gen_field(values->PolygonStippleYOffset, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_POLY_STIPPLE_PATTERN_length_bias 0x00000002
+#define GEN7_3DSTATE_POLY_STIPPLE_PATTERN_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  7,                  \
+   .DwordLength          = 31
+
+#define GEN7_3DSTATE_POLY_STIPPLE_PATTERN_length 0x00000021
+
+struct GEN7_3DSTATE_POLY_STIPPLE_PATTERN {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PatternRow[32];
+};
+
+static inline void
+GEN7_3DSTATE_POLY_STIPPLE_PATTERN_pack(__gen_user_data *data, void * restrict dst,
+                                       const struct GEN7_3DSTATE_POLY_STIPPLE_PATTERN * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   for (uint32_t i = 0, j = 1; i < 32; i += 1, j++) {
+      dw[j] =
+         __gen_field(values->PatternRow[i + 0], 0, 31) |
+         0;
+   }
+
+}
+
+#define GEN7_3DSTATE_PS_length_bias 0x00000002
+#define GEN7_3DSTATE_PS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 32,                  \
+   .DwordLength          =  6
+
+#define GEN7_3DSTATE_PS_length 0x00000008
+
+struct GEN7_3DSTATE_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer0;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleProgramFlowSPF;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnableVME;
+   uint32_t                                     SamplerCount;
+#define     FTZ                                                0
+#define     RET                                                1
+   uint32_t                                     DenormalMode;
+   uint32_t                                     BindingTableEntryCount;
+#define     IEEE745                                            0
+#define     Alt                                                1
+   uint32_t                                     FloatingPointMode;
+#define     RTNE                                               0
+#define     RU                                                 1
+#define     RD                                                 2
+#define     RTZ                                                3
+   uint32_t                                     RoundingMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         PushConstantEnable;
+   bool                                         AttributeEnable;
+   bool                                         oMaskPresenttoRenderTarget;
+   bool                                         RenderTargetFastClearEnable;
+   bool                                         DualSourceBlendEnable;
+   bool                                         RenderTargetResolveEnable;
+#define     POSOFFSET_NONE                                     0
+#define     POSOFFSET_CENTROID                                 2
+#define     POSOFFSET_SAMPLE                                   3
+   uint32_t                                     PositionXYOffsetSelect;
+   bool                                         _32PixelDispatchEnable;
+   bool                                         _16PixelDispatchEnable;
+   bool                                         _8PixelDispatchEnable;
+   uint32_t                                     DispatchGRFStartRegisterforConstantSetupData0;
+   uint32_t                                     DispatchGRFStartRegisterforConstantSetupData1;
+   uint32_t                                     DispatchGRFStartRegisterforConstantSetupData2;
+   uint32_t                                     KernelStartPointer1;
+   uint32_t                                     KernelStartPointer2;
+};
+
+static inline void
+GEN7_3DSTATE_PS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer0, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleProgramFlowSPF, 31, 31) |
+      __gen_field(values->VectorMaskEnableVME, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->DenormalMode, 26, 26) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->RoundingMode, 14, 15) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->MaximumNumberofThreads, 24, 31) |
+      __gen_field(values->PushConstantEnable, 11, 11) |
+      __gen_field(values->AttributeEnable, 10, 10) |
+      __gen_field(values->oMaskPresenttoRenderTarget, 9, 9) |
+      __gen_field(values->RenderTargetFastClearEnable, 8, 8) |
+      __gen_field(values->DualSourceBlendEnable, 7, 7) |
+      __gen_field(values->RenderTargetResolveEnable, 6, 6) |
+      __gen_field(values->PositionXYOffsetSelect, 3, 4) |
+      __gen_field(values->_32PixelDispatchEnable, 2, 2) |
+      __gen_field(values->_16PixelDispatchEnable, 1, 1) |
+      __gen_field(values->_8PixelDispatchEnable, 0, 0) |
+      0;
+
+   dw[5] =
+      __gen_field(values->DispatchGRFStartRegisterforConstantSetupData0, 16, 22) |
+      __gen_field(values->DispatchGRFStartRegisterforConstantSetupData1, 8, 14) |
+      __gen_field(values->DispatchGRFStartRegisterforConstantSetupData2, 0, 6) |
+      0;
+
+   dw[6] =
+      __gen_offset(values->KernelStartPointer1, 6, 31) |
+      0;
+
+   dw[7] =
+      __gen_offset(values->KernelStartPointer2, 6, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS_length_bias 0x00000002
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 20,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS_length 0x00000002
+
+struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferOffset;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 19) |
+      __gen_field(values->ConstantBufferSize, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS_length_bias 0x00000002
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 21,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS_length 0x00000002
+
+struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferOffset;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 19) |
+      __gen_field(values->ConstantBufferSize, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS_length_bias 0x00000002
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 19,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS_length 0x00000002
+
+struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferOffset;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 19) |
+      __gen_field(values->ConstantBufferSize, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS_length_bias 0x00000002
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 22,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS_length 0x00000002
+
+struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferOffset;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 19) |
+      __gen_field(values->ConstantBufferSize, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS_length_bias 0x00000002
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 18,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS_length 0x00000002
+
+struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferOffset;
+#define     _0KB                                               0
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 19) |
+      __gen_field(values->ConstantBufferSize, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD0_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD0_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  2
+
+#define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD0_length 0x00000000
+
+#define GEN7_PALETTE_ENTRY_length 0x00000001
+
+struct GEN7_PALETTE_ENTRY {
+   uint32_t                                     Alpha;
+   uint32_t                                     Red;
+   uint32_t                                     Green;
+   uint32_t                                     Blue;
+};
+
+static inline void
+GEN7_PALETTE_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN7_PALETTE_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->Alpha, 24, 31) |
+      __gen_field(values->Red, 16, 23) |
+      __gen_field(values->Green, 8, 15) |
+      __gen_field(values->Blue, 0, 7) |
+      0;
+
+}
+
+struct GEN7_3DSTATE_SAMPLER_PALETTE_LOAD0 {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_PALETTE_LOAD0_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN7_3DSTATE_SAMPLER_PALETTE_LOAD0 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD1_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD1_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 12
+
+#define GEN7_3DSTATE_SAMPLER_PALETTE_LOAD1_length 0x00000000
+
+struct GEN7_3DSTATE_SAMPLER_PALETTE_LOAD1 {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_PALETTE_LOAD1_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN7_3DSTATE_SAMPLER_PALETTE_LOAD1 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 45,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS_length 0x00000002
+
+struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDSSamplerState;
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 46,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS_length 0x00000002
+
+struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoGSSamplerState;
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoGSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 44,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS_length 0x00000002
+
+struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoHSSamplerState;
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoHSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 47,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS_length 0x00000002
+
+struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoPSSamplerState;
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoPSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 43,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS_length 0x00000002
+
+struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoVSSamplerState;
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoVSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SAMPLE_MASK_length_bias 0x00000002
+#define GEN7_3DSTATE_SAMPLE_MASK_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 24,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SAMPLE_MASK_length 0x00000002
+
+struct GEN7_3DSTATE_SAMPLE_MASK {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SampleMask;
+};
+
+static inline void
+GEN7_3DSTATE_SAMPLE_MASK_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_3DSTATE_SAMPLE_MASK * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SampleMask, 0, 7) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SBE_length_bias 0x00000002
+#define GEN7_3DSTATE_SBE_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 31,                  \
+   .DwordLength          = 12
+
+#define GEN7_3DSTATE_SBE_length 0x0000000e
+
+struct GEN7_3DSTATE_SBE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     SWIZ_0_15                                          0
+#define     SWIZ_16_31                                         1
+   uint32_t                                     AttributeSwizzleControlMode;
+   uint32_t                                     NumberofSFOutputAttributes;
+   bool                                         AttributeSwizzleEnable;
+#define     UPPERLEFT                                          0
+#define     LOWERLEFT                                          1
+   uint32_t                                     PointSpriteTextureCoordinateOrigin;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   bool                                         Attribute2n1ComponentOverrideW;
+   bool                                         Attribute2n1ComponentOverrideZ;
+   bool                                         Attribute2n1ComponentOverrideY;
+   bool                                         Attribute2n1ComponentOverrideX;
+#define     CONST_0000                                         0
+#define     CONST_0001_FLOAT                                   1
+#define     CONST_1111_FLOAT                                   2
+#define     PRIM_ID                                            3
+   uint32_t                                     Attribute2n1ConstantSource;
+#define     INPUTATTR                                          0
+#define     INPUTATTR_FACING                                   1
+#define     INPUTATTR_W                                        2
+#define     INPUTATTR_FACING_W                                 3
+   uint32_t                                     Attribute2n1SwizzleSelect;
+   uint32_t                                     Attribute2n1SourceAttribute;
+   bool                                         Attribute2nComponentOverrideW;
+   bool                                         Attribute2nComponentOverrideZ;
+   bool                                         Attribute2nComponentOverrideY;
+   bool                                         Attribute2nComponentOverrideX;
+#define     CONST_0000                                         0
+#define     CONST_0001_FLOAT                                   1
+#define     CONST_1111_FLOAT                                   2
+#define     PRIM_ID                                            3
+   uint32_t                                     Attribute2nConstantSource;
+#define     INPUTATTR                                          0
+#define     INPUTATTR_FACING                                   1
+#define     INPUTATTR_W                                        2
+#define     INPUTATTR_FACING_W                                 3
+   uint32_t                                     Attribute2nSwizzleSelect;
+   uint32_t                                     Attribute2nSourceAttribute;
+   uint32_t                                     PointSpriteTextureCoordinateEnable;
+   uint32_t                                     ConstantInterpolationEnable310;
+   uint32_t                                     Attribute7WrapShortestEnables;
+   uint32_t                                     Attribute6WrapShortestEnables;
+   uint32_t                                     Attribute5WrapShortestEnables;
+   uint32_t                                     Attribute4WrapShortestEnables;
+   uint32_t                                     Attribute3WrapShortestEnables;
+   uint32_t                                     Attribute2WrapShortestEnables;
+   uint32_t                                     Attribute1WrapShortestEnables;
+   uint32_t                                     Attribute0WrapShortestEnables;
+   uint32_t                                     Attribute15WrapShortestEnables;
+   uint32_t                                     Attribute14WrapShortestEnables;
+   uint32_t                                     Attribute13WrapShortestEnables;
+   uint32_t                                     Attribute12WrapShortestEnables;
+   uint32_t                                     Attribute11WrapShortestEnables;
+   uint32_t                                     Attribute10WrapShortestEnables;
+   uint32_t                                     Attribute9WrapShortestEnables;
+   uint32_t                                     Attribute8WrapShortestEnables;
+};
+
+static inline void
+GEN7_3DSTATE_SBE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN7_3DSTATE_SBE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AttributeSwizzleControlMode, 28, 28) |
+      __gen_field(values->NumberofSFOutputAttributes, 22, 27) |
+      __gen_field(values->AttributeSwizzleEnable, 21, 21) |
+      __gen_field(values->PointSpriteTextureCoordinateOrigin, 20, 20) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 15) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Attribute2n1ComponentOverrideW, 31, 31) |
+      __gen_field(values->Attribute2n1ComponentOverrideZ, 30, 30) |
+      __gen_field(values->Attribute2n1ComponentOverrideY, 29, 29) |
+      __gen_field(values->Attribute2n1ComponentOverrideX, 28, 28) |
+      __gen_field(values->Attribute2n1ConstantSource, 25, 26) |
+      __gen_field(values->Attribute2n1SwizzleSelect, 22, 23) |
+      __gen_field(values->Attribute2n1SourceAttribute, 16, 20) |
+      __gen_field(values->Attribute2nComponentOverrideW, 15, 15) |
+      __gen_field(values->Attribute2nComponentOverrideZ, 14, 14) |
+      __gen_field(values->Attribute2nComponentOverrideY, 13, 13) |
+      __gen_field(values->Attribute2nComponentOverrideX, 12, 12) |
+      __gen_field(values->Attribute2nConstantSource, 9, 10) |
+      __gen_field(values->Attribute2nSwizzleSelect, 6, 7) |
+      __gen_field(values->Attribute2nSourceAttribute, 0, 4) |
+      0;
+
+   dw[10] =
+      __gen_field(values->PointSpriteTextureCoordinateEnable, 0, 31) |
+      0;
+
+   dw[11] =
+      __gen_field(values->ConstantInterpolationEnable310, 0, 31) |
+      0;
+
+   dw[12] =
+      __gen_field(values->Attribute7WrapShortestEnables, 28, 31) |
+      __gen_field(values->Attribute6WrapShortestEnables, 24, 27) |
+      __gen_field(values->Attribute5WrapShortestEnables, 20, 23) |
+      __gen_field(values->Attribute4WrapShortestEnables, 16, 19) |
+      __gen_field(values->Attribute3WrapShortestEnables, 12, 15) |
+      __gen_field(values->Attribute2WrapShortestEnables, 8, 11) |
+      __gen_field(values->Attribute1WrapShortestEnables, 4, 7) |
+      __gen_field(values->Attribute0WrapShortestEnables, 0, 3) |
+      0;
+
+   dw[13] =
+      __gen_field(values->Attribute15WrapShortestEnables, 28, 31) |
+      __gen_field(values->Attribute14WrapShortestEnables, 24, 27) |
+      __gen_field(values->Attribute13WrapShortestEnables, 20, 23) |
+      __gen_field(values->Attribute12WrapShortestEnables, 16, 19) |
+      __gen_field(values->Attribute11WrapShortestEnables, 12, 15) |
+      __gen_field(values->Attribute10WrapShortestEnables, 8, 11) |
+      __gen_field(values->Attribute9WrapShortestEnables, 4, 7) |
+      __gen_field(values->Attribute8WrapShortestEnables, 0, 3) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SCISSOR_STATE_POINTERS_length_bias 0x00000002
+#define GEN7_3DSTATE_SCISSOR_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 15,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_SCISSOR_STATE_POINTERS_length 0x00000002
+
+struct GEN7_3DSTATE_SCISSOR_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ScissorRectPointer;
+};
+
+static inline void
+GEN7_3DSTATE_SCISSOR_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN7_3DSTATE_SCISSOR_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ScissorRectPointer, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SF_length_bias 0x00000002
+#define GEN7_3DSTATE_SF_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 19,                  \
+   .DwordLength          =  5
+
+#define GEN7_3DSTATE_SF_length 0x00000007
+
+struct GEN7_3DSTATE_SF {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     D32_FLOAT_S8X24_UINT                               0
+#define     D32_FLOAT                                          1
+#define     D24_UNORM_S8_UINT                                  2
+#define     D24_UNORM_X8_UINT                                  3
+#define     D16_UNORM                                          5
+   uint32_t                                     DepthBufferSurfaceFormat;
+   bool                                         LegacyGlobalDepthBiasEnable;
+   bool                                         StatisticsEnable;
+   bool                                         GlobalDepthOffsetEnableSolid;
+   bool                                         GlobalDepthOffsetEnableWireframe;
+   bool                                         GlobalDepthOffsetEnablePoint;
+#define     RASTER_SOLID                                       0
+#define     RASTER_WIREFRAME                                   1
+#define     RASTER_POINT                                       2
+   uint32_t                                     FrontFaceFillMode;
+#define     RASTER_SOLID                                       0
+#define     RASTER_WIREFRAME                                   1
+#define     RASTER_POINT                                       2
+   uint32_t                                     BackFaceFillMode;
+   bool                                         ViewTransformEnable;
+   uint32_t                                     FrontWinding;
+   bool                                         AntiAliasingEnable;
+#define     CULLMODE_BOTH                                      0
+#define     CULLMODE_NONE                                      1
+#define     CULLMODE_FRONT                                     2
+#define     CULLMODE_BACK                                      3
+   uint32_t                                     CullMode;
+   float                                        LineWidth;
+   uint32_t                                     LineEndCapAntialiasingRegionWidth;
+   bool                                         ScissorRectangleEnable;
+   uint32_t                                     MultisampleRasterizationMode;
+   bool                                         LastPixelEnable;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleStripListProvokingVertexSelect;
+   uint32_t                                     LineStripListProvokingVertexSelect;
+#define     Vertex0                                            0
+#define     Vertex1                                            1
+#define     Vertex2                                            2
+   uint32_t                                     TriangleFanProvokingVertexSelect;
+#define     AALINEDISTANCE_TRUE                                1
+   uint32_t                                     AALineDistanceMode;
+   uint32_t                                     VertexSubPixelPrecisionSelect;
+   uint32_t                                     UsePointWidthState;
+   float                                        PointWidth;
+   float                                        GlobalDepthOffsetConstant;
+   float                                        GlobalDepthOffsetScale;
+   float                                        GlobalDepthOffsetClamp;
+};
+
+static inline void
+GEN7_3DSTATE_SF_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_SF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DepthBufferSurfaceFormat, 12, 14) |
+      __gen_field(values->LegacyGlobalDepthBiasEnable, 11, 11) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->GlobalDepthOffsetEnableSolid, 9, 9) |
+      __gen_field(values->GlobalDepthOffsetEnableWireframe, 8, 8) |
+      __gen_field(values->GlobalDepthOffsetEnablePoint, 7, 7) |
+      __gen_field(values->FrontFaceFillMode, 5, 6) |
+      __gen_field(values->BackFaceFillMode, 3, 4) |
+      __gen_field(values->ViewTransformEnable, 1, 1) |
+      __gen_field(values->FrontWinding, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_field(values->AntiAliasingEnable, 31, 31) |
+      __gen_field(values->CullMode, 29, 30) |
+      __gen_field(values->LineWidth * (1 << 7), 18, 27) |
+      __gen_field(values->LineEndCapAntialiasingRegionWidth, 16, 17) |
+      __gen_field(values->ScissorRectangleEnable, 11, 11) |
+      __gen_field(values->MultisampleRasterizationMode, 8, 9) |
+      0;
+
+   dw[3] =
+      __gen_field(values->LastPixelEnable, 31, 31) |
+      __gen_field(values->TriangleStripListProvokingVertexSelect, 29, 30) |
+      __gen_field(values->LineStripListProvokingVertexSelect, 27, 28) |
+      __gen_field(values->TriangleFanProvokingVertexSelect, 25, 26) |
+      __gen_field(values->AALineDistanceMode, 14, 14) |
+      __gen_field(values->VertexSubPixelPrecisionSelect, 12, 12) |
+      __gen_field(values->UsePointWidthState, 11, 11) |
+      __gen_field(values->PointWidth * (1 << 3), 0, 10) |
+      0;
+
+   dw[4] =
+      __gen_float(values->GlobalDepthOffsetConstant) |
+      0;
+
+   dw[5] =
+      __gen_float(values->GlobalDepthOffsetScale) |
+      0;
+
+   dw[6] =
+      __gen_float(values->GlobalDepthOffsetClamp) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_SO_BUFFER_length_bias 0x00000002
+#define GEN7_3DSTATE_SO_BUFFER_header           \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 24,                  \
+   .DwordLength          =  2
+
+#define GEN7_3DSTATE_SO_BUFFER_length 0x00000004
+
+struct GEN7_3DSTATE_SO_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SOBufferIndex;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      SOBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   __gen_address_type                           SurfaceEndAddress;
+};
+
+static inline void
+GEN7_3DSTATE_SO_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_3DSTATE_SO_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SOBufferObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SOBufferObjectControlState, &values->SOBufferObjectControlState);
+   dw[1] =
+      __gen_field(values->SOBufferIndex, 29, 30) |
+      __gen_field(dw_SOBufferObjectControlState, 25, 28) |
+      __gen_field(values->SurfacePitch, 0, 11) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->SurfaceEndAddress, dw3);
+
+}
+
+#define GEN7_3DSTATE_SO_DECL_LIST_length_bias 0x00000002
+#define GEN7_3DSTATE_SO_DECL_LIST_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 23
+
+#define GEN7_3DSTATE_SO_DECL_LIST_length 0x00000000
+
+#define GEN7_SO_DECL_ENTRY_length 0x00000002
+
+#define GEN7_SO_DECL_length 0x00000001
+
+struct GEN7_SO_DECL {
+   uint32_t                                     OutputBufferSlot;
+   uint32_t                                     HoleFlag;
+   uint32_t                                     RegisterIndex;
+   uint32_t                                     ComponentMask;
+};
+
+static inline void
+GEN7_SO_DECL_pack(__gen_user_data *data, void * restrict dst,
+                  const struct GEN7_SO_DECL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->OutputBufferSlot, 12, 13) |
+      __gen_field(values->HoleFlag, 11, 11) |
+      __gen_field(values->RegisterIndex, 4, 9) |
+      __gen_field(values->ComponentMask, 0, 3) |
+      0;
+
+}
+
+struct GEN7_SO_DECL_ENTRY {
+   struct GEN7_SO_DECL                          Stream3Decl;
+   struct GEN7_SO_DECL                          Stream2Decl;
+   struct GEN7_SO_DECL                          Stream1Decl;
+   struct GEN7_SO_DECL                          Stream0Decl;
+};
+
+static inline void
+GEN7_SO_DECL_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN7_SO_DECL_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_Stream3Decl;
+   GEN7_SO_DECL_pack(data, &dw_Stream3Decl, &values->Stream3Decl);
+   uint32_t dw_Stream2Decl;
+   GEN7_SO_DECL_pack(data, &dw_Stream2Decl, &values->Stream2Decl);
+   uint32_t dw_Stream1Decl;
+   GEN7_SO_DECL_pack(data, &dw_Stream1Decl, &values->Stream1Decl);
+   uint32_t dw_Stream0Decl;
+   GEN7_SO_DECL_pack(data, &dw_Stream0Decl, &values->Stream0Decl);
+   uint64_t qw0 =
+      __gen_field(dw_Stream3Decl, 48, 63) |
+      __gen_field(dw_Stream2Decl, 32, 47) |
+      __gen_field(dw_Stream1Decl, 16, 31) |
+      __gen_field(dw_Stream0Decl, 0, 15) |
+      0;
+
+   dw[0] = qw0;
+   dw[1] = qw0 >> 32;
+
+}
+
+struct GEN7_3DSTATE_SO_DECL_LIST {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StreamtoBufferSelects3;
+   uint32_t                                     StreamtoBufferSelects2;
+   uint32_t                                     StreamtoBufferSelects1;
+   uint32_t                                     StreamtoBufferSelects0;
+   uint32_t                                     NumEntries3;
+   uint32_t                                     NumEntries2;
+   uint32_t                                     NumEntries1;
+   uint32_t                                     NumEntries0;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_3DSTATE_SO_DECL_LIST_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_3DSTATE_SO_DECL_LIST * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StreamtoBufferSelects3, 12, 15) |
+      __gen_field(values->StreamtoBufferSelects2, 8, 11) |
+      __gen_field(values->StreamtoBufferSelects1, 4, 7) |
+      __gen_field(values->StreamtoBufferSelects0, 0, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->NumEntries3, 24, 31) |
+      __gen_field(values->NumEntries2, 16, 23) |
+      __gen_field(values->NumEntries1, 8, 15) |
+      __gen_field(values->NumEntries0, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_3DSTATE_STENCIL_BUFFER_length_bias 0x00000002
+#define GEN7_3DSTATE_STENCIL_BUFFER_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  6,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_STENCIL_BUFFER_length 0x00000003
+
+struct GEN7_3DSTATE_STENCIL_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      StencilBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+};
+
+static inline void
+GEN7_3DSTATE_STENCIL_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN7_3DSTATE_STENCIL_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_StencilBufferObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_StencilBufferObjectControlState, &values->StencilBufferObjectControlState);
+   dw[1] =
+      __gen_field(dw_StencilBufferObjectControlState, 25, 28) |
+      __gen_field(values->SurfacePitch, 0, 16) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+}
+
+#define GEN7_3DSTATE_STREAMOUT_length_bias 0x00000002
+#define GEN7_3DSTATE_STREAMOUT_header           \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 30,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_STREAMOUT_length 0x00000003
+
+struct GEN7_3DSTATE_STREAMOUT {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SOFunctionEnable;
+   uint32_t                                     RenderingDisable;
+   uint32_t                                     RenderStreamSelect;
+#define     LEADING                                            0
+#define     TRAILING                                           1
+   uint32_t                                     ReorderMode;
+   bool                                         SOStatisticsEnable;
+   uint32_t                                     SOBufferEnable3;
+   uint32_t                                     SOBufferEnable2;
+   uint32_t                                     SOBufferEnable1;
+   uint32_t                                     SOBufferEnable0;
+   uint32_t                                     Stream3VertexReadOffset;
+   uint32_t                                     Stream3VertexReadLength;
+   uint32_t                                     Stream2VertexReadOffset;
+   uint32_t                                     Stream2VertexReadLength;
+   uint32_t                                     Stream1VertexReadOffset;
+   uint32_t                                     Stream1VertexReadLength;
+   uint32_t                                     Stream0VertexReadOffset;
+   uint32_t                                     Stream0VertexReadLength;
+};
+
+static inline void
+GEN7_3DSTATE_STREAMOUT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_3DSTATE_STREAMOUT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SOFunctionEnable, 31, 31) |
+      __gen_field(values->RenderingDisable, 30, 30) |
+      __gen_field(values->RenderStreamSelect, 27, 28) |
+      __gen_field(values->ReorderMode, 26, 26) |
+      __gen_field(values->SOStatisticsEnable, 25, 25) |
+      __gen_field(values->SOBufferEnable3, 11, 11) |
+      __gen_field(values->SOBufferEnable2, 10, 10) |
+      __gen_field(values->SOBufferEnable1, 9, 9) |
+      __gen_field(values->SOBufferEnable0, 8, 8) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Stream3VertexReadOffset, 29, 29) |
+      __gen_field(values->Stream3VertexReadLength, 24, 28) |
+      __gen_field(values->Stream2VertexReadOffset, 21, 21) |
+      __gen_field(values->Stream2VertexReadLength, 16, 20) |
+      __gen_field(values->Stream1VertexReadOffset, 13, 13) |
+      __gen_field(values->Stream1VertexReadLength, 8, 12) |
+      __gen_field(values->Stream0VertexReadOffset, 5, 5) |
+      __gen_field(values->Stream0VertexReadLength, 0, 4) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_TE_length_bias 0x00000002
+#define GEN7_3DSTATE_TE_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 28,                  \
+   .DwordLength          =  2
+
+#define GEN7_3DSTATE_TE_length 0x00000004
+
+struct GEN7_3DSTATE_TE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     INTEGER                                            0
+#define     ODD_FRACTIONAL                                     1
+#define     EVEN_FRACTIONAL                                    2
+   uint32_t                                     Partitioning;
+#define     POINT                                              0
+#define     OUTPUT_LINE                                        1
+#define     OUTPUT_TRI_CW                                      2
+#define     OUTPUT_TRI_CCW                                     3
+   uint32_t                                     OutputTopology;
+#define     QUAD                                               0
+#define     TRI                                                1
+#define     ISOLINE                                            2
+   uint32_t                                     TEDomain;
+#define     HW_TESS                                            0
+#define     SW_TESS                                            1
+   uint32_t                                     TEMode;
+   bool                                         TEEnable;
+   float                                        MaximumTessellationFactorOdd;
+   float                                        MaximumTessellationFactorNotOdd;
+};
+
+static inline void
+GEN7_3DSTATE_TE_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_TE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Partitioning, 12, 13) |
+      __gen_field(values->OutputTopology, 8, 9) |
+      __gen_field(values->TEDomain, 4, 5) |
+      __gen_field(values->TEMode, 1, 2) |
+      __gen_field(values->TEEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_float(values->MaximumTessellationFactorOdd) |
+      0;
+
+   dw[3] =
+      __gen_float(values->MaximumTessellationFactorNotOdd) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_URB_DS_length_bias 0x00000002
+#define GEN7_3DSTATE_URB_DS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 50,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_URB_DS_length 0x00000002
+
+struct GEN7_3DSTATE_URB_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     DSURBStartingAddress;
+   uint32_t                                     DSURBEntryAllocationSize;
+   uint32_t                                     DSNumberofURBEntries;
+};
+
+static inline void
+GEN7_3DSTATE_URB_DS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_3DSTATE_URB_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DSURBStartingAddress, 25, 29) |
+      __gen_field(values->DSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->DSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_URB_GS_length_bias 0x00000002
+#define GEN7_3DSTATE_URB_GS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 51,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_URB_GS_length 0x00000002
+
+struct GEN7_3DSTATE_URB_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     GSURBStartingAddress;
+   uint32_t                                     GSURBEntryAllocationSize;
+   uint32_t                                     GSNumberofURBEntries;
+};
+
+static inline void
+GEN7_3DSTATE_URB_GS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_3DSTATE_URB_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->GSURBStartingAddress, 25, 29) |
+      __gen_field(values->GSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->GSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_URB_HS_length_bias 0x00000002
+#define GEN7_3DSTATE_URB_HS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 49,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_URB_HS_length 0x00000002
+
+struct GEN7_3DSTATE_URB_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     HSURBStartingAddress;
+   uint32_t                                     HSURBEntryAllocationSize;
+   uint32_t                                     HSNumberofURBEntries;
+};
+
+static inline void
+GEN7_3DSTATE_URB_HS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_3DSTATE_URB_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->HSURBStartingAddress, 25, 29) |
+      __gen_field(values->HSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->HSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_VERTEX_BUFFERS_length_bias 0x00000002
+#define GEN7_3DSTATE_VERTEX_BUFFERS_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  8
+
+#define GEN7_3DSTATE_VERTEX_BUFFERS_length 0x00000000
+
+#define GEN7_VERTEX_BUFFER_STATE_length 0x00000004
+
+struct GEN7_VERTEX_BUFFER_STATE {
+   uint32_t                                     VertexBufferIndex;
+#define     VERTEXDATA                                         0
+#define     INSTANCEDATA                                       1
+   uint32_t                                     BufferAccessType;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      VertexBufferMemoryObjectControlState;
+   uint32_t                                     AddressModifyEnable;
+   bool                                         NullVertexBuffer;
+   uint32_t                                     VertexFetchInvalidate;
+   uint32_t                                     BufferPitch;
+   __gen_address_type                           BufferStartingAddress;
+   __gen_address_type                           EndAddress;
+   uint32_t                                     InstanceDataStepRate;
+};
+
+static inline void
+GEN7_VERTEX_BUFFER_STATE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_VERTEX_BUFFER_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_VertexBufferMemoryObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_VertexBufferMemoryObjectControlState, &values->VertexBufferMemoryObjectControlState);
+   dw[0] =
+      __gen_field(values->VertexBufferIndex, 26, 31) |
+      __gen_field(values->BufferAccessType, 20, 20) |
+      __gen_field(dw_VertexBufferMemoryObjectControlState, 16, 19) |
+      __gen_field(values->AddressModifyEnable, 14, 14) |
+      __gen_field(values->NullVertexBuffer, 13, 13) |
+      __gen_field(values->VertexFetchInvalidate, 12, 12) |
+      __gen_field(values->BufferPitch, 0, 11) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BufferStartingAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->EndAddress, dw2);
+
+   dw[3] =
+      __gen_field(values->InstanceDataStepRate, 0, 31) |
+      0;
+
+}
+
+struct GEN7_3DSTATE_VERTEX_BUFFERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_3DSTATE_VERTEX_BUFFERS_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN7_3DSTATE_VERTEX_BUFFERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_3DSTATE_VERTEX_ELEMENTS_length_bias 0x00000002
+#define GEN7_3DSTATE_VERTEX_ELEMENTS_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  9
+
+#define GEN7_3DSTATE_VERTEX_ELEMENTS_length 0x00000000
+
+#define GEN7_VERTEX_ELEMENT_STATE_length 0x00000002
+
+struct GEN7_VERTEX_ELEMENT_STATE {
+   uint32_t                                     VertexBufferIndex;
+   bool                                         Valid;
+   uint32_t                                     SourceElementFormat;
+   bool                                         EdgeFlagEnable;
+   uint32_t                                     SourceElementOffset;
+   uint32_t                                     Component0Control;
+   uint32_t                                     Component1Control;
+   uint32_t                                     Component2Control;
+   uint32_t                                     Component3Control;
+};
+
+static inline void
+GEN7_VERTEX_ELEMENT_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_VERTEX_ELEMENT_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->VertexBufferIndex, 26, 31) |
+      __gen_field(values->Valid, 25, 25) |
+      __gen_field(values->SourceElementFormat, 16, 24) |
+      __gen_field(values->EdgeFlagEnable, 15, 15) |
+      __gen_field(values->SourceElementOffset, 0, 11) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Component0Control, 28, 30) |
+      __gen_field(values->Component1Control, 24, 26) |
+      __gen_field(values->Component2Control, 20, 22) |
+      __gen_field(values->Component3Control, 16, 18) |
+      0;
+
+}
+
+struct GEN7_3DSTATE_VERTEX_ELEMENTS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_3DSTATE_VERTEX_ELEMENTS_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN7_3DSTATE_VERTEX_ELEMENTS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_3DSTATE_VF_STATISTICS_length_bias 0x00000001
+#define GEN7_3DSTATE_VF_STATISTICS_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  1,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 11
+
+#define GEN7_3DSTATE_VF_STATISTICS_length 0x00000001
+
+struct GEN7_3DSTATE_VF_STATISTICS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         StatisticsEnable;
+};
+
+static inline void
+GEN7_3DSTATE_VF_STATISTICS_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN7_3DSTATE_VF_STATISTICS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->StatisticsEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC_length_bias 0x00000002
+#define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 35,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC_length 0x00000002
+
+struct GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CCViewportPointer;
+};
+
+static inline void
+GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->CCViewportPointer, 5, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_length_bias 0x00000002
+#define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 33,                  \
+   .DwordLength          =  0
+
+#define GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_length 0x00000002
+
+struct GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SFClipViewportPointer;
+};
+
+static inline void
+GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_pack(__gen_user_data *data, void * restrict dst,
+                                                  const struct GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SFClipViewportPointer, 6, 31) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_VS_length_bias 0x00000002
+#define GEN7_3DSTATE_VS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 16,                  \
+   .DwordLength          =  4
+
+#define GEN7_3DSTATE_VS_length 0x00000006
+
+struct GEN7_3DSTATE_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleVertexDispatch;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnableVME;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ScratchSpaceBaseOffset;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     DispatchGRFStartRegisterforURBData;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         StatisticsEnable;
+   bool                                         VertexCacheDisable;
+   bool                                         VSFunctionEnable;
+};
+
+static inline void
+GEN7_3DSTATE_VS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SingleVertexDispatch, 31, 31) |
+      __gen_field(values->VectorMaskEnableVME, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->ScratchSpaceBaseOffset, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DispatchGRFStartRegisterforURBData, 20, 24) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[5] =
+      __gen_field(values->MaximumNumberofThreads, 25, 31) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->VertexCacheDisable, 1, 1) |
+      __gen_field(values->VSFunctionEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN7_3DSTATE_WM_length_bias 0x00000002
+#define GEN7_3DSTATE_WM_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 20,                  \
+   .DwordLength          =  1
+
+#define GEN7_3DSTATE_WM_length 0x00000003
+
+struct GEN7_3DSTATE_WM {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         StatisticsEnable;
+   bool                                         DepthBufferClear;
+   bool                                         ThreadDispatchEnable;
+   bool                                         DepthBufferResolveEnable;
+   bool                                         HierarchicalDepthBufferResolveEnable;
+   bool                                         LegacyDiamondLineRasterization;
+   bool                                         PixelShaderKillPixel;
+#define     PSCDEPTH_OFF                                       0
+#define     PSCDEPTH_ON                                        1
+#define     PSCDEPTH_ON_GE                                     2
+#define     PSCDEPTH_ON_LE                                     3
+   uint32_t                                     PixelShaderComputedDepthMode;
+#define     EDSC_NORMAL                                        0
+#define     EDSC_PSEXEC                                        1
+#define     EDSC_PREPS                                         2
+   uint32_t                                     EarlyDepthStencilControl;
+   bool                                         PixelShaderUsesSourceDepth;
+   bool                                         PixelShaderUsesSourceW;
+#define     INTERP_PIXEL                                       0
+#define     INTERP_CENTROID                                    2
+#define     INTERP_SAMPLE                                      3
+   uint32_t                                     PositionZWInterpolationMode;
+   uint32_t                                     BarycentricInterpolationMode;
+   bool                                         PixelShaderUsesInputCoverageMask;
+   uint32_t                                     LineEndCapAntialiasingRegionWidth;
+   uint32_t                                     LineAntialiasingRegionWidth;
+   bool                                         PolygonStippleEnable;
+   bool                                         LineStippleEnable;
+#define     RASTRULE_UPPER_LEFT                                0
+#define     RASTRULE_UPPER_RIGHT                               1
+   uint32_t                                     PointRasterizationRule;
+#define     MSRASTMODE_OFF_PIXEL                               0
+#define     MSRASTMODE_OFF_PATTERN                             1
+#define     MSRASTMODE_ON_PIXEL                                2
+#define     MSRASTMODE_ON_PATTERN                              3
+   uint32_t                                     MultisampleRasterizationMode;
+#define     MSDISPMODE_PERSAMPLE                               0
+#define     MSDISPMODE_PERPIXEL                                1
+   uint32_t                                     MultisampleDispatchMode;
+};
+
+static inline void
+GEN7_3DSTATE_WM_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_3DSTATE_WM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StatisticsEnable, 31, 31) |
+      __gen_field(values->DepthBufferClear, 30, 30) |
+      __gen_field(values->ThreadDispatchEnable, 29, 29) |
+      __gen_field(values->DepthBufferResolveEnable, 28, 28) |
+      __gen_field(values->HierarchicalDepthBufferResolveEnable, 27, 27) |
+      __gen_field(values->LegacyDiamondLineRasterization, 26, 26) |
+      __gen_field(values->PixelShaderKillPixel, 25, 25) |
+      __gen_field(values->PixelShaderComputedDepthMode, 23, 24) |
+      __gen_field(values->EarlyDepthStencilControl, 21, 22) |
+      __gen_field(values->PixelShaderUsesSourceDepth, 20, 20) |
+      __gen_field(values->PixelShaderUsesSourceW, 19, 19) |
+      __gen_field(values->PositionZWInterpolationMode, 17, 18) |
+      __gen_field(values->BarycentricInterpolationMode, 11, 16) |
+      __gen_field(values->PixelShaderUsesInputCoverageMask, 10, 10) |
+      __gen_field(values->LineEndCapAntialiasingRegionWidth, 8, 9) |
+      __gen_field(values->LineAntialiasingRegionWidth, 6, 7) |
+      __gen_field(values->PolygonStippleEnable, 4, 4) |
+      __gen_field(values->LineStippleEnable, 3, 3) |
+      __gen_field(values->PointRasterizationRule, 2, 2) |
+      __gen_field(values->MultisampleRasterizationMode, 0, 1) |
+      0;
+
+   dw[2] =
+      __gen_field(values->MultisampleDispatchMode, 31, 31) |
+      0;
+
+}
+
+#define GEN7_GPGPU_OBJECT_length_bias 0x00000002
+#define GEN7_GPGPU_OBJECT_header                \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  4,                  \
+   .DwordLength          =  6
+
+#define GEN7_GPGPU_OBJECT_length 0x00000008
+
+struct GEN7_GPGPU_OBJECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SharedLocalMemoryFixedOffset;
+   uint32_t                                     InterfaceDescriptorOffset;
+   uint32_t                                     SharedLocalMemoryOffset;
+   uint32_t                                     EndofThreadGroup;
+#define     HalfSlice1                                         2
+#define     HalfSlice0                                         1
+#define     EitherHalfSlice                                    0
+   uint32_t                                     HalfSliceDestinationSelect;
+   uint32_t                                     IndirectDataLength;
+   uint32_t                                     IndirectDataStartAddress;
+   uint32_t                                     ThreadGroupIDX;
+   uint32_t                                     ThreadGroupIDY;
+   uint32_t                                     ThreadGroupIDZ;
+   uint32_t                                     ExecutionMask;
+};
+
+static inline void
+GEN7_GPGPU_OBJECT_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_GPGPU_OBJECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SharedLocalMemoryFixedOffset, 7, 7) |
+      __gen_field(values->InterfaceDescriptorOffset, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SharedLocalMemoryOffset, 28, 31) |
+      __gen_field(values->EndofThreadGroup, 24, 24) |
+      __gen_field(values->HalfSliceDestinationSelect, 17, 18) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->IndirectDataStartAddress, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ThreadGroupIDX, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ThreadGroupIDY, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ThreadGroupIDZ, 0, 31) |
+      0;
+
+   dw[7] =
+      __gen_field(values->ExecutionMask, 0, 31) |
+      0;
+
+}
+
+#define GEN7_GPGPU_WALKER_length_bias 0x00000002
+#define GEN7_GPGPU_WALKER_header                \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcodeA           =  5,                  \
+   .DwordLength          =  9
+
+#define GEN7_GPGPU_WALKER_length 0x0000000b
+
+struct GEN7_GPGPU_WALKER {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcodeA;
+   bool                                         IndirectParameterEnable;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+#define     SIMD8                                              0
+#define     SIMD16                                             1
+#define     SIMD32                                             2
+   uint32_t                                     SIMDSize;
+   uint32_t                                     ThreadDepthCounterMaximum;
+   uint32_t                                     ThreadHeightCounterMaximum;
+   uint32_t                                     ThreadWidthCounterMaximum;
+   uint32_t                                     ThreadGroupIDStartingX;
+   uint32_t                                     ThreadGroupIDXDimension;
+   uint32_t                                     ThreadGroupIDStartingY;
+   uint32_t                                     ThreadGroupIDYDimension;
+   uint32_t                                     ThreadGroupIDStartingZ;
+   uint32_t                                     ThreadGroupIDZDimension;
+   uint32_t                                     RightExecutionMask;
+   uint32_t                                     BottomExecutionMask;
+};
+
+static inline void
+GEN7_GPGPU_WALKER_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_GPGPU_WALKER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcodeA, 16, 23) |
+      __gen_field(values->IndirectParameterEnable, 10, 10) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_field(values->SIMDSize, 30, 31) |
+      __gen_field(values->ThreadDepthCounterMaximum, 16, 21) |
+      __gen_field(values->ThreadHeightCounterMaximum, 8, 13) |
+      __gen_field(values->ThreadWidthCounterMaximum, 0, 5) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ThreadGroupIDStartingX, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ThreadGroupIDXDimension, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ThreadGroupIDStartingY, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ThreadGroupIDYDimension, 0, 31) |
+      0;
+
+   dw[7] =
+      __gen_field(values->ThreadGroupIDStartingZ, 0, 31) |
+      0;
+
+   dw[8] =
+      __gen_field(values->ThreadGroupIDZDimension, 0, 31) |
+      0;
+
+   dw[9] =
+      __gen_field(values->RightExecutionMask, 0, 31) |
+      0;
+
+   dw[10] =
+      __gen_field(values->BottomExecutionMask, 0, 31) |
+      0;
+
+}
+
+#define GEN7_MEDIA_CURBE_LOAD_length_bias 0x00000002
+#define GEN7_MEDIA_CURBE_LOAD_header            \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  1,                  \
+   .DwordLength          =  2
+
+#define GEN7_MEDIA_CURBE_LOAD_length 0x00000004
+
+struct GEN7_MEDIA_CURBE_LOAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CURBETotalDataLength;
+   uint32_t                                     CURBEDataStartAddress;
+};
+
+static inline void
+GEN7_MEDIA_CURBE_LOAD_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN7_MEDIA_CURBE_LOAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->CURBETotalDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_field(values->CURBEDataStartAddress, 0, 31) |
+      0;
+
+}
+
+#define GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD_length_bias 0x00000002
+#define GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD_header\
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  2,                  \
+   .DwordLength          =  2
+
+#define GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD_length 0x00000004
+
+struct GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorTotalLength;
+   uint32_t                                     InterfaceDescriptorDataStartAddress;
+};
+
+static inline void
+GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN7_MEDIA_INTERFACE_DESCRIPTOR_LOAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->InterfaceDescriptorTotalLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->InterfaceDescriptorDataStartAddress, 0, 31) |
+      0;
+
+}
+
+#define GEN7_MEDIA_OBJECT_length_bias 0x00000002
+#define GEN7_MEDIA_OBJECT_header                \
+   .CommandType          =  3,                  \
+   .MediaCommandPipeline =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .MediaCommandSubOpcode =  0
+
+#define GEN7_MEDIA_OBJECT_length 0x00000000
+
+struct GEN7_MEDIA_OBJECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MediaCommandPipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     MediaCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+#define     Nothreadsynchronization                            0
+#define     Threaddispatchissynchronizedbythespawnrootthreadmessage       1
+   uint32_t                                     ThreadSynchronization;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+#define     HalfSlice1                                         2
+#define     HalfSlice0                                         1
+#define     Eitherhalfslice                                    0
+   uint32_t                                     HalfSliceDestinationSelect;
+   uint32_t                                     IndirectDataLength;
+   __gen_address_type                           IndirectDataStartAddress;
+   uint32_t                                     ScoredboardY;
+   uint32_t                                     ScoreboardX;
+   uint32_t                                     ScoreboardColor;
+   bool                                         ScoreboardMask;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_MEDIA_OBJECT_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_MEDIA_OBJECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MediaCommandPipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->MediaCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->ThreadSynchronization, 24, 24) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->HalfSliceDestinationSelect, 17, 18) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->IndirectDataStartAddress, dw3);
+
+   dw[4] =
+      __gen_field(values->ScoredboardY, 16, 24) |
+      __gen_field(values->ScoreboardX, 0, 8) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardColor, 16, 19) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_MEDIA_OBJECT_PRT_length_bias 0x00000002
+#define GEN7_MEDIA_OBJECT_PRT_header            \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  2,                  \
+   .DwordLength          = 14
+
+#define GEN7_MEDIA_OBJECT_PRT_length 0x00000010
+
+struct GEN7_MEDIA_OBJECT_PRT {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+   bool                                         PRT_FenceNeeded;
+#define     Rootthreadqueue                                    0
+#define     VFEstateflush                                      1
+   uint32_t                                     PRT_FenceType;
+   uint32_t                                     InlineData[12];
+};
+
+static inline void
+GEN7_MEDIA_OBJECT_PRT_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN7_MEDIA_OBJECT_PRT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->PRT_FenceNeeded, 23, 23) |
+      __gen_field(values->PRT_FenceType, 22, 22) |
+      0;
+
+   dw[3] =
+      0;
+
+   for (uint32_t i = 0, j = 4; i < 12; i += 1, j++) {
+      dw[j] =
+         __gen_field(values->InlineData[i + 0], 0, 31) |
+         0;
+   }
+
+}
+
+#define GEN7_MEDIA_OBJECT_WALKER_length_bias 0x00000002
+#define GEN7_MEDIA_OBJECT_WALKER_header         \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  3
+
+#define GEN7_MEDIA_OBJECT_WALKER_length 0x00000000
+
+struct GEN7_MEDIA_OBJECT_WALKER {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+#define     Nothreadsynchronization                            0
+#define     Threaddispatchissynchronizedbythespawnrootthreadmessage       1
+   uint32_t                                     ThreadSynchronization;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+   uint32_t                                     IndirectDataLength;
+   uint32_t                                     IndirectDataStartAddress;
+   bool                                         ScoreboardMask;
+   bool                                         DualMode;
+   bool                                         Repel;
+   uint32_t                                     ColorCountMinusOne;
+   uint32_t                                     MiddleLoopExtraSteps;
+   uint32_t                                     LocalMidLoopUnitY;
+   uint32_t                                     MidLoopUnitX;
+   uint32_t                                     GlobalLoopExecCount;
+   uint32_t                                     LocalLoopExecCount;
+   uint32_t                                     BlockResolutionY;
+   uint32_t                                     BlockResolutionX;
+   uint32_t                                     LocalStartY;
+   uint32_t                                     LocalStartX;
+   uint32_t                                     LocalEndY;
+   uint32_t                                     LocalEndX;
+   uint32_t                                     LocalOuterLoopStrideY;
+   uint32_t                                     LocalOuterLoopStrideX;
+   uint32_t                                     LocalInnerLoopUnitY;
+   uint32_t                                     LocalInnerLoopUnitX;
+   uint32_t                                     GlobalResolutionY;
+   uint32_t                                     GlobalResolutionX;
+   uint32_t                                     GlobalStartY;
+   uint32_t                                     GlobalStartX;
+   uint32_t                                     GlobalOuterLoopStrideY;
+   uint32_t                                     GlobalOuterLoopStrideX;
+   uint32_t                                     GlobalInnerLoopUnitY;
+   uint32_t                                     GlobalInnerLoopUnitX;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_MEDIA_OBJECT_WALKER_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_MEDIA_OBJECT_WALKER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->ThreadSynchronization, 24, 24) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->IndirectDataStartAddress, 0, 31) |
+      0;
+
+   dw[4] =
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->DualMode, 31, 31) |
+      __gen_field(values->Repel, 30, 30) |
+      __gen_field(values->ColorCountMinusOne, 24, 27) |
+      __gen_field(values->MiddleLoopExtraSteps, 16, 20) |
+      __gen_field(values->LocalMidLoopUnitY, 12, 13) |
+      __gen_field(values->MidLoopUnitX, 8, 9) |
+      0;
+
+   dw[7] =
+      __gen_field(values->GlobalLoopExecCount, 16, 25) |
+      __gen_field(values->LocalLoopExecCount, 0, 9) |
+      0;
+
+   dw[8] =
+      __gen_field(values->BlockResolutionY, 16, 24) |
+      __gen_field(values->BlockResolutionX, 0, 8) |
+      0;
+
+   dw[9] =
+      __gen_field(values->LocalStartY, 16, 24) |
+      __gen_field(values->LocalStartX, 0, 8) |
+      0;
+
+   dw[10] =
+      __gen_field(values->LocalEndY, 16, 24) |
+      __gen_field(values->LocalEndX, 0, 8) |
+      0;
+
+   dw[11] =
+      __gen_field(values->LocalOuterLoopStrideY, 16, 25) |
+      __gen_field(values->LocalOuterLoopStrideX, 0, 9) |
+      0;
+
+   dw[12] =
+      __gen_field(values->LocalInnerLoopUnitY, 16, 25) |
+      __gen_field(values->LocalInnerLoopUnitX, 0, 9) |
+      0;
+
+   dw[13] =
+      __gen_field(values->GlobalResolutionY, 16, 24) |
+      __gen_field(values->GlobalResolutionX, 0, 8) |
+      0;
+
+   dw[14] =
+      __gen_field(values->GlobalStartY, 16, 25) |
+      __gen_field(values->GlobalStartX, 0, 9) |
+      0;
+
+   dw[15] =
+      __gen_field(values->GlobalOuterLoopStrideY, 16, 25) |
+      __gen_field(values->GlobalOuterLoopStrideX, 0, 9) |
+      0;
+
+   dw[16] =
+      __gen_field(values->GlobalInnerLoopUnitY, 16, 25) |
+      __gen_field(values->GlobalInnerLoopUnitX, 0, 9) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN7_MEDIA_STATE_FLUSH_length_bias 0x00000002
+#define GEN7_MEDIA_STATE_FLUSH_header           \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  4,                  \
+   .DwordLength          =  0
+
+#define GEN7_MEDIA_STATE_FLUSH_length 0x00000002
+
+struct GEN7_MEDIA_STATE_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     WatermarkRequired;
+   uint32_t                                     InterfaceDescriptorOffset;
+};
+
+static inline void
+GEN7_MEDIA_STATE_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_MEDIA_STATE_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->WatermarkRequired, 6, 6) |
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+}
+
+#define GEN7_MEDIA_VFE_STATE_length_bias 0x00000002
+#define GEN7_MEDIA_VFE_STATE_header             \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  0,                  \
+   .DwordLength          =  6
+
+#define GEN7_MEDIA_VFE_STATE_length 0x00000008
+
+struct GEN7_MEDIA_VFE_STATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     NumberofURBEntries;
+#define     Maintainingtheexistingtimestampstate               0
+#define     Resettingrelativetimerandlatchingtheglobaltimestamp       1
+   uint32_t                                     ResetGatewayTimer;
+#define     MaintainingOpenGatewayForwardMsgCloseGatewayprotocollegacymode       0
+#define     BypassingOpenGatewayCloseGatewayprotocol           1
+   uint32_t                                     BypassGatewayControl;
+#define     NoMMIOreadwriteallowed                             0
+#define     MMIOreadwritetoanyaddress                          2
+   uint32_t                                     GatewayMMIOAccessControl;
+   uint32_t                                     GPGPUMode;
+   uint32_t                                     URBEntryAllocationSize;
+   uint32_t                                     CURBEAllocationSize;
+#define     Scoreboarddisabled                                 0
+#define     Scoreboardenabled                                  1
+   uint32_t                                     ScoreboardEnable;
+#define     StallingScoreboard                                 0
+#define     NonStallingScoreboard                              1
+   uint32_t                                     ScoreboardType;
+   uint32_t                                     ScoreboardMask;
+   uint32_t                                     Scoreboard3DeltaY;
+   uint32_t                                     Scoreboard3DeltaX;
+   uint32_t                                     Scoreboard2DeltaY;
+   uint32_t                                     Scoreboard2DeltaX;
+   uint32_t                                     Scoreboard1DeltaY;
+   uint32_t                                     Scoreboard1DeltaX;
+   uint32_t                                     Scoreboard0DeltaY;
+   uint32_t                                     Scoreboard0DeltaX;
+   uint32_t                                     Scoreboard7DeltaY;
+   uint32_t                                     Scoreboard7DeltaX;
+   uint32_t                                     Scoreboard6DeltaY;
+   uint32_t                                     Scoreboard6DeltaX;
+   uint32_t                                     Scoreboard5DeltaY;
+   uint32_t                                     Scoreboard5DeltaX;
+   uint32_t                                     Scoreboard4DeltaY;
+   uint32_t                                     Scoreboard4DeltaX;
+};
+
+static inline void
+GEN7_MEDIA_VFE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN7_MEDIA_VFE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->MaximumNumberofThreads, 16, 31) |
+      __gen_field(values->NumberofURBEntries, 8, 15) |
+      __gen_field(values->ResetGatewayTimer, 7, 7) |
+      __gen_field(values->BypassGatewayControl, 6, 6) |
+      __gen_field(values->GatewayMMIOAccessControl, 3, 4) |
+      __gen_field(values->GPGPUMode, 2, 2) |
+      0;
+
+   dw[3] =
+      0;
+
+   dw[4] =
+      __gen_field(values->URBEntryAllocationSize, 16, 31) |
+      __gen_field(values->CURBEAllocationSize, 0, 15) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardEnable, 31, 31) |
+      __gen_field(values->ScoreboardType, 30, 30) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->Scoreboard3DeltaY, 28, 31) |
+      __gen_field(values->Scoreboard3DeltaX, 24, 27) |
+      __gen_field(values->Scoreboard2DeltaY, 20, 23) |
+      __gen_field(values->Scoreboard2DeltaX, 16, 19) |
+      __gen_field(values->Scoreboard1DeltaY, 12, 15) |
+      __gen_field(values->Scoreboard1DeltaX, 8, 11) |
+      __gen_field(values->Scoreboard0DeltaY, 4, 7) |
+      __gen_field(values->Scoreboard0DeltaX, 0, 3) |
+      0;
+
+   dw[7] =
+      __gen_field(values->Scoreboard7DeltaY, 28, 31) |
+      __gen_field(values->Scoreboard7DeltaX, 24, 27) |
+      __gen_field(values->Scoreboard6DeltaY, 20, 23) |
+      __gen_field(values->Scoreboard6DeltaX, 16, 19) |
+      __gen_field(values->Scoreboard5DeltaY, 12, 15) |
+      __gen_field(values->Scoreboard5DeltaX, 8, 11) |
+      __gen_field(values->Scoreboard4DeltaY, 4, 7) |
+      __gen_field(values->Scoreboard4DeltaX, 0, 3) |
+      0;
+
+}
+
+#define GEN7_MI_ARB_CHECK_length_bias 0x00000001
+#define GEN7_MI_ARB_CHECK_header                \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  5
+
+#define GEN7_MI_ARB_CHECK_length 0x00000001
+
+struct GEN7_MI_ARB_CHECK {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN7_MI_ARB_CHECK_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_MI_ARB_CHECK * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN7_MI_ARB_ON_OFF_length_bias 0x00000001
+#define GEN7_MI_ARB_ON_OFF_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  8
+
+#define GEN7_MI_ARB_ON_OFF_length 0x00000001
+
+struct GEN7_MI_ARB_ON_OFF {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         ArbitrationEnable;
+};
+
+static inline void
+GEN7_MI_ARB_ON_OFF_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN7_MI_ARB_ON_OFF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ArbitrationEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN7_MI_BATCH_BUFFER_END_length_bias 0x00000001
+#define GEN7_MI_BATCH_BUFFER_END_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 10
+
+#define GEN7_MI_BATCH_BUFFER_END_length 0x00000001
+
+struct GEN7_MI_BATCH_BUFFER_END {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN7_MI_BATCH_BUFFER_END_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_MI_BATCH_BUFFER_END * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN7_MI_BATCH_BUFFER_START_length_bias 0x00000002
+#define GEN7_MI_BATCH_BUFFER_START_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 49,                  \
+   .DwordLength          =  0
+
+#define GEN7_MI_BATCH_BUFFER_START_length 0x00000002
+
+struct GEN7_MI_BATCH_BUFFER_START {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         ClearCommandBufferEnable;
+#define     ASI_GGTT                                           0
+#define     ASI_PPGTT                                          1
+   uint32_t                                     AddressSpaceIndicator;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BatchBufferStartAddress;
+};
+
+static inline void
+GEN7_MI_BATCH_BUFFER_START_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN7_MI_BATCH_BUFFER_START * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ClearCommandBufferEnable, 11, 11) |
+      __gen_field(values->AddressSpaceIndicator, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->BatchBufferStartAddress, dw1);
+
+}
+
+#define GEN7_MI_CLFLUSH_length_bias 0x00000002
+#define GEN7_MI_CLFLUSH_header                  \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 39
+
+#define GEN7_MI_CLFLUSH_length 0x00000000
+
+struct GEN7_MI_CLFLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           PageBaseAddress;
+   uint32_t                                     StartingCachelineOffset;
+   __gen_address_type                           PageBaseAddressHigh;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_MI_CLFLUSH_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN7_MI_CLFLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 9) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->StartingCachelineOffset, 6, 11) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->PageBaseAddress, dw1);
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->PageBaseAddressHigh, dw2);
+
+   /* variable length fields follow */
+}
+
+#define GEN7_MI_CONDITIONAL_BATCH_BUFFER_END_length_bias 0x00000002
+#define GEN7_MI_CONDITIONAL_BATCH_BUFFER_END_header\
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 54,                  \
+   .UseGlobalGTT         =  0,                  \
+   .CompareSemaphore     =  0,                  \
+   .DwordLength          =  0
+
+#define GEN7_MI_CONDITIONAL_BATCH_BUFFER_END_length 0x00000002
+
+struct GEN7_MI_CONDITIONAL_BATCH_BUFFER_END {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     CompareSemaphore;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CompareDataDword;
+   __gen_address_type                           CompareAddress;
+};
+
+static inline void
+GEN7_MI_CONDITIONAL_BATCH_BUFFER_END_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN7_MI_CONDITIONAL_BATCH_BUFFER_END * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->CompareSemaphore, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->CompareDataDword, 0, 31) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->CompareAddress, dw2);
+
+}
+
+#define GEN7_MI_FLUSH_length_bias 0x00000001
+#define GEN7_MI_FLUSH_header                    \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  4
+
+#define GEN7_MI_FLUSH_length 0x00000001
+
+struct GEN7_MI_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         IndirectStatePointersDisable;
+   bool                                         GenericMediaStateClear;
+#define     DontReset                                          0
+#define     Reset                                              1
+   bool                                         GlobalSnapshotCountReset;
+#define     Flush                                              0
+#define     DontFlush                                          1
+   bool                                         RenderCacheFlushInhibit;
+#define     DontInvalidate                                     0
+#define     Invalidate                                         1
+   bool                                         StateInstructionCacheInvalidate;
+};
+
+static inline void
+GEN7_MI_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                   const struct GEN7_MI_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->IndirectStatePointersDisable, 5, 5) |
+      __gen_field(values->GenericMediaStateClear, 4, 4) |
+      __gen_field(values->GlobalSnapshotCountReset, 3, 3) |
+      __gen_field(values->RenderCacheFlushInhibit, 2, 2) |
+      __gen_field(values->StateInstructionCacheInvalidate, 1, 1) |
+      0;
+
+}
+
+#define GEN7_MI_LOAD_REGISTER_IMM_length_bias 0x00000002
+#define GEN7_MI_LOAD_REGISTER_IMM_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 34,                  \
+   .DwordLength          =  1
+
+#define GEN7_MI_LOAD_REGISTER_IMM_length 0x00000003
+
+struct GEN7_MI_LOAD_REGISTER_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     ByteWriteDisables;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterOffset;
+   uint32_t                                     DataDWord;
+};
+
+static inline void
+GEN7_MI_LOAD_REGISTER_IMM_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_MI_LOAD_REGISTER_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ByteWriteDisables, 8, 11) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterOffset, 2, 22) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DataDWord, 0, 31) |
+      0;
+
+}
+
+#define GEN7_MI_LOAD_REGISTER_MEM_length_bias 0x00000002
+#define GEN7_MI_LOAD_REGISTER_MEM_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 41,                  \
+   .DwordLength          =  1
+
+#define GEN7_MI_LOAD_REGISTER_MEM_length 0x00000003
+
+struct GEN7_MI_LOAD_REGISTER_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     AsyncModeEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN7_MI_LOAD_REGISTER_MEM_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_MI_LOAD_REGISTER_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->AsyncModeEnable, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterAddress, 2, 22) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+}
+
+#define GEN7_MI_NOOP_length_bias 0x00000001
+#define GEN7_MI_NOOP_header                     \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  0
+
+#define GEN7_MI_NOOP_length 0x00000001
+
+struct GEN7_MI_NOOP {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         IdentificationNumberRegisterWriteEnable;
+   uint32_t                                     IdentificationNumber;
+};
+
+static inline void
+GEN7_MI_NOOP_pack(__gen_user_data *data, void * restrict dst,
+                  const struct GEN7_MI_NOOP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->IdentificationNumberRegisterWriteEnable, 22, 22) |
+      __gen_field(values->IdentificationNumber, 0, 21) |
+      0;
+
+}
+
+#define GEN7_MI_PREDICATE_length_bias 0x00000001
+#define GEN7_MI_PREDICATE_header                \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 12
+
+#define GEN7_MI_PREDICATE_length 0x00000001
+
+struct GEN7_MI_PREDICATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     LOAD_KEEP                                          0
+#define     LOAD_LOAD                                          2
+#define     LOAD_LOADINV                                       3
+   uint32_t                                     LoadOperation;
+#define     COMBINE_SET                                        0
+#define     COMBINE_AND                                        1
+#define     COMBINE_OR                                         2
+#define     COMBINE_XOR                                        3
+   uint32_t                                     CombineOperation;
+#define     COMPARE_SRCS_EQUAL                                 2
+#define     COMPARE_DELTAS_EQUAL                               3
+   uint32_t                                     CompareOperation;
+};
+
+static inline void
+GEN7_MI_PREDICATE_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_MI_PREDICATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->LoadOperation, 6, 7) |
+      __gen_field(values->CombineOperation, 3, 4) |
+      __gen_field(values->CompareOperation, 0, 1) |
+      0;
+
+}
+
+#define GEN7_MI_REPORT_HEAD_length_bias 0x00000001
+#define GEN7_MI_REPORT_HEAD_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  7
+
+#define GEN7_MI_REPORT_HEAD_length 0x00000001
+
+struct GEN7_MI_REPORT_HEAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN7_MI_REPORT_HEAD_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_MI_REPORT_HEAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN7_MI_SEMAPHORE_MBOX_length_bias 0x00000002
+#define GEN7_MI_SEMAPHORE_MBOX_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 22,                  \
+   .DwordLength          =  1
+
+#define GEN7_MI_SEMAPHORE_MBOX_length 0x00000003
+
+struct GEN7_MI_SEMAPHORE_MBOX {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     RVSYNC                                             0
+#define     RBSYNC                                             2
+#define     UseGeneralRegisterSelect                           3
+   uint32_t                                     RegisterSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SemaphoreDataDword;
+};
+
+static inline void
+GEN7_MI_SEMAPHORE_MBOX_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_MI_SEMAPHORE_MBOX * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->RegisterSelect, 16, 17) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SemaphoreDataDword, 0, 31) |
+      0;
+
+   dw[2] =
+      0;
+
+}
+
+#define GEN7_MI_SET_CONTEXT_length_bias 0x00000002
+#define GEN7_MI_SET_CONTEXT_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 24,                  \
+   .DwordLength          =  0
+
+#define GEN7_MI_SET_CONTEXT_length 0x00000002
+
+struct GEN7_MI_SET_CONTEXT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           LogicalContextAddress;
+   uint32_t                                     ReservedMustbe1;
+   bool                                         ExtendedStateSaveEnable;
+   bool                                         ExtendedStateRestoreEnable;
+   uint32_t                                     ForceRestore;
+   uint32_t                                     RestoreInhibit;
+};
+
+static inline void
+GEN7_MI_SET_CONTEXT_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN7_MI_SET_CONTEXT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->ReservedMustbe1, 8, 8) |
+      __gen_field(values->ExtendedStateSaveEnable, 3, 3) |
+      __gen_field(values->ExtendedStateRestoreEnable, 2, 2) |
+      __gen_field(values->ForceRestore, 1, 1) |
+      __gen_field(values->RestoreInhibit, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->LogicalContextAddress, dw1);
+
+}
+
+#define GEN7_MI_STORE_DATA_IMM_length_bias 0x00000002
+#define GEN7_MI_STORE_DATA_IMM_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 32,                  \
+   .DwordLength          =  2
+
+#define GEN7_MI_STORE_DATA_IMM_length 0x00000004
+
+struct GEN7_MI_STORE_DATA_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   uint32_t                                     Address;
+   uint32_t                                     CoreModeEnable;
+   uint32_t                                     DataDWord0;
+   uint32_t                                     DataDWord1;
+};
+
+static inline void
+GEN7_MI_STORE_DATA_IMM_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_MI_STORE_DATA_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->Address, 2, 31) |
+      __gen_field(values->CoreModeEnable, 0, 0) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DataDWord1, 0, 31) |
+      0;
+
+}
+
+#define GEN7_MI_STORE_DATA_INDEX_length_bias 0x00000002
+#define GEN7_MI_STORE_DATA_INDEX_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 33,                  \
+   .DwordLength          =  1
+
+#define GEN7_MI_STORE_DATA_INDEX_length 0x00000003
+
+struct GEN7_MI_STORE_DATA_INDEX {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     Offset;
+   uint32_t                                     DataDWord0;
+   uint32_t                                     DataDWord1;
+};
+
+static inline void
+GEN7_MI_STORE_DATA_INDEX_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_MI_STORE_DATA_INDEX * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Offset, 2, 11) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DataDWord1, 0, 31) |
+      0;
+
+}
+
+#define GEN7_MI_SUSPEND_FLUSH_length_bias 0x00000001
+#define GEN7_MI_SUSPEND_FLUSH_header            \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 11
+
+#define GEN7_MI_SUSPEND_FLUSH_length 0x00000001
+
+struct GEN7_MI_SUSPEND_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         SuspendFlush;
+};
+
+static inline void
+GEN7_MI_SUSPEND_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN7_MI_SUSPEND_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->SuspendFlush, 0, 0) |
+      0;
+
+}
+
+#define GEN7_MI_TOPOLOGY_FILTER_length_bias 0x00000001
+#define GEN7_MI_TOPOLOGY_FILTER_header          \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 13
+
+#define GEN7_MI_TOPOLOGY_FILTER_length 0x00000001
+
+struct GEN7_MI_TOPOLOGY_FILTER {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     TopologyFilterValue;
+};
+
+static inline void
+GEN7_MI_TOPOLOGY_FILTER_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN7_MI_TOPOLOGY_FILTER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->TopologyFilterValue, 0, 5) |
+      0;
+
+}
+
+#define GEN7_MI_UPDATE_GTT_length_bias 0x00000002
+#define GEN7_MI_UPDATE_GTT_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 35
+
+#define GEN7_MI_UPDATE_GTT_length 0x00000000
+
+struct GEN7_MI_UPDATE_GTT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           EntryAddress;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN7_MI_UPDATE_GTT_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN7_MI_UPDATE_GTT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->EntryAddress, dw1);
+
+   /* variable length fields follow */
+}
+
+#define GEN7_MI_URB_CLEAR_length_bias 0x00000002
+#define GEN7_MI_URB_CLEAR_header                \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 25,                  \
+   .DwordLength          =  0
+
+#define GEN7_MI_URB_CLEAR_length 0x00000002
+
+struct GEN7_MI_URB_CLEAR {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBClearLength;
+   uint32_t                                     URBAddress;
+};
+
+static inline void
+GEN7_MI_URB_CLEAR_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_MI_URB_CLEAR * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBClearLength, 16, 28) |
+      __gen_offset(values->URBAddress, 0, 13) |
+      0;
+
+}
+
+#define GEN7_MI_USER_INTERRUPT_length_bias 0x00000001
+#define GEN7_MI_USER_INTERRUPT_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  2
+
+#define GEN7_MI_USER_INTERRUPT_length 0x00000001
+
+struct GEN7_MI_USER_INTERRUPT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN7_MI_USER_INTERRUPT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_MI_USER_INTERRUPT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN7_MI_WAIT_FOR_EVENT_length_bias 0x00000001
+#define GEN7_MI_WAIT_FOR_EVENT_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  3
+
+#define GEN7_MI_WAIT_FOR_EVENT_length 0x00000001
+
+struct GEN7_MI_WAIT_FOR_EVENT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         DisplayPipeCHorizontalBlankWaitEnable;
+   bool                                         DisplayPipeCVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteCFlipPendingWaitEnable;
+#define     Notenabled                                         0
+   uint32_t                                     ConditionCodeWaitSelect;
+   bool                                         DisplayPlaneCFlipPendingWaitEnable;
+   bool                                         DisplayPipeCScanLineWaitEnable;
+   bool                                         DisplayPipeBHorizontalBlankWaitEnable;
+   bool                                         DisplayPipeBVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteBFlipPendingWaitEnable;
+   bool                                         DisplayPlaneBFlipPendingWaitEnable;
+   bool                                         DisplayPipeBScanLineWaitEnable;
+   bool                                         DisplayPipeAHorizontalBlankWaitEnable;
+   bool                                         DisplayPipeAVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteAFlipPendingWaitEnable;
+   bool                                         DisplayPlaneAFlipPendingWaitEnable;
+   bool                                         DisplayPipeAScanLineWaitEnable;
+};
+
+static inline void
+GEN7_MI_WAIT_FOR_EVENT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN7_MI_WAIT_FOR_EVENT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPipeCHorizontalBlankWaitEnable, 22, 22) |
+      __gen_field(values->DisplayPipeCVerticalBlankWaitEnable, 21, 21) |
+      __gen_field(values->DisplaySpriteCFlipPendingWaitEnable, 20, 20) |
+      __gen_field(values->ConditionCodeWaitSelect, 16, 19) |
+      __gen_field(values->DisplayPlaneCFlipPendingWaitEnable, 15, 15) |
+      __gen_field(values->DisplayPipeCScanLineWaitEnable, 14, 14) |
+      __gen_field(values->DisplayPipeBHorizontalBlankWaitEnable, 13, 13) |
+      __gen_field(values->DisplayPipeBVerticalBlankWaitEnable, 11, 11) |
+      __gen_field(values->DisplaySpriteBFlipPendingWaitEnable, 10, 10) |
+      __gen_field(values->DisplayPlaneBFlipPendingWaitEnable, 9, 9) |
+      __gen_field(values->DisplayPipeBScanLineWaitEnable, 8, 8) |
+      __gen_field(values->DisplayPipeAHorizontalBlankWaitEnable, 5, 5) |
+      __gen_field(values->DisplayPipeAVerticalBlankWaitEnable, 3, 3) |
+      __gen_field(values->DisplaySpriteAFlipPendingWaitEnable, 2, 2) |
+      __gen_field(values->DisplayPlaneAFlipPendingWaitEnable, 1, 1) |
+      __gen_field(values->DisplayPipeAScanLineWaitEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN7_PIPE_CONTROL_length_bias 0x00000002
+#define GEN7_PIPE_CONTROL_header                \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  2,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  3
+
+#define GEN7_PIPE_CONTROL_length 0x00000005
+
+struct GEN7_PIPE_CONTROL {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     DAT_PPGTT                                          0
+#define     DAT_GGTT                                           1
+   uint32_t                                     DestinationAddressType;
+#define     NoLRIOperation                                     0
+#define     MMIOWriteImmediateData                             1
+   uint32_t                                     LRIPostSyncOperation;
+   uint32_t                                     StoreDataIndex;
+   uint32_t                                     CommandStreamerStallEnable;
+#define     DontReset                                          0
+#define     Reset                                              1
+   uint32_t                                     GlobalSnapshotCountReset;
+   uint32_t                                     TLBInvalidate;
+   bool                                         GenericMediaStateClear;
+#define     NoWrite                                            0
+#define     WriteImmediateData                                 1
+#define     WritePSDepthCount                                  2
+#define     WriteTimestamp                                     3
+   uint32_t                                     PostSyncOperation;
+   bool                                         DepthStallEnable;
+#define     DisableFlush                                       0
+#define     EnableFlush                                        1
+   bool                                         RenderTargetCacheFlushEnable;
+   bool                                         InstructionCacheInvalidateEnable;
+   bool                                         TextureCacheInvalidationEnable;
+   bool                                         IndirectStatePointersDisable;
+   bool                                         NotifyEnable;
+   bool                                         PipeControlFlushEnable;
+   bool                                         DCFlushEnable;
+   bool                                         VFCacheInvalidationEnable;
+   bool                                         ConstantCacheInvalidationEnable;
+   bool                                         StateCacheInvalidationEnable;
+   bool                                         StallAtPixelScoreboard;
+#define     FlushDisabled                                      0
+#define     FlushEnabled                                       1
+   bool                                         DepthCacheFlushEnable;
+   __gen_address_type                           Address;
+   uint32_t                                     ImmediateData;
+   uint32_t                                     ImmediateData0;
+};
+
+static inline void
+GEN7_PIPE_CONTROL_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_PIPE_CONTROL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DestinationAddressType, 24, 24) |
+      __gen_field(values->LRIPostSyncOperation, 23, 23) |
+      __gen_field(values->StoreDataIndex, 21, 21) |
+      __gen_field(values->CommandStreamerStallEnable, 20, 20) |
+      __gen_field(values->GlobalSnapshotCountReset, 19, 19) |
+      __gen_field(values->TLBInvalidate, 18, 18) |
+      __gen_field(values->GenericMediaStateClear, 16, 16) |
+      __gen_field(values->PostSyncOperation, 14, 15) |
+      __gen_field(values->DepthStallEnable, 13, 13) |
+      __gen_field(values->RenderTargetCacheFlushEnable, 12, 12) |
+      __gen_field(values->InstructionCacheInvalidateEnable, 11, 11) |
+      __gen_field(values->TextureCacheInvalidationEnable, 10, 10) |
+      __gen_field(values->IndirectStatePointersDisable, 9, 9) |
+      __gen_field(values->NotifyEnable, 8, 8) |
+      __gen_field(values->PipeControlFlushEnable, 7, 7) |
+      __gen_field(values->DCFlushEnable, 5, 5) |
+      __gen_field(values->VFCacheInvalidationEnable, 4, 4) |
+      __gen_field(values->ConstantCacheInvalidationEnable, 3, 3) |
+      __gen_field(values->StateCacheInvalidationEnable, 2, 2) |
+      __gen_field(values->StallAtPixelScoreboard, 1, 1) |
+      __gen_field(values->DepthCacheFlushEnable, 0, 0) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   dw[2] =
+      __gen_combine_address(data, &dw[2], values->Address, dw2);
+
+   dw[3] =
+      __gen_field(values->ImmediateData, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ImmediateData, 0, 31) |
+      0;
+
+}
+
+#define GEN7_SCISSOR_RECT_length 0x00000002
+
+struct GEN7_SCISSOR_RECT {
+   uint32_t                                     ScissorRectangleYMin;
+   uint32_t                                     ScissorRectangleXMin;
+   uint32_t                                     ScissorRectangleYMax;
+   uint32_t                                     ScissorRectangleXMax;
+};
+
+static inline void
+GEN7_SCISSOR_RECT_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN7_SCISSOR_RECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ScissorRectangleYMin, 16, 31) |
+      __gen_field(values->ScissorRectangleXMin, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ScissorRectangleYMax, 16, 31) |
+      __gen_field(values->ScissorRectangleXMax, 0, 15) |
+      0;
+
+}
+
+#define GEN7_SF_CLIP_VIEWPORT_length 0x00000010
+
+struct GEN7_SF_CLIP_VIEWPORT {
+   float                                        ViewportMatrixElementm00;
+   float                                        ViewportMatrixElementm11;
+   float                                        ViewportMatrixElementm22;
+   float                                        ViewportMatrixElementm30;
+   float                                        ViewportMatrixElementm31;
+   float                                        ViewportMatrixElementm32;
+   float                                        XMinClipGuardband;
+   float                                        XMaxClipGuardband;
+   float                                        YMinClipGuardband;
+   float                                        YMaxClipGuardband;
+};
+
+static inline void
+GEN7_SF_CLIP_VIEWPORT_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN7_SF_CLIP_VIEWPORT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->ViewportMatrixElementm00) |
+      0;
+
+   dw[1] =
+      __gen_float(values->ViewportMatrixElementm11) |
+      0;
+
+   dw[2] =
+      __gen_float(values->ViewportMatrixElementm22) |
+      0;
+
+   dw[3] =
+      __gen_float(values->ViewportMatrixElementm30) |
+      0;
+
+   dw[4] =
+      __gen_float(values->ViewportMatrixElementm31) |
+      0;
+
+   dw[5] =
+      __gen_float(values->ViewportMatrixElementm32) |
+      0;
+
+   dw[6] =
+      0;
+
+   dw[7] =
+      0;
+
+   dw[8] =
+      __gen_float(values->XMinClipGuardband) |
+      0;
+
+   dw[9] =
+      __gen_float(values->XMaxClipGuardband) |
+      0;
+
+   dw[10] =
+      __gen_float(values->YMinClipGuardband) |
+      0;
+
+   dw[11] =
+      __gen_float(values->YMaxClipGuardband) |
+      0;
+
+   for (uint32_t i = 0, j = 12; i < 4; i += 1, j++) {
+      dw[j] =
+         0;
+   }
+
+}
+
+#define GEN7_BLEND_STATE_length 0x00000002
+
+struct GEN7_BLEND_STATE {
+   bool                                         ColorBufferBlendEnable;
+   bool                                         IndependentAlphaBlendEnable;
+#define     BLENDFUNCTION_ADD                                  0
+#define     BLENDFUNCTION_SUBTRACT                             1
+#define     BLENDFUNCTION_REVERSE_SUBTRACT                     2
+#define     BLENDFUNCTION_MIN                                  3
+#define     BLENDFUNCTION_MAX                                  4
+   uint32_t                                     AlphaBlendFunction;
+#define     BLENDFACTOR_ONE                                    1
+#define     BLENDFACTOR_SRC_COLOR                              2
+#define     BLENDFACTOR_SRC_ALPHA                              3
+#define     BLENDFACTOR_DST_ALPHA                              4
+#define     BLENDFACTOR_DST_COLOR                              5
+#define     BLENDFACTOR_SRC_ALPHA_SATURATE                     6
+#define     BLENDFACTOR_CONST_COLOR                            7
+#define     BLENDFACTOR_CONST_ALPHA                            8
+#define     BLENDFACTOR_SRC1_COLOR                             9
+#define     BLENDFACTOR_SRC1_ALPHA                            10
+#define     BLENDFACTOR_ZERO                                  17
+#define     BLENDFACTOR_INV_SRC_COLOR                         18
+#define     BLENDFACTOR_INV_SRC_ALPHA                         19
+#define     BLENDFACTOR_INV_DST_ALPHA                         20
+#define     BLENDFACTOR_INV_DST_COLOR                         21
+#define     BLENDFACTOR_INV_CONST_COLOR                       23
+#define     BLENDFACTOR_INV_CONST_ALPHA                       24
+#define     BLENDFACTOR_INV_SRC1_COLOR                        25
+#define     BLENDFACTOR_INV_SRC1_ALPHA                        26
+   uint32_t                                     SourceAlphaBlendFactor;
+   uint32_t                                     DestinationAlphaBlendFactor;
+#define     BLENDFUNCTION_ADD                                  0
+#define     BLENDFUNCTION_SUBTRACT                             1
+#define     BLENDFUNCTION_REVERSE_SUBTRACT                     2
+#define     BLENDFUNCTION_MIN                                  3
+#define     BLENDFUNCTION_MAX                                  4
+   uint32_t                                     ColorBlendFunction;
+   uint32_t                                     SourceBlendFactor;
+   uint32_t                                     DestinationBlendFactor;
+   bool                                         AlphaToCoverageEnable;
+   bool                                         AlphaToOneEnable;
+   bool                                         AlphaToCoverageDitherEnable;
+   bool                                         WriteDisableAlpha;
+   bool                                         WriteDisableRed;
+   bool                                         WriteDisableGreen;
+   bool                                         WriteDisableBlue;
+   bool                                         LogicOpEnable;
+#define     LOGICOP_CLEAR                                      0
+#define     LOGICOP_NOR                                        1
+#define     LOGICOP_AND_INVERTED                               2
+#define     LOGICOP_COPY_INVERTED                              3
+#define     LOGICOP_AND_REVERSE                                4
+#define     LOGICOP_INVERT                                     5
+#define     LOGICOP_XOR                                        6
+#define     LOGICOP_NAND                                       7
+#define     LOGICOP_AND                                        8
+#define     LOGICOP_EQUIV                                      9
+#define     LOGICOP_NOOP                                      10
+#define     LOGICOP_OR_INVERTED                               11
+#define     LOGICOP_COPY                                      12
+#define     LOGICOP_OR_REVERSE                                13
+#define     LOGICOP_OR                                        14
+#define     LOGICOP_SET                                       15
+   uint32_t                                     LogicOpFunction;
+   bool                                         AlphaTestEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     AlphaTestFunction;
+   bool                                         ColorDitherEnable;
+   uint32_t                                     XDitherOffset;
+   uint32_t                                     YDitherOffset;
+#define     COLORCLAMP_UNORM                                   0
+#define     COLORCLAMP_SNORM                                   1
+#define     COLORCLAMP_RTFORMAT                                2
+   uint32_t                                     ColorClampRange;
+   bool                                         PreBlendColorClampEnable;
+   bool                                         PostBlendColorClampEnable;
+};
+
+static inline void
+GEN7_BLEND_STATE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN7_BLEND_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ColorBufferBlendEnable, 31, 31) |
+      __gen_field(values->IndependentAlphaBlendEnable, 30, 30) |
+      __gen_field(values->AlphaBlendFunction, 26, 28) |
+      __gen_field(values->SourceAlphaBlendFactor, 20, 24) |
+      __gen_field(values->DestinationAlphaBlendFactor, 15, 19) |
+      __gen_field(values->ColorBlendFunction, 11, 13) |
+      __gen_field(values->SourceBlendFactor, 5, 9) |
+      __gen_field(values->DestinationBlendFactor, 0, 4) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AlphaToCoverageEnable, 31, 31) |
+      __gen_field(values->AlphaToOneEnable, 30, 30) |
+      __gen_field(values->AlphaToCoverageDitherEnable, 29, 29) |
+      __gen_field(values->WriteDisableAlpha, 27, 27) |
+      __gen_field(values->WriteDisableRed, 26, 26) |
+      __gen_field(values->WriteDisableGreen, 25, 25) |
+      __gen_field(values->WriteDisableBlue, 24, 24) |
+      __gen_field(values->LogicOpEnable, 22, 22) |
+      __gen_field(values->LogicOpFunction, 18, 21) |
+      __gen_field(values->AlphaTestEnable, 16, 16) |
+      __gen_field(values->AlphaTestFunction, 13, 15) |
+      __gen_field(values->ColorDitherEnable, 12, 12) |
+      __gen_field(values->XDitherOffset, 10, 11) |
+      __gen_field(values->YDitherOffset, 8, 9) |
+      __gen_field(values->ColorClampRange, 2, 3) |
+      __gen_field(values->PreBlendColorClampEnable, 1, 1) |
+      __gen_field(values->PostBlendColorClampEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN7_CC_VIEWPORT_length 0x00000002
+
+struct GEN7_CC_VIEWPORT {
+   float                                        MinimumDepth;
+   float                                        MaximumDepth;
+};
+
+static inline void
+GEN7_CC_VIEWPORT_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN7_CC_VIEWPORT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->MinimumDepth) |
+      0;
+
+   dw[1] =
+      __gen_float(values->MaximumDepth) |
+      0;
+
+}
+
+#define GEN7_COLOR_CALC_STATE_length 0x00000006
+
+struct GEN7_COLOR_CALC_STATE {
+   uint32_t                                     StencilReferenceValue;
+   uint32_t                                     BackFaceStencilReferenceValue;
+#define     Cancelled                                          0
+#define     NotCancelled                                       1
+   uint32_t                                     RoundDisableFunctionDisable;
+#define     ALPHATEST_UNORM8                                   0
+#define     ALPHATEST_FLOAT32                                  1
+   uint32_t                                     AlphaTestFormat;
+   uint32_t                                     AlphaReferenceValueAsUNORM8;
+   float                                        AlphaReferenceValueAsFLOAT32;
+   float                                        BlendConstantColorRed;
+   float                                        BlendConstantColorGreen;
+   float                                        BlendConstantColorBlue;
+   float                                        BlendConstantColorAlpha;
+};
+
+static inline void
+GEN7_COLOR_CALC_STATE_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN7_COLOR_CALC_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->StencilReferenceValue, 24, 31) |
+      __gen_field(values->BackFaceStencilReferenceValue, 16, 23) |
+      __gen_field(values->RoundDisableFunctionDisable, 15, 15) |
+      __gen_field(values->AlphaTestFormat, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AlphaReferenceValueAsUNORM8, 0, 31) |
+      __gen_float(values->AlphaReferenceValueAsFLOAT32) |
+      0;
+
+   dw[2] =
+      __gen_float(values->BlendConstantColorRed) |
+      0;
+
+   dw[3] =
+      __gen_float(values->BlendConstantColorGreen) |
+      0;
+
+   dw[4] =
+      __gen_float(values->BlendConstantColorBlue) |
+      0;
+
+   dw[5] =
+      __gen_float(values->BlendConstantColorAlpha) |
+      0;
+
+}
+
+#define GEN7_DEPTH_STENCIL_STATE_length 0x00000003
+
+struct GEN7_DEPTH_STENCIL_STATE {
+   bool                                         StencilTestEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     StencilTestFunction;
+#define     STENCILOP_KEEP                                     0
+#define     STENCILOP_ZERO                                     1
+#define     STENCILOP_REPLACE                                  2
+#define     STENCILOP_INCRSAT                                  3
+#define     STENCILOP_DECRSAT                                  4
+#define     STENCILOP_INCR                                     5
+#define     STENCILOP_DECR                                     6
+#define     STENCILOP_INVERT                                   7
+   uint32_t                                     StencilFailOp;
+   uint32_t                                     StencilPassDepthFailOp;
+   uint32_t                                     StencilPassDepthPassOp;
+   bool                                         StencilBufferWriteEnable;
+   bool                                         DoubleSidedStencilEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     BackFaceStencilTestFunction;
+#define     STENCILOP_KEEP                                     0
+#define     STENCILOP_ZERO                                     1
+#define     STENCILOP_REPLACE                                  2
+#define     STENCILOP_INCRSAT                                  3
+#define     STENCILOP_DECRSAT                                  4
+#define     STENCILOP_INCR                                     5
+#define     STENCILOP_DECR                                     6
+#define     STENCILOP_INVERT                                   7
+   uint32_t                                     BackfaceStencilFailOp;
+   uint32_t                                     BackfaceStencilPassDepthFailOp;
+   uint32_t                                     BackfaceStencilPassDepthPassOp;
+   uint32_t                                     StencilTestMask;
+   uint32_t                                     StencilWriteMask;
+   uint32_t                                     BackfaceStencilTestMask;
+   uint32_t                                     BackfaceStencilWriteMask;
+   bool                                         DepthTestEnable;
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+   uint32_t                                     DepthTestFunction;
+   bool                                         DepthBufferWriteEnable;
+};
+
+static inline void
+GEN7_DEPTH_STENCIL_STATE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_DEPTH_STENCIL_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->StencilTestEnable, 31, 31) |
+      __gen_field(values->StencilTestFunction, 28, 30) |
+      __gen_field(values->StencilFailOp, 25, 27) |
+      __gen_field(values->StencilPassDepthFailOp, 22, 24) |
+      __gen_field(values->StencilPassDepthPassOp, 19, 21) |
+      __gen_field(values->StencilBufferWriteEnable, 18, 18) |
+      __gen_field(values->DoubleSidedStencilEnable, 15, 15) |
+      __gen_field(values->BackFaceStencilTestFunction, 12, 14) |
+      __gen_field(values->BackfaceStencilFailOp, 9, 11) |
+      __gen_field(values->BackfaceStencilPassDepthFailOp, 6, 8) |
+      __gen_field(values->BackfaceStencilPassDepthPassOp, 3, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StencilTestMask, 24, 31) |
+      __gen_field(values->StencilWriteMask, 16, 23) |
+      __gen_field(values->BackfaceStencilTestMask, 8, 15) |
+      __gen_field(values->BackfaceStencilWriteMask, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DepthTestEnable, 31, 31) |
+      __gen_field(values->DepthTestFunction, 27, 29) |
+      __gen_field(values->DepthBufferWriteEnable, 26, 26) |
+      0;
+
+}
+
+#define GEN7_INTERFACE_DESCRIPTOR_DATA_length 0x00000008
+
+struct GEN7_INTERFACE_DESCRIPTOR_DATA {
+   uint32_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleProgramFlow;
+#define     NormalPriority                                     0
+#define     HighPriority                                       1
+   uint32_t                                     ThreadPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     SamplerStatePointer;
+#define     Nosamplersused                                     0
+#define     Between1and4samplersused                           1
+#define     Between5and8samplersused                           2
+#define     Between9and12samplersused                          3
+#define     Between13and16samplersused                         4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTablePointer;
+   uint32_t                                     BindingTableEntryCount;
+   uint32_t                                     ConstantURBEntryReadLength;
+   uint32_t                                     ConstantURBEntryReadOffset;
+#define     RTNE                                               0
+#define     RU                                                 1
+#define     RD                                                 2
+#define     RTZ                                                3
+   uint32_t                                     RoundingMode;
+   bool                                         BarrierEnable;
+   uint32_t                                     SharedLocalMemorySize;
+   uint32_t                                     NumberofThreadsinGPGPUThreadGroup;
+};
+
+static inline void
+GEN7_INTERFACE_DESCRIPTOR_DATA_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN7_INTERFACE_DESCRIPTOR_DATA * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SingleProgramFlow, 18, 18) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->SamplerStatePointer, 5, 31) |
+      __gen_field(values->SamplerCount, 2, 4) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->BindingTablePointer, 5, 15) |
+      __gen_field(values->BindingTableEntryCount, 0, 4) |
+      0;
+
+   dw[4] =
+      __gen_field(values->ConstantURBEntryReadLength, 16, 31) |
+      __gen_field(values->ConstantURBEntryReadOffset, 0, 15) |
+      0;
+
+   dw[5] =
+      __gen_field(values->RoundingMode, 22, 23) |
+      __gen_field(values->BarrierEnable, 21, 21) |
+      __gen_field(values->SharedLocalMemorySize, 16, 20) |
+      __gen_field(values->NumberofThreadsinGPGPUThreadGroup, 0, 7) |
+      0;
+
+   dw[6] =
+      0;
+
+   dw[7] =
+      0;
+
+}
+
+#define GEN7_BINDING_TABLE_STATE_length 0x00000001
+
+struct GEN7_BINDING_TABLE_STATE {
+   uint32_t                                     SurfaceStatePointer;
+};
+
+static inline void
+GEN7_BINDING_TABLE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN7_BINDING_TABLE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->SurfaceStatePointer, 5, 31) |
+      0;
+
+}
+
+#define GEN7_RENDER_SURFACE_STATE_length 0x00000008
+
+struct GEN7_RENDER_SURFACE_STATE {
+#define     SURFTYPE_1D                                        0
+#define     SURFTYPE_2D                                        1
+#define     SURFTYPE_3D                                        2
+#define     SURFTYPE_CUBE                                      3
+#define     SURFTYPE_BUFFER                                    4
+#define     SURFTYPE_STRBUF                                    5
+#define     SURFTYPE_NULL                                      7
+   uint32_t                                     SurfaceType;
+   bool                                         SurfaceArray;
+   uint32_t                                     SurfaceFormat;
+#define     VALIGN_2                                           0
+#define     VALIGN_4                                           1
+   uint32_t                                     SurfaceVerticalAlignment;
+#define     HALIGN_4                                           0
+#define     HALIGN_8                                           1
+   uint32_t                                     SurfaceHorizontalAlignment;
+   uint32_t                                     TiledSurface;
+#define     TILEWALK_XMAJOR                                    0
+#define     TILEWALK_YMAJOR                                    1
+   uint32_t                                     TileWalk;
+   uint32_t                                     VerticalLineStride;
+   uint32_t                                     VerticalLineStrideOffset;
+#define     ARYSPC_FULL                                        0
+#define     ARYSPC_LOD0                                        1
+   uint32_t                                     SurfaceArraySpacing;
+   uint32_t                                     RenderCacheReadWriteMode;
+#define     NORMAL_MODE                                        0
+#define     PROGRESSIVE_FRAME                                  2
+#define     INTERLACED_FRAME                                   3
+   uint32_t                                     MediaBoundaryPixelMode;
+   uint32_t                                     CubeFaceEnables;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     Height;
+   uint32_t                                     Width;
+   uint32_t                                     Depth;
+   uint32_t                                     SurfacePitch;
+#define     RTROTATE_0DEG                                      0
+#define     RTROTATE_90DEG                                     1
+#define     RTROTATE_270DEG                                    3
+   uint32_t                                     RenderTargetRotation;
+   uint32_t                                     MinimumArrayElement;
+   uint32_t                                     RenderTargetViewExtent;
+#define     MSFMT_MSS                                          0
+#define     MSFMT_DEPTH_STENCIL                                1
+   uint32_t                                     MultisampledSurfaceStorageFormat;
+#define     MULTISAMPLECOUNT_1                                 0
+#define     MULTISAMPLECOUNT_4                                 2
+#define     MULTISAMPLECOUNT_8                                 3
+   uint32_t                                     NumberofMultisamples;
+   uint32_t                                     MultisamplePositionPaletteIndex;
+   uint32_t                                     MinimumArrayElement0;
+   uint32_t                                     XOffset;
+   uint32_t                                     YOffset;
+   struct GEN7_MEMORY_OBJECT_CONTROL_STATE      SurfaceObjectControlState;
+   uint32_t                                     SurfaceMinLOD;
+   uint32_t                                     MIPCountLOD;
+   __gen_address_type                           MCSBaseAddress;
+   uint32_t                                     MCSSurfacePitch;
+   __gen_address_type                           AppendCounterAddress;
+   bool                                         AppendCounterEnable;
+   bool                                         MCSEnable;
+   uint32_t                                     XOffsetforUVPlane;
+   uint32_t                                     YOffsetforUVPlane;
+#define     CC_ZERO                                            0
+#define     CC_ONE                                             1
+   uint32_t                                     RedClearColor;
+#define     CC_ZERO                                            0
+#define     CC_ONE                                             1
+   uint32_t                                     GreenClearColor;
+#define     CC_ZERO                                            0
+#define     CC_ONE                                             1
+   uint32_t                                     BlueClearColor;
+#define     CC_ZERO                                            0
+#define     CC_ONE                                             1
+   uint32_t                                     AlphaClearColor;
+   float                                        ResourceMinLOD;
+};
+
+static inline void
+GEN7_RENDER_SURFACE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN7_RENDER_SURFACE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->SurfaceType, 29, 31) |
+      __gen_field(values->SurfaceArray, 28, 28) |
+      __gen_field(values->SurfaceFormat, 18, 26) |
+      __gen_field(values->SurfaceVerticalAlignment, 16, 17) |
+      __gen_field(values->SurfaceHorizontalAlignment, 15, 15) |
+      __gen_field(values->TiledSurface, 14, 14) |
+      __gen_field(values->TileWalk, 13, 13) |
+      __gen_field(values->VerticalLineStride, 12, 12) |
+      __gen_field(values->VerticalLineStrideOffset, 11, 11) |
+      __gen_field(values->SurfaceArraySpacing, 10, 10) |
+      __gen_field(values->RenderCacheReadWriteMode, 8, 8) |
+      __gen_field(values->MediaBoundaryPixelMode, 6, 7) |
+      __gen_field(values->CubeFaceEnables, 0, 5) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->SurfaceBaseAddress, dw1);
+
+   dw[2] =
+      __gen_field(values->Height, 16, 29) |
+      __gen_field(values->Width, 0, 13) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Depth, 21, 31) |
+      __gen_field(values->SurfacePitch, 0, 17) |
+      0;
+
+   dw[4] =
+      __gen_field(values->RenderTargetRotation, 29, 30) |
+      __gen_field(values->MinimumArrayElement, 18, 28) |
+      __gen_field(values->RenderTargetViewExtent, 7, 17) |
+      __gen_field(values->MultisampledSurfaceStorageFormat, 6, 6) |
+      __gen_field(values->NumberofMultisamples, 3, 5) |
+      __gen_field(values->MultisamplePositionPaletteIndex, 0, 2) |
+      __gen_field(values->MinimumArrayElement, 0, 26) |
+      0;
+
+   uint32_t dw_SurfaceObjectControlState;
+   GEN7_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceObjectControlState, &values->SurfaceObjectControlState);
+   dw[5] =
+      __gen_offset(values->XOffset, 25, 31) |
+      __gen_offset(values->YOffset, 20, 23) |
+      __gen_field(dw_SurfaceObjectControlState, 16, 19) |
+      __gen_field(values->SurfaceMinLOD, 4, 7) |
+      __gen_field(values->MIPCountLOD, 0, 3) |
+      0;
+
+   uint32_t dw6 =
+      __gen_field(values->MCSSurfacePitch, 3, 11) |
+      __gen_field(values->AppendCounterEnable, 1, 1) |
+      __gen_field(values->MCSEnable, 0, 0) |
+      __gen_field(values->XOffsetforUVPlane, 16, 29) |
+      __gen_field(values->YOffsetforUVPlane, 0, 13) |
+      0;
+
+   dw[6] =
+      __gen_combine_address(data, &dw[6], values->AppendCounterAddress, dw6);
+
+   dw[7] =
+      __gen_field(values->RedClearColor, 31, 31) |
+      __gen_field(values->GreenClearColor, 30, 30) |
+      __gen_field(values->BlueClearColor, 29, 29) |
+      __gen_field(values->AlphaClearColor, 28, 28) |
+      __gen_field(values->ResourceMinLOD * (1 << 8), 0, 11) |
+      0;
+
+}
+
+#define GEN7_SAMPLER_BORDER_COLOR_STATE_length 0x00000004
+
+struct GEN7_SAMPLER_BORDER_COLOR_STATE {
+   float                                        BorderColorRedDX100GL;
+   uint32_t                                     BorderColorAlpha;
+   uint32_t                                     BorderColorBlue;
+   uint32_t                                     BorderColorGreen;
+   uint32_t                                     BorderColorRedDX9;
+   float                                        BorderColorGreen0;
+   float                                        BorderColorBlue0;
+   float                                        BorderColorAlpha0;
+};
+
+static inline void
+GEN7_SAMPLER_BORDER_COLOR_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN7_SAMPLER_BORDER_COLOR_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->BorderColorRedDX100GL) |
+      __gen_field(values->BorderColorAlpha, 24, 31) |
+      __gen_field(values->BorderColorBlue, 16, 23) |
+      __gen_field(values->BorderColorGreen, 8, 15) |
+      __gen_field(values->BorderColorRedDX9, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_float(values->BorderColorGreen) |
+      0;
+
+   dw[2] =
+      __gen_float(values->BorderColorBlue) |
+      0;
+
+   dw[3] =
+      __gen_float(values->BorderColorAlpha) |
+      0;
+
+}
+
+#define GEN7_SAMPLER_STATE_length 0x00000004
+
+struct GEN7_SAMPLER_STATE {
+   bool                                         SamplerDisable;
+#define     DX10OGL                                            0
+#define     DX9                                                1
+   uint32_t                                     TextureBorderColorMode;
+#define     OGL                                                1
+   uint32_t                                     LODPreClampEnable;
+   float                                        BaseMipLevel;
+#define     MIPFILTER_NONE                                     0
+#define     MIPFILTER_NEAREST                                  1
+#define     MIPFILTER_LINEAR                                   3
+   uint32_t                                     MipModeFilter;
+#define     MAPFILTER_NEAREST                                  0
+#define     MAPFILTER_LINEAR                                   1
+#define     MAPFILTER_ANISOTROPIC                              2
+#define     MAPFILTER_MONO                                     6
+   uint32_t                                     MagModeFilter;
+#define     MAPFILTER_NEAREST                                  0
+#define     MAPFILTER_LINEAR                                   1
+#define     MAPFILTER_ANISOTROPIC                              2
+#define     MAPFILTER_MONO                                     6
+   uint32_t                                     MinModeFilter;
+   uint32_t                                     TextureLODBias;
+#define     LEGACY                                             0
+#define     EWAApproximation                                   1
+   uint32_t                                     AnisotropicAlgorithm;
+   float                                        MinLOD;
+   float                                        MaxLOD;
+#define     PREFILTEROPALWAYS                                  0
+#define     PREFILTEROPNEVER                                   1
+#define     PREFILTEROPLESS                                    2
+#define     PREFILTEROPEQUAL                                   3
+#define     PREFILTEROPLEQUAL                                  4
+#define     PREFILTEROPGREATER                                 5
+#define     PREFILTEROPNOTEQUAL                                6
+#define     PREFILTEROPGEQUAL                                  7
+   uint32_t                                     ShadowFunction;
+#define     PROGRAMMED                                         0
+#define     OVERRIDE                                           1
+   uint32_t                                     CubeSurfaceControlMode;
+   uint32_t                                     BorderColorPointer;
+   bool                                         ChromaKeyEnable;
+   uint32_t                                     ChromaKeyIndex;
+#define     KEYFILTER_KILL_ON_ANY_MATCH                        0
+#define     KEYFILTER_REPLACE_BLACK                            1
+   uint32_t                                     ChromaKeyMode;
+#define     RATIO21                                            0
+#define     RATIO41                                            1
+#define     RATIO61                                            2
+#define     RATIO81                                            3
+#define     RATIO101                                           4
+#define     RATIO121                                           5
+#define     RATIO141                                           6
+#define     RATIO161                                           7
+   uint32_t                                     MaximumAnisotropy;
+   bool                                         RAddressMinFilterRoundingEnable;
+   bool                                         RAddressMagFilterRoundingEnable;
+   bool                                         VAddressMinFilterRoundingEnable;
+   bool                                         VAddressMagFilterRoundingEnable;
+   bool                                         UAddressMinFilterRoundingEnable;
+   bool                                         UAddressMagFilterRoundingEnable;
+#define     FULL                                               0
+#define     MED                                                2
+#define     LOW                                                3
+   uint32_t                                     TrilinearFilterQuality;
+   bool                                         NonnormalizedCoordinateEnable;
+   uint32_t                                     TCXAddressControlMode;
+   uint32_t                                     TCYAddressControlMode;
+   uint32_t                                     TCZAddressControlMode;
+};
+
+static inline void
+GEN7_SAMPLER_STATE_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN7_SAMPLER_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->SamplerDisable, 31, 31) |
+      __gen_field(values->TextureBorderColorMode, 29, 29) |
+      __gen_field(values->LODPreClampEnable, 28, 28) |
+      __gen_field(values->BaseMipLevel * (1 << 1), 22, 26) |
+      __gen_field(values->MipModeFilter, 20, 21) |
+      __gen_field(values->MagModeFilter, 17, 19) |
+      __gen_field(values->MinModeFilter, 14, 16) |
+      __gen_field(values->TextureLODBias, 1, 13) |
+      __gen_field(values->AnisotropicAlgorithm, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MinLOD * (1 << 8), 20, 31) |
+      __gen_field(values->MaxLOD * (1 << 8), 8, 19) |
+      __gen_field(values->ShadowFunction, 1, 3) |
+      __gen_field(values->CubeSurfaceControlMode, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->BorderColorPointer, 5, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ChromaKeyEnable, 25, 25) |
+      __gen_field(values->ChromaKeyIndex, 23, 24) |
+      __gen_field(values->ChromaKeyMode, 22, 22) |
+      __gen_field(values->MaximumAnisotropy, 19, 21) |
+      __gen_field(values->RAddressMinFilterRoundingEnable, 13, 13) |
+      __gen_field(values->RAddressMagFilterRoundingEnable, 14, 14) |
+      __gen_field(values->VAddressMinFilterRoundingEnable, 15, 15) |
+      __gen_field(values->VAddressMagFilterRoundingEnable, 16, 16) |
+      __gen_field(values->UAddressMinFilterRoundingEnable, 17, 17) |
+      __gen_field(values->UAddressMagFilterRoundingEnable, 18, 18) |
+      __gen_field(values->TrilinearFilterQuality, 11, 12) |
+      __gen_field(values->NonnormalizedCoordinateEnable, 10, 10) |
+      __gen_field(values->TCXAddressControlMode, 6, 8) |
+      __gen_field(values->TCYAddressControlMode, 3, 5) |
+      __gen_field(values->TCZAddressControlMode, 0, 2) |
+      0;
+
+}
+
+/* Enum 3D_Prim_Topo_Type */
+#define     _3DPRIM_POINTLIST                                  1
+#define     _3DPRIM_LINELIST                                   2
+#define     _3DPRIM_LINESTRIP                                  3
+#define     _3DPRIM_TRILIST                                    4
+#define     _3DPRIM_TRISTRIP                                   5
+#define     _3DPRIM_TRIFAN                                     6
+#define     _3DPRIM_QUADLIST                                   7
+#define     _3DPRIM_QUADSTRIP                                  8
+#define     _3DPRIM_LINELIST_ADJ                               9
+#define     _3DPRIM_LINESTRIP_ADJ                             10
+#define     _3DPRIM_TRILIST_ADJ                               11
+#define     _3DPRIM_TRISTRIP_ADJ                              12
+#define     _3DPRIM_TRISTRIP_REVERSE                          13
+#define     _3DPRIM_POLYGON                                   14
+#define     _3DPRIM_RECTLIST                                  15
+#define     _3DPRIM_LINELOOP                                  16
+#define     _3DPRIM_POINTLIST_BF                              17
+#define     _3DPRIM_LINESTRIP_CONT                            18
+#define     _3DPRIM_LINESTRIP_BF                              19
+#define     _3DPRIM_LINESTRIP_CONT_BF                         20
+#define     _3DPRIM_TRIFAN_NOSTIPPLE                          22
+#define     _3DPRIM_PATCHLIST_1                               32
+#define     _3DPRIM_PATCHLIST_2                               33
+#define     _3DPRIM_PATCHLIST_3                               34
+#define     _3DPRIM_PATCHLIST_4                               35
+#define     _3DPRIM_PATCHLIST_5                               36
+#define     _3DPRIM_PATCHLIST_6                               37
+#define     _3DPRIM_PATCHLIST_7                               38
+#define     _3DPRIM_PATCHLIST_8                               39
+#define     _3DPRIM_PATCHLIST_9                               40
+#define     _3DPRIM_PATCHLIST_10                              41
+#define     _3DPRIM_PATCHLIST_11                              42
+#define     _3DPRIM_PATCHLIST_12                              43
+#define     _3DPRIM_PATCHLIST_13                              44
+#define     _3DPRIM_PATCHLIST_14                              45
+#define     _3DPRIM_PATCHLIST_15                              46
+#define     _3DPRIM_PATCHLIST_16                              47
+#define     _3DPRIM_PATCHLIST_17                              48
+#define     _3DPRIM_PATCHLIST_18                              49
+#define     _3DPRIM_PATCHLIST_19                              50
+#define     _3DPRIM_PATCHLIST_20                              51
+#define     _3DPRIM_PATCHLIST_21                              52
+#define     _3DPRIM_PATCHLIST_22                              53
+#define     _3DPRIM_PATCHLIST_23                              54
+#define     _3DPRIM_PATCHLIST_24                              55
+#define     _3DPRIM_PATCHLIST_25                              56
+#define     _3DPRIM_PATCHLIST_26                              57
+#define     _3DPRIM_PATCHLIST_27                              58
+#define     _3DPRIM_PATCHLIST_28                              59
+#define     _3DPRIM_PATCHLIST_29                              60
+#define     _3DPRIM_PATCHLIST_30                              61
+#define     _3DPRIM_PATCHLIST_31                              62
+#define     _3DPRIM_PATCHLIST_32                              63
+
+/* Enum 3D_Vertex_Component_Control */
+#define     VFCOMP_NOSTORE                                     0
+#define     VFCOMP_STORE_SRC                                   1
+#define     VFCOMP_STORE_0                                     2
+#define     VFCOMP_STORE_1_FP                                  3
+#define     VFCOMP_STORE_1_INT                                 4
+#define     VFCOMP_STORE_VID                                   5
+#define     VFCOMP_STORE_IID                                   6
+#define     VFCOMP_STORE_PID                                   7
+
+/* Enum 3D_Compare_Function */
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+
+/* Enum SURFACE_FORMAT */
+#define     R32G32B32A32_FLOAT                                 0
+#define     R32G32B32A32_SINT                                  1
+#define     R32G32B32A32_UINT                                  2
+#define     R32G32B32A32_UNORM                                 3
+#define     R32G32B32A32_SNORM                                 4
+#define     R64G64_FLOAT                                       5
+#define     R32G32B32X32_FLOAT                                 6
+#define     R32G32B32A32_SSCALED                               7
+#define     R32G32B32A32_USCALED                               8
+#define     R32G32B32A32_SFIXED                               32
+#define     R64G64_PASSTHRU                                   33
+#define     R32G32B32_FLOAT                                   64
+#define     R32G32B32_SINT                                    65
+#define     R32G32B32_UINT                                    66
+#define     R32G32B32_UNORM                                   67
+#define     R32G32B32_SNORM                                   68
+#define     R32G32B32_SSCALED                                 69
+#define     R32G32B32_USCALED                                 70
+#define     R32G32B32_SFIXED                                  80
+#define     R16G16B16A16_UNORM                               128
+#define     R16G16B16A16_SNORM                               129
+#define     R16G16B16A16_SINT                                130
+#define     R16G16B16A16_UINT                                131
+#define     R16G16B16A16_FLOAT                               132
+#define     R32G32_FLOAT                                     133
+#define     R32G32_SINT                                      134
+#define     R32G32_UINT                                      135
+#define     R32_FLOAT_X8X24_TYPELESS                         136
+#define     X32_TYPELESS_G8X24_UINT                          137
+#define     L32A32_FLOAT                                     138
+#define     R32G32_UNORM                                     139
+#define     R32G32_SNORM                                     140
+#define     R64_FLOAT                                        141
+#define     R16G16B16X16_UNORM                               142
+#define     R16G16B16X16_FLOAT                               143
+#define     A32X32_FLOAT                                     144
+#define     L32X32_FLOAT                                     145
+#define     I32X32_FLOAT                                     146
+#define     R16G16B16A16_SSCALED                             147
+#define     R16G16B16A16_USCALED                             148
+#define     R32G32_SSCALED                                   149
+#define     R32G32_USCALED                                   150
+#define     R32G32_SFIXED                                    160
+#define     R64_PASSTHRU                                     161
+#define     B8G8R8A8_UNORM                                   192
+#define     B8G8R8A8_UNORM_SRGB                              193
+#define     R10G10B10A2_UNORM                                194
+#define     R10G10B10A2_UNORM_SRGB                           195
+#define     R10G10B10A2_UINT                                 196
+#define     R10G10B10_SNORM_A2_UNORM                         197
+#define     R8G8B8A8_UNORM                                   199
+#define     R8G8B8A8_UNORM_SRGB                              200
+#define     R8G8B8A8_SNORM                                   201
+#define     R8G8B8A8_SINT                                    202
+#define     R8G8B8A8_UINT                                    203
+#define     R16G16_UNORM                                     204
+#define     R16G16_SNORM                                     205
+#define     R16G16_SINT                                      206
+#define     R16G16_UINT                                      207
+#define     R16G16_FLOAT                                     208
+#define     B10G10R10A2_UNORM                                209
+#define     B10G10R10A2_UNORM_SRGB                           210
+#define     R11G11B10_FLOAT                                  211
+#define     R32_SINT                                         214
+#define     R32_UINT                                         215
+#define     R32_FLOAT                                        216
+#define     R24_UNORM_X8_TYPELESS                            217
+#define     X24_TYPELESS_G8_UINT                             218
+#define     L32_UNORM                                        221
+#define     A32_UNORM                                        222
+#define     L16A16_UNORM                                     223
+#define     I24X8_UNORM                                      224
+#define     L24X8_UNORM                                      225
+#define     A24X8_UNORM                                      226
+#define     I32_FLOAT                                        227
+#define     L32_FLOAT                                        228
+#define     A32_FLOAT                                        229
+#define     X8B8_UNORM_G8R8_SNORM                            230
+#define     A8X8_UNORM_G8R8_SNORM                            231
+#define     B8X8_UNORM_G8R8_SNORM                            232
+#define     B8G8R8X8_UNORM                                   233
+#define     B8G8R8X8_UNORM_SRGB                              234
+#define     R8G8B8X8_UNORM                                   235
+#define     R8G8B8X8_UNORM_SRGB                              236
+#define     R9G9B9E5_SHAREDEXP                               237
+#define     B10G10R10X2_UNORM                                238
+#define     L16A16_FLOAT                                     240
+#define     R32_UNORM                                        241
+#define     R32_SNORM                                        242
+#define     R10G10B10X2_USCALED                              243
+#define     R8G8B8A8_SSCALED                                 244
+#define     R8G8B8A8_USCALED                                 245
+#define     R16G16_SSCALED                                   246
+#define     R16G16_USCALED                                   247
+#define     R32_SSCALED                                      248
+#define     R32_USCALED                                      249
+#define     B5G6R5_UNORM                                     256
+#define     B5G6R5_UNORM_SRGB                                257
+#define     B5G5R5A1_UNORM                                   258
+#define     B5G5R5A1_UNORM_SRGB                              259
+#define     B4G4R4A4_UNORM                                   260
+#define     B4G4R4A4_UNORM_SRGB                              261
+#define     R8G8_UNORM                                       262
+#define     R8G8_SNORM                                       263
+#define     R8G8_SINT                                        264
+#define     R8G8_UINT                                        265
+#define     R16_UNORM                                        266
+#define     R16_SNORM                                        267
+#define     R16_SINT                                         268
+#define     R16_UINT                                         269
+#define     R16_FLOAT                                        270
+#define     A8P8_UNORM_PALETTE0                              271
+#define     A8P8_UNORM_PALETTE1                              272
+#define     I16_UNORM                                        273
+#define     L16_UNORM                                        274
+#define     A16_UNORM                                        275
+#define     L8A8_UNORM                                       276
+#define     I16_FLOAT                                        277
+#define     L16_FLOAT                                        278
+#define     A16_FLOAT                                        279
+#define     L8A8_UNORM_SRGB                                  280
+#define     R5G5_SNORM_B6_UNORM                              281
+#define     B5G5R5X1_UNORM                                   282
+#define     B5G5R5X1_UNORM_SRGB                              283
+#define     R8G8_SSCALED                                     284
+#define     R8G8_USCALED                                     285
+#define     R16_SSCALED                                      286
+#define     R16_USCALED                                      287
+#define     P8A8_UNORM_PALETTE0                              290
+#define     P8A8_UNORM_PALETTE1                              291
+#define     A1B5G5R5_UNORM                                   292
+#define     A4B4G4R4_UNORM                                   293
+#define     L8A8_UINT                                        294
+#define     L8A8_SINT                                        295
+#define     R8_UNORM                                         320
+#define     R8_SNORM                                         321
+#define     R8_SINT                                          322
+#define     R8_UINT                                          323
+#define     A8_UNORM                                         324
+#define     I8_UNORM                                         325
+#define     L8_UNORM                                         326
+#define     P4A4_UNORM_PALETTE0                              327
+#define     A4P4_UNORM_PALETTE0                              328
+#define     R8_SSCALED                                       329
+#define     R8_USCALED                                       330
+#define     P8_UNORM_PALETTE0                                331
+#define     L8_UNORM_SRGB                                    332
+#define     P8_UNORM_PALETTE1                                333
+#define     P4A4_UNORM_PALETTE1                              334
+#define     A4P4_UNORM_PALETTE1                              335
+#define     Y8_UNORM                                         336
+#define     L8_UINT                                          338
+#define     L8_SINT                                          339
+#define     I8_UINT                                          340
+#define     I8_SINT                                          341
+#define     DXT1_RGB_SRGB                                    384
+#define     R1_UNORM                                         385
+#define     YCRCB_NORMAL                                     386
+#define     YCRCB_SWAPUVY                                    387
+#define     P2_UNORM_PALETTE0                                388
+#define     P2_UNORM_PALETTE1                                389
+#define     BC1_UNORM                                        390
+#define     BC2_UNORM                                        391
+#define     BC3_UNORM                                        392
+#define     BC4_UNORM                                        393
+#define     BC5_UNORM                                        394
+#define     BC1_UNORM_SRGB                                   395
+#define     BC2_UNORM_SRGB                                   396
+#define     BC3_UNORM_SRGB                                   397
+#define     MONO8                                            398
+#define     YCRCB_SWAPUV                                     399
+#define     YCRCB_SWAPY                                      400
+#define     DXT1_RGB                                         401
+#define     FXT1                                             402
+#define     R8G8B8_UNORM                                     403
+#define     R8G8B8_SNORM                                     404
+#define     R8G8B8_SSCALED                                   405
+#define     R8G8B8_USCALED                                   406
+#define     R64G64B64A64_FLOAT                               407
+#define     R64G64B64_FLOAT                                  408
+#define     BC4_SNORM                                        409
+#define     BC5_SNORM                                        410
+#define     R16G16B16_FLOAT                                  411
+#define     R16G16B16_UNORM                                  412
+#define     R16G16B16_SNORM                                  413
+#define     R16G16B16_SSCALED                                414
+#define     R16G16B16_USCALED                                415
+#define     BC6H_SF16                                        417
+#define     BC7_UNORM                                        418
+#define     BC7_UNORM_SRGB                                   419
+#define     BC6H_UF16                                        420
+#define     PLANAR_420_8                                     421
+#define     R8G8B8_UNORM_SRGB                                424
+#define     ETC1_RGB8                                        425
+#define     ETC2_RGB8                                        426
+#define     EAC_R11                                          427
+#define     EAC_RG11                                         428
+#define     EAC_SIGNED_R11                                   429
+#define     EAC_SIGNED_RG11                                  430
+#define     ETC2_SRGB8                                       431
+#define     R16G16B16_UINT                                   432
+#define     R16G16B16_SINT                                   433
+#define     R32_SFIXED                                       434
+#define     R10G10B10A2_SNORM                                435
+#define     R10G10B10A2_USCALED                              436
+#define     R10G10B10A2_SSCALED                              437
+#define     R10G10B10A2_SINT                                 438
+#define     B10G10R10A2_SNORM                                439
+#define     B10G10R10A2_USCALED                              440
+#define     B10G10R10A2_SSCALED                              441
+#define     B10G10R10A2_UINT                                 442
+#define     B10G10R10A2_SINT                                 443
+#define     R64G64B64A64_PASSTHRU                            444
+#define     R64G64B64_PASSTHRU                               445
+#define     ETC2_RGB8_PTA                                    448
+#define     ETC2_SRGB8_PTA                                   449
+#define     ETC2_EAC_RGBA8                                   450
+#define     ETC2_EAC_SRGB8_A8                                451
+#define     R8G8B8_UINT                                      456
+#define     R8G8B8_SINT                                      457
+#define     RAW                                              511
+
+/* Enum Texture Coordinate Mode */
+#define     TCM_WRAP                                           0
+#define     TCM_MIRROR                                         1
+#define     TCM_CLAMP                                          2
+#define     TCM_CUBE                                           3
+#define     TCM_CLAMP_BORDER                                   4
+#define     TCM_MIRROR_ONCE                                    5
+
diff --git a/src/vulkan/gen7_pipeline.c b/src/vulkan/gen7_pipeline.c
new file mode 100644 (file)
index 0000000..1fed33a
--- /dev/null
@@ -0,0 +1,597 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static void
+gen7_emit_vertex_input(struct anv_pipeline *pipeline,
+                       const VkPipelineVertexInputStateCreateInfo *info)
+{
+   const bool sgvs = pipeline->vs_prog_data.uses_vertexid ||
+      pipeline->vs_prog_data.uses_instanceid;
+   const uint32_t element_count = info->attributeCount + (sgvs ? 1 : 0);
+   const uint32_t num_dwords = 1 + element_count * 2;
+   uint32_t *p;
+
+   if (info->attributeCount == 0 && !sgvs)
+      return;
+
+   p = anv_batch_emitn(&pipeline->batch, num_dwords,
+                       GEN7_3DSTATE_VERTEX_ELEMENTS);
+
+   for (uint32_t i = 0; i < info->attributeCount; i++) {
+      const VkVertexInputAttributeDescription *desc =
+         &info->pVertexAttributeDescriptions[i];
+      const struct anv_format *format = anv_format_for_vk_format(desc->format);
+
+      struct GEN7_VERTEX_ELEMENT_STATE element = {
+         .VertexBufferIndex = desc->binding,
+         .Valid = true,
+         .SourceElementFormat = format->surface_format,
+         .EdgeFlagEnable = false,
+         .SourceElementOffset = desc->offsetInBytes,
+         .Component0Control = VFCOMP_STORE_SRC,
+         .Component1Control = format->num_channels >= 2 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
+         .Component2Control = format->num_channels >= 3 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
+         .Component3Control = format->num_channels >= 4 ? VFCOMP_STORE_SRC : VFCOMP_STORE_1_FP
+      };
+      GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + i * 2], &element);
+   }
+
+   if (sgvs) {
+      struct GEN7_VERTEX_ELEMENT_STATE element = {
+         .Valid = true,
+         /* FIXME: Do we need to provide the base vertex as component 0 here
+          * to support the correct base vertex ID? */
+         .Component0Control = VFCOMP_STORE_0,
+         .Component1Control = VFCOMP_STORE_0,
+         .Component2Control = VFCOMP_STORE_VID,
+         .Component3Control = VFCOMP_STORE_IID
+      };
+      GEN7_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + info->attributeCount * 2], &element);
+   }
+}
+
+static const uint32_t vk_to_gen_cullmode[] = {
+   [VK_CULL_MODE_NONE]                          = CULLMODE_NONE,
+   [VK_CULL_MODE_FRONT]                         = CULLMODE_FRONT,
+   [VK_CULL_MODE_BACK]                          = CULLMODE_BACK,
+   [VK_CULL_MODE_FRONT_AND_BACK]                = CULLMODE_BOTH
+};
+
+static const uint32_t vk_to_gen_fillmode[] = {
+   [VK_FILL_MODE_POINTS]                        = RASTER_POINT,
+   [VK_FILL_MODE_WIREFRAME]                     = RASTER_WIREFRAME,
+   [VK_FILL_MODE_SOLID]                         = RASTER_SOLID
+};
+
+static const uint32_t vk_to_gen_front_face[] = {
+   [VK_FRONT_FACE_CCW]                          = CounterClockwise,
+   [VK_FRONT_FACE_CW]                           = Clockwise
+};
+
+static void
+gen7_emit_rs_state(struct anv_pipeline *pipeline,
+                   const VkPipelineRasterStateCreateInfo *info,
+                   const struct anv_graphics_pipeline_create_info *extra)
+{
+   struct GEN7_3DSTATE_SF sf = {
+      GEN7_3DSTATE_SF_header,
+
+      /* FIXME: Get this from pass info */
+      .DepthBufferSurfaceFormat                 = D24_UNORM_X8_UINT,
+
+      /* LegacyGlobalDepthBiasEnable */
+
+      .StatisticsEnable                         = true,
+      .FrontFaceFillMode                        = vk_to_gen_fillmode[info->fillMode],
+      .BackFaceFillMode                         = vk_to_gen_fillmode[info->fillMode],
+      .ViewTransformEnable                      = !(extra && extra->disable_viewport),
+      .FrontWinding                             = vk_to_gen_front_face[info->frontFace],
+      /* bool                                         AntiAliasingEnable; */
+
+      .CullMode                                 = vk_to_gen_cullmode[info->cullMode],
+
+      /* uint32_t                                     LineEndCapAntialiasingRegionWidth; */
+      .ScissorRectangleEnable                   =  !(extra && extra->disable_scissor),
+
+      /* uint32_t                                     MultisampleRasterizationMode; */
+      /* bool                                         LastPixelEnable; */
+
+      .TriangleStripListProvokingVertexSelect   = 0,
+      .LineStripListProvokingVertexSelect       = 0,
+      .TriangleFanProvokingVertexSelect         = 0,
+
+      /* uint32_t                                     AALineDistanceMode; */
+      /* uint32_t                                     VertexSubPixelPrecisionSelect; */
+      .UsePointWidthState                       = !pipeline->writes_point_size,
+      .PointWidth                               = 1.0,
+   };
+
+   GEN7_3DSTATE_SF_pack(NULL, &pipeline->gen7.sf, &sf);
+}
+
+static const uint32_t vk_to_gen_compare_op[] = {
+   [VK_COMPARE_OP_NEVER]                        = PREFILTEROPNEVER,
+   [VK_COMPARE_OP_LESS]                         = PREFILTEROPLESS,
+   [VK_COMPARE_OP_EQUAL]                        = PREFILTEROPEQUAL,
+   [VK_COMPARE_OP_LESS_EQUAL]                   = PREFILTEROPLEQUAL,
+   [VK_COMPARE_OP_GREATER]                      = PREFILTEROPGREATER,
+   [VK_COMPARE_OP_NOT_EQUAL]                    = PREFILTEROPNOTEQUAL,
+   [VK_COMPARE_OP_GREATER_EQUAL]                = PREFILTEROPGEQUAL,
+   [VK_COMPARE_OP_ALWAYS]                       = PREFILTEROPALWAYS,
+};
+
+static const uint32_t vk_to_gen_stencil_op[] = {
+   [VK_STENCIL_OP_KEEP]                         = STENCILOP_KEEP,
+   [VK_STENCIL_OP_ZERO]                         = STENCILOP_ZERO,
+   [VK_STENCIL_OP_REPLACE]                      = STENCILOP_REPLACE,
+   [VK_STENCIL_OP_INC_CLAMP]                    = STENCILOP_INCRSAT,
+   [VK_STENCIL_OP_DEC_CLAMP]                    = STENCILOP_DECRSAT,
+   [VK_STENCIL_OP_INVERT]                       = STENCILOP_INVERT,
+   [VK_STENCIL_OP_INC_WRAP]                     = STENCILOP_INCR,
+   [VK_STENCIL_OP_DEC_WRAP]                     = STENCILOP_DECR,
+};
+
+static const uint32_t vk_to_gen_blend_op[] = {
+   [VK_BLEND_OP_ADD]                            = BLENDFUNCTION_ADD,
+   [VK_BLEND_OP_SUBTRACT]                       = BLENDFUNCTION_SUBTRACT,
+   [VK_BLEND_OP_REVERSE_SUBTRACT]               = BLENDFUNCTION_REVERSE_SUBTRACT,
+   [VK_BLEND_OP_MIN]                            = BLENDFUNCTION_MIN,
+   [VK_BLEND_OP_MAX]                            = BLENDFUNCTION_MAX,
+};
+
+static const uint32_t vk_to_gen_logic_op[] = {
+   [VK_LOGIC_OP_COPY]                           = LOGICOP_COPY,
+   [VK_LOGIC_OP_CLEAR]                          = LOGICOP_CLEAR,
+   [VK_LOGIC_OP_AND]                            = LOGICOP_AND,
+   [VK_LOGIC_OP_AND_REVERSE]                    = LOGICOP_AND_REVERSE,
+   [VK_LOGIC_OP_AND_INVERTED]                   = LOGICOP_AND_INVERTED,
+   [VK_LOGIC_OP_NOOP]                           = LOGICOP_NOOP,
+   [VK_LOGIC_OP_XOR]                            = LOGICOP_XOR,
+   [VK_LOGIC_OP_OR]                             = LOGICOP_OR,
+   [VK_LOGIC_OP_NOR]                            = LOGICOP_NOR,
+   [VK_LOGIC_OP_EQUIV]                          = LOGICOP_EQUIV,
+   [VK_LOGIC_OP_INVERT]                         = LOGICOP_INVERT,
+   [VK_LOGIC_OP_OR_REVERSE]                     = LOGICOP_OR_REVERSE,
+   [VK_LOGIC_OP_COPY_INVERTED]                  = LOGICOP_COPY_INVERTED,
+   [VK_LOGIC_OP_OR_INVERTED]                    = LOGICOP_OR_INVERTED,
+   [VK_LOGIC_OP_NAND]                           = LOGICOP_NAND,
+   [VK_LOGIC_OP_SET]                            = LOGICOP_SET,
+};
+
+static const uint32_t vk_to_gen_blend[] = {
+   [VK_BLEND_ZERO]                              = BLENDFACTOR_ZERO,
+   [VK_BLEND_ONE]                               = BLENDFACTOR_ONE,
+   [VK_BLEND_SRC_COLOR]                         = BLENDFACTOR_SRC_COLOR,
+   [VK_BLEND_ONE_MINUS_SRC_COLOR]               = BLENDFACTOR_INV_SRC_COLOR,
+   [VK_BLEND_DEST_COLOR]                        = BLENDFACTOR_DST_COLOR,
+   [VK_BLEND_ONE_MINUS_DEST_COLOR]              = BLENDFACTOR_INV_DST_COLOR,
+   [VK_BLEND_SRC_ALPHA]                         = BLENDFACTOR_SRC_ALPHA,
+   [VK_BLEND_ONE_MINUS_SRC_ALPHA]               = BLENDFACTOR_INV_SRC_ALPHA,
+   [VK_BLEND_DEST_ALPHA]                        = BLENDFACTOR_DST_ALPHA,
+   [VK_BLEND_ONE_MINUS_DEST_ALPHA]              = BLENDFACTOR_INV_DST_ALPHA,
+   [VK_BLEND_CONSTANT_COLOR]                    = BLENDFACTOR_CONST_COLOR,
+   [VK_BLEND_ONE_MINUS_CONSTANT_COLOR]          = BLENDFACTOR_INV_CONST_COLOR,
+   [VK_BLEND_CONSTANT_ALPHA]                    = BLENDFACTOR_CONST_ALPHA,
+   [VK_BLEND_ONE_MINUS_CONSTANT_ALPHA]          = BLENDFACTOR_INV_CONST_ALPHA,
+   [VK_BLEND_SRC_ALPHA_SATURATE]                = BLENDFACTOR_SRC_ALPHA_SATURATE,
+   [VK_BLEND_SRC1_COLOR]                        = BLENDFACTOR_SRC1_COLOR,
+   [VK_BLEND_ONE_MINUS_SRC1_COLOR]              = BLENDFACTOR_INV_SRC1_COLOR,
+   [VK_BLEND_SRC1_ALPHA]                        = BLENDFACTOR_SRC1_ALPHA,
+   [VK_BLEND_ONE_MINUS_SRC1_ALPHA]              = BLENDFACTOR_INV_SRC1_ALPHA,
+};
+
+static void
+gen7_emit_ds_state(struct anv_pipeline *pipeline,
+                   const VkPipelineDepthStencilStateCreateInfo *info)
+{
+   if (info == NULL) {
+      /* We're going to OR this together with the dynamic state.  We need
+       * to make sure it's initialized to something useful.
+       */
+      memset(pipeline->gen7.depth_stencil_state, 0,
+             sizeof(pipeline->gen7.depth_stencil_state));
+      return;
+   }
+
+   bool has_stencil = false;  /* enable if subpass has stencil? */
+
+   struct GEN7_DEPTH_STENCIL_STATE state = {
+      /* Is this what we need to do? */
+      .StencilBufferWriteEnable = has_stencil,
+
+      .StencilTestEnable = info->stencilTestEnable,
+      .StencilTestFunction = vk_to_gen_compare_op[info->front.stencilCompareOp],
+      .StencilFailOp = vk_to_gen_stencil_op[info->front.stencilFailOp],
+      .StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.stencilDepthFailOp],
+      .StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.stencilPassOp],
+
+      .DoubleSidedStencilEnable = true,
+
+      .BackFaceStencilTestFunction = vk_to_gen_compare_op[info->back.stencilCompareOp],
+      .BackfaceStencilFailOp = vk_to_gen_stencil_op[info->back.stencilFailOp],
+      .BackfaceStencilPassDepthFailOp = vk_to_gen_stencil_op[info->back.stencilDepthFailOp],
+      .BackfaceStencilPassDepthPassOp = vk_to_gen_stencil_op[info->back.stencilPassOp],
+
+      .DepthTestEnable = info->depthTestEnable,
+      .DepthTestFunction = vk_to_gen_compare_op[info->depthCompareOp],
+      .DepthBufferWriteEnable = info->depthWriteEnable,
+   };
+   
+   GEN7_DEPTH_STENCIL_STATE_pack(NULL, &pipeline->gen7.depth_stencil_state, &state);
+}
+
+static void
+gen7_emit_cb_state(struct anv_pipeline *pipeline,
+                   const VkPipelineColorBlendStateCreateInfo *info)
+{
+   struct anv_device *device = pipeline->device;
+
+   uint32_t num_dwords = GEN7_BLEND_STATE_length;
+   pipeline->blend_state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+   if (info->pAttachments == NULL) {
+      struct GEN7_BLEND_STATE blend_state = {
+         .ColorBufferBlendEnable = false,
+         .WriteDisableAlpha = false,
+         .WriteDisableRed = false,
+         .WriteDisableGreen = false,
+         .WriteDisableBlue = false,
+      };
+
+      GEN7_BLEND_STATE_pack(NULL, pipeline->blend_state.map, &blend_state);
+   } else {
+      /* FIXME-GEN7: All render targets share blend state settings on gen7, we
+       * can't implement this.
+       */
+      const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[0];
+
+      struct GEN7_BLEND_STATE blend_state = {
+         .ColorBufferBlendEnable = a->blendEnable,
+         .IndependentAlphaBlendEnable = true, /* FIXME: yes? */
+         .AlphaBlendFunction = vk_to_gen_blend_op[a->blendOpAlpha],
+
+         .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcBlendAlpha],
+         .DestinationAlphaBlendFactor = vk_to_gen_blend[a->destBlendAlpha],
+
+         .ColorBlendFunction = vk_to_gen_blend_op[a->blendOpColor],
+         .SourceBlendFactor = vk_to_gen_blend[a->srcBlendColor],
+         .DestinationBlendFactor = vk_to_gen_blend[a->destBlendColor],
+         .AlphaToCoverageEnable = info->alphaToCoverageEnable,
+
+#     if 0
+         bool                                         AlphaToOneEnable;
+         bool                                         AlphaToCoverageDitherEnable;
+#     endif
+
+         .WriteDisableAlpha = !(a->channelWriteMask & VK_CHANNEL_A_BIT),
+         .WriteDisableRed = !(a->channelWriteMask & VK_CHANNEL_R_BIT),
+         .WriteDisableGreen = !(a->channelWriteMask & VK_CHANNEL_G_BIT),
+         .WriteDisableBlue = !(a->channelWriteMask & VK_CHANNEL_B_BIT),
+
+         .LogicOpEnable = info->logicOpEnable,
+         .LogicOpFunction = vk_to_gen_logic_op[info->logicOp],
+
+#     if 0
+         bool                                         AlphaTestEnable;
+         uint32_t                                     AlphaTestFunction;
+         bool                                         ColorDitherEnable;
+         uint32_t                                     XDitherOffset;
+         uint32_t                                     YDitherOffset;
+         uint32_t                                     ColorClampRange;
+         bool                                         PreBlendColorClampEnable;
+         bool                                         PostBlendColorClampEnable;
+#     endif
+      };
+
+      GEN7_BLEND_STATE_pack(NULL, pipeline->blend_state.map, &blend_state);
+    }
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_BLEND_STATE_POINTERS,
+                  .BlendStatePointer = pipeline->blend_state.offset);
+}
+
+static const uint32_t vk_to_gen_primitive_type[] = {
+   [VK_PRIMITIVE_TOPOLOGY_POINT_LIST]           = _3DPRIM_POINTLIST,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_LIST]            = _3DPRIM_LINELIST,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP]           = _3DPRIM_LINESTRIP,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST]        = _3DPRIM_TRILIST,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP]       = _3DPRIM_TRISTRIP,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN]         = _3DPRIM_TRIFAN,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ]        = _3DPRIM_LINELIST_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ]       = _3DPRIM_LINESTRIP_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ]    = _3DPRIM_TRILIST_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ]   = _3DPRIM_TRISTRIP_ADJ,
+   [VK_PRIMITIVE_TOPOLOGY_PATCH]                = _3DPRIM_PATCHLIST_1
+};
+
+static inline uint32_t
+scratch_space(const struct brw_stage_prog_data *prog_data)
+{
+   return ffs(prog_data->total_scratch / 1024);
+}
+
+VkResult
+gen7_graphics_pipeline_create(
+    VkDevice                                    _device,
+    const VkGraphicsPipelineCreateInfo*         pCreateInfo,
+    const struct anv_graphics_pipeline_create_info *extra,
+    VkPipeline*                                 pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_pipeline *pipeline;
+   VkResult result;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
+   
+   pipeline = anv_device_alloc(device, sizeof(*pipeline), 8,
+                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pipeline == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   result = anv_pipeline_init(pipeline, device, pCreateInfo, extra);
+   if (result != VK_SUCCESS) {
+      anv_device_free(device, pipeline);
+      return result;
+   }
+
+   assert(pCreateInfo->pVertexInputState);
+   gen7_emit_vertex_input(pipeline, pCreateInfo->pVertexInputState);
+
+   assert(pCreateInfo->pRasterState);
+   gen7_emit_rs_state(pipeline, pCreateInfo->pRasterState, extra);
+
+   gen7_emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
+
+   gen7_emit_cb_state(pipeline, pCreateInfo->pColorBlendState);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_VF_STATISTICS,
+                   .StatisticsEnable = true);
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_HS, .Enable = false);
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_TE, .TEEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_DS, .DSFunctionEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_STREAMOUT, .SOFunctionEnable = false);
+
+   /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1:
+    *
+    *    "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth stall
+    *    needs to be sent just prior to any 3DSTATE_VS, 3DSTATE_URB_VS,
+    *    3DSTATE_CONSTANT_VS, 3DSTATE_BINDING_TABLE_POINTER_VS,
+    *    3DSTATE_SAMPLER_STATE_POINTER_VS command.  Only one PIPE_CONTROL
+    *    needs to be sent before any combination of VS associated 3DSTATE."
+    */
+   anv_batch_emit(&pipeline->batch, GEN7_PIPE_CONTROL,
+                  .DepthStallEnable = true,
+                  .PostSyncOperation = WriteImmediateData,
+                  .Address = { &device->workaround_bo, 0 });
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
+                  .ConstantBufferOffset = 0,
+                  .ConstantBufferSize = 4);
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
+                  .ConstantBufferOffset = 4,
+                  .ConstantBufferSize = 4);
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
+                  .ConstantBufferOffset = 8,
+                  .ConstantBufferSize = 4);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_AA_LINE_PARAMETERS);
+
+   const VkPipelineRasterStateCreateInfo *rs_info = pCreateInfo->pRasterState;
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_CLIP,
+      .FrontWinding                             = vk_to_gen_front_face[rs_info->frontFace],
+      .CullMode                                 = vk_to_gen_cullmode[rs_info->cullMode],
+      .ClipEnable                               = true,
+      .APIMode                                  = APIMODE_OGL,
+      .ViewportXYClipTestEnable                 = !(extra && extra->disable_viewport),
+      .ClipMode                                 = CLIPMODE_NORMAL,
+      .TriangleStripListProvokingVertexSelect   = 0,
+      .LineStripListProvokingVertexSelect       = 0,
+      .TriangleFanProvokingVertexSelect         = 0,
+      .MinimumPointWidth                        = 0.125,
+      .MaximumPointWidth                        = 255.875);
+
+   uint32_t samples = 1;
+   uint32_t log2_samples = __builtin_ffs(samples) - 1;
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_MULTISAMPLE,
+      .PixelLocation                            = PIXLOC_CENTER,
+      .NumberofMultisamples                     = log2_samples);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_SAMPLE_MASK,
+      .SampleMask                               = 0xff);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_URB_VS,
+      .VSURBStartingAddress                     = pipeline->urb.vs_start,
+      .VSURBEntryAllocationSize                 = pipeline->urb.vs_size - 1,
+      .VSNumberofURBEntries                     = pipeline->urb.nr_vs_entries);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_URB_GS,
+      .GSURBStartingAddress                     = pipeline->urb.gs_start,
+      .GSURBEntryAllocationSize                 = pipeline->urb.gs_size - 1,
+      .GSNumberofURBEntries                     = pipeline->urb.nr_gs_entries);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_URB_HS,
+      .HSURBStartingAddress                     = pipeline->urb.vs_start,
+      .HSURBEntryAllocationSize                 = 0,
+      .HSNumberofURBEntries                     = 0);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_URB_DS,
+      .DSURBStartingAddress                     = pipeline->urb.vs_start,
+      .DSURBEntryAllocationSize                 = 0,
+      .DSNumberofURBEntries                     = 0);
+
+   const struct brw_vue_prog_data *vue_prog_data = &pipeline->vs_prog_data.base;
+   /* The last geometry producing stage will set urb_offset and urb_length,
+    * which we use in 3DSTATE_SBE. Skip the VUE header and position slots. */
+   uint32_t urb_offset = 1;
+   uint32_t urb_length = (vue_prog_data->vue_map.num_slots + 1) / 2 - urb_offset;
+
+#if 0 
+   /* From gen7_vs_state.c */
+
+   /**
+    * From Graphics BSpec: 3D-Media-GPGPU Engine > 3D Pipeline Stages >
+    * Geometry > Geometry Shader > State:
+    *
+    *     "Note: Because of corruption in IVB:GT2, software needs to flush the
+    *     whole fixed function pipeline when the GS enable changes value in
+    *     the 3DSTATE_GS."
+    *
+    * The hardware architects have clarified that in this context "flush the
+    * whole fixed function pipeline" means to emit a PIPE_CONTROL with the "CS
+    * Stall" bit set.
+    */
+   if (!brw->is_haswell && !brw->is_baytrail)
+      gen7_emit_vs_workaround_flush(brw);
+#endif
+
+   if (pipeline->vs_vec4 == NO_KERNEL || (extra && extra->disable_vs))
+      anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_VS, .VSFunctionEnable = false);
+   else
+      anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_VS,
+         .KernelStartPointer                    = pipeline->vs_vec4,
+         .ScratchSpaceBaseOffset                = pipeline->scratch_start[VK_SHADER_STAGE_VERTEX],
+         .PerThreadScratchSpace                 = scratch_space(&vue_prog_data->base),
+
+         .DispatchGRFStartRegisterforURBData    =
+            vue_prog_data->base.dispatch_grf_start_reg,
+         .VertexURBEntryReadLength              = vue_prog_data->urb_read_length,
+         .VertexURBEntryReadOffset              = 0,
+
+         .MaximumNumberofThreads                = device->info.max_vs_threads - 1,
+         .StatisticsEnable                      = true,
+         .VSFunctionEnable                      = true);
+
+   const struct brw_gs_prog_data *gs_prog_data = &pipeline->gs_prog_data;
+
+   if (pipeline->gs_vec4 == NO_KERNEL || (extra && extra->disable_vs)) {
+      anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_GS, .GSEnable = false);
+   } else {
+      urb_offset = 1;
+      urb_length = (gs_prog_data->base.vue_map.num_slots + 1) / 2 - urb_offset;
+
+      anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_GS,
+         .KernelStartPointer                    = pipeline->gs_vec4,
+         .ScratchSpaceBasePointer               = pipeline->scratch_start[VK_SHADER_STAGE_GEOMETRY],
+         .PerThreadScratchSpace                 = scratch_space(&gs_prog_data->base.base),
+
+         .OutputVertexSize                      = gs_prog_data->output_vertex_size_hwords * 2 - 1,
+         .OutputTopology                        = gs_prog_data->output_topology,
+         .VertexURBEntryReadLength              = gs_prog_data->base.urb_read_length,
+         .DispatchGRFStartRegisterforURBData    =
+            gs_prog_data->base.base.dispatch_grf_start_reg,
+
+         .MaximumNumberofThreads                = device->info.max_gs_threads - 1,
+         /* This in the next dword on HSW. */
+         .ControlDataFormat                     = gs_prog_data->control_data_format,
+         .ControlDataHeaderSize                 = gs_prog_data->control_data_header_size_hwords,
+         .InstanceControl                       = MAX2(gs_prog_data->invocations, 1) - 1,
+         .DispatchMode                          = gs_prog_data->base.dispatch_mode,
+         .GSStatisticsEnable                    = true,
+         .IncludePrimitiveID                    = gs_prog_data->include_primitive_id,
+         .ReorderEnable                         = true,
+         .GSEnable                              = true);
+   }
+
+   const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
+   if (wm_prog_data->urb_setup[VARYING_SLOT_BFC0] != -1 ||
+       wm_prog_data->urb_setup[VARYING_SLOT_BFC1] != -1)
+      anv_finishme("two-sided color needs sbe swizzling setup");
+   if (wm_prog_data->urb_setup[VARYING_SLOT_PRIMITIVE_ID] != -1)
+      anv_finishme("primitive_id needs sbe swizzling setup");
+
+   /* FIXME: generated header doesn't emit attr swizzle fields */
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_SBE,
+      .NumberofSFOutputAttributes               = pipeline->wm_prog_data.num_varying_inputs,
+      .VertexURBEntryReadLength                 = urb_length,
+      .VertexURBEntryReadOffset                 = urb_offset,
+      .PointSpriteTextureCoordinateOrigin       = UPPERLEFT);
+
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_PS,
+      .KernelStartPointer0                      = pipeline->ps_ksp0,
+      .ScratchSpaceBasePointer                  = pipeline->scratch_start[VK_SHADER_STAGE_FRAGMENT],
+      .PerThreadScratchSpace                    = scratch_space(&wm_prog_data->base),
+                  
+      .MaximumNumberofThreads                   = device->info.max_wm_threads - 1,
+      .PushConstantEnable                       = wm_prog_data->base.nr_params > 0,
+      .AttributeEnable                          = wm_prog_data->num_varying_inputs > 0,
+      .oMaskPresenttoRenderTarget               = wm_prog_data->uses_omask,
+
+      .RenderTargetFastClearEnable              = false,
+      .DualSourceBlendEnable                    = false,
+      .RenderTargetResolveEnable                = false,
+
+      .PositionXYOffsetSelect                   = wm_prog_data->uses_pos_offset ?
+         POSOFFSET_SAMPLE : POSOFFSET_NONE,
+
+      ._32PixelDispatchEnable                   = false,
+      ._16PixelDispatchEnable                   = pipeline->ps_simd16 != NO_KERNEL,
+      ._8PixelDispatchEnable                    = pipeline->ps_simd8 != NO_KERNEL,
+
+      .DispatchGRFStartRegisterforConstantSetupData0 = pipeline->ps_grf_start0,
+      .DispatchGRFStartRegisterforConstantSetupData1 = 0,
+      .DispatchGRFStartRegisterforConstantSetupData2 = pipeline->ps_grf_start2,
+
+#if 0
+   /* Haswell requires the sample mask to be set in this packet as well as
+    * in 3DSTATE_SAMPLE_MASK; the values should match. */
+   /* _NEW_BUFFERS, _NEW_MULTISAMPLE */
+#endif
+
+      .KernelStartPointer1                      = 0,
+      .KernelStartPointer2                      = pipeline->ps_ksp2);
+
+   /* FIXME-GEN7: This needs a lot more work, cf gen7 upload_wm_state(). */
+   anv_batch_emit(&pipeline->batch, GEN7_3DSTATE_WM,
+      .StatisticsEnable                         = true,
+      .ThreadDispatchEnable                     = true,
+      .LineEndCapAntialiasingRegionWidth        = _05pixels,
+      .LineAntialiasingRegionWidth              = _10pixels,
+      .EarlyDepthStencilControl                 = NORMAL,
+      .PointRasterizationRule                   = RASTRULE_UPPER_RIGHT,
+      .PixelShaderComputedDepthMode             = wm_prog_data->computed_depth_mode,
+      .BarycentricInterpolationMode             = wm_prog_data->barycentric_interp_modes);
+
+   *pPipeline = anv_pipeline_to_handle(pipeline);
+
+   return VK_SUCCESS;
+}
+
+VkResult gen7_compute_pipeline_create(
+    VkDevice                                    _device,
+    const VkComputePipelineCreateInfo*          pCreateInfo,
+    VkPipeline*                                 pPipeline)
+{
+   anv_finishme("primitive_id needs sbe swizzling setup");
+   abort();
+}
diff --git a/src/vulkan/gen7_state.c b/src/vulkan/gen7_state.c
new file mode 100644 (file)
index 0000000..a53b6e3
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+void
+gen7_fill_buffer_surface_state(void *state, const struct anv_format *format,
+                               uint32_t offset, uint32_t range, uint32_t stride)
+{
+   uint32_t num_elements = range / stride;
+
+   struct GEN7_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType                              = SURFTYPE_BUFFER,
+      .SurfaceFormat                            = format->surface_format,
+      .SurfaceVerticalAlignment                 = VALIGN_4,
+      .SurfaceHorizontalAlignment               = HALIGN_4,
+      .TiledSurface                             = false,
+      .RenderCacheReadWriteMode                 = false,
+      .SurfaceObjectControlState                = GEN7_MOCS,
+      .Height                                   = (num_elements >> 7) & 0x3fff,
+      .Width                                    = num_elements & 0x7f,
+      .Depth                                    = (num_elements >> 21) & 0x3f,
+      .SurfacePitch                             = stride - 1,
+      .SurfaceBaseAddress                       = { NULL, offset },
+   };
+
+   GEN7_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
+}
+
+static const uint32_t vk_to_gen_tex_filter[] = {
+   [VK_TEX_FILTER_NEAREST]                      = MAPFILTER_NEAREST,
+   [VK_TEX_FILTER_LINEAR]                       = MAPFILTER_LINEAR
+};
+
+static const uint32_t vk_to_gen_mipmap_mode[] = {
+   [VK_TEX_MIPMAP_MODE_BASE]                    = MIPFILTER_NONE,
+   [VK_TEX_MIPMAP_MODE_NEAREST]                 = MIPFILTER_NEAREST,
+   [VK_TEX_MIPMAP_MODE_LINEAR]                  = MIPFILTER_LINEAR
+};
+
+static const uint32_t vk_to_gen_tex_address[] = {
+   [VK_TEX_ADDRESS_MODE_WRAP]                   = TCM_WRAP,
+   [VK_TEX_ADDRESS_MODE_MIRROR]                 = TCM_MIRROR,
+   [VK_TEX_ADDRESS_MODE_CLAMP]                  = TCM_CLAMP,
+   [VK_TEX_ADDRESS_MODE_MIRROR_ONCE]            = TCM_MIRROR_ONCE,
+   [VK_TEX_ADDRESS_MODE_CLAMP_BORDER]           = TCM_CLAMP_BORDER,
+};
+
+static const uint32_t vk_to_gen_compare_op[] = {
+   [VK_COMPARE_OP_NEVER]                        = PREFILTEROPNEVER,
+   [VK_COMPARE_OP_LESS]                         = PREFILTEROPLESS,
+   [VK_COMPARE_OP_EQUAL]                        = PREFILTEROPEQUAL,
+   [VK_COMPARE_OP_LESS_EQUAL]                   = PREFILTEROPLEQUAL,
+   [VK_COMPARE_OP_GREATER]                      = PREFILTEROPGREATER,
+   [VK_COMPARE_OP_NOT_EQUAL]                    = PREFILTEROPNOTEQUAL,
+   [VK_COMPARE_OP_GREATER_EQUAL]                = PREFILTEROPGEQUAL,
+   [VK_COMPARE_OP_ALWAYS]                       = PREFILTEROPALWAYS,
+};
+
+static struct anv_state
+gen7_alloc_surface_state(struct anv_device *device,
+                         struct anv_cmd_buffer *cmd_buffer)
+{
+      if (cmd_buffer) {
+         return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+      } else {
+         return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+      }
+}
+
+VkResult gen7_CreateSampler(
+    VkDevice                                    _device,
+    const VkSamplerCreateInfo*                  pCreateInfo,
+    VkSampler*                                  pSampler)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_sampler *sampler;
+   uint32_t mag_filter, min_filter, max_anisotropy;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+
+   sampler = anv_device_alloc(device, sizeof(*sampler), 8,
+                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!sampler)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   if (pCreateInfo->maxAnisotropy > 1) {
+      mag_filter = MAPFILTER_ANISOTROPIC;
+      min_filter = MAPFILTER_ANISOTROPIC;
+      max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
+   } else {
+      mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
+      min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
+      max_anisotropy = RATIO21;
+   }
+
+   struct GEN7_SAMPLER_STATE sampler_state = {
+      .SamplerDisable = false,
+      .TextureBorderColorMode = DX10OGL,
+      .BaseMipLevel = 0.0,
+      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
+      .MagModeFilter = mag_filter,
+      .MinModeFilter = min_filter,
+      .TextureLODBias = pCreateInfo->mipLodBias * 256,
+      .AnisotropicAlgorithm = EWAApproximation,
+      .MinLOD = pCreateInfo->minLod,
+      .MaxLOD = pCreateInfo->maxLod,
+      .ChromaKeyEnable = 0,
+      .ChromaKeyIndex = 0,
+      .ChromaKeyMode = 0,
+      .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
+      .CubeSurfaceControlMode = 0,
+
+      .BorderColorPointer =
+         device->border_colors.offset +
+         pCreateInfo->borderColor * sizeof(float) * 4,
+
+      .MaximumAnisotropy = max_anisotropy,
+      .RAddressMinFilterRoundingEnable = 0,
+      .RAddressMagFilterRoundingEnable = 0,
+      .VAddressMinFilterRoundingEnable = 0,
+      .VAddressMagFilterRoundingEnable = 0,
+      .UAddressMinFilterRoundingEnable = 0,
+      .UAddressMagFilterRoundingEnable = 0,
+      .TrilinearFilterQuality = 0,
+      .NonnormalizedCoordinateEnable = pCreateInfo->unnormalizedCoordinates,
+      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeU],
+      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeV],
+      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
+   };
+
+   GEN7_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
+
+   *pSampler = anv_sampler_to_handle(sampler);
+
+   return VK_SUCCESS;
+}
+
+static const uint8_t anv_halign[] = {
+    [4] = HALIGN_4,
+    [8] = HALIGN_8,
+};
+
+static const uint8_t anv_valign[] = {
+    [2] = VALIGN_2,
+    [4] = VALIGN_4,
+};
+
+void
+gen7_image_view_init(struct anv_image_view *iview,
+                     struct anv_device *device,
+                     const VkImageViewCreateInfo* pCreateInfo,
+                     struct anv_cmd_buffer *cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+
+   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+
+   struct anv_surface *surface =
+      anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
+
+   const struct anv_format *format =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
+      anv_finishme("non-2D image views");
+
+   iview->image = image;
+   iview->bo = image->bo;
+   iview->offset = image->offset + surface->offset;
+   iview->format = anv_format_for_vk_format(pCreateInfo->format);
+
+   iview->extent = (VkExtent3D) {
+      .width = anv_minify(image->extent.width, range->baseMipLevel),
+      .height = anv_minify(image->extent.height, range->baseMipLevel),
+      .depth = anv_minify(image->extent.depth, range->baseMipLevel),
+   };
+
+   uint32_t depth = 1;
+   if (range->arraySize > 1) {
+      depth = range->arraySize;
+   } else if (image->extent.depth > 1) {
+      depth = image->extent.depth;
+   }
+
+   struct GEN7_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = image->surface_type,
+      .SurfaceArray = image->array_size > 1,
+      .SurfaceFormat = format->surface_format,
+      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
+      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
+
+      /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
+       * Tiled Surface is False."
+       */
+      .TiledSurface = surface->tiling != ISL_TILING_LINEAR,
+      .TileWalk = surface->tiling == ISL_TILING_Y ?
+                  TILEWALK_YMAJOR : TILEWALK_XMAJOR,
+
+      .VerticalLineStride = 0,
+      .VerticalLineStrideOffset = 0,
+
+      .RenderCacheReadWriteMode = 0, /* TEMPLATE */
+
+      .Height = image->extent.height - 1,
+      .Width = image->extent.width - 1,
+      .Depth = depth - 1,
+      .SurfacePitch = surface->stride - 1,
+      .MinimumArrayElement = range->baseArrayLayer,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .XOffset = 0,
+      .YOffset = 0,
+
+      .SurfaceObjectControlState = GEN7_MOCS,
+
+      .MIPCountLOD = 0, /* TEMPLATE */
+      .SurfaceMinLOD = 0, /* TEMPLATE */
+
+      .MCSEnable = false,
+      .RedClearColor = 0,
+      .GreenClearColor = 0,
+      .BlueClearColor = 0,
+      .AlphaClearColor = 0,
+      .ResourceMinLOD = 0.0,
+      .SurfaceBaseAddress = { NULL, iview->offset },
+   };
+
+   if (image->needs_nonrt_surface_state) {
+      iview->nonrt_surface_state =
+         gen7_alloc_surface_state(device, cmd_buffer);
+
+      surface_state.RenderCacheReadWriteMode = false;
+
+      /* For non render target surfaces, the hardware interprets field
+       * MIPCount/LOD as MIPCount.  The range of levels accessible by the
+       * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
+       */
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->mipLevels - 1;
+
+      GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->nonrt_surface_state.map,
+                                     &surface_state);
+   }
+
+   if (image->needs_color_rt_surface_state) {
+      iview->color_rt_surface_state =
+         gen7_alloc_surface_state(device, cmd_buffer);
+
+      surface_state.RenderCacheReadWriteMode = WriteOnlyCache;
+
+      /* For render target surfaces, the hardware interprets field MIPCount/LOD as
+       * LOD. The Broadwell PRM says:
+       *
+       *    MIPCountLOD defines the LOD that will be rendered into.
+       *    SurfaceMinLOD is ignored.
+       */
+      surface_state.MIPCountLOD = range->baseMipLevel;
+      surface_state.SurfaceMinLOD = 0;
+
+      GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->color_rt_surface_state.map,
+                                     &surface_state);
+   }
+}
diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c
new file mode 100644 (file)
index 0000000..f626cad
--- /dev/null
@@ -0,0 +1,1072 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static void
+gen8_cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer)
+{
+   static const uint32_t push_constant_opcodes[] = {
+      [VK_SHADER_STAGE_VERTEX]                  = 21,
+      [VK_SHADER_STAGE_TESS_CONTROL]            = 25, /* HS */
+      [VK_SHADER_STAGE_TESS_EVALUATION]         = 26, /* DS */
+      [VK_SHADER_STAGE_GEOMETRY]                = 22,
+      [VK_SHADER_STAGE_FRAGMENT]                = 23,
+      [VK_SHADER_STAGE_COMPUTE]                 = 0,
+   };
+
+   VkShaderStage stage;
+   VkShaderStageFlags flushed = 0;
+
+   for_each_bit(stage, cmd_buffer->state.push_constants_dirty) {
+      struct anv_state state = anv_cmd_buffer_push_constants(cmd_buffer, stage);
+
+      if (state.offset == 0)
+         continue;
+
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CONSTANT_VS,
+                     ._3DCommandSubOpcode = push_constant_opcodes[stage],
+                     .ConstantBody = {
+                        .PointerToConstantBuffer0 = { .offset = state.offset },
+                        .ConstantBuffer0ReadLength = DIV_ROUND_UP(state.alloc_size, 32),
+                     });
+
+      flushed |= 1 << stage;
+   }
+
+   cmd_buffer->state.push_constants_dirty &= ~flushed;
+}
+
+static void
+gen8_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   uint32_t *p;
+
+   uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
+
+   assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
+
+   if (cmd_buffer->state.current_pipeline != _3D) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
+                     .PipelineSelection = _3D);
+      cmd_buffer->state.current_pipeline = _3D;
+   }
+
+   if (vb_emit) {
+      const uint32_t num_buffers = __builtin_popcount(vb_emit);
+      const uint32_t num_dwords = 1 + num_buffers * 4;
+
+      p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
+                          GEN8_3DSTATE_VERTEX_BUFFERS);
+      uint32_t vb, i = 0;
+      for_each_bit(vb, vb_emit) {
+         struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
+         uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
+
+         struct GEN8_VERTEX_BUFFER_STATE state = {
+            .VertexBufferIndex = vb,
+            .MemoryObjectControlState = GEN8_MOCS,
+            .AddressModifyEnable = true,
+            .BufferPitch = pipeline->binding_stride[vb],
+            .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
+            .BufferSize = buffer->size - offset
+         };
+
+         GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
+         i++;
+      }
+   }
+
+   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_PIPELINE) {
+      /* If somebody compiled a pipeline after starting a command buffer the
+       * scratch bo may have grown since we started this cmd buffer (and
+       * emitted STATE_BASE_ADDRESS).  If we're binding that pipeline now,
+       * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
+      if (cmd_buffer->state.scratch_size < pipeline->total_scratch)
+         anv_cmd_buffer_emit_state_base_address(cmd_buffer);
+
+      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+   }
+
+   if (cmd_buffer->state.descriptors_dirty)
+      anv_flush_descriptor_sets(cmd_buffer);
+
+   if (cmd_buffer->state.push_constants_dirty)
+      gen8_cmd_buffer_flush_push_constants(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT)
+      anv_cmd_buffer_emit_viewport(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & ANV_CMD_DIRTY_DYNAMIC_SCISSOR)
+      anv_cmd_buffer_emit_scissor(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH)) {
+      uint32_t sf_dw[GEN8_3DSTATE_SF_length];
+      struct GEN8_3DSTATE_SF sf = {
+         GEN8_3DSTATE_SF_header,
+         .LineWidth = cmd_buffer->state.dynamic.line_width,
+      };
+      GEN8_3DSTATE_SF_pack(NULL, sf_dw, &sf);
+      anv_batch_emit_merge(&cmd_buffer->batch, sf_dw, pipeline->gen8.sf);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS)){
+      bool enable_bias = cmd_buffer->state.dynamic.depth_bias.bias != 0.0f ||
+         cmd_buffer->state.dynamic.depth_bias.slope_scaled != 0.0f;
+
+      uint32_t raster_dw[GEN8_3DSTATE_RASTER_length];
+      struct GEN8_3DSTATE_RASTER raster = {
+         GEN8_3DSTATE_RASTER_header,
+         .GlobalDepthOffsetEnableSolid = enable_bias,
+         .GlobalDepthOffsetEnableWireframe = enable_bias,
+         .GlobalDepthOffsetEnablePoint = enable_bias,
+         .GlobalDepthOffsetConstant = cmd_buffer->state.dynamic.depth_bias.bias,
+         .GlobalDepthOffsetScale = cmd_buffer->state.dynamic.depth_bias.slope_scaled,
+         .GlobalDepthOffsetClamp = cmd_buffer->state.dynamic.depth_bias.clamp
+      };
+      GEN8_3DSTATE_RASTER_pack(NULL, raster_dw, &raster);
+      anv_batch_emit_merge(&cmd_buffer->batch, raster_dw,
+                           pipeline->gen8.raster);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS |
+                                  ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE)) {
+      struct anv_state cc_state =
+         anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
+                                            GEN8_COLOR_CALC_STATE_length, 64);
+      struct GEN8_COLOR_CALC_STATE cc = {
+         .BlendConstantColorRed = cmd_buffer->state.dynamic.blend_constants[0],
+         .BlendConstantColorGreen = cmd_buffer->state.dynamic.blend_constants[1],
+         .BlendConstantColorBlue = cmd_buffer->state.dynamic.blend_constants[2],
+         .BlendConstantColorAlpha = cmd_buffer->state.dynamic.blend_constants[3],
+         .StencilReferenceValue =
+            cmd_buffer->state.dynamic.stencil_reference.front,
+         .BackFaceStencilReferenceValue =
+            cmd_buffer->state.dynamic.stencil_reference.back,
+      };
+      GEN8_COLOR_CALC_STATE_pack(NULL, cc_state.map, &cc);
+
+      anv_batch_emit(&cmd_buffer->batch,
+                     GEN8_3DSTATE_CC_STATE_POINTERS,
+                     .ColorCalcStatePointer = cc_state.offset,
+                     .ColorCalcStatePointerValid = true);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK |
+                                  ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK)) {
+      uint32_t wm_depth_stencil_dw[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
+
+      struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+         GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
+
+         /* Is this what we need to do? */
+         .StencilBufferWriteEnable =
+            cmd_buffer->state.dynamic.stencil_write_mask.front != 0,
+
+         .StencilTestMask =
+            cmd_buffer->state.dynamic.stencil_compare_mask.front & 0xff,
+         .StencilWriteMask =
+            cmd_buffer->state.dynamic.stencil_write_mask.front & 0xff,
+
+         .BackfaceStencilTestMask =
+            cmd_buffer->state.dynamic.stencil_compare_mask.back & 0xff,
+         .BackfaceStencilWriteMask =
+            cmd_buffer->state.dynamic.stencil_write_mask.back & 0xff,
+      };
+      GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, wm_depth_stencil_dw,
+                                         &wm_depth_stencil);
+
+      anv_batch_emit_merge(&cmd_buffer->batch, wm_depth_stencil_dw,
+                           pipeline->gen8.wm_depth_stencil);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_DIRTY_PIPELINE |
+                                  ANV_CMD_DIRTY_INDEX_BUFFER)) {
+      anv_batch_emit_merge(&cmd_buffer->batch,
+                           cmd_buffer->state.state_vf, pipeline->gen8.vf);
+   }
+
+   cmd_buffer->state.vb_dirty &= ~vb_emit;
+   cmd_buffer->state.dirty = 0;
+}
+
+void gen8_CmdDraw(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    vertexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstVertex,
+    uint32_t                                    firstInstance)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .VertexAccessType = SEQUENTIAL,
+                  .VertexCountPerInstance = vertexCount,
+                  .StartVertexLocation = firstVertex,
+                  .InstanceCount = instanceCount,
+                  .StartInstanceLocation = firstInstance,
+                  .BaseVertexLocation = 0);
+}
+
+void gen8_CmdDrawIndexed(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    indexCount,
+    uint32_t                                    instanceCount,
+    uint32_t                                    firstIndex,
+    int32_t                                     vertexOffset,
+    uint32_t                                    firstInstance)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .VertexAccessType = RANDOM,
+                  .VertexCountPerInstance = indexCount,
+                  .StartVertexLocation = firstIndex,
+                  .InstanceCount = instanceCount,
+                  .StartInstanceLocation = firstInstance,
+                  .BaseVertexLocation = vertexOffset);
+}
+
+static void
+emit_lrm(struct anv_batch *batch,
+         uint32_t reg, struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg,
+                  .MemoryAddress = { bo, offset });
+}
+
+static void
+emit_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
+{
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
+                  .RegisterOffset = reg,
+                  .DataDWord = imm);
+}
+
+/* Auto-Draw / Indirect Registers */
+#define GEN7_3DPRIM_END_OFFSET          0x2420
+#define GEN7_3DPRIM_START_VERTEX        0x2430
+#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
+#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
+#define GEN7_3DPRIM_START_INSTANCE      0x243C
+#define GEN7_3DPRIM_BASE_VERTEX         0x2440
+
+void gen8_CmdDrawIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
+   emit_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .IndirectParameterEnable = true,
+                  .VertexAccessType = SEQUENTIAL);
+}
+
+void gen8_CmdBindIndexBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    VkIndexType                                 indexType)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   static const uint32_t vk_to_gen_index_type[] = {
+      [VK_INDEX_TYPE_UINT16]                    = INDEX_WORD,
+      [VK_INDEX_TYPE_UINT32]                    = INDEX_DWORD,
+   };
+
+   struct GEN8_3DSTATE_VF vf = {
+      GEN8_3DSTATE_VF_header,
+      .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
+   };
+   GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state.state_vf, &vf);
+
+   cmd_buffer->state.dirty |= ANV_CMD_DIRTY_INDEX_BUFFER;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
+                  .IndexFormat = vk_to_gen_index_type[indexType],
+                  .MemoryObjectControlState = GEN8_MOCS,
+                  .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
+                  .BufferSize = buffer->size - offset);
+}
+
+static VkResult
+gen8_flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct anv_state surfaces = { 0, }, samplers = { 0, };
+   VkResult result;
+
+   result = anv_cmd_buffer_emit_samplers(cmd_buffer,
+                                         VK_SHADER_STAGE_COMPUTE, &samplers);
+   if (result != VK_SUCCESS)
+      return result;
+   result = anv_cmd_buffer_emit_binding_table(cmd_buffer,
+                                               VK_SHADER_STAGE_COMPUTE, &surfaces);
+   if (result != VK_SUCCESS)
+      return result;
+
+   struct GEN8_INTERFACE_DESCRIPTOR_DATA desc = {
+      .KernelStartPointer = pipeline->cs_simd,
+      .KernelStartPointerHigh = 0,
+      .BindingTablePointer = surfaces.offset,
+      .BindingTableEntryCount = 0,
+      .SamplerStatePointer = samplers.offset,
+      .SamplerCount = 0,
+      .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
+   };
+
+   uint32_t size = GEN8_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
+   struct anv_state state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
+
+   GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
+                  .InterfaceDescriptorTotalLength = size,
+                  .InterfaceDescriptorDataStartAddress = state.offset);
+
+   return VK_SUCCESS;
+}
+
+static void
+gen8_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   VkResult result;
+
+   assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
+
+   if (cmd_buffer->state.current_pipeline != GPGPU) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
+                     .PipelineSelection = GPGPU);
+      cmd_buffer->state.current_pipeline = GPGPU;
+   }
+
+   if (cmd_buffer->state.compute_dirty & ANV_CMD_DIRTY_PIPELINE)
+      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+
+   if ((cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
+       (cmd_buffer->state.compute_dirty & ANV_CMD_DIRTY_PIPELINE)) {
+      result = gen8_flush_compute_descriptor_set(cmd_buffer);
+      assert(result == VK_SUCCESS);
+      cmd_buffer->state.descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
+   }
+
+   cmd_buffer->state.compute_dirty = 0;
+}
+
+void gen8_CmdDrawIndexedIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .IndirectParameterEnable = true,
+                  .VertexAccessType = RANDOM);
+}
+
+void gen8_CmdDispatch(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    x,
+    uint32_t                                    y,
+    uint32_t                                    z)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+
+   gen8_cmd_buffer_flush_compute_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
+                  .SIMDSize = prog_data->simd_size / 16,
+                  .ThreadDepthCounterMaximum = 0,
+                  .ThreadHeightCounterMaximum = 0,
+                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
+                  .ThreadGroupIDXDimension = x,
+                  .ThreadGroupIDYDimension = y,
+                  .ThreadGroupIDZDimension = z,
+                  .RightExecutionMask = pipeline->cs_right_mask,
+                  .BottomExecutionMask = 0xffffffff);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
+}
+
+#define GPGPU_DISPATCHDIMX 0x2500
+#define GPGPU_DISPATCHDIMY 0x2504
+#define GPGPU_DISPATCHDIMZ 0x2508
+
+void gen8_CmdDispatchIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen8_cmd_buffer_flush_compute_state(cmd_buffer);
+
+   emit_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
+                  .IndirectParameterEnable = true,
+                  .SIMDSize = prog_data->simd_size / 16,
+                  .ThreadDepthCounterMaximum = 0,
+                  .ThreadHeightCounterMaximum = 0,
+                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
+                  .RightExecutionMask = pipeline->cs_right_mask,
+                  .BottomExecutionMask = 0xffffffff);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
+}
+
+static void
+gen8_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
+{
+   const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   const struct anv_image_view *iview =
+      anv_cmd_buffer_get_depth_stencil_view(cmd_buffer);
+   const struct anv_image *image = iview ? iview->image : NULL;
+   const bool has_depth = iview && iview->format->depth_format;
+   const bool has_stencil = iview && iview->format->has_stencil;
+
+   /* FIXME: Implement the PMA stall W/A */
+   /* FIXME: Width and Height are wrong */
+
+   /* Emit 3DSTATE_DEPTH_BUFFER */
+   if (has_depth) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
+         .SurfaceType = SURFTYPE_2D,
+         .DepthWriteEnable = iview->format->depth_format,
+         .StencilWriteEnable = has_stencil,
+         .HierarchicalDepthBufferEnable = false,
+         .SurfaceFormat = iview->format->depth_format,
+         .SurfacePitch = image->depth_surface.stride - 1,
+         .SurfaceBaseAddress = {
+            .bo = image->bo,
+            .offset = image->depth_surface.offset,
+         },
+         .Height = fb->height - 1,
+         .Width = fb->width - 1,
+         .LOD = 0,
+         .Depth = 1 - 1,
+         .MinimumArrayElement = 0,
+         .DepthBufferObjectControlState = GEN8_MOCS,
+         .RenderTargetViewExtent = 1 - 1,
+         .SurfaceQPitch = image->depth_surface.qpitch >> 2);
+   } else {
+      /* Even when no depth buffer is present, the hardware requires that
+       * 3DSTATE_DEPTH_BUFFER be programmed correctly. The Broadwell PRM says:
+       *
+       *    If a null depth buffer is bound, the driver must instead bind depth as:
+       *       3DSTATE_DEPTH.SurfaceType = SURFTYPE_2D
+       *       3DSTATE_DEPTH.Width = 1
+       *       3DSTATE_DEPTH.Height = 1
+       *       3DSTATE_DEPTH.SuraceFormat = D16_UNORM
+       *       3DSTATE_DEPTH.SurfaceBaseAddress = 0
+       *       3DSTATE_DEPTH.HierarchicalDepthBufferEnable = 0
+       *       3DSTATE_WM_DEPTH_STENCIL.DepthTestEnable = 0
+       *       3DSTATE_WM_DEPTH_STENCIL.DepthBufferWriteEnable = 0
+       *
+       * The PRM is wrong, though. The width and height must be programmed to
+       * actual framebuffer's width and height, even when neither depth buffer
+       * nor stencil buffer is present.
+       */
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
+         .SurfaceType = SURFTYPE_2D,
+         .SurfaceFormat = D16_UNORM,
+         .Width = fb->width - 1,
+         .Height = fb->height - 1,
+         .StencilWriteEnable = has_stencil);
+   }
+
+   /* Emit 3DSTATE_STENCIL_BUFFER */
+   if (has_stencil) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
+         .StencilBufferEnable = true,
+         .StencilBufferObjectControlState = GEN8_MOCS,
+
+         /* Stencil buffers have strange pitch. The PRM says:
+          *
+          *    The pitch must be set to 2x the value computed based on width,
+          *    as the stencil buffer is stored with two rows interleaved.
+          */
+         .SurfacePitch = 2 * image->stencil_surface.stride - 1,
+
+         .SurfaceBaseAddress = {
+            .bo = image->bo,
+            .offset = image->offset + image->stencil_surface.offset,
+         },
+         .SurfaceQPitch = image->stencil_surface.stride >> 2);
+   } else {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER);
+   }
+
+   /* Disable hierarchial depth buffers. */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
+
+   /* Clear the clear params. */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
+}
+
+void
+gen8_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_subpass *subpass)
+{
+   cmd_buffer->state.subpass = subpass;
+
+   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
+
+   gen8_cmd_buffer_emit_depth_stencil(cmd_buffer);
+}
+
+void gen8_CmdBeginRenderPass(
+    VkCmdBuffer                                 cmdBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    VkRenderPassContents                        contents)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
+   ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
+
+   cmd_buffer->state.framebuffer = framebuffer;
+   cmd_buffer->state.pass = pass;
+
+   const VkRect2D *render_area = &pRenderPassBegin->renderArea;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
+                  .ClippedDrawingRectangleYMin = render_area->offset.y,
+                  .ClippedDrawingRectangleXMin = render_area->offset.x,
+                  .ClippedDrawingRectangleYMax =
+                     render_area->offset.y + render_area->extent.height - 1,
+                  .ClippedDrawingRectangleXMax =
+                     render_area->offset.x + render_area->extent.width - 1,
+                  .DrawingRectangleOriginY = 0,
+                  .DrawingRectangleOriginX = 0);
+
+   anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
+                                    pRenderPassBegin->pClearValues);
+
+   gen8_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
+}
+
+void gen8_CmdNextSubpass(
+    VkCmdBuffer                                 cmdBuffer,
+    VkRenderPassContents                        contents)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+
+   gen8_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
+}
+
+void gen8_CmdEndRenderPass(
+    VkCmdBuffer                                 cmdBuffer)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   /* Emit a flushing pipe control at the end of a pass.  This is kind of a
+    * hack but it ensures that render targets always actually get written.
+    * Eventually, we should do flushing based on image format transitions
+    * or something of that nature.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                  .PostSyncOperation = NoWrite,
+                  .RenderTargetCacheFlushEnable = true,
+                  .InstructionCacheInvalidateEnable = true,
+                  .DepthCacheFlushEnable = true,
+                  .VFCacheInvalidationEnable = true,
+                  .TextureCacheInvalidationEnable = true,
+                  .CommandStreamerStallEnable = true);
+}
+
+static void
+emit_ps_depth_count(struct anv_batch *batch,
+                    struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN8_PIPE_CONTROL,
+                  .DestinationAddressType = DAT_PPGTT,
+                  .PostSyncOperation = WritePSDepthCount,
+                  .Address = { bo, offset });  /* FIXME: This is only lower 32 bits */
+}
+
+void gen8_CmdBeginQuery(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    slot,
+    VkQueryControlFlags                         flags)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+
+   switch (pool->type) {
+   case VK_QUERY_TYPE_OCCLUSION:
+      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
+                                    slot * sizeof(struct anv_query_pool_slot));
+      break;
+
+   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
+   default:
+      unreachable("");
+   }
+}
+
+void gen8_CmdEndQuery(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    slot)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+
+   switch (pool->type) {
+   case VK_QUERY_TYPE_OCCLUSION:
+      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
+                          slot * sizeof(struct anv_query_pool_slot) + 8);
+      break;
+
+   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
+   default:
+      unreachable("");
+   }
+}
+
+#define TIMESTAMP 0x2358
+
+void gen8_CmdWriteTimestamp(
+    VkCmdBuffer                                 cmdBuffer,
+    VkTimestampType                             timestampType,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
+   struct anv_bo *bo = buffer->bo;
+
+   switch (timestampType) {
+   case VK_TIMESTAMP_TYPE_TOP:
+      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                     .RegisterAddress = TIMESTAMP,
+                     .MemoryAddress = { bo, buffer->offset + destOffset });
+      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                     .RegisterAddress = TIMESTAMP + 4,
+                     .MemoryAddress = { bo, buffer->offset + destOffset + 4 });
+      break;
+
+   case VK_TIMESTAMP_TYPE_BOTTOM:
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                     .DestinationAddressType = DAT_PPGTT,
+                     .PostSyncOperation = WriteTimestamp,
+                     .Address = /* FIXME: This is only lower 32 bits */
+                        { bo, buffer->offset + destOffset });
+      break;
+
+   default:
+      break;
+   }
+}
+
+#define alu_opcode(v)   __gen_field((v),  20, 31)
+#define alu_operand1(v) __gen_field((v),  10, 19)
+#define alu_operand2(v) __gen_field((v),   0,  9)
+#define alu(opcode, operand1, operand2) \
+   alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
+
+#define OPCODE_NOOP      0x000
+#define OPCODE_LOAD      0x080
+#define OPCODE_LOADINV   0x480
+#define OPCODE_LOAD0     0x081
+#define OPCODE_LOAD1     0x481
+#define OPCODE_ADD       0x100
+#define OPCODE_SUB       0x101
+#define OPCODE_AND       0x102
+#define OPCODE_OR        0x103
+#define OPCODE_XOR       0x104
+#define OPCODE_STORE     0x180
+#define OPCODE_STOREINV  0x580
+
+#define OPERAND_R0   0x00
+#define OPERAND_R1   0x01
+#define OPERAND_R2   0x02
+#define OPERAND_R3   0x03
+#define OPERAND_R4   0x04
+#define OPERAND_SRCA 0x20
+#define OPERAND_SRCB 0x21
+#define OPERAND_ACCU 0x31
+#define OPERAND_ZF   0x32
+#define OPERAND_CF   0x33
+
+#define CS_GPR(n) (0x2600 + (n) * 8)
+
+static void
+emit_load_alu_reg_u64(struct anv_batch *batch, uint32_t reg,
+                      struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg,
+                  .MemoryAddress = { bo, offset });
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg + 4,
+                  .MemoryAddress = { bo, offset + 4 });
+}
+
+void gen8_CmdCopyQueryPoolResults(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                destStride,
+    VkQueryResultFlags                          flags)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
+   uint32_t slot_offset, dst_offset;
+
+   if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
+      /* Where is the availabilty info supposed to go? */
+      anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
+      return;
+   }
+
+   assert(pool->type == VK_QUERY_TYPE_OCCLUSION);
+
+   /* FIXME: If we're not waiting, should we just do this on the CPU? */
+   if (flags & VK_QUERY_RESULT_WAIT_BIT)
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                     .CommandStreamerStallEnable = true,
+                     .StallAtPixelScoreboard = true);
+
+   dst_offset = buffer->offset + destOffset;
+   for (uint32_t i = 0; i < queryCount; i++) {
+
+      slot_offset = (startQuery + i) * sizeof(struct anv_query_pool_slot);
+
+      emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(0), &pool->bo, slot_offset);
+      emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(1), &pool->bo, slot_offset + 8);
+
+      /* FIXME: We need to clamp the result for 32 bit. */
+
+      uint32_t *dw = anv_batch_emitn(&cmd_buffer->batch, 5, GEN8_MI_MATH);
+      dw[1] = alu(OPCODE_LOAD, OPERAND_SRCA, OPERAND_R1);
+      dw[2] = alu(OPCODE_LOAD, OPERAND_SRCB, OPERAND_R0);
+      dw[3] = alu(OPCODE_SUB, 0, 0);
+      dw[4] = alu(OPCODE_STORE, OPERAND_R2, OPERAND_ACCU);
+
+      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                     .RegisterAddress = CS_GPR(2),
+                     /* FIXME: This is only lower 32 bits */
+                     .MemoryAddress = { buffer->bo, dst_offset });
+
+      if (flags & VK_QUERY_RESULT_64_BIT)
+         anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                        .RegisterAddress = CS_GPR(2) + 4,
+                        /* FIXME: This is only lower 32 bits */
+                        .MemoryAddress = { buffer->bo, dst_offset + 4 });
+
+      dst_offset += destStride;
+   }
+}
+
+void
+gen8_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_bo *scratch_bo = NULL;
+
+   cmd_buffer->state.scratch_size =
+      anv_block_pool_size(&device->scratch_block_pool);
+   if (cmd_buffer->state.scratch_size > 0)
+      scratch_bo = &device->scratch_block_pool.bo;
+
+   /* Emit a render target cache flush.
+    *
+    * This isn't documented anywhere in the PRM.  However, it seems to be
+    * necessary prior to changing the surface state base adress.  Without
+    * this, we get GPU hangs when using multi-level command buffers which
+    * clear depth, reset state base address, and then go render stuff.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                  .RenderTargetCacheFlushEnable = true);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
+                  .GeneralStateBaseAddress = { scratch_bo, 0 },
+                  .GeneralStateMemoryObjectControlState = GEN8_MOCS,
+                  .GeneralStateBaseAddressModifyEnable = true,
+                  .GeneralStateBufferSize = 0xfffff,
+                  .GeneralStateBufferSizeModifyEnable = true,
+
+                  .SurfaceStateBaseAddress = anv_cmd_buffer_surface_base_address(cmd_buffer),
+                  .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
+                  .SurfaceStateBaseAddressModifyEnable = true,
+
+                  .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
+                  .DynamicStateMemoryObjectControlState = GEN8_MOCS,
+                  .DynamicStateBaseAddressModifyEnable = true,
+                  .DynamicStateBufferSize = 0xfffff,
+                  .DynamicStateBufferSizeModifyEnable = true,
+
+                  .IndirectObjectBaseAddress = { NULL, 0 },
+                  .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
+                  .IndirectObjectBaseAddressModifyEnable = true,
+                  .IndirectObjectBufferSize = 0xfffff,
+                  .IndirectObjectBufferSizeModifyEnable = true,
+
+                  .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
+                  .InstructionMemoryObjectControlState = GEN8_MOCS,
+                  .InstructionBaseAddressModifyEnable = true,
+                  .InstructionBufferSize = 0xfffff,
+                  .InstructionBuffersizeModifyEnable = true);
+
+   /* After re-setting the surface state base address, we have to do some
+    * cache flusing so that the sampler engine will pick up the new
+    * SURFACE_STATE objects and binding tables. From the Broadwell PRM,
+    * Shared Function > 3D Sampler > State > State Caching (page 96):
+    *
+    *    Coherency with system memory in the state cache, like the texture
+    *    cache is handled partially by software. It is expected that the
+    *    command stream or shader will issue Cache Flush operation or
+    *    Cache_Flush sampler message to ensure that the L1 cache remains
+    *    coherent with system memory.
+    *
+    *    [...]
+    *
+    *    Whenever the value of the Dynamic_State_Base_Addr,
+    *    Surface_State_Base_Addr are altered, the L1 state cache must be
+    *    invalidated to ensure the new surface or sampler state is fetched
+    *    from system memory.
+    *
+    * The PIPE_CONTROL command has a "State Cache Invalidation Enable" bit
+    * which, according the PIPE_CONTROL instruction documentation in the
+    * Broadwell PRM:
+    *
+    *    Setting this bit is independent of any other bit in this packet.
+    *    This bit controls the invalidation of the L1 and L2 state caches
+    *    at the top of the pipe i.e. at the parsing time.
+    *
+    * Unfortunately, experimentation seems to indicate that state cache
+    * invalidation through a PIPE_CONTROL does nothing whatsoever in
+    * regards to surface state and binding tables.  In stead, it seems that
+    * invalidating the texture cache is what is actually needed.
+    *
+    * XXX:  As far as we have been able to determine through
+    * experimentation, shows that flush the texture cache appears to be
+    * sufficient.  The theory here is that all of the sampling/rendering
+    * units cache the binding table in the texture cache.  However, we have
+    * yet to be able to actually confirm this.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                  .TextureCacheInvalidationEnable = true);
+}
+
+void gen8_CmdPipelineBarrier(
+    VkCmdBuffer                                 cmdBuffer,
+    VkPipelineStageFlags                        srcStageMask,
+    VkPipelineStageFlags                        destStageMask,
+    VkBool32                                    byRegion,
+    uint32_t                                    memBarrierCount,
+    const void* const*                          ppMemBarriers)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   uint32_t b, *dw;
+
+   struct GEN8_PIPE_CONTROL cmd = {
+      GEN8_PIPE_CONTROL_header,
+      .PostSyncOperation = NoWrite,
+   };
+
+   /* XXX: I think waitEvent is a no-op on our HW.  We should verify that. */
+
+   if (anv_clear_mask(&srcStageMask, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)) {
+      /* This is just what PIPE_CONTROL does */
+   }
+
+   if (anv_clear_mask(&srcStageMask,
+                      VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT |
+                      VK_PIPELINE_STAGE_VERTEX_INPUT_BIT |
+                      VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
+                      VK_PIPELINE_STAGE_TESS_CONTROL_SHADER_BIT |
+                      VK_PIPELINE_STAGE_TESS_EVALUATION_SHADER_BIT |
+                      VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT |
+                      VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
+                      VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
+                      VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT |
+                      VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT)) {
+      cmd.StallAtPixelScoreboard = true;
+   }
+
+
+   if (anv_clear_mask(&srcStageMask,
+                      VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT |
+                      VK_PIPELINE_STAGE_TRANSFER_BIT)) {
+      cmd.CommandStreamerStallEnable = true;
+   }
+
+   if (anv_clear_mask(&srcStageMask, VK_PIPELINE_STAGE_HOST_BIT)) {
+      anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
+   }
+
+   /* On our hardware, all stages will wait for execution as needed. */
+   (void)destStageMask;
+
+   /* We checked all known VkPipeEventFlags. */
+   anv_assert(srcStageMask == 0);
+
+   /* XXX: Right now, we're really dumb and just flush whatever categories
+    * the app asks for.  One of these days we may make this a bit better
+    * but right now that's all the hardware allows for in most areas.
+    */
+   VkMemoryOutputFlags out_flags = 0;
+   VkMemoryInputFlags in_flags = 0;
+
+   for (uint32_t i = 0; i < memBarrierCount; i++) {
+      const struct anv_common *common = ppMemBarriers[i];
+      switch (common->sType) {
+      case VK_STRUCTURE_TYPE_MEMORY_BARRIER: {
+         ANV_COMMON_TO_STRUCT(VkMemoryBarrier, barrier, common);
+         out_flags |= barrier->outputMask;
+         in_flags |= barrier->inputMask;
+         break;
+      }
+      case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: {
+         ANV_COMMON_TO_STRUCT(VkBufferMemoryBarrier, barrier, common);
+         out_flags |= barrier->outputMask;
+         in_flags |= barrier->inputMask;
+         break;
+      }
+      case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER: {
+         ANV_COMMON_TO_STRUCT(VkImageMemoryBarrier, barrier, common);
+         out_flags |= barrier->outputMask;
+         in_flags |= barrier->inputMask;
+         break;
+      }
+      default:
+         unreachable("Invalid memory barrier type");
+      }
+   }
+
+   for_each_bit(b, out_flags) {
+      switch ((VkMemoryOutputFlags)(1 << b)) {
+      case VK_MEMORY_OUTPUT_HOST_WRITE_BIT:
+         break; /* FIXME: Little-core systems */
+      case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT:
+         cmd.DCFlushEnable = true;
+         break;
+      case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT:
+         cmd.RenderTargetCacheFlushEnable = true;
+         break;
+      case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
+         cmd.DepthCacheFlushEnable = true;
+         break;
+      case VK_MEMORY_OUTPUT_TRANSFER_BIT:
+         cmd.RenderTargetCacheFlushEnable = true;
+         cmd.DepthCacheFlushEnable = true;
+         break;
+      default:
+         unreachable("Invalid memory output flag");
+      }
+   }
+
+   for_each_bit(b, out_flags) {
+      switch ((VkMemoryInputFlags)(1 << b)) {
+      case VK_MEMORY_INPUT_HOST_READ_BIT:
+         break; /* FIXME: Little-core systems */
+      case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT:
+      case VK_MEMORY_INPUT_INDEX_FETCH_BIT:
+      case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT:
+         cmd.VFCacheInvalidationEnable = true;
+         break;
+      case VK_MEMORY_INPUT_UNIFORM_READ_BIT:
+         cmd.ConstantCacheInvalidationEnable = true;
+         /* fallthrough */
+      case VK_MEMORY_INPUT_SHADER_READ_BIT:
+         cmd.DCFlushEnable = true;
+         cmd.TextureCacheInvalidationEnable = true;
+         break;
+      case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT:
+      case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
+         break; /* XXX: Hunh? */
+      case VK_MEMORY_INPUT_TRANSFER_BIT:
+         cmd.TextureCacheInvalidationEnable = true;
+         break;
+      }
+   }
+
+   dw = anv_batch_emit_dwords(&cmd_buffer->batch, GEN8_PIPE_CONTROL_length);
+   GEN8_PIPE_CONTROL_pack(&cmd_buffer->batch, dw, &cmd);
+}
diff --git a/src/vulkan/gen8_pack.h b/src/vulkan/gen8_pack.h
new file mode 100644 (file)
index 0000000..4d6b7c0
--- /dev/null
@@ -0,0 +1,9179 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+
+/* Instructions, enums and structures for BDW.
+ *
+ * This file has been generated, do not hand edit.
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef __gen_validate_value
+#define __gen_validate_value(x)
+#endif
+
+#ifndef __gen_field_functions
+#define __gen_field_functions
+
+union __gen_value {
+   float f;
+   uint32_t dw;
+};
+
+static inline uint64_t
+__gen_mbo(uint32_t start, uint32_t end)
+{
+   return (~0ul >> (64 - (end - start + 1))) << start;
+}
+
+static inline uint64_t
+__gen_field(uint64_t v, uint32_t start, uint32_t end)
+{
+   __gen_validate_value(v);
+#if DEBUG
+   if (end - start + 1 < 64)
+      assert(v < 1ul << (end - start + 1));
+#endif
+
+   return v << start;
+}
+
+static inline uint64_t
+__gen_offset(uint64_t v, uint32_t start, uint32_t end)
+{
+   __gen_validate_value(v);
+#if DEBUG
+   uint64_t mask = (~0ul >> (64 - (end - start + 1))) << start;
+
+   assert((v & ~mask) == 0);
+#endif
+
+   return v;
+}
+
+static inline uint32_t
+__gen_float(float v)
+{
+   __gen_validate_value(v);
+   return ((union __gen_value) { .f = (v) }).dw;
+}
+
+#ifndef __gen_address_type
+#error #define __gen_address_type before including this file
+#endif
+
+#ifndef __gen_user_data
+#error #define __gen_combine_address before including this file
+#endif
+
+#endif
+
+#define GEN8_3DSTATE_URB_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_URB_VS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 48,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_URB_VS_length 0x00000002
+
+struct GEN8_3DSTATE_URB_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     VSURBStartingAddress;
+   uint32_t                                     VSURBEntryAllocationSize;
+   uint32_t                                     VSNumberofURBEntries;
+};
+
+static inline void
+GEN8_3DSTATE_URB_VS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_3DSTATE_URB_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->VSURBStartingAddress, 25, 31) |
+      __gen_field(values->VSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->VSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_VS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 16,                  \
+   .DwordLength          =  7
+
+#define GEN8_3DSTATE_VS_length 0x00000009
+
+struct GEN8_3DSTATE_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint64_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleVertexDispatch;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         AccessesUAV;
+   bool                                         SoftwareExceptionEnable;
+   uint64_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         StatisticsEnable;
+   bool                                         SIMD8DispatchEnable;
+   bool                                         VertexCacheDisable;
+   bool                                         FunctionEnable;
+   uint32_t                                     VertexURBEntryOutputReadOffset;
+   uint32_t                                     VertexURBEntryOutputLength;
+   uint32_t                                     UserClipDistanceClipTestEnableBitmask;
+   uint32_t                                     UserClipDistanceCullTestEnableBitmask;
+};
+
+static inline void
+GEN8_3DSTATE_VS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint64_t qw1 =
+      __gen_offset(values->KernelStartPointer, 6, 63) |
+      0;
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->SingleVertexDispatch, 31, 31) |
+      __gen_field(values->VectorMaskEnable, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->AccessesUAV, 12, 12) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   uint64_t qw4 =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 63) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+   dw[6] =
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 20, 24) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[7] =
+      __gen_field(values->MaximumNumberofThreads, 23, 31) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->SIMD8DispatchEnable, 2, 2) |
+      __gen_field(values->VertexCacheDisable, 1, 1) |
+      __gen_field(values->FunctionEnable, 0, 0) |
+      0;
+
+   dw[8] =
+      __gen_field(values->VertexURBEntryOutputReadOffset, 21, 26) |
+      __gen_field(values->VertexURBEntryOutputLength, 16, 20) |
+      __gen_field(values->UserClipDistanceClipTestEnableBitmask, 8, 15) |
+      __gen_field(values->UserClipDistanceCullTestEnableBitmask, 0, 7) |
+      0;
+
+}
+
+#define GEN8_GPGPU_CSR_BASE_ADDRESS_length_bias 0x00000002
+#define GEN8_GPGPU_CSR_BASE_ADDRESS_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  1
+
+#define GEN8_GPGPU_CSR_BASE_ADDRESS_length 0x00000003
+
+struct GEN8_GPGPU_CSR_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GPGPUCSRBaseAddress;
+};
+
+static inline void
+GEN8_GPGPU_CSR_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN8_GPGPU_CSR_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->GPGPUCSRBaseAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+}
+
+#define GEN8_MI_ATOMIC_length_bias 0x00000002
+#define GEN8_MI_ATOMIC_header                   \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 47
+
+#define GEN8_MI_ATOMIC_length 0x00000003
+
+struct GEN8_MI_ATOMIC {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     MemoryType;
+   uint32_t                                     PostSyncOperation;
+#define     DWORD                                              0
+#define     QWORD                                              1
+#define     OCTWORD                                            2
+#define     RESERVED                                           3
+   uint32_t                                     DataSize;
+   uint32_t                                     InlineData;
+   uint32_t                                     CSSTALL;
+   uint32_t                                     ReturnDataControl;
+   uint32_t                                     ATOMICOPCODE;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           MemoryAddress;
+   uint32_t                                     Operand1DataDword0;
+   uint32_t                                     Operand2DataDword0;
+   uint32_t                                     Operand1DataDword1;
+   uint32_t                                     Operand2DataDword1;
+   uint32_t                                     Operand1DataDword2;
+   uint32_t                                     Operand2DataDword2;
+   uint32_t                                     Operand1DataDword3;
+   uint32_t                                     Operand2DataDword3;
+};
+
+static inline void
+GEN8_MI_ATOMIC_pack(__gen_user_data *data, void * restrict dst,
+                    const struct GEN8_MI_ATOMIC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->MemoryType, 22, 22) |
+      __gen_field(values->PostSyncOperation, 21, 21) |
+      __gen_field(values->DataSize, 19, 20) |
+      __gen_field(values->InlineData, 18, 18) |
+      __gen_field(values->CSSTALL, 17, 17) |
+      __gen_field(values->ReturnDataControl, 16, 16) |
+      __gen_field(values->ATOMICOPCODE, 8, 15) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->MemoryAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->Operand1DataDword0, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->Operand2DataDword0, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->Operand1DataDword1, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->Operand2DataDword1, 0, 31) |
+      0;
+
+   dw[7] =
+      __gen_field(values->Operand1DataDword2, 0, 31) |
+      0;
+
+   dw[8] =
+      __gen_field(values->Operand2DataDword2, 0, 31) |
+      0;
+
+   dw[9] =
+      __gen_field(values->Operand1DataDword3, 0, 31) |
+      0;
+
+   dw[10] =
+      __gen_field(values->Operand2DataDword3, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MI_LOAD_REGISTER_REG_length_bias 0x00000002
+#define GEN8_MI_LOAD_REGISTER_REG_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 42,                  \
+   .DwordLength          =  1
+
+#define GEN8_MI_LOAD_REGISTER_REG_length 0x00000003
+
+struct GEN8_MI_LOAD_REGISTER_REG {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SourceRegisterAddress;
+   uint32_t                                     DestinationRegisterAddress;
+};
+
+static inline void
+GEN8_MI_LOAD_REGISTER_REG_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_MI_LOAD_REGISTER_REG * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SourceRegisterAddress, 2, 22) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->DestinationRegisterAddress, 2, 22) |
+      0;
+
+}
+
+#define GEN8_MI_SEMAPHORE_SIGNAL_length_bias 0x00000002
+#define GEN8_MI_SEMAPHORE_SIGNAL_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 27,                  \
+   .DwordLength          =  0
+
+#define GEN8_MI_SEMAPHORE_SIGNAL_length 0x00000002
+
+struct GEN8_MI_SEMAPHORE_SIGNAL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     PostSyncOperation;
+#define     RCS                                                0
+#define     VCS0                                               1
+#define     BCS                                                2
+#define     VECS                                               3
+#define     VCS1                                               4
+   uint32_t                                     TargetEngineSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     TargetContextID;
+};
+
+static inline void
+GEN8_MI_SEMAPHORE_SIGNAL_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_MI_SEMAPHORE_SIGNAL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->PostSyncOperation, 21, 21) |
+      __gen_field(values->TargetEngineSelect, 15, 17) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->TargetContextID, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MI_SEMAPHORE_WAIT_length_bias 0x00000002
+#define GEN8_MI_SEMAPHORE_WAIT_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 28,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_SEMAPHORE_WAIT_length 0x00000004
+
+struct GEN8_MI_SEMAPHORE_WAIT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     MemoryType;
+#define     PollingMode                                        1
+#define     SignalMode                                         0
+   uint32_t                                     WaitMode;
+#define     SAD_GREATER_THAN_SDD                               0
+#define     SAD_GREATER_THAN_OR_EQUAL_SDD                      1
+#define     SAD_LESS_THAN_SDD                                  2
+#define     SAD_LESS_THAN_OR_EQUAL_SDD                         3
+#define     SAD_EQUAL_SDD                                      4
+#define     SAD_NOT_EQUAL_SDD                                  5
+   uint32_t                                     CompareOperation;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SemaphoreDataDword;
+   __gen_address_type                           SemaphoreAddress;
+};
+
+static inline void
+GEN8_MI_SEMAPHORE_WAIT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_MI_SEMAPHORE_WAIT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->MemoryType, 22, 22) |
+      __gen_field(values->WaitMode, 15, 15) |
+      __gen_field(values->CompareOperation, 12, 14) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SemaphoreDataDword, 0, 31) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->SemaphoreAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+}
+
+#define GEN8_MI_STORE_REGISTER_MEM_length_bias 0x00000002
+#define GEN8_MI_STORE_REGISTER_MEM_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 36,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_STORE_REGISTER_MEM_length 0x00000004
+
+struct GEN8_MI_STORE_REGISTER_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN8_MI_STORE_REGISTER_MEM_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN8_MI_STORE_REGISTER_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->PredicateEnable, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterAddress, 2, 22) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+}
+
+#define GEN8_PIPELINE_SELECT_length_bias 0x00000001
+#define GEN8_PIPELINE_SELECT_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  1,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4
+
+#define GEN8_PIPELINE_SELECT_length 0x00000001
+
+struct GEN8_PIPELINE_SELECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+#define     _3D                                                0
+#define     Media                                              1
+#define     GPGPU                                              2
+   uint32_t                                     PipelineSelection;
+};
+
+static inline void
+GEN8_PIPELINE_SELECT_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN8_PIPELINE_SELECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->PipelineSelection, 0, 1) |
+      0;
+
+}
+
+#define GEN8_STATE_BASE_ADDRESS_length_bias 0x00000002
+#define GEN8_STATE_BASE_ADDRESS_header          \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  1,                  \
+   .DwordLength          = 14
+
+#define GEN8_STATE_BASE_ADDRESS_length 0x00000010
+
+#define GEN8_MEMORY_OBJECT_CONTROL_STATE_length 0x00000001
+
+struct GEN8_MEMORY_OBJECT_CONTROL_STATE {
+#define     UCwithFenceifcoherentcycle                         0
+#define     UCUncacheable                                      1
+#define     WT                                                 2
+#define     WB                                                 3
+   uint32_t                                     MemoryTypeLLCeLLCCacheabilityControl;
+#define     eLLCOnlywheneDRAMispresentelsegetsallocatedinLLC       0
+#define     LLCOnly                                            1
+#define     LLCeLLCAllowed                                     2
+#define     L3DefertoPATforLLCeLLCselection                    3
+   uint32_t                                     TargetCache;
+   uint32_t                                     AgeforQUADLRU;
+};
+
+static inline void
+GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN8_MEMORY_OBJECT_CONTROL_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->MemoryTypeLLCeLLCCacheabilityControl, 5, 6) |
+      __gen_field(values->TargetCache, 3, 4) |
+      __gen_field(values->AgeforQUADLRU, 0, 1) |
+      0;
+
+}
+
+struct GEN8_STATE_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GeneralStateBaseAddress;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      GeneralStateMemoryObjectControlState;
+   bool                                         GeneralStateBaseAddressModifyEnable;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      StatelessDataPortAccessMemoryObjectControlState;
+   __gen_address_type                           SurfaceStateBaseAddress;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      SurfaceStateMemoryObjectControlState;
+   bool                                         SurfaceStateBaseAddressModifyEnable;
+   __gen_address_type                           DynamicStateBaseAddress;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      DynamicStateMemoryObjectControlState;
+   bool                                         DynamicStateBaseAddressModifyEnable;
+   __gen_address_type                           IndirectObjectBaseAddress;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      IndirectObjectMemoryObjectControlState;
+   bool                                         IndirectObjectBaseAddressModifyEnable;
+   __gen_address_type                           InstructionBaseAddress;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      InstructionMemoryObjectControlState;
+   bool                                         InstructionBaseAddressModifyEnable;
+   uint32_t                                     GeneralStateBufferSize;
+   bool                                         GeneralStateBufferSizeModifyEnable;
+   uint32_t                                     DynamicStateBufferSize;
+   bool                                         DynamicStateBufferSizeModifyEnable;
+   uint32_t                                     IndirectObjectBufferSize;
+   bool                                         IndirectObjectBufferSizeModifyEnable;
+   uint32_t                                     InstructionBufferSize;
+   bool                                         InstructionBuffersizeModifyEnable;
+};
+
+static inline void
+GEN8_STATE_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN8_STATE_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_GeneralStateMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_GeneralStateMemoryObjectControlState, &values->GeneralStateMemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(dw_GeneralStateMemoryObjectControlState, 4, 10) |
+      __gen_field(values->GeneralStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->GeneralStateBaseAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   uint32_t dw_StatelessDataPortAccessMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_StatelessDataPortAccessMemoryObjectControlState, &values->StatelessDataPortAccessMemoryObjectControlState);
+   dw[3] =
+      __gen_field(dw_StatelessDataPortAccessMemoryObjectControlState, 16, 22) |
+      0;
+
+   uint32_t dw_SurfaceStateMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceStateMemoryObjectControlState, &values->SurfaceStateMemoryObjectControlState);
+   uint32_t dw4 =
+      __gen_field(dw_SurfaceStateMemoryObjectControlState, 4, 10) |
+      __gen_field(values->SurfaceStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   uint64_t qw4 =
+      __gen_combine_address(data, &dw[4], values->SurfaceStateBaseAddress, dw4);
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+   uint32_t dw_DynamicStateMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_DynamicStateMemoryObjectControlState, &values->DynamicStateMemoryObjectControlState);
+   uint32_t dw6 =
+      __gen_field(dw_DynamicStateMemoryObjectControlState, 4, 10) |
+      __gen_field(values->DynamicStateBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   uint64_t qw6 =
+      __gen_combine_address(data, &dw[6], values->DynamicStateBaseAddress, dw6);
+
+   dw[6] = qw6;
+   dw[7] = qw6 >> 32;
+
+   uint32_t dw_IndirectObjectMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_IndirectObjectMemoryObjectControlState, &values->IndirectObjectMemoryObjectControlState);
+   uint32_t dw8 =
+      __gen_field(dw_IndirectObjectMemoryObjectControlState, 4, 10) |
+      __gen_field(values->IndirectObjectBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   uint64_t qw8 =
+      __gen_combine_address(data, &dw[8], values->IndirectObjectBaseAddress, dw8);
+
+   dw[8] = qw8;
+   dw[9] = qw8 >> 32;
+
+   uint32_t dw_InstructionMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_InstructionMemoryObjectControlState, &values->InstructionMemoryObjectControlState);
+   uint32_t dw10 =
+      __gen_field(dw_InstructionMemoryObjectControlState, 4, 10) |
+      __gen_field(values->InstructionBaseAddressModifyEnable, 0, 0) |
+      0;
+
+   uint64_t qw10 =
+      __gen_combine_address(data, &dw[10], values->InstructionBaseAddress, dw10);
+
+   dw[10] = qw10;
+   dw[11] = qw10 >> 32;
+
+   dw[12] =
+      __gen_field(values->GeneralStateBufferSize, 12, 31) |
+      __gen_field(values->GeneralStateBufferSizeModifyEnable, 0, 0) |
+      0;
+
+   dw[13] =
+      __gen_field(values->DynamicStateBufferSize, 12, 31) |
+      __gen_field(values->DynamicStateBufferSizeModifyEnable, 0, 0) |
+      0;
+
+   dw[14] =
+      __gen_field(values->IndirectObjectBufferSize, 12, 31) |
+      __gen_field(values->IndirectObjectBufferSizeModifyEnable, 0, 0) |
+      0;
+
+   dw[15] =
+      __gen_field(values->InstructionBufferSize, 12, 31) |
+      __gen_field(values->InstructionBuffersizeModifyEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN8_STATE_PREFETCH_length_bias 0x00000002
+#define GEN8_STATE_PREFETCH_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  3,                  \
+   .DwordLength          =  0
+
+#define GEN8_STATE_PREFETCH_length 0x00000002
+
+struct GEN8_STATE_PREFETCH {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           PrefetchPointer;
+   uint32_t                                     PrefetchCount;
+};
+
+static inline void
+GEN8_STATE_PREFETCH_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_STATE_PREFETCH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->PrefetchCount, 0, 2) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->PrefetchPointer, dw1);
+
+}
+
+#define GEN8_STATE_SIP_length_bias 0x00000002
+#define GEN8_STATE_SIP_header                   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  2,                  \
+   .DwordLength          =  1
+
+#define GEN8_STATE_SIP_length 0x00000003
+
+struct GEN8_STATE_SIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint64_t                                     SystemInstructionPointer;
+};
+
+static inline void
+GEN8_STATE_SIP_pack(__gen_user_data *data, void * restrict dst,
+                    const struct GEN8_STATE_SIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint64_t qw1 =
+      __gen_offset(values->SystemInstructionPointer, 4, 63) |
+      0;
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+}
+
+#define GEN8_SWTESS_BASE_ADDRESS_length_bias 0x00000002
+#define GEN8_SWTESS_BASE_ADDRESS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  0,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  3,                  \
+   .DwordLength          =  0
+
+#define GEN8_SWTESS_BASE_ADDRESS_length 0x00000002
+
+struct GEN8_SWTESS_BASE_ADDRESS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           SWTessellationBaseAddress;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      SWTessellationMemoryObjectControlState;
+};
+
+static inline void
+GEN8_SWTESS_BASE_ADDRESS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_SWTESS_BASE_ADDRESS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SWTessellationMemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SWTessellationMemoryObjectControlState, &values->SWTessellationMemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(dw_SWTessellationMemoryObjectControlState, 8, 11) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->SWTessellationBaseAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+}
+
+#define GEN8_3DPRIMITIVE_length_bias 0x00000002
+#define GEN8_3DPRIMITIVE_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  3,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  5
+
+#define GEN8_3DPRIMITIVE_length 0x00000007
+
+struct GEN8_3DPRIMITIVE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         IndirectParameterEnable;
+   uint32_t                                     UAVCoherencyRequired;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   bool                                         EndOffsetEnable;
+#define     SEQUENTIAL                                         0
+#define     RANDOM                                             1
+   uint32_t                                     VertexAccessType;
+   uint32_t                                     PrimitiveTopologyType;
+   uint32_t                                     VertexCountPerInstance;
+   uint32_t                                     StartVertexLocation;
+   uint32_t                                     InstanceCount;
+   uint32_t                                     StartInstanceLocation;
+   uint32_t                                     BaseVertexLocation;
+};
+
+static inline void
+GEN8_3DPRIMITIVE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN8_3DPRIMITIVE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->IndirectParameterEnable, 10, 10) |
+      __gen_field(values->UAVCoherencyRequired, 9, 9) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->EndOffsetEnable, 9, 9) |
+      __gen_field(values->VertexAccessType, 8, 8) |
+      __gen_field(values->PrimitiveTopologyType, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->VertexCountPerInstance, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->StartVertexLocation, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->InstanceCount, 0, 31) |
+      0;
+
+   dw[5] =
+      __gen_field(values->StartInstanceLocation, 0, 31) |
+      0;
+
+   dw[6] =
+      __gen_field(values->BaseVertexLocation, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_AA_LINE_PARAMETERS_length_bias 0x00000002
+#define GEN8_3DSTATE_AA_LINE_PARAMETERS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 10,                  \
+   .DwordLength          =  1
+
+#define GEN8_3DSTATE_AA_LINE_PARAMETERS_length 0x00000003
+
+struct GEN8_3DSTATE_AA_LINE_PARAMETERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   float                                        AAPointCoverageBias;
+   float                                        AACoverageBias;
+   float                                        AAPointCoverageSlope;
+   float                                        AACoverageSlope;
+   float                                        AAPointCoverageEndCapBias;
+   float                                        AACoverageEndCapBias;
+   float                                        AAPointCoverageEndCapSlope;
+   float                                        AACoverageEndCapSlope;
+};
+
+static inline void
+GEN8_3DSTATE_AA_LINE_PARAMETERS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_3DSTATE_AA_LINE_PARAMETERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AAPointCoverageBias * (1 << 8), 24, 31) |
+      __gen_field(values->AACoverageBias * (1 << 8), 16, 23) |
+      __gen_field(values->AAPointCoverageSlope * (1 << 8), 8, 15) |
+      __gen_field(values->AACoverageSlope * (1 << 8), 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->AAPointCoverageEndCapBias * (1 << 8), 24, 31) |
+      __gen_field(values->AACoverageEndCapBias * (1 << 8), 16, 23) |
+      __gen_field(values->AAPointCoverageEndCapSlope * (1 << 8), 8, 15) |
+      __gen_field(values->AACoverageEndCapSlope * (1 << 8), 0, 7) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 70
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_DS_length 0x00000000
+
+#define GEN8_BINDING_TABLE_EDIT_ENTRY_length 0x00000001
+
+struct GEN8_BINDING_TABLE_EDIT_ENTRY {
+   uint32_t                                     BindingTableIndex;
+   uint32_t                                     SurfaceStatePointer;
+};
+
+static inline void
+GEN8_BINDING_TABLE_EDIT_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                                   const struct GEN8_BINDING_TABLE_EDIT_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->BindingTableIndex, 16, 23) |
+      __gen_offset(values->SurfaceStatePointer, 0, 15) |
+      0;
+
+}
+
+struct GEN8_3DSTATE_BINDING_TABLE_EDIT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_EDIT_DS_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_BINDING_TABLE_EDIT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 68
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_GS_length 0x00000000
+
+struct GEN8_3DSTATE_BINDING_TABLE_EDIT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_EDIT_GS_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_BINDING_TABLE_EDIT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 69
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_HS_length 0x00000000
+
+struct GEN8_3DSTATE_BINDING_TABLE_EDIT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_EDIT_HS_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_BINDING_TABLE_EDIT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 71
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_PS_length 0x00000000
+
+struct GEN8_3DSTATE_BINDING_TABLE_EDIT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_EDIT_PS_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_BINDING_TABLE_EDIT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 67
+
+#define GEN8_3DSTATE_BINDING_TABLE_EDIT_VS_length 0x00000000
+
+struct GEN8_3DSTATE_BINDING_TABLE_EDIT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BindingTableBlockClear;
+#define     AllCores                                           3
+#define     Core1                                              2
+#define     Core0                                              1
+   uint32_t                                     BindingTableEditTarget;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_EDIT_VS_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_BINDING_TABLE_EDIT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BindingTableBlockClear, 16, 31) |
+      __gen_field(values->BindingTableEditTarget, 0, 1) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 40,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS_length 0x00000002
+
+struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDSBindingTable;
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 41,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS_length 0x00000002
+
+struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoGSBindingTable;
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoGSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 39,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS_length 0x00000002
+
+struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoHSBindingTable;
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoHSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 42,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS_length 0x00000002
+
+struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoPSBindingTable;
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoPSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 38,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS_length 0x00000002
+
+struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoVSBindingTable;
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoVSBindingTable, 5, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC_length_bias 0x00000002
+#define GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 25,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC_length 0x00000004
+
+struct GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BindingTablePoolBaseAddress;
+   uint32_t                                     BindingTablePoolEnable;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      SurfaceObjectControlState;
+#define     NoValidData                                        0
+   uint32_t                                     BindingTablePoolBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC_pack(__gen_user_data *data, void * restrict dst,
+                                           const struct GEN8_3DSTATE_BINDING_TABLE_POOL_ALLOC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SurfaceObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SurfaceObjectControlState, &values->SurfaceObjectControlState);
+   uint32_t dw1 =
+      __gen_field(values->BindingTablePoolEnable, 11, 11) |
+      __gen_field(dw_SurfaceObjectControlState, 0, 6) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->BindingTablePoolBaseAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->BindingTablePoolBufferSize, 12, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_BLEND_STATE_POINTERS_length_bias 0x00000002
+#define GEN8_3DSTATE_BLEND_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 36,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_BLEND_STATE_POINTERS_length 0x00000002
+
+struct GEN8_3DSTATE_BLEND_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     BlendStatePointer;
+   bool                                         BlendStatePointerValid;
+};
+
+static inline void
+GEN8_3DSTATE_BLEND_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                       const struct GEN8_3DSTATE_BLEND_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->BlendStatePointer, 6, 31) |
+      __gen_field(values->BlendStatePointerValid, 0, 0) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_CC_STATE_POINTERS_length_bias 0x00000002
+#define GEN8_3DSTATE_CC_STATE_POINTERS_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 14,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_CC_STATE_POINTERS_length 0x00000002
+
+struct GEN8_3DSTATE_CC_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ColorCalcStatePointer;
+   bool                                         ColorCalcStatePointerValid;
+};
+
+static inline void
+GEN8_3DSTATE_CC_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN8_3DSTATE_CC_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ColorCalcStatePointer, 6, 31) |
+      __gen_field(values->ColorCalcStatePointerValid, 0, 0) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_CHROMA_KEY_length_bias 0x00000002
+#define GEN8_3DSTATE_CHROMA_KEY_header          \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_CHROMA_KEY_length 0x00000004
+
+struct GEN8_3DSTATE_CHROMA_KEY {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ChromaKeyTableIndex;
+   uint32_t                                     ChromaKeyLowValue;
+   uint32_t                                     ChromaKeyHighValue;
+};
+
+static inline void
+GEN8_3DSTATE_CHROMA_KEY_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN8_3DSTATE_CHROMA_KEY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ChromaKeyTableIndex, 30, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChromaKeyLowValue, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ChromaKeyHighValue, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_CLEAR_PARAMS_length_bias 0x00000002
+#define GEN8_3DSTATE_CLEAR_PARAMS_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  4,                  \
+   .DwordLength          =  1
+
+#define GEN8_3DSTATE_CLEAR_PARAMS_length 0x00000003
+
+struct GEN8_3DSTATE_CLEAR_PARAMS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   float                                        DepthClearValue;
+   bool                                         DepthClearValueValid;
+};
+
+static inline void
+GEN8_3DSTATE_CLEAR_PARAMS_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_3DSTATE_CLEAR_PARAMS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_float(values->DepthClearValue) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DepthClearValueValid, 0, 0) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_CLIP_length_bias 0x00000002
+#define GEN8_3DSTATE_CLIP_header                \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 18,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_CLIP_length 0x00000004
+
+struct GEN8_3DSTATE_CLIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     Normal                                             0
+#define     Force                                              1
+   bool                                         ForceUserClipDistanceCullTestEnableBitmask;
+#define     _8Bit                                              0
+#define     _4Bit                                              1
+   uint32_t                                     VertexSubPixelPrecisionSelect;
+   bool                                         EarlyCullEnable;
+#define     Normal                                             0
+#define     Force                                              1
+   bool                                         ForceUserClipDistanceClipTestEnableBitmask;
+#define     Normal                                             0
+#define     Force                                              1
+   bool                                         ForceClipMode;
+   bool                                         ClipperStatisticsEnable;
+   uint32_t                                     UserClipDistanceCullTestEnableBitmask;
+   bool                                         ClipEnable;
+#define     API_OGL                                            0
+   uint32_t                                     APIMode;
+   bool                                         ViewportXYClipTestEnable;
+   bool                                         GuardbandClipTestEnable;
+   uint32_t                                     UserClipDistanceClipTestEnableBitmask;
+#define     NORMAL                                             0
+#define     REJECT_ALL                                         3
+#define     ACCEPT_ALL                                         4
+   uint32_t                                     ClipMode;
+   bool                                         PerspectiveDivideDisable;
+   bool                                         NonPerspectiveBarycentricEnable;
+   uint32_t                                     TriangleStripListProvokingVertexSelect;
+   uint32_t                                     LineStripListProvokingVertexSelect;
+   uint32_t                                     TriangleFanProvokingVertexSelect;
+   float                                        MinimumPointWidth;
+   float                                        MaximumPointWidth;
+   bool                                         ForceZeroRTAIndexEnable;
+   uint32_t                                     MaximumVPIndex;
+};
+
+static inline void
+GEN8_3DSTATE_CLIP_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_3DSTATE_CLIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ForceUserClipDistanceCullTestEnableBitmask, 20, 20) |
+      __gen_field(values->VertexSubPixelPrecisionSelect, 19, 19) |
+      __gen_field(values->EarlyCullEnable, 18, 18) |
+      __gen_field(values->ForceUserClipDistanceClipTestEnableBitmask, 17, 17) |
+      __gen_field(values->ForceClipMode, 16, 16) |
+      __gen_field(values->ClipperStatisticsEnable, 10, 10) |
+      __gen_field(values->UserClipDistanceCullTestEnableBitmask, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClipEnable, 31, 31) |
+      __gen_field(values->APIMode, 30, 30) |
+      __gen_field(values->ViewportXYClipTestEnable, 28, 28) |
+      __gen_field(values->GuardbandClipTestEnable, 26, 26) |
+      __gen_field(values->UserClipDistanceClipTestEnableBitmask, 16, 23) |
+      __gen_field(values->ClipMode, 13, 15) |
+      __gen_field(values->PerspectiveDivideDisable, 9, 9) |
+      __gen_field(values->NonPerspectiveBarycentricEnable, 8, 8) |
+      __gen_field(values->TriangleStripListProvokingVertexSelect, 4, 5) |
+      __gen_field(values->LineStripListProvokingVertexSelect, 2, 3) |
+      __gen_field(values->TriangleFanProvokingVertexSelect, 0, 1) |
+      0;
+
+   dw[3] =
+      __gen_field(values->MinimumPointWidth * (1 << 3), 17, 27) |
+      __gen_field(values->MaximumPointWidth * (1 << 3), 6, 16) |
+      __gen_field(values->ForceZeroRTAIndexEnable, 5, 5) |
+      __gen_field(values->MaximumVPIndex, 0, 3) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_CONSTANT_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_CONSTANT_DS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 26,                  \
+   .DwordLength          =  9
+
+#define GEN8_3DSTATE_CONSTANT_DS_length 0x0000000b
+
+#define GEN8_3DSTATE_CONSTANT_BODY_length 0x0000000a
+
+struct GEN8_3DSTATE_CONSTANT_BODY {
+   uint32_t                                     ConstantBuffer1ReadLength;
+   uint32_t                                     ConstantBuffer0ReadLength;
+   uint32_t                                     ConstantBuffer3ReadLength;
+   uint32_t                                     ConstantBuffer2ReadLength;
+   __gen_address_type                           PointerToConstantBuffer0;
+   __gen_address_type                           PointerToConstantBuffer1;
+   __gen_address_type                           PointerToConstantBuffer2;
+   __gen_address_type                           PointerToConstantBuffer3;
+};
+
+static inline void
+GEN8_3DSTATE_CONSTANT_BODY_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN8_3DSTATE_CONSTANT_BODY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ConstantBuffer1ReadLength, 16, 31) |
+      __gen_field(values->ConstantBuffer0ReadLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBuffer3ReadLength, 16, 31) |
+      __gen_field(values->ConstantBuffer2ReadLength, 0, 15) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->PointerToConstantBuffer0, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   uint32_t dw4 =
+      0;
+
+   uint64_t qw4 =
+      __gen_combine_address(data, &dw[4], values->PointerToConstantBuffer1, dw4);
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+   uint32_t dw6 =
+      0;
+
+   uint64_t qw6 =
+      __gen_combine_address(data, &dw[6], values->PointerToConstantBuffer2, dw6);
+
+   dw[6] = qw6;
+   dw[7] = qw6 >> 32;
+
+   uint32_t dw8 =
+      0;
+
+   uint64_t qw8 =
+      __gen_combine_address(data, &dw[8], values->PointerToConstantBuffer3, dw8);
+
+   dw[8] = qw8;
+   dw[9] = qw8 >> 32;
+
+}
+
+struct GEN8_3DSTATE_CONSTANT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      ConstantBufferObjectControlState;
+   uint32_t                                     DwordLength;
+   struct GEN8_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN8_3DSTATE_CONSTANT_DS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_CONSTANT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_ConstantBufferObjectControlState, 8, 14) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN8_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN8_3DSTATE_CONSTANT_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_CONSTANT_GS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 22,                  \
+   .DwordLength          =  9
+
+#define GEN8_3DSTATE_CONSTANT_GS_length 0x0000000b
+
+struct GEN8_3DSTATE_CONSTANT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      ConstantBufferObjectControlState;
+   uint32_t                                     DwordLength;
+   struct GEN8_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN8_3DSTATE_CONSTANT_GS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_CONSTANT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_ConstantBufferObjectControlState, 8, 14) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN8_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN8_3DSTATE_CONSTANT_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_CONSTANT_HS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 25,                  \
+   .DwordLength          =  9
+
+#define GEN8_3DSTATE_CONSTANT_HS_length 0x0000000b
+
+struct GEN8_3DSTATE_CONSTANT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      ConstantBufferObjectControlState;
+   uint32_t                                     DwordLength;
+   struct GEN8_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN8_3DSTATE_CONSTANT_HS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_CONSTANT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_ConstantBufferObjectControlState, 8, 14) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN8_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN8_3DSTATE_CONSTANT_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_CONSTANT_PS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 23,                  \
+   .DwordLength          =  9
+
+#define GEN8_3DSTATE_CONSTANT_PS_length 0x0000000b
+
+struct GEN8_3DSTATE_CONSTANT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      ConstantBufferObjectControlState;
+   uint32_t                                     DwordLength;
+   struct GEN8_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN8_3DSTATE_CONSTANT_PS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_CONSTANT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_ConstantBufferObjectControlState, 8, 14) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN8_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN8_3DSTATE_CONSTANT_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_CONSTANT_VS_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 21,                  \
+   .DwordLength          =  9
+
+#define GEN8_3DSTATE_CONSTANT_VS_length 0x0000000b
+
+struct GEN8_3DSTATE_CONSTANT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      ConstantBufferObjectControlState;
+   uint32_t                                     DwordLength;
+   struct GEN8_3DSTATE_CONSTANT_BODY            ConstantBody;
+};
+
+static inline void
+GEN8_3DSTATE_CONSTANT_VS_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_CONSTANT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_ConstantBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_ConstantBufferObjectControlState, &values->ConstantBufferObjectControlState);
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(dw_ConstantBufferObjectControlState, 8, 14) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   GEN8_3DSTATE_CONSTANT_BODY_pack(data, &dw[1], &values->ConstantBody);
+}
+
+#define GEN8_3DSTATE_DEPTH_BUFFER_length_bias 0x00000002
+#define GEN8_3DSTATE_DEPTH_BUFFER_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  5,                  \
+   .DwordLength          =  6
+
+#define GEN8_3DSTATE_DEPTH_BUFFER_length 0x00000008
+
+struct GEN8_3DSTATE_DEPTH_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     SURFTYPE_1D                                        0
+#define     SURFTYPE_2D                                        1
+#define     SURFTYPE_3D                                        2
+#define     SURFTYPE_CUBE                                      3
+#define     SURFTYPE_NULL                                      7
+   uint32_t                                     SurfaceType;
+   bool                                         DepthWriteEnable;
+   bool                                         StencilWriteEnable;
+   bool                                         HierarchicalDepthBufferEnable;
+#define     D32_FLOAT                                          1
+#define     D24_UNORM_X8_UINT                                  3
+#define     D16_UNORM                                          5
+   uint32_t                                     SurfaceFormat;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     Height;
+   uint32_t                                     Width;
+   uint32_t                                     LOD;
+   uint32_t                                     Depth;
+   uint32_t                                     MinimumArrayElement;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      DepthBufferObjectControlState;
+   uint32_t                                     RenderTargetViewExtent;
+   uint32_t                                     SurfaceQPitch;
+};
+
+static inline void
+GEN8_3DSTATE_DEPTH_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_3DSTATE_DEPTH_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SurfaceType, 29, 31) |
+      __gen_field(values->DepthWriteEnable, 28, 28) |
+      __gen_field(values->StencilWriteEnable, 27, 27) |
+      __gen_field(values->HierarchicalDepthBufferEnable, 22, 22) |
+      __gen_field(values->SurfaceFormat, 18, 20) |
+      __gen_field(values->SurfacePitch, 0, 17) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   dw[4] =
+      __gen_field(values->Height, 18, 31) |
+      __gen_field(values->Width, 4, 17) |
+      __gen_field(values->LOD, 0, 3) |
+      0;
+
+   uint32_t dw_DepthBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_DepthBufferObjectControlState, &values->DepthBufferObjectControlState);
+   dw[5] =
+      __gen_field(values->Depth, 21, 31) |
+      __gen_field(values->MinimumArrayElement, 10, 20) |
+      __gen_field(dw_DepthBufferObjectControlState, 0, 6) |
+      0;
+
+   dw[6] =
+      0;
+
+   dw[7] =
+      __gen_field(values->RenderTargetViewExtent, 21, 31) |
+      __gen_field(values->SurfaceQPitch, 0, 14) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_DRAWING_RECTANGLE_length_bias 0x00000002
+#define GEN8_3DSTATE_DRAWING_RECTANGLE_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_DRAWING_RECTANGLE_length 0x00000004
+
+struct GEN8_3DSTATE_DRAWING_RECTANGLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+#define     Legacy                                             0
+#define     Core0Enabled                                       1
+#define     Core1Enabled                                       2
+   uint32_t                                     CoreModeSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ClippedDrawingRectangleYMin;
+   uint32_t                                     ClippedDrawingRectangleXMin;
+   uint32_t                                     ClippedDrawingRectangleYMax;
+   uint32_t                                     ClippedDrawingRectangleXMax;
+   uint32_t                                     DrawingRectangleOriginY;
+   uint32_t                                     DrawingRectangleOriginX;
+};
+
+static inline void
+GEN8_3DSTATE_DRAWING_RECTANGLE_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN8_3DSTATE_DRAWING_RECTANGLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->CoreModeSelect, 14, 15) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ClippedDrawingRectangleYMin, 16, 31) |
+      __gen_field(values->ClippedDrawingRectangleXMin, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClippedDrawingRectangleYMax, 16, 31) |
+      __gen_field(values->ClippedDrawingRectangleXMax, 0, 15) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DrawingRectangleOriginY, 16, 31) |
+      __gen_field(values->DrawingRectangleOriginX, 0, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_DS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 29,                  \
+   .DwordLength          =  7
+
+#define GEN8_3DSTATE_DS_length 0x00000009
+
+struct GEN8_3DSTATE_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint64_t                                     KernelStartPointer;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleDomainPointDispatch;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         AccessesUAV;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint64_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     PatchURBEntryReadLength;
+   uint32_t                                     PatchURBEntryReadOffset;
+   uint32_t                                     MaximumNumberofThreads;
+   bool                                         StatisticsEnable;
+   bool                                         SIMD8DispatchEnable;
+   bool                                         ComputeWCoordinateEnable;
+   bool                                         CacheDisable;
+   bool                                         FunctionEnable;
+   uint32_t                                     VertexURBEntryOutputReadOffset;
+   uint32_t                                     VertexURBEntryOutputLength;
+   uint32_t                                     UserClipDistanceClipTestEnableBitmask;
+   uint32_t                                     UserClipDistanceCullTestEnableBitmask;
+};
+
+static inline void
+GEN8_3DSTATE_DS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint64_t qw1 =
+      __gen_offset(values->KernelStartPointer, 6, 63) |
+      0;
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->SingleDomainPointDispatch, 31, 31) |
+      __gen_field(values->VectorMaskEnable, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->AccessesUAV, 14, 14) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   uint64_t qw4 =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 63) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+   dw[6] =
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 20, 24) |
+      __gen_field(values->PatchURBEntryReadLength, 11, 17) |
+      __gen_field(values->PatchURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[7] =
+      __gen_field(values->MaximumNumberofThreads, 21, 29) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->SIMD8DispatchEnable, 3, 3) |
+      __gen_field(values->ComputeWCoordinateEnable, 2, 2) |
+      __gen_field(values->CacheDisable, 1, 1) |
+      __gen_field(values->FunctionEnable, 0, 0) |
+      0;
+
+   dw[8] =
+      __gen_field(values->VertexURBEntryOutputReadOffset, 21, 26) |
+      __gen_field(values->VertexURBEntryOutputLength, 16, 20) |
+      __gen_field(values->UserClipDistanceClipTestEnableBitmask, 8, 15) |
+      __gen_field(values->UserClipDistanceCullTestEnableBitmask, 0, 7) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_GATHER_CONSTANT_DS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 55
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_DS_length 0x00000000
+
+#define GEN8_GATHER_CONSTANT_ENTRY_length 0x00000001
+
+struct GEN8_GATHER_CONSTANT_ENTRY {
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ChannelMask;
+   uint32_t                                     BindingTableIndexOffset;
+};
+
+static inline void
+GEN8_GATHER_CONSTANT_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN8_GATHER_CONSTANT_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->ConstantBufferOffset, 8, 15) |
+      __gen_field(values->ChannelMask, 4, 7) |
+      __gen_field(values->BindingTableIndexOffset, 0, 3) |
+      0;
+
+}
+
+struct GEN8_3DSTATE_GATHER_CONSTANT_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9GenerateStall;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_GATHER_CONSTANT_DS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_3DSTATE_GATHER_CONSTANT_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9GenerateStall, 5, 5) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_GATHER_CONSTANT_GS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 53
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_GS_length 0x00000000
+
+struct GEN8_3DSTATE_GATHER_CONSTANT_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9GenerateStall;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_GATHER_CONSTANT_GS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_3DSTATE_GATHER_CONSTANT_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9GenerateStall, 5, 5) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_GATHER_CONSTANT_HS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 54
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_HS_length 0x00000000
+
+struct GEN8_3DSTATE_GATHER_CONSTANT_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9GenerateStall;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_GATHER_CONSTANT_HS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_3DSTATE_GATHER_CONSTANT_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9GenerateStall, 5, 5) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_GATHER_CONSTANT_PS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 56
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_PS_length 0x00000000
+
+struct GEN8_3DSTATE_GATHER_CONSTANT_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9GenerateStall;
+   bool                                         ConstantBufferDx9Enable;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_GATHER_CONSTANT_PS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_3DSTATE_GATHER_CONSTANT_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9GenerateStall, 5, 5) |
+      __gen_field(values->ConstantBufferDx9Enable, 4, 4) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_GATHER_CONSTANT_VS_header  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 52
+
+#define GEN8_3DSTATE_GATHER_CONSTANT_VS_length 0x00000000
+
+struct GEN8_3DSTATE_GATHER_CONSTANT_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferValid;
+   uint32_t                                     ConstantBufferBindingTableBlock;
+   uint32_t                                     GatherBufferOffset;
+   bool                                         ConstantBufferDx9GenerateStall;
+   bool                                         ConstantBufferDx9Enable;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_GATHER_CONSTANT_VS_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_3DSTATE_GATHER_CONSTANT_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferValid, 16, 31) |
+      __gen_field(values->ConstantBufferBindingTableBlock, 12, 15) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->GatherBufferOffset, 6, 22) |
+      __gen_field(values->ConstantBufferDx9GenerateStall, 5, 5) |
+      __gen_field(values->ConstantBufferDx9Enable, 4, 4) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_GATHER_POOL_ALLOC_length_bias 0x00000002
+#define GEN8_3DSTATE_GATHER_POOL_ALLOC_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 26,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_GATHER_POOL_ALLOC_length 0x00000004
+
+struct GEN8_3DSTATE_GATHER_POOL_ALLOC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           GatherPoolBaseAddress;
+   bool                                         GatherPoolEnable;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      MemoryObjectControlState;
+   uint32_t                                     GatherPoolBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_GATHER_POOL_ALLOC_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN8_3DSTATE_GATHER_POOL_ALLOC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   uint32_t dw1 =
+      __gen_field(values->GatherPoolEnable, 11, 11) |
+      __gen_field(dw_MemoryObjectControlState, 0, 6) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->GatherPoolBaseAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->GatherPoolBufferSize, 12, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_GS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 17,                  \
+   .DwordLength          =  8
+
+#define GEN8_3DSTATE_GS_length 0x0000000a
+
+struct GEN8_3DSTATE_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint64_t                                     KernelStartPointer;
+   uint32_t                                     SingleProgramFlow;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         AccessesUAV;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     ExpectedVertexCount;
+   uint64_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     OutputVertexSize;
+   uint32_t                                     OutputTopology;
+   uint32_t                                     VertexURBEntryReadLength;
+   bool                                         IncludeVertexHandles;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     ControlDataHeaderSize;
+   uint32_t                                     InstanceControl;
+   uint32_t                                     DefaultStreamId;
+#define     DispatchModeSingle                                 0
+#define     DispatchModeDualInstance                           1
+#define     DispatchModeDualObject                             2
+#define     DispatchModeSIMD8                                  3
+   uint32_t                                     DispatchMode;
+   bool                                         StatisticsEnable;
+   uint32_t                                     InvocationsIncrementValue;
+   bool                                         IncludePrimitiveID;
+   uint32_t                                     Hint;
+#define     LEADING                                            0
+#define     TRAILING                                           1
+   uint32_t                                     ReorderMode;
+   bool                                         DiscardAdjacency;
+   bool                                         Enable;
+#define     CUT                                                0
+#define     SID                                                1
+   uint32_t                                     ControlDataFormat;
+   bool                                         StaticOutput;
+   uint32_t                                     StaticOutputVertexCount;
+   uint32_t                                     VertexURBEntryOutputReadOffset;
+   uint32_t                                     VertexURBEntryOutputLength;
+   uint32_t                                     UserClipDistanceClipTestEnableBitmask;
+   uint32_t                                     UserClipDistanceCullTestEnableBitmask;
+};
+
+static inline void
+GEN8_3DSTATE_GS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint64_t qw1 =
+      __gen_offset(values->KernelStartPointer, 6, 63) |
+      0;
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->SingleProgramFlow, 31, 31) |
+      __gen_field(values->VectorMaskEnable, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->AccessesUAV, 12, 12) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      __gen_field(values->ExpectedVertexCount, 0, 5) |
+      0;
+
+   uint64_t qw4 =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 63) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+   dw[6] =
+      __gen_field(values->OutputVertexSize, 23, 28) |
+      __gen_field(values->OutputTopology, 17, 22) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->IncludeVertexHandles, 10, 10) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 0, 3) |
+      0;
+
+   dw[7] =
+      __gen_field(values->MaximumNumberofThreads, 24, 31) |
+      __gen_field(values->ControlDataHeaderSize, 20, 23) |
+      __gen_field(values->InstanceControl, 15, 19) |
+      __gen_field(values->DefaultStreamId, 13, 14) |
+      __gen_field(values->DispatchMode, 11, 12) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->InvocationsIncrementValue, 5, 9) |
+      __gen_field(values->IncludePrimitiveID, 4, 4) |
+      __gen_field(values->Hint, 3, 3) |
+      __gen_field(values->ReorderMode, 2, 2) |
+      __gen_field(values->DiscardAdjacency, 1, 1) |
+      __gen_field(values->Enable, 0, 0) |
+      0;
+
+   dw[8] =
+      __gen_field(values->ControlDataFormat, 31, 31) |
+      __gen_field(values->StaticOutput, 30, 30) |
+      __gen_field(values->StaticOutputVertexCount, 16, 26) |
+      0;
+
+   dw[9] =
+      __gen_field(values->VertexURBEntryOutputReadOffset, 21, 26) |
+      __gen_field(values->VertexURBEntryOutputLength, 16, 20) |
+      __gen_field(values->UserClipDistanceClipTestEnableBitmask, 8, 15) |
+      __gen_field(values->UserClipDistanceCullTestEnableBitmask, 0, 7) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_HIER_DEPTH_BUFFER_length_bias 0x00000002
+#define GEN8_3DSTATE_HIER_DEPTH_BUFFER_header   \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  7,                  \
+   .DwordLength          =  3
+
+#define GEN8_3DSTATE_HIER_DEPTH_BUFFER_length 0x00000005
+
+struct GEN8_3DSTATE_HIER_DEPTH_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      HierarchicalDepthBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     SurfaceQPitch;
+};
+
+static inline void
+GEN8_3DSTATE_HIER_DEPTH_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN8_3DSTATE_HIER_DEPTH_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_HierarchicalDepthBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_HierarchicalDepthBufferObjectControlState, &values->HierarchicalDepthBufferObjectControlState);
+   dw[1] =
+      __gen_field(dw_HierarchicalDepthBufferObjectControlState, 25, 31) |
+      __gen_field(values->SurfacePitch, 0, 16) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   dw[4] =
+      __gen_field(values->SurfaceQPitch, 0, 14) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_HS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 27,                  \
+   .DwordLength          =  7
+
+#define GEN8_3DSTATE_HS_length 0x00000009
+
+struct GEN8_3DSTATE_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   bool                                         Enable;
+   bool                                         StatisticsEnable;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     InstanceCount;
+   uint64_t                                     KernelStartPointer;
+   uint64_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   bool                                         SingleProgramFlow;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+   bool                                         AccessesUAV;
+   bool                                         IncludeVertexHandles;
+   uint32_t                                     DispatchGRFStartRegisterForURBData;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+};
+
+static inline void
+GEN8_3DSTATE_HS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->SoftwareExceptionEnable, 12, 12) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Enable, 31, 31) |
+      __gen_field(values->StatisticsEnable, 29, 29) |
+      __gen_field(values->MaximumNumberofThreads, 8, 16) |
+      __gen_field(values->InstanceCount, 0, 3) |
+      0;
+
+   uint64_t qw3 =
+      __gen_offset(values->KernelStartPointer, 6, 63) |
+      0;
+
+   dw[3] = qw3;
+   dw[4] = qw3 >> 32;
+
+   uint64_t qw5 =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 63) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[5] = qw5;
+   dw[6] = qw5 >> 32;
+
+   dw[7] =
+      __gen_field(values->SingleProgramFlow, 27, 27) |
+      __gen_field(values->VectorMaskEnable, 26, 26) |
+      __gen_field(values->AccessesUAV, 25, 25) |
+      __gen_field(values->IncludeVertexHandles, 24, 24) |
+      __gen_field(values->DispatchGRFStartRegisterForURBData, 19, 23) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 16) |
+      __gen_field(values->VertexURBEntryReadOffset, 4, 9) |
+      0;
+
+   dw[8] =
+      0;
+
+}
+
+#define GEN8_3DSTATE_INDEX_BUFFER_length_bias 0x00000002
+#define GEN8_3DSTATE_INDEX_BUFFER_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 10,                  \
+   .DwordLength          =  3
+
+#define GEN8_3DSTATE_INDEX_BUFFER_length 0x00000005
+
+struct GEN8_3DSTATE_INDEX_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     INDEX_BYTE                                         0
+#define     INDEX_WORD                                         1
+#define     INDEX_DWORD                                        2
+   uint32_t                                     IndexFormat;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      MemoryObjectControlState;
+   __gen_address_type                           BufferStartingAddress;
+   uint32_t                                     BufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_INDEX_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_3DSTATE_INDEX_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   dw[1] =
+      __gen_field(values->IndexFormat, 8, 9) |
+      __gen_field(dw_MemoryObjectControlState, 0, 6) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->BufferStartingAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   dw[4] =
+      __gen_field(values->BufferSize, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_LINE_STIPPLE_length_bias 0x00000002
+#define GEN8_3DSTATE_LINE_STIPPLE_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  8,                  \
+   .DwordLength          =  1
+
+#define GEN8_3DSTATE_LINE_STIPPLE_length 0x00000003
+
+struct GEN8_3DSTATE_LINE_STIPPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         ModifyEnableCurrentRepeatCounterCurrentStippleIndex;
+   uint32_t                                     CurrentRepeatCounter;
+   uint32_t                                     CurrentStippleIndex;
+   uint32_t                                     LineStipplePattern;
+   float                                        LineStippleInverseRepeatCount;
+   uint32_t                                     LineStippleRepeatCount;
+};
+
+static inline void
+GEN8_3DSTATE_LINE_STIPPLE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_3DSTATE_LINE_STIPPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ModifyEnableCurrentRepeatCounterCurrentStippleIndex, 31, 31) |
+      __gen_field(values->CurrentRepeatCounter, 21, 29) |
+      __gen_field(values->CurrentStippleIndex, 16, 19) |
+      __gen_field(values->LineStipplePattern, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->LineStippleInverseRepeatCount * (1 << 16), 15, 31) |
+      __gen_field(values->LineStippleRepeatCount, 0, 8) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_MONOFILTER_SIZE_length_bias 0x00000002
+#define GEN8_3DSTATE_MONOFILTER_SIZE_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 17,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_MONOFILTER_SIZE_length 0x00000002
+
+struct GEN8_3DSTATE_MONOFILTER_SIZE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     MonochromeFilterWidth;
+   uint32_t                                     MonochromeFilterHeight;
+};
+
+static inline void
+GEN8_3DSTATE_MONOFILTER_SIZE_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN8_3DSTATE_MONOFILTER_SIZE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MonochromeFilterWidth, 3, 5) |
+      __gen_field(values->MonochromeFilterHeight, 0, 2) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_MULTISAMPLE_length_bias 0x00000002
+#define GEN8_3DSTATE_MULTISAMPLE_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 13,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_MULTISAMPLE_length 0x00000002
+
+struct GEN8_3DSTATE_MULTISAMPLE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PixelPositionOffsetEnable;
+#define     CENTER                                             0
+#define     UL_CORNER                                          1
+   uint32_t                                     PixelLocation;
+   uint32_t                                     NumberofMultisamples;
+};
+
+static inline void
+GEN8_3DSTATE_MULTISAMPLE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_MULTISAMPLE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PixelPositionOffsetEnable, 5, 5) |
+      __gen_field(values->PixelLocation, 4, 4) |
+      __gen_field(values->NumberofMultisamples, 1, 3) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_POLY_STIPPLE_OFFSET_length_bias 0x00000002
+#define GEN8_3DSTATE_POLY_STIPPLE_OFFSET_header \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  6,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_POLY_STIPPLE_OFFSET_length 0x00000002
+
+struct GEN8_3DSTATE_POLY_STIPPLE_OFFSET {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PolygonStippleXOffset;
+   uint32_t                                     PolygonStippleYOffset;
+};
+
+static inline void
+GEN8_3DSTATE_POLY_STIPPLE_OFFSET_pack(__gen_user_data *data, void * restrict dst,
+                                      const struct GEN8_3DSTATE_POLY_STIPPLE_OFFSET * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PolygonStippleXOffset, 8, 12) |
+      __gen_field(values->PolygonStippleYOffset, 0, 4) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_POLY_STIPPLE_PATTERN_length_bias 0x00000002
+#define GEN8_3DSTATE_POLY_STIPPLE_PATTERN_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  7,                  \
+   .DwordLength          = 31
+
+#define GEN8_3DSTATE_POLY_STIPPLE_PATTERN_length 0x00000021
+
+struct GEN8_3DSTATE_POLY_STIPPLE_PATTERN {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PatternRow[32];
+};
+
+static inline void
+GEN8_3DSTATE_POLY_STIPPLE_PATTERN_pack(__gen_user_data *data, void * restrict dst,
+                                       const struct GEN8_3DSTATE_POLY_STIPPLE_PATTERN * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   for (uint32_t i = 0, j = 1; i < 32; i += 1, j++) {
+      dw[j] =
+         __gen_field(values->PatternRow[i + 0], 0, 31) |
+         0;
+   }
+
+}
+
+#define GEN8_3DSTATE_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_PS_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 32,                  \
+   .DwordLength          = 10
+
+#define GEN8_3DSTATE_PS_length 0x0000000c
+
+struct GEN8_3DSTATE_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint64_t                                     KernelStartPointer0;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleProgramFlow;
+#define     Dmask                                              0
+#define     Vmask                                              1
+   uint32_t                                     VectorMaskEnable;
+#define     NoSamplers                                         0
+#define     _14Samplers                                        1
+#define     _58Samplers                                        2
+#define     _912Samplers                                       3
+#define     _1316Samplers                                      4
+   uint32_t                                     SamplerCount;
+#define     FlushedtoZero                                      0
+#define     Retained                                           1
+   uint32_t                                     SinglePrecisionDenormalMode;
+   uint32_t                                     BindingTableEntryCount;
+#define     Normal                                             0
+#define     High                                               1
+   uint32_t                                     ThreadDispatchPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+#define     RTNE                                               0
+#define     RU                                                 1
+#define     RD                                                 2
+#define     RTZ                                                3
+   uint32_t                                     RoundingMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint64_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     MaximumNumberofThreadsPerPSD;
+   bool                                         PushConstantEnable;
+   bool                                         RenderTargetFastClearEnable;
+   bool                                         RenderTargetResolveEnable;
+#define     POSOFFSET_NONE                                     0
+#define     POSOFFSET_CENTROID                                 2
+#define     POSOFFSET_SAMPLE                                   3
+   uint32_t                                     PositionXYOffsetSelect;
+   bool                                         _32PixelDispatchEnable;
+   bool                                         _16PixelDispatchEnable;
+   bool                                         _8PixelDispatchEnable;
+   uint32_t                                     DispatchGRFStartRegisterForConstantSetupData0;
+   uint32_t                                     DispatchGRFStartRegisterForConstantSetupData1;
+   uint32_t                                     DispatchGRFStartRegisterForConstantSetupData2;
+   uint64_t                                     KernelStartPointer1;
+   uint64_t                                     KernelStartPointer2;
+};
+
+static inline void
+GEN8_3DSTATE_PS_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint64_t qw1 =
+      __gen_offset(values->KernelStartPointer0, 6, 63) |
+      0;
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->SingleProgramFlow, 31, 31) |
+      __gen_field(values->VectorMaskEnable, 30, 30) |
+      __gen_field(values->SamplerCount, 27, 29) |
+      __gen_field(values->SinglePrecisionDenormalMode, 26, 26) |
+      __gen_field(values->BindingTableEntryCount, 18, 25) |
+      __gen_field(values->ThreadDispatchPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->RoundingMode, 14, 15) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   uint64_t qw4 =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 63) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+   dw[6] =
+      __gen_field(values->MaximumNumberofThreadsPerPSD, 23, 31) |
+      __gen_field(values->PushConstantEnable, 11, 11) |
+      __gen_field(values->RenderTargetFastClearEnable, 8, 8) |
+      __gen_field(values->RenderTargetResolveEnable, 6, 6) |
+      __gen_field(values->PositionXYOffsetSelect, 3, 4) |
+      __gen_field(values->_32PixelDispatchEnable, 2, 2) |
+      __gen_field(values->_16PixelDispatchEnable, 1, 1) |
+      __gen_field(values->_8PixelDispatchEnable, 0, 0) |
+      0;
+
+   dw[7] =
+      __gen_field(values->DispatchGRFStartRegisterForConstantSetupData0, 16, 22) |
+      __gen_field(values->DispatchGRFStartRegisterForConstantSetupData1, 8, 14) |
+      __gen_field(values->DispatchGRFStartRegisterForConstantSetupData2, 0, 6) |
+      0;
+
+   uint64_t qw8 =
+      __gen_offset(values->KernelStartPointer1, 6, 63) |
+      0;
+
+   dw[8] = qw8;
+   dw[9] = qw8 >> 32;
+
+   uint64_t qw10 =
+      __gen_offset(values->KernelStartPointer2, 6, 63) |
+      0;
+
+   dw[10] = qw10;
+   dw[11] = qw10 >> 32;
+
+}
+
+#define GEN8_3DSTATE_PS_BLEND_length_bias 0x00000002
+#define GEN8_3DSTATE_PS_BLEND_header            \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 77,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PS_BLEND_length 0x00000002
+
+struct GEN8_3DSTATE_PS_BLEND {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         AlphaToCoverageEnable;
+   bool                                         HasWriteableRT;
+   bool                                         ColorBufferBlendEnable;
+   uint32_t                                     SourceAlphaBlendFactor;
+   uint32_t                                     DestinationAlphaBlendFactor;
+   uint32_t                                     SourceBlendFactor;
+   uint32_t                                     DestinationBlendFactor;
+   bool                                         AlphaTestEnable;
+   bool                                         IndependentAlphaBlendEnable;
+};
+
+static inline void
+GEN8_3DSTATE_PS_BLEND_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_3DSTATE_PS_BLEND * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AlphaToCoverageEnable, 31, 31) |
+      __gen_field(values->HasWriteableRT, 30, 30) |
+      __gen_field(values->ColorBufferBlendEnable, 29, 29) |
+      __gen_field(values->SourceAlphaBlendFactor, 24, 28) |
+      __gen_field(values->DestinationAlphaBlendFactor, 19, 23) |
+      __gen_field(values->SourceBlendFactor, 14, 18) |
+      __gen_field(values->DestinationBlendFactor, 9, 13) |
+      __gen_field(values->AlphaTestEnable, 8, 8) |
+      __gen_field(values->IndependentAlphaBlendEnable, 7, 7) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_PS_EXTRA_length_bias 0x00000002
+#define GEN8_3DSTATE_PS_EXTRA_header            \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 79,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PS_EXTRA_length 0x00000002
+
+struct GEN8_3DSTATE_PS_EXTRA {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         PixelShaderValid;
+   bool                                         PixelShaderDoesnotwritetoRT;
+   bool                                         oMaskPresenttoRenderTarget;
+   bool                                         PixelShaderKillsPixel;
+#define     PSCDEPTH_OFF                                       0
+#define     PSCDEPTH_ON                                        1
+#define     PSCDEPTH_ON_GE                                     2
+#define     PSCDEPTH_ON_LE                                     3
+   uint32_t                                     PixelShaderComputedDepthMode;
+   bool                                         ForceComputedDepth;
+   bool                                         PixelShaderUsesSourceDepth;
+   bool                                         PixelShaderUsesSourceW;
+   uint32_t                                     Removed;
+   bool                                         AttributeEnable;
+   bool                                         PixelShaderDisablesAlphaToCoverage;
+   bool                                         PixelShaderIsPerSample;
+   bool                                         PixelShaderHasUAV;
+   bool                                         PixelShaderUsesInputCoverageMask;
+};
+
+static inline void
+GEN8_3DSTATE_PS_EXTRA_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_3DSTATE_PS_EXTRA * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PixelShaderValid, 31, 31) |
+      __gen_field(values->PixelShaderDoesnotwritetoRT, 30, 30) |
+      __gen_field(values->oMaskPresenttoRenderTarget, 29, 29) |
+      __gen_field(values->PixelShaderKillsPixel, 28, 28) |
+      __gen_field(values->PixelShaderComputedDepthMode, 26, 27) |
+      __gen_field(values->ForceComputedDepth, 25, 25) |
+      __gen_field(values->PixelShaderUsesSourceDepth, 24, 24) |
+      __gen_field(values->PixelShaderUsesSourceW, 23, 23) |
+      __gen_field(values->Removed, 17, 17) |
+      __gen_field(values->AttributeEnable, 8, 8) |
+      __gen_field(values->PixelShaderDisablesAlphaToCoverage, 7, 7) |
+      __gen_field(values->PixelShaderIsPerSample, 6, 6) |
+      __gen_field(values->PixelShaderHasUAV, 2, 2) |
+      __gen_field(values->PixelShaderUsesInputCoverageMask, 1, 1) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 20,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS_length 0x00000002
+
+struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 21,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS_length 0x00000002
+
+struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 19,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS_length 0x00000002
+
+struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 22,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS_length 0x00000002
+
+struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 18,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS_length 0x00000002
+
+struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ConstantBufferOffset;
+   uint32_t                                     ConstantBufferSize;
+};
+
+static inline void
+GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ConstantBufferOffset, 16, 20) |
+      __gen_field(values->ConstantBufferSize, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_RASTER_length_bias 0x00000002
+#define GEN8_3DSTATE_RASTER_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 80,                  \
+   .DwordLength          =  3
+
+#define GEN8_3DSTATE_RASTER_length 0x00000005
+
+struct GEN8_3DSTATE_RASTER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     DX9OGL                                             0
+#define     DX100                                              1
+#define     DX101                                              2
+   uint32_t                                     APIMode;
+#define     Clockwise                                          0
+#define     CounterClockwise                                   1
+   uint32_t                                     FrontWinding;
+#define     FSC_NUMRASTSAMPLES_0                               0
+#define     FSC_NUMRASTSAMPLES_1                               1
+#define     FSC_NUMRASTSAMPLES_2                               2
+#define     FSC_NUMRASTSAMPLES_4                               3
+#define     FSC_NUMRASTSAMPLES_8                               4
+#define     FSC_NUMRASTSAMPLES_16                              5
+   uint32_t                                     ForcedSampleCount;
+#define     CULLMODE_BOTH                                      0
+#define     CULLMODE_NONE                                      1
+#define     CULLMODE_FRONT                                     2
+#define     CULLMODE_BACK                                      3
+   uint32_t                                     CullMode;
+#define     Normal                                             0
+#define     Force                                              1
+   uint32_t                                     ForceMultisampling;
+   bool                                         SmoothPointEnable;
+   bool                                         DXMultisampleRasterizationEnable;
+#define     MSRASTMODE_OFF_PIXEL                               0
+#define     MSRASTMODE_OFF_PATTERN                             1
+#define     MSRASTMODE_ON_PIXEL                                2
+#define     MSRASTMODE_ON_PATTERN                              3
+   uint32_t                                     DXMultisampleRasterizationMode;
+   bool                                         GlobalDepthOffsetEnableSolid;
+   bool                                         GlobalDepthOffsetEnableWireframe;
+   bool                                         GlobalDepthOffsetEnablePoint;
+#define     RASTER_SOLID                                       0
+#define     RASTER_WIREFRAME                                   1
+#define     RASTER_POINT                                       2
+   uint32_t                                     FrontFaceFillMode;
+#define     RASTER_SOLID                                       0
+#define     RASTER_WIREFRAME                                   1
+#define     RASTER_POINT                                       2
+   uint32_t                                     BackFaceFillMode;
+   bool                                         AntialiasingEnable;
+   bool                                         ScissorRectangleEnable;
+   bool                                         ViewportZClipTestEnable;
+   float                                        GlobalDepthOffsetConstant;
+   float                                        GlobalDepthOffsetScale;
+   float                                        GlobalDepthOffsetClamp;
+};
+
+static inline void
+GEN8_3DSTATE_RASTER_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_3DSTATE_RASTER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->APIMode, 22, 23) |
+      __gen_field(values->FrontWinding, 21, 21) |
+      __gen_field(values->ForcedSampleCount, 18, 20) |
+      __gen_field(values->CullMode, 16, 17) |
+      __gen_field(values->ForceMultisampling, 14, 14) |
+      __gen_field(values->SmoothPointEnable, 13, 13) |
+      __gen_field(values->DXMultisampleRasterizationEnable, 12, 12) |
+      __gen_field(values->DXMultisampleRasterizationMode, 10, 11) |
+      __gen_field(values->GlobalDepthOffsetEnableSolid, 9, 9) |
+      __gen_field(values->GlobalDepthOffsetEnableWireframe, 8, 8) |
+      __gen_field(values->GlobalDepthOffsetEnablePoint, 7, 7) |
+      __gen_field(values->FrontFaceFillMode, 5, 6) |
+      __gen_field(values->BackFaceFillMode, 3, 4) |
+      __gen_field(values->AntialiasingEnable, 2, 2) |
+      __gen_field(values->ScissorRectangleEnable, 1, 1) |
+      __gen_field(values->ViewportZClipTestEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_float(values->GlobalDepthOffsetConstant) |
+      0;
+
+   dw[3] =
+      __gen_float(values->GlobalDepthOffsetScale) |
+      0;
+
+   dw[4] =
+      __gen_float(values->GlobalDepthOffsetClamp) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD0_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD0_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  =  2
+
+#define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD0_length 0x00000000
+
+#define GEN8_PALETTE_ENTRY_length 0x00000001
+
+struct GEN8_PALETTE_ENTRY {
+   uint32_t                                     Alpha;
+   uint32_t                                     Red;
+   uint32_t                                     Green;
+   uint32_t                                     Blue;
+};
+
+static inline void
+GEN8_PALETTE_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN8_PALETTE_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->Alpha, 24, 31) |
+      __gen_field(values->Red, 16, 23) |
+      __gen_field(values->Green, 8, 15) |
+      __gen_field(values->Blue, 0, 7) |
+      0;
+
+}
+
+struct GEN8_3DSTATE_SAMPLER_PALETTE_LOAD0 {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_PALETTE_LOAD0_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_SAMPLER_PALETTE_LOAD0 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 12
+
+#define GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1_length 0x00000000
+
+struct GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1 {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1_pack(__gen_user_data *data, void * restrict dst,
+                                        const struct GEN8_3DSTATE_SAMPLER_PALETTE_LOAD1 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 45,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS_length 0x00000002
+
+struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoDSSamplerState;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoDSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 46,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS_length 0x00000002
+
+struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoGSSamplerState;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoGSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 44,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS_length 0x00000002
+
+struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoHSSamplerState;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoHSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 47,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS_length 0x00000002
+
+struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoPSSamplerState;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_PS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoPSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 43,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS_length 0x00000002
+
+struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PointertoVSSamplerState;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS_pack(__gen_user_data *data, void * restrict dst,
+                                            const struct GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->PointertoVSSamplerState, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLE_MASK_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLE_MASK_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 24,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SAMPLE_MASK_length 0x00000002
+
+struct GEN8_3DSTATE_SAMPLE_MASK {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SampleMask;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLE_MASK_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_SAMPLE_MASK * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SampleMask, 0, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SAMPLE_PATTERN_length_bias 0x00000002
+#define GEN8_3DSTATE_SAMPLE_PATTERN_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 28,                  \
+   .DwordLength          =  7
+
+#define GEN8_3DSTATE_SAMPLE_PATTERN_length 0x00000009
+
+struct GEN8_3DSTATE_SAMPLE_PATTERN {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   float                                        _8xSample7XOffset;
+   float                                        _8xSample7YOffset;
+   float                                        _8xSample6XOffset;
+   float                                        _8xSample6YOffset;
+   float                                        _8xSample5XOffset;
+   float                                        _8xSample5YOffset;
+   float                                        _8xSample4XOffset;
+   float                                        _8xSample4YOffset;
+   float                                        _8xSample3XOffset;
+   float                                        _8xSample3YOffset;
+   float                                        _8xSample2XOffset;
+   float                                        _8xSample2YOffset;
+   float                                        _8xSample1XOffset;
+   float                                        _8xSample1YOffset;
+   float                                        _8xSample0XOffset;
+   float                                        _8xSample0YOffset;
+   float                                        _4xSample3XOffset;
+   float                                        _4xSample3YOffset;
+   float                                        _4xSample2XOffset;
+   float                                        _4xSample2YOffset;
+   float                                        _4xSample1XOffset;
+   float                                        _4xSample1YOffset;
+   float                                        _4xSample0XOffset;
+   float                                        _4xSample0YOffset;
+   float                                        _1xSample0XOffset;
+   float                                        _1xSample0YOffset;
+   float                                        _2xSample1XOffset;
+   float                                        _2xSample1YOffset;
+   float                                        _2xSample0XOffset;
+   float                                        _2xSample0YOffset;
+};
+
+static inline void
+GEN8_3DSTATE_SAMPLE_PATTERN_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN8_3DSTATE_SAMPLE_PATTERN * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   for (uint32_t i = 0, j = 1; i < 4; i += 1, j++) {
+      dw[j] =
+         0;
+   }
+
+   dw[5] =
+      __gen_field(values->_8xSample7XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->_8xSample7YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->_8xSample6XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->_8xSample6YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->_8xSample5XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->_8xSample5YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->_8xSample4XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->_8xSample4YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[6] =
+      __gen_field(values->_8xSample3XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->_8xSample3YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->_8xSample2XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->_8xSample2YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->_8xSample1XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->_8xSample1YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->_8xSample0XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->_8xSample0YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[7] =
+      __gen_field(values->_4xSample3XOffset * (1 << 4), 28, 31) |
+      __gen_field(values->_4xSample3YOffset * (1 << 4), 24, 27) |
+      __gen_field(values->_4xSample2XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->_4xSample2YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->_4xSample1XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->_4xSample1YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->_4xSample0XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->_4xSample0YOffset * (1 << 4), 0, 3) |
+      0;
+
+   dw[8] =
+      __gen_field(values->_1xSample0XOffset * (1 << 4), 20, 23) |
+      __gen_field(values->_1xSample0YOffset * (1 << 4), 16, 19) |
+      __gen_field(values->_2xSample1XOffset * (1 << 4), 12, 15) |
+      __gen_field(values->_2xSample1YOffset * (1 << 4), 8, 11) |
+      __gen_field(values->_2xSample0XOffset * (1 << 4), 4, 7) |
+      __gen_field(values->_2xSample0YOffset * (1 << 4), 0, 3) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SBE_length_bias 0x00000002
+#define GEN8_3DSTATE_SBE_header                 \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 31,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_SBE_length 0x00000004
+
+struct GEN8_3DSTATE_SBE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         ForceVertexURBEntryReadLength;
+   bool                                         ForceVertexURBEntryReadOffset;
+   uint32_t                                     NumberofSFOutputAttributes;
+   bool                                         AttributeSwizzleEnable;
+#define     UPPERLEFT                                          0
+#define     LOWERLEFT                                          1
+   uint32_t                                     PointSpriteTextureCoordinateOrigin;
+   bool                                         PrimitiveIDOverrideComponentW;
+   bool                                         PrimitiveIDOverrideComponentZ;
+   bool                                         PrimitiveIDOverrideComponentY;
+   bool                                         PrimitiveIDOverrideComponentX;
+   uint32_t                                     VertexURBEntryReadLength;
+   uint32_t                                     VertexURBEntryReadOffset;
+   uint32_t                                     PrimitiveIDOverrideAttributeSelect;
+   uint32_t                                     PointSpriteTextureCoordinateEnable;
+   uint32_t                                     ConstantInterpolationEnable;
+};
+
+static inline void
+GEN8_3DSTATE_SBE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN8_3DSTATE_SBE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ForceVertexURBEntryReadLength, 29, 29) |
+      __gen_field(values->ForceVertexURBEntryReadOffset, 28, 28) |
+      __gen_field(values->NumberofSFOutputAttributes, 22, 27) |
+      __gen_field(values->AttributeSwizzleEnable, 21, 21) |
+      __gen_field(values->PointSpriteTextureCoordinateOrigin, 20, 20) |
+      __gen_field(values->PrimitiveIDOverrideComponentW, 19, 19) |
+      __gen_field(values->PrimitiveIDOverrideComponentZ, 18, 18) |
+      __gen_field(values->PrimitiveIDOverrideComponentY, 17, 17) |
+      __gen_field(values->PrimitiveIDOverrideComponentX, 16, 16) |
+      __gen_field(values->VertexURBEntryReadLength, 11, 15) |
+      __gen_field(values->VertexURBEntryReadOffset, 5, 10) |
+      __gen_field(values->PrimitiveIDOverrideAttributeSelect, 0, 4) |
+      0;
+
+   dw[2] =
+      __gen_field(values->PointSpriteTextureCoordinateEnable, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ConstantInterpolationEnable, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SBE_SWIZ_length_bias 0x00000002
+#define GEN8_3DSTATE_SBE_SWIZ_header            \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 81,                  \
+   .DwordLength          =  9
+
+#define GEN8_3DSTATE_SBE_SWIZ_length 0x0000000b
+
+#define GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL_length 0x00000001
+
+struct GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL {
+   bool                                         ComponentOverrideW;
+   bool                                         ComponentOverrideZ;
+   bool                                         ComponentOverrideY;
+   bool                                         ComponentOverrideX;
+   uint32_t                                     SwizzleControlMode;
+#define     CONST_0000                                         0
+#define     CONST_0001_FLOAT                                   1
+#define     CONST_1111_FLOAT                                   2
+#define     PRIM_ID                                            3
+   uint32_t                                     ConstantSource;
+#define     INPUTATTR                                          0
+#define     INPUTATTR_FACING                                   1
+#define     INPUTATTR_W                                        2
+#define     INPUTATTR_FACING_W                                 3
+   uint32_t                                     SwizzleSelect;
+   uint32_t                                     SourceAttribute;
+};
+
+static inline void
+GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL_pack(__gen_user_data *data, void * restrict dst,
+                                     const struct GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ComponentOverrideW, 15, 15) |
+      __gen_field(values->ComponentOverrideZ, 14, 14) |
+      __gen_field(values->ComponentOverrideY, 13, 13) |
+      __gen_field(values->ComponentOverrideX, 12, 12) |
+      __gen_field(values->SwizzleControlMode, 11, 11) |
+      __gen_field(values->ConstantSource, 9, 10) |
+      __gen_field(values->SwizzleSelect, 6, 7) |
+      __gen_field(values->SourceAttribute, 0, 4) |
+      0;
+
+}
+
+struct GEN8_3DSTATE_SBE_SWIZ {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   struct GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL       Attribute[16];
+   uint32_t                                     AttributeWrapShortestEnables[16];
+};
+
+static inline void
+GEN8_3DSTATE_SBE_SWIZ_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_3DSTATE_SBE_SWIZ * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   for (uint32_t i = 0, j = 1; i < 16; i += 2, j++) {
+      uint32_t dw_Attribute0;
+      GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL_pack(data, &dw_Attribute0, &values->Attribute[i + 0]);
+      uint32_t dw_Attribute1;
+      GEN8_SF_OUTPUT_ATTRIBUTE_DETAIL_pack(data, &dw_Attribute1, &values->Attribute[i + 1]);
+      dw[j] =
+         __gen_field(dw_Attribute0, 0, 15) |
+         __gen_field(dw_Attribute1, 16, 31) |
+         0;
+   }
+
+   for (uint32_t i = 0, j = 9; i < 16; i += 8, j++) {
+      dw[j] =
+         __gen_field(values->AttributeWrapShortestEnables[i + 0], 0, 3) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 1], 4, 7) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 2], 8, 11) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 3], 12, 15) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 4], 16, 19) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 5], 20, 23) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 6], 24, 27) |
+         __gen_field(values->AttributeWrapShortestEnables[i + 7], 28, 31) |
+         0;
+   }
+
+}
+
+#define GEN8_3DSTATE_SCISSOR_STATE_POINTERS_length_bias 0x00000002
+#define GEN8_3DSTATE_SCISSOR_STATE_POINTERS_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 15,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_SCISSOR_STATE_POINTERS_length 0x00000002
+
+struct GEN8_3DSTATE_SCISSOR_STATE_POINTERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ScissorRectPointer;
+};
+
+static inline void
+GEN8_3DSTATE_SCISSOR_STATE_POINTERS_pack(__gen_user_data *data, void * restrict dst,
+                                         const struct GEN8_3DSTATE_SCISSOR_STATE_POINTERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ScissorRectPointer, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SF_length_bias 0x00000002
+#define GEN8_3DSTATE_SF_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 19,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_SF_length 0x00000004
+
+struct GEN8_3DSTATE_SF {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         LegacyGlobalDepthBiasEnable;
+   bool                                         StatisticsEnable;
+   bool                                         ViewportTransformEnable;
+   float                                        LineWidth;
+#define     _05pixels                                          0
+#define     _10pixels                                          1
+#define     _20pixels                                          2
+#define     _40pixels                                          3
+   uint32_t                                     LineEndCapAntialiasingRegionWidth;
+   bool                                         LastPixelEnable;
+   uint32_t                                     TriangleStripListProvokingVertexSelect;
+   uint32_t                                     LineStripListProvokingVertexSelect;
+   uint32_t                                     TriangleFanProvokingVertexSelect;
+#define     AALINEDISTANCE_TRUE                                1
+   uint32_t                                     AALineDistanceMode;
+   bool                                         SmoothPointEnable;
+   uint32_t                                     VertexSubPixelPrecisionSelect;
+#define     Vertex                                             0
+#define     State                                              1
+   uint32_t                                     PointWidthSource;
+   float                                        PointWidth;
+};
+
+static inline void
+GEN8_3DSTATE_SF_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_SF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->LegacyGlobalDepthBiasEnable, 11, 11) |
+      __gen_field(values->StatisticsEnable, 10, 10) |
+      __gen_field(values->ViewportTransformEnable, 1, 1) |
+      0;
+
+   dw[2] =
+      __gen_field(values->LineWidth * (1 << 7), 18, 27) |
+      __gen_field(values->LineEndCapAntialiasingRegionWidth, 16, 17) |
+      0;
+
+   dw[3] =
+      __gen_field(values->LastPixelEnable, 31, 31) |
+      __gen_field(values->TriangleStripListProvokingVertexSelect, 29, 30) |
+      __gen_field(values->LineStripListProvokingVertexSelect, 27, 28) |
+      __gen_field(values->TriangleFanProvokingVertexSelect, 25, 26) |
+      __gen_field(values->AALineDistanceMode, 14, 14) |
+      __gen_field(values->SmoothPointEnable, 13, 13) |
+      __gen_field(values->VertexSubPixelPrecisionSelect, 12, 12) |
+      __gen_field(values->PointWidthSource, 11, 11) |
+      __gen_field(values->PointWidth * (1 << 3), 0, 10) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SO_BUFFER_length_bias 0x00000002
+#define GEN8_3DSTATE_SO_BUFFER_header           \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 24,                  \
+   .DwordLength          =  6
+
+#define GEN8_3DSTATE_SO_BUFFER_length 0x00000008
+
+struct GEN8_3DSTATE_SO_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         SOBufferEnable;
+   uint32_t                                     SOBufferIndex;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      SOBufferObjectControlState;
+   bool                                         StreamOffsetWriteEnable;
+   bool                                         StreamOutputBufferOffsetAddressEnable;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     SurfaceSize;
+   __gen_address_type                           StreamOutputBufferOffsetAddress;
+   uint32_t                                     StreamOffset;
+};
+
+static inline void
+GEN8_3DSTATE_SO_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_3DSTATE_SO_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_SOBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_SOBufferObjectControlState, &values->SOBufferObjectControlState);
+   dw[1] =
+      __gen_field(values->SOBufferEnable, 31, 31) |
+      __gen_field(values->SOBufferIndex, 29, 30) |
+      __gen_field(dw_SOBufferObjectControlState, 22, 28) |
+      __gen_field(values->StreamOffsetWriteEnable, 21, 21) |
+      __gen_field(values->StreamOutputBufferOffsetAddressEnable, 20, 20) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   dw[4] =
+      __gen_field(values->SurfaceSize, 0, 29) |
+      0;
+
+   uint32_t dw5 =
+      0;
+
+   uint64_t qw5 =
+      __gen_combine_address(data, &dw[5], values->StreamOutputBufferOffsetAddress, dw5);
+
+   dw[5] = qw5;
+   dw[6] = qw5 >> 32;
+
+   dw[7] =
+      __gen_field(values->StreamOffset, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_SO_DECL_LIST_length_bias 0x00000002
+#define GEN8_3DSTATE_SO_DECL_LIST_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  1,                  \
+   ._3DCommandSubOpcode  = 23
+
+#define GEN8_3DSTATE_SO_DECL_LIST_length 0x00000000
+
+#define GEN8_SO_DECL_ENTRY_length 0x00000002
+
+#define GEN8_SO_DECL_length 0x00000001
+
+struct GEN8_SO_DECL {
+   uint32_t                                     OutputBufferSlot;
+   uint32_t                                     HoleFlag;
+   uint32_t                                     RegisterIndex;
+   uint32_t                                     ComponentMask;
+};
+
+static inline void
+GEN8_SO_DECL_pack(__gen_user_data *data, void * restrict dst,
+                  const struct GEN8_SO_DECL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->OutputBufferSlot, 12, 13) |
+      __gen_field(values->HoleFlag, 11, 11) |
+      __gen_field(values->RegisterIndex, 4, 9) |
+      __gen_field(values->ComponentMask, 0, 3) |
+      0;
+
+}
+
+struct GEN8_SO_DECL_ENTRY {
+   struct GEN8_SO_DECL                          Stream3Decl;
+   struct GEN8_SO_DECL                          Stream2Decl;
+   struct GEN8_SO_DECL                          Stream1Decl;
+   struct GEN8_SO_DECL                          Stream0Decl;
+};
+
+static inline void
+GEN8_SO_DECL_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN8_SO_DECL_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_Stream3Decl;
+   GEN8_SO_DECL_pack(data, &dw_Stream3Decl, &values->Stream3Decl);
+   uint32_t dw_Stream2Decl;
+   GEN8_SO_DECL_pack(data, &dw_Stream2Decl, &values->Stream2Decl);
+   uint32_t dw_Stream1Decl;
+   GEN8_SO_DECL_pack(data, &dw_Stream1Decl, &values->Stream1Decl);
+   uint32_t dw_Stream0Decl;
+   GEN8_SO_DECL_pack(data, &dw_Stream0Decl, &values->Stream0Decl);
+   uint64_t qw0 =
+      __gen_field(dw_Stream3Decl, 48, 63) |
+      __gen_field(dw_Stream2Decl, 32, 47) |
+      __gen_field(dw_Stream1Decl, 16, 31) |
+      __gen_field(dw_Stream0Decl, 0, 15) |
+      0;
+
+   dw[0] = qw0;
+   dw[1] = qw0 >> 32;
+
+}
+
+struct GEN8_3DSTATE_SO_DECL_LIST {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StreamtoBufferSelects3;
+   uint32_t                                     StreamtoBufferSelects2;
+   uint32_t                                     StreamtoBufferSelects1;
+   uint32_t                                     StreamtoBufferSelects0;
+   uint32_t                                     NumEntries3;
+   uint32_t                                     NumEntries2;
+   uint32_t                                     NumEntries1;
+   uint32_t                                     NumEntries0;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_SO_DECL_LIST_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_3DSTATE_SO_DECL_LIST * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 8) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StreamtoBufferSelects3, 12, 15) |
+      __gen_field(values->StreamtoBufferSelects2, 8, 11) |
+      __gen_field(values->StreamtoBufferSelects1, 4, 7) |
+      __gen_field(values->StreamtoBufferSelects0, 0, 3) |
+      0;
+
+   dw[2] =
+      __gen_field(values->NumEntries3, 24, 31) |
+      __gen_field(values->NumEntries2, 16, 23) |
+      __gen_field(values->NumEntries1, 8, 15) |
+      __gen_field(values->NumEntries0, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_STENCIL_BUFFER_length_bias 0x00000002
+#define GEN8_3DSTATE_STENCIL_BUFFER_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  6,                  \
+   .DwordLength          =  3
+
+#define GEN8_3DSTATE_STENCIL_BUFFER_length 0x00000005
+
+struct GEN8_3DSTATE_STENCIL_BUFFER {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StencilBufferEnable;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      StencilBufferObjectControlState;
+   uint32_t                                     SurfacePitch;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     SurfaceQPitch;
+};
+
+static inline void
+GEN8_3DSTATE_STENCIL_BUFFER_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN8_3DSTATE_STENCIL_BUFFER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw_StencilBufferObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_StencilBufferObjectControlState, &values->StencilBufferObjectControlState);
+   dw[1] =
+      __gen_field(values->StencilBufferEnable, 31, 31) |
+      __gen_field(dw_StencilBufferObjectControlState, 22, 28) |
+      __gen_field(values->SurfacePitch, 0, 16) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->SurfaceBaseAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   dw[4] =
+      __gen_field(values->SurfaceQPitch, 0, 14) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_STREAMOUT_length_bias 0x00000002
+#define GEN8_3DSTATE_STREAMOUT_header           \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 30,                  \
+   .DwordLength          =  3
+
+#define GEN8_3DSTATE_STREAMOUT_length 0x00000005
+
+struct GEN8_3DSTATE_STREAMOUT {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SOFunctionEnable;
+   uint32_t                                     APIRenderingDisable;
+   uint32_t                                     RenderStreamSelect;
+#define     LEADING                                            0
+#define     TRAILING                                           1
+   uint32_t                                     ReorderMode;
+   bool                                         SOStatisticsEnable;
+#define     Normal                                             0
+#define     Resreved                                           1
+#define     Force_Off                                          2
+#define     Force_on                                           3
+   uint32_t                                     ForceRendering;
+   uint32_t                                     Stream3VertexReadOffset;
+   uint32_t                                     Stream3VertexReadLength;
+   uint32_t                                     Stream2VertexReadOffset;
+   uint32_t                                     Stream2VertexReadLength;
+   uint32_t                                     Stream1VertexReadOffset;
+   uint32_t                                     Stream1VertexReadLength;
+   uint32_t                                     Stream0VertexReadOffset;
+   uint32_t                                     Stream0VertexReadLength;
+   uint32_t                                     Buffer1SurfacePitch;
+   uint32_t                                     Buffer0SurfacePitch;
+   uint32_t                                     Buffer3SurfacePitch;
+   uint32_t                                     Buffer2SurfacePitch;
+};
+
+static inline void
+GEN8_3DSTATE_STREAMOUT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_3DSTATE_STREAMOUT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->SOFunctionEnable, 31, 31) |
+      __gen_field(values->APIRenderingDisable, 30, 30) |
+      __gen_field(values->RenderStreamSelect, 27, 28) |
+      __gen_field(values->ReorderMode, 26, 26) |
+      __gen_field(values->SOStatisticsEnable, 25, 25) |
+      __gen_field(values->ForceRendering, 23, 24) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Stream3VertexReadOffset, 29, 29) |
+      __gen_field(values->Stream3VertexReadLength, 24, 28) |
+      __gen_field(values->Stream2VertexReadOffset, 21, 21) |
+      __gen_field(values->Stream2VertexReadLength, 16, 20) |
+      __gen_field(values->Stream1VertexReadOffset, 13, 13) |
+      __gen_field(values->Stream1VertexReadLength, 8, 12) |
+      __gen_field(values->Stream0VertexReadOffset, 5, 5) |
+      __gen_field(values->Stream0VertexReadLength, 0, 4) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Buffer1SurfacePitch, 16, 27) |
+      __gen_field(values->Buffer0SurfacePitch, 0, 11) |
+      0;
+
+   dw[4] =
+      __gen_field(values->Buffer3SurfacePitch, 16, 27) |
+      __gen_field(values->Buffer2SurfacePitch, 0, 11) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_TE_length_bias 0x00000002
+#define GEN8_3DSTATE_TE_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 28,                  \
+   .DwordLength          =  2
+
+#define GEN8_3DSTATE_TE_length 0x00000004
+
+struct GEN8_3DSTATE_TE {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     INTEGER                                            0
+#define     ODD_FRACTIONAL                                     1
+#define     EVEN_FRACTIONAL                                    2
+   uint32_t                                     Partitioning;
+#define     POINT                                              0
+#define     OUTPUT_LINE                                        1
+#define     OUTPUT_TRI_CW                                      2
+#define     OUTPUT_TRI_CCW                                     3
+   uint32_t                                     OutputTopology;
+#define     QUAD                                               0
+#define     TRI                                                1
+#define     ISOLINE                                            2
+   uint32_t                                     TEDomain;
+#define     HW_TESS                                            0
+#define     SW_TESS                                            1
+   uint32_t                                     TEMode;
+   bool                                         TEEnable;
+   float                                        MaximumTessellationFactorOdd;
+   float                                        MaximumTessellationFactorNotOdd;
+};
+
+static inline void
+GEN8_3DSTATE_TE_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_TE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Partitioning, 12, 13) |
+      __gen_field(values->OutputTopology, 8, 9) |
+      __gen_field(values->TEDomain, 4, 5) |
+      __gen_field(values->TEMode, 1, 2) |
+      __gen_field(values->TEEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_float(values->MaximumTessellationFactorOdd) |
+      0;
+
+   dw[3] =
+      __gen_float(values->MaximumTessellationFactorNotOdd) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_URB_DS_length_bias 0x00000002
+#define GEN8_3DSTATE_URB_DS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 50,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_URB_DS_length 0x00000002
+
+struct GEN8_3DSTATE_URB_DS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     DSURBStartingAddress;
+   uint32_t                                     DSURBEntryAllocationSize;
+   uint32_t                                     DSNumberofURBEntries;
+};
+
+static inline void
+GEN8_3DSTATE_URB_DS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_3DSTATE_URB_DS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DSURBStartingAddress, 25, 31) |
+      __gen_field(values->DSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->DSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_URB_GS_length_bias 0x00000002
+#define GEN8_3DSTATE_URB_GS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 51,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_URB_GS_length 0x00000002
+
+struct GEN8_3DSTATE_URB_GS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     GSURBStartingAddress;
+   uint32_t                                     GSURBEntryAllocationSize;
+   uint32_t                                     GSNumberofURBEntries;
+};
+
+static inline void
+GEN8_3DSTATE_URB_GS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_3DSTATE_URB_GS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->GSURBStartingAddress, 25, 31) |
+      __gen_field(values->GSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->GSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_URB_HS_length_bias 0x00000002
+#define GEN8_3DSTATE_URB_HS_header              \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 49,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_URB_HS_length 0x00000002
+
+struct GEN8_3DSTATE_URB_HS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     HSURBStartingAddress;
+   uint32_t                                     HSURBEntryAllocationSize;
+   uint32_t                                     HSNumberofURBEntries;
+};
+
+static inline void
+GEN8_3DSTATE_URB_HS_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_3DSTATE_URB_HS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->HSURBStartingAddress, 25, 31) |
+      __gen_field(values->HSURBEntryAllocationSize, 16, 24) |
+      __gen_field(values->HSNumberofURBEntries, 0, 15) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VERTEX_BUFFERS_length_bias 0x00000002
+#define GEN8_3DSTATE_VERTEX_BUFFERS_header      \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  8
+
+#define GEN8_3DSTATE_VERTEX_BUFFERS_length 0x00000000
+
+#define GEN8_VERTEX_BUFFER_STATE_length 0x00000004
+
+struct GEN8_VERTEX_BUFFER_STATE {
+   uint32_t                                     VertexBufferIndex;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      MemoryObjectControlState;
+   uint32_t                                     AddressModifyEnable;
+   bool                                         NullVertexBuffer;
+   uint32_t                                     BufferPitch;
+   __gen_address_type                           BufferStartingAddress;
+   uint32_t                                     BufferSize;
+};
+
+static inline void
+GEN8_VERTEX_BUFFER_STATE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_VERTEX_BUFFER_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   dw[0] =
+      __gen_field(values->VertexBufferIndex, 26, 31) |
+      __gen_field(dw_MemoryObjectControlState, 16, 22) |
+      __gen_field(values->AddressModifyEnable, 14, 14) |
+      __gen_field(values->NullVertexBuffer, 13, 13) |
+      __gen_field(values->BufferPitch, 0, 11) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->BufferStartingAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->BufferSize, 0, 31) |
+      0;
+
+}
+
+struct GEN8_3DSTATE_VERTEX_BUFFERS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_VERTEX_BUFFERS_pack(__gen_user_data *data, void * restrict dst,
+                                 const struct GEN8_3DSTATE_VERTEX_BUFFERS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_VERTEX_ELEMENTS_length_bias 0x00000002
+#define GEN8_3DSTATE_VERTEX_ELEMENTS_header     \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  =  9
+
+#define GEN8_3DSTATE_VERTEX_ELEMENTS_length 0x00000000
+
+#define GEN8_VERTEX_ELEMENT_STATE_length 0x00000002
+
+struct GEN8_VERTEX_ELEMENT_STATE {
+   uint32_t                                     VertexBufferIndex;
+   bool                                         Valid;
+   uint32_t                                     SourceElementFormat;
+   bool                                         EdgeFlagEnable;
+   uint32_t                                     SourceElementOffset;
+   uint32_t                                     Component0Control;
+   uint32_t                                     Component1Control;
+   uint32_t                                     Component2Control;
+   uint32_t                                     Component3Control;
+};
+
+static inline void
+GEN8_VERTEX_ELEMENT_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_VERTEX_ELEMENT_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->VertexBufferIndex, 26, 31) |
+      __gen_field(values->Valid, 25, 25) |
+      __gen_field(values->SourceElementFormat, 16, 24) |
+      __gen_field(values->EdgeFlagEnable, 15, 15) |
+      __gen_field(values->SourceElementOffset, 0, 11) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Component0Control, 28, 30) |
+      __gen_field(values->Component1Control, 24, 26) |
+      __gen_field(values->Component2Control, 20, 22) |
+      __gen_field(values->Component3Control, 16, 18) |
+      0;
+
+}
+
+struct GEN8_3DSTATE_VERTEX_ELEMENTS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_3DSTATE_VERTEX_ELEMENTS_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN8_3DSTATE_VERTEX_ELEMENTS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_3DSTATE_VF_length_bias 0x00000002
+#define GEN8_3DSTATE_VF_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 12,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_VF_length 0x00000002
+
+struct GEN8_3DSTATE_VF {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         IndexedDrawCutIndexEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CutIndex;
+};
+
+static inline void
+GEN8_3DSTATE_VF_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_VF * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->IndexedDrawCutIndexEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->CutIndex, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VF_INSTANCING_length_bias 0x00000002
+#define GEN8_3DSTATE_VF_INSTANCING_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 73,                  \
+   .DwordLength          =  1
+
+#define GEN8_3DSTATE_VF_INSTANCING_length 0x00000003
+
+struct GEN8_3DSTATE_VF_INSTANCING {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         InstancingEnable;
+   uint32_t                                     VertexElementIndex;
+   uint32_t                                     InstanceDataStepRate;
+};
+
+static inline void
+GEN8_3DSTATE_VF_INSTANCING_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN8_3DSTATE_VF_INSTANCING * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InstancingEnable, 8, 8) |
+      __gen_field(values->VertexElementIndex, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->InstanceDataStepRate, 0, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VF_SGVS_length_bias 0x00000002
+#define GEN8_3DSTATE_VF_SGVS_header             \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 74,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_VF_SGVS_length 0x00000002
+
+struct GEN8_3DSTATE_VF_SGVS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         InstanceIDEnable;
+#define     COMP_0                                             0
+#define     COMP_1                                             1
+#define     COMP_2                                             2
+#define     COMP_3                                             3
+   uint32_t                                     InstanceIDComponentNumber;
+   uint32_t                                     InstanceIDElementOffset;
+   bool                                         VertexIDEnable;
+#define     COMP_0                                             0
+#define     COMP_1                                             1
+#define     COMP_2                                             2
+#define     COMP_3                                             3
+   uint32_t                                     VertexIDComponentNumber;
+   uint32_t                                     VertexIDElementOffset;
+};
+
+static inline void
+GEN8_3DSTATE_VF_SGVS_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN8_3DSTATE_VF_SGVS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InstanceIDEnable, 31, 31) |
+      __gen_field(values->InstanceIDComponentNumber, 29, 30) |
+      __gen_field(values->InstanceIDElementOffset, 16, 21) |
+      __gen_field(values->VertexIDEnable, 15, 15) |
+      __gen_field(values->VertexIDComponentNumber, 13, 14) |
+      __gen_field(values->VertexIDElementOffset, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VF_STATISTICS_length_bias 0x00000001
+#define GEN8_3DSTATE_VF_STATISTICS_header       \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  1,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 11
+
+#define GEN8_3DSTATE_VF_STATISTICS_length 0x00000001
+
+struct GEN8_3DSTATE_VF_STATISTICS {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   bool                                         StatisticsEnable;
+};
+
+static inline void
+GEN8_3DSTATE_VF_STATISTICS_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN8_3DSTATE_VF_STATISTICS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->StatisticsEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VF_TOPOLOGY_length_bias 0x00000002
+#define GEN8_3DSTATE_VF_TOPOLOGY_header         \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 75,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_VF_TOPOLOGY_length 0x00000002
+
+struct GEN8_3DSTATE_VF_TOPOLOGY {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     PrimitiveTopologyType;
+};
+
+static inline void
+GEN8_3DSTATE_VF_TOPOLOGY_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_3DSTATE_VF_TOPOLOGY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->PrimitiveTopologyType, 0, 5) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC_length_bias 0x00000002
+#define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 35,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC_length 0x00000002
+
+struct GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CCViewportPointer;
+};
+
+static inline void
+GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->CCViewportPointer, 5, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_length_bias 0x00000002
+#define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_header\
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 33,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_length 0x00000002
+
+struct GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     SFClipViewportPointer;
+};
+
+static inline void
+GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP_pack(__gen_user_data *data, void * restrict dst,
+                                                  const struct GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->SFClipViewportPointer, 6, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_WM_length_bias 0x00000002
+#define GEN8_3DSTATE_WM_header                  \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 20,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_WM_length 0x00000002
+
+struct GEN8_3DSTATE_WM {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         StatisticsEnable;
+   bool                                         LegacyDepthBufferClearEnable;
+   bool                                         LegacyDepthBufferResolveEnable;
+   bool                                         LegacyHierarchicalDepthBufferResolveEnable;
+   bool                                         LegacyDiamondLineRasterization;
+#define     NORMAL                                             0
+#define     PSEXEC                                             1
+#define     PREPS                                              2
+   uint32_t                                     EarlyDepthStencilControl;
+#define     Normal                                             0
+#define     ForceOff                                           1
+#define     ForceON                                            2
+   uint32_t                                     ForceThreadDispatchEnable;
+#define     INTERP_PIXEL                                       0
+#define     INTERP_CENTROID                                    2
+#define     INTERP_SAMPLE                                      3
+   uint32_t                                     PositionZWInterpolationMode;
+   uint32_t                                     BarycentricInterpolationMode;
+#define     _05pixels                                          0
+#define     _10pixels                                          1
+#define     _20pixels                                          2
+#define     _40pixels                                          3
+   uint32_t                                     LineEndCapAntialiasingRegionWidth;
+#define     _05pixels                                          0
+#define     _10pixels                                          1
+#define     _20pixels                                          2
+#define     _40pixels                                          3
+   uint32_t                                     LineAntialiasingRegionWidth;
+   bool                                         PolygonStippleEnable;
+   bool                                         LineStippleEnable;
+#define     RASTRULE_UPPER_LEFT                                0
+#define     RASTRULE_UPPER_RIGHT                               1
+   uint32_t                                     PointRasterizationRule;
+#define     Normal                                             0
+#define     ForceOff                                           1
+#define     ForceON                                            2
+   uint32_t                                     ForceKillPixelEnable;
+};
+
+static inline void
+GEN8_3DSTATE_WM_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_3DSTATE_WM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StatisticsEnable, 31, 31) |
+      __gen_field(values->LegacyDepthBufferClearEnable, 30, 30) |
+      __gen_field(values->LegacyDepthBufferResolveEnable, 28, 28) |
+      __gen_field(values->LegacyHierarchicalDepthBufferResolveEnable, 27, 27) |
+      __gen_field(values->LegacyDiamondLineRasterization, 26, 26) |
+      __gen_field(values->EarlyDepthStencilControl, 21, 22) |
+      __gen_field(values->ForceThreadDispatchEnable, 19, 20) |
+      __gen_field(values->PositionZWInterpolationMode, 17, 18) |
+      __gen_field(values->BarycentricInterpolationMode, 11, 16) |
+      __gen_field(values->LineEndCapAntialiasingRegionWidth, 8, 9) |
+      __gen_field(values->LineAntialiasingRegionWidth, 6, 7) |
+      __gen_field(values->PolygonStippleEnable, 4, 4) |
+      __gen_field(values->LineStippleEnable, 3, 3) |
+      __gen_field(values->PointRasterizationRule, 2, 2) |
+      __gen_field(values->ForceKillPixelEnable, 0, 1) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_WM_CHROMAKEY_length_bias 0x00000002
+#define GEN8_3DSTATE_WM_CHROMAKEY_header        \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 76,                  \
+   .DwordLength          =  0
+
+#define GEN8_3DSTATE_WM_CHROMAKEY_length 0x00000002
+
+struct GEN8_3DSTATE_WM_CHROMAKEY {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         ChromaKeyKillEnable;
+};
+
+static inline void
+GEN8_3DSTATE_WM_CHROMAKEY_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_3DSTATE_WM_CHROMAKEY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ChromaKeyKillEnable, 31, 31) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_WM_DEPTH_STENCIL_length_bias 0x00000002
+#define GEN8_3DSTATE_WM_DEPTH_STENCIL_header    \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 78,                  \
+   .DwordLength          =  1
+
+#define GEN8_3DSTATE_WM_DEPTH_STENCIL_length 0x00000003
+
+struct GEN8_3DSTATE_WM_DEPTH_STENCIL {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StencilFailOp;
+   uint32_t                                     StencilPassDepthFailOp;
+   uint32_t                                     StencilPassDepthPassOp;
+   uint32_t                                     BackfaceStencilTestFunction;
+   uint32_t                                     BackfaceStencilFailOp;
+   uint32_t                                     BackfaceStencilPassDepthFailOp;
+   uint32_t                                     BackfaceStencilPassDepthPassOp;
+   uint32_t                                     StencilTestFunction;
+   uint32_t                                     DepthTestFunction;
+   bool                                         DoubleSidedStencilEnable;
+   bool                                         StencilTestEnable;
+   bool                                         StencilBufferWriteEnable;
+   bool                                         DepthTestEnable;
+   bool                                         DepthBufferWriteEnable;
+   uint32_t                                     StencilTestMask;
+   uint32_t                                     StencilWriteMask;
+   uint32_t                                     BackfaceStencilTestMask;
+   uint32_t                                     BackfaceStencilWriteMask;
+};
+
+static inline void
+GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(__gen_user_data *data, void * restrict dst,
+                                   const struct GEN8_3DSTATE_WM_DEPTH_STENCIL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StencilFailOp, 29, 31) |
+      __gen_field(values->StencilPassDepthFailOp, 26, 28) |
+      __gen_field(values->StencilPassDepthPassOp, 23, 25) |
+      __gen_field(values->BackfaceStencilTestFunction, 20, 22) |
+      __gen_field(values->BackfaceStencilFailOp, 17, 19) |
+      __gen_field(values->BackfaceStencilPassDepthFailOp, 14, 16) |
+      __gen_field(values->BackfaceStencilPassDepthPassOp, 11, 13) |
+      __gen_field(values->StencilTestFunction, 8, 10) |
+      __gen_field(values->DepthTestFunction, 5, 7) |
+      __gen_field(values->DoubleSidedStencilEnable, 4, 4) |
+      __gen_field(values->StencilTestEnable, 3, 3) |
+      __gen_field(values->StencilBufferWriteEnable, 2, 2) |
+      __gen_field(values->DepthTestEnable, 1, 1) |
+      __gen_field(values->DepthBufferWriteEnable, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_field(values->StencilTestMask, 24, 31) |
+      __gen_field(values->StencilWriteMask, 16, 23) |
+      __gen_field(values->BackfaceStencilTestMask, 8, 15) |
+      __gen_field(values->BackfaceStencilWriteMask, 0, 7) |
+      0;
+
+}
+
+#define GEN8_3DSTATE_WM_HZ_OP_length_bias 0x00000002
+#define GEN8_3DSTATE_WM_HZ_OP_header            \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  0,                  \
+   ._3DCommandSubOpcode  = 82,                  \
+   .DwordLength          =  3
+
+#define GEN8_3DSTATE_WM_HZ_OP_length 0x00000005
+
+struct GEN8_3DSTATE_WM_HZ_OP {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         StencilBufferClearEnable;
+   bool                                         DepthBufferClearEnable;
+   bool                                         ScissorRectangleEnable;
+   bool                                         DepthBufferResolveEnable;
+   bool                                         HierarchicalDepthBufferResolveEnable;
+   uint32_t                                     PixelPositionOffsetEnable;
+   bool                                         FullSurfaceDepthClear;
+   uint32_t                                     StencilClearValue;
+   uint32_t                                     NumberofMultisamples;
+   uint32_t                                     ClearRectangleYMin;
+   uint32_t                                     ClearRectangleXMin;
+   uint32_t                                     ClearRectangleYMax;
+   uint32_t                                     ClearRectangleXMax;
+   uint32_t                                     SampleMask;
+};
+
+static inline void
+GEN8_3DSTATE_WM_HZ_OP_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_3DSTATE_WM_HZ_OP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StencilBufferClearEnable, 31, 31) |
+      __gen_field(values->DepthBufferClearEnable, 30, 30) |
+      __gen_field(values->ScissorRectangleEnable, 29, 29) |
+      __gen_field(values->DepthBufferResolveEnable, 28, 28) |
+      __gen_field(values->HierarchicalDepthBufferResolveEnable, 27, 27) |
+      __gen_field(values->PixelPositionOffsetEnable, 26, 26) |
+      __gen_field(values->FullSurfaceDepthClear, 25, 25) |
+      __gen_field(values->StencilClearValue, 16, 23) |
+      __gen_field(values->NumberofMultisamples, 13, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ClearRectangleYMin, 16, 31) |
+      __gen_field(values->ClearRectangleXMin, 0, 15) |
+      0;
+
+   dw[3] =
+      __gen_field(values->ClearRectangleYMax, 16, 31) |
+      __gen_field(values->ClearRectangleXMax, 0, 15) |
+      0;
+
+   dw[4] =
+      __gen_field(values->SampleMask, 0, 15) |
+      0;
+
+}
+
+#define GEN8_GPGPU_WALKER_length_bias 0x00000002
+#define GEN8_GPGPU_WALKER_header                \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  5,                  \
+   .DwordLength          = 13
+
+#define GEN8_GPGPU_WALKER_length 0x0000000f
+
+struct GEN8_GPGPU_WALKER {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   bool                                         IndirectParameterEnable;
+   bool                                         PredicateEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   uint32_t                                     IndirectDataLength;
+   uint32_t                                     IndirectDataStartAddress;
+#define     SIMD8                                              0
+#define     SIMD16                                             1
+#define     SIMD32                                             2
+   uint32_t                                     SIMDSize;
+   uint32_t                                     ThreadDepthCounterMaximum;
+   uint32_t                                     ThreadHeightCounterMaximum;
+   uint32_t                                     ThreadWidthCounterMaximum;
+   uint32_t                                     ThreadGroupIDStartingX;
+   uint32_t                                     ThreadGroupIDXDimension;
+   uint32_t                                     ThreadGroupIDStartingY;
+   uint32_t                                     ThreadGroupIDYDimension;
+   uint32_t                                     ThreadGroupIDStartingResumeZ;
+   uint32_t                                     ThreadGroupIDZDimension;
+   uint32_t                                     RightExecutionMask;
+   uint32_t                                     BottomExecutionMask;
+};
+
+static inline void
+GEN8_GPGPU_WALKER_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_GPGPU_WALKER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->IndirectParameterEnable, 10, 10) |
+      __gen_field(values->PredicateEnable, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->IndirectDataStartAddress, 6, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->SIMDSize, 30, 31) |
+      __gen_field(values->ThreadDepthCounterMaximum, 16, 21) |
+      __gen_field(values->ThreadHeightCounterMaximum, 8, 13) |
+      __gen_field(values->ThreadWidthCounterMaximum, 0, 5) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ThreadGroupIDStartingX, 0, 31) |
+      0;
+
+   dw[6] =
+      0;
+
+   dw[7] =
+      __gen_field(values->ThreadGroupIDXDimension, 0, 31) |
+      0;
+
+   dw[8] =
+      __gen_field(values->ThreadGroupIDStartingY, 0, 31) |
+      0;
+
+   dw[9] =
+      0;
+
+   dw[10] =
+      __gen_field(values->ThreadGroupIDYDimension, 0, 31) |
+      0;
+
+   dw[11] =
+      __gen_field(values->ThreadGroupIDStartingResumeZ, 0, 31) |
+      0;
+
+   dw[12] =
+      __gen_field(values->ThreadGroupIDZDimension, 0, 31) |
+      0;
+
+   dw[13] =
+      __gen_field(values->RightExecutionMask, 0, 31) |
+      0;
+
+   dw[14] =
+      __gen_field(values->BottomExecutionMask, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MEDIA_CURBE_LOAD_length_bias 0x00000002
+#define GEN8_MEDIA_CURBE_LOAD_header            \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  1,                  \
+   .DwordLength          =  2
+
+#define GEN8_MEDIA_CURBE_LOAD_length 0x00000004
+
+struct GEN8_MEDIA_CURBE_LOAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CURBETotalDataLength;
+   uint32_t                                     CURBEDataStartAddress;
+};
+
+static inline void
+GEN8_MEDIA_CURBE_LOAD_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_MEDIA_CURBE_LOAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->CURBETotalDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_field(values->CURBEDataStartAddress, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD_length_bias 0x00000002
+#define GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD_header\
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  2,                  \
+   .DwordLength          =  2
+
+#define GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD_length 0x00000004
+
+struct GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorTotalLength;
+   uint32_t                                     InterfaceDescriptorDataStartAddress;
+};
+
+static inline void
+GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      0;
+
+   dw[2] =
+      __gen_field(values->InterfaceDescriptorTotalLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->InterfaceDescriptorDataStartAddress, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MEDIA_OBJECT_length_bias 0x00000002
+#define GEN8_MEDIA_OBJECT_header                \
+   .CommandType          =  3,                  \
+   .MediaCommandPipeline =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .MediaCommandSubOpcode =  0
+
+#define GEN8_MEDIA_OBJECT_length 0x00000000
+
+struct GEN8_MEDIA_OBJECT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MediaCommandPipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     MediaCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+#define     Nothreadsynchronization                            0
+#define     Threaddispatchissynchronizedbythespawnrootthreadmessage       1
+   uint32_t                                     ThreadSynchronization;
+   uint32_t                                     ForceDestination;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+#define     Slice0                                             0
+#define     Slice1                                             1
+#define     Slice2                                             2
+   uint32_t                                     SliceDestinationSelect;
+#define     SubSlice2                                          2
+#define     SubSlice1                                          1
+#define     SubSlice0                                          0
+   uint32_t                                     SubSliceDestinationSelect;
+   uint32_t                                     IndirectDataLength;
+   __gen_address_type                           IndirectDataStartAddress;
+   uint32_t                                     ScoredboardY;
+   uint32_t                                     ScoreboardX;
+   uint32_t                                     ScoreboardColor;
+   bool                                         ScoreboardMask;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_MEDIA_OBJECT_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_MEDIA_OBJECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MediaCommandPipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->MediaCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->ThreadSynchronization, 24, 24) |
+      __gen_field(values->ForceDestination, 22, 22) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->SliceDestinationSelect, 19, 20) |
+      __gen_field(values->SubSliceDestinationSelect, 17, 18) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->IndirectDataStartAddress, dw3);
+
+   dw[4] =
+      __gen_field(values->ScoredboardY, 16, 24) |
+      __gen_field(values->ScoreboardX, 0, 8) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardColor, 16, 19) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_MEDIA_OBJECT_GRPID_length_bias 0x00000002
+#define GEN8_MEDIA_OBJECT_GRPID_header          \
+   .CommandType          =  3,                  \
+   .MediaCommandPipeline =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .MediaCommandSubOpcode =  6
+
+#define GEN8_MEDIA_OBJECT_GRPID_length 0x00000000
+
+struct GEN8_MEDIA_OBJECT_GRPID {
+   uint32_t                                     CommandType;
+   uint32_t                                     MediaCommandPipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     MediaCommandSubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   uint32_t                                     EndofThreadGroup;
+   uint32_t                                     ForceDestination;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+#define     Slice0                                             0
+#define     Slice1                                             1
+#define     Slice2                                             2
+   uint32_t                                     SliceDestinationSelect;
+#define     SubSlice2                                          2
+#define     SubSlice1                                          1
+#define     SubSlice0                                          0
+   uint32_t                                     SubSliceDestinationSelect;
+   uint32_t                                     IndirectDataLength;
+   __gen_address_type                           IndirectDataStartAddress;
+   uint32_t                                     ScoreboardY;
+   uint32_t                                     ScoreboardX;
+   uint32_t                                     ScoreboardColor;
+   bool                                         ScoreboardMask;
+   uint32_t                                     GroupID;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_MEDIA_OBJECT_GRPID_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN8_MEDIA_OBJECT_GRPID * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MediaCommandPipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->MediaCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->EndofThreadGroup, 23, 23) |
+      __gen_field(values->ForceDestination, 22, 22) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->SliceDestinationSelect, 19, 20) |
+      __gen_field(values->SubSliceDestinationSelect, 17, 18) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   uint32_t dw3 =
+      0;
+
+   dw[3] =
+      __gen_combine_address(data, &dw[3], values->IndirectDataStartAddress, dw3);
+
+   dw[4] =
+      __gen_field(values->ScoreboardY, 16, 24) |
+      __gen_field(values->ScoreboardX, 0, 8) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ScoreboardColor, 16, 19) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->GroupID, 0, 31) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_MEDIA_OBJECT_PRT_length_bias 0x00000002
+#define GEN8_MEDIA_OBJECT_PRT_header            \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  2,                  \
+   .DwordLength          = 14
+
+#define GEN8_MEDIA_OBJECT_PRT_length 0x00000010
+
+struct GEN8_MEDIA_OBJECT_PRT {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+   bool                                         PRT_FenceNeeded;
+#define     Rootthreadqueue                                    0
+#define     VFEstateflush                                      1
+   uint32_t                                     PRT_FenceType;
+   uint32_t                                     InlineData[12];
+};
+
+static inline void
+GEN8_MEDIA_OBJECT_PRT_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_MEDIA_OBJECT_PRT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->PRT_FenceNeeded, 23, 23) |
+      __gen_field(values->PRT_FenceType, 22, 22) |
+      0;
+
+   dw[3] =
+      0;
+
+   for (uint32_t i = 0, j = 4; i < 12; i += 1, j++) {
+      dw[j] =
+         __gen_field(values->InlineData[i + 0], 0, 31) |
+         0;
+   }
+
+}
+
+#define GEN8_MEDIA_OBJECT_WALKER_length_bias 0x00000002
+#define GEN8_MEDIA_OBJECT_WALKER_header         \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  1,                  \
+   .SubOpcode            =  3
+
+#define GEN8_MEDIA_OBJECT_WALKER_length 0x00000000
+
+struct GEN8_MEDIA_OBJECT_WALKER {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     InterfaceDescriptorOffset;
+   bool                                         ChildrenPresent;
+#define     Nothreadsynchronization                            0
+#define     Threaddispatchissynchronizedbythespawnrootthreadmessage       1
+   uint32_t                                     ThreadSynchronization;
+#define     Notusingscoreboard                                 0
+#define     Usingscoreboard                                    1
+   uint32_t                                     UseScoreboard;
+   uint32_t                                     IndirectDataLength;
+   uint32_t                                     IndirectDataStartAddress;
+   uint32_t                                     GroupIDLoopSelect;
+   bool                                         ScoreboardMask;
+   uint32_t                                     ColorCountMinusOne;
+   uint32_t                                     MiddleLoopExtraSteps;
+   uint32_t                                     LocalMidLoopUnitY;
+   uint32_t                                     MidLoopUnitX;
+   uint32_t                                     GlobalLoopExecCount;
+   uint32_t                                     LocalLoopExecCount;
+   uint32_t                                     BlockResolutionY;
+   uint32_t                                     BlockResolutionX;
+   uint32_t                                     LocalStartY;
+   uint32_t                                     LocalStartX;
+   uint32_t                                     LocalOuterLoopStrideY;
+   uint32_t                                     LocalOuterLoopStrideX;
+   uint32_t                                     LocalInnerLoopUnitY;
+   uint32_t                                     LocalInnerLoopUnitX;
+   uint32_t                                     GlobalResolutionY;
+   uint32_t                                     GlobalResolutionX;
+   uint32_t                                     GlobalStartY;
+   uint32_t                                     GlobalStartX;
+   uint32_t                                     GlobalOuterLoopStrideY;
+   uint32_t                                     GlobalOuterLoopStrideX;
+   uint32_t                                     GlobalInnerLoopUnitY;
+   uint32_t                                     GlobalInnerLoopUnitX;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_MEDIA_OBJECT_WALKER_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_MEDIA_OBJECT_WALKER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ChildrenPresent, 31, 31) |
+      __gen_field(values->ThreadSynchronization, 24, 24) |
+      __gen_field(values->UseScoreboard, 21, 21) |
+      __gen_field(values->IndirectDataLength, 0, 16) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->IndirectDataStartAddress, 0, 31) |
+      0;
+
+   dw[4] =
+      0;
+
+   dw[5] =
+      __gen_field(values->GroupIDLoopSelect, 8, 31) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ColorCountMinusOne, 24, 27) |
+      __gen_field(values->MiddleLoopExtraSteps, 16, 20) |
+      __gen_field(values->LocalMidLoopUnitY, 12, 13) |
+      __gen_field(values->MidLoopUnitX, 8, 9) |
+      0;
+
+   dw[7] =
+      __gen_field(values->GlobalLoopExecCount, 16, 25) |
+      __gen_field(values->LocalLoopExecCount, 0, 9) |
+      0;
+
+   dw[8] =
+      __gen_field(values->BlockResolutionY, 16, 24) |
+      __gen_field(values->BlockResolutionX, 0, 8) |
+      0;
+
+   dw[9] =
+      __gen_field(values->LocalStartY, 16, 24) |
+      __gen_field(values->LocalStartX, 0, 8) |
+      0;
+
+   dw[10] =
+      0;
+
+   dw[11] =
+      __gen_field(values->LocalOuterLoopStrideY, 16, 25) |
+      __gen_field(values->LocalOuterLoopStrideX, 0, 9) |
+      0;
+
+   dw[12] =
+      __gen_field(values->LocalInnerLoopUnitY, 16, 25) |
+      __gen_field(values->LocalInnerLoopUnitX, 0, 9) |
+      0;
+
+   dw[13] =
+      __gen_field(values->GlobalResolutionY, 16, 24) |
+      __gen_field(values->GlobalResolutionX, 0, 8) |
+      0;
+
+   dw[14] =
+      __gen_field(values->GlobalStartY, 16, 25) |
+      __gen_field(values->GlobalStartX, 0, 9) |
+      0;
+
+   dw[15] =
+      __gen_field(values->GlobalOuterLoopStrideY, 16, 25) |
+      __gen_field(values->GlobalOuterLoopStrideX, 0, 9) |
+      0;
+
+   dw[16] =
+      __gen_field(values->GlobalInnerLoopUnitY, 16, 25) |
+      __gen_field(values->GlobalInnerLoopUnitX, 0, 9) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_MEDIA_STATE_FLUSH_length_bias 0x00000002
+#define GEN8_MEDIA_STATE_FLUSH_header           \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  4,                  \
+   .DwordLength          =  0
+
+#define GEN8_MEDIA_STATE_FLUSH_length 0x00000002
+
+struct GEN8_MEDIA_STATE_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   bool                                         FlushtoGO;
+   uint32_t                                     WatermarkRequired;
+   uint32_t                                     InterfaceDescriptorOffset;
+};
+
+static inline void
+GEN8_MEDIA_STATE_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_MEDIA_STATE_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->FlushtoGO, 7, 7) |
+      __gen_field(values->WatermarkRequired, 6, 6) |
+      __gen_field(values->InterfaceDescriptorOffset, 0, 5) |
+      0;
+
+}
+
+#define GEN8_MEDIA_VFE_STATE_length_bias 0x00000002
+#define GEN8_MEDIA_VFE_STATE_header             \
+   .CommandType          =  3,                  \
+   .Pipeline             =  2,                  \
+   .MediaCommandOpcode   =  0,                  \
+   .SubOpcode            =  0,                  \
+   .DwordLength          =  7
+
+#define GEN8_MEDIA_VFE_STATE_length 0x00000009
+
+struct GEN8_MEDIA_VFE_STATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     Pipeline;
+   uint32_t                                     MediaCommandOpcode;
+   uint32_t                                     SubOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ScratchSpaceBasePointer;
+   uint32_t                                     StackSize;
+   uint32_t                                     PerThreadScratchSpace;
+   uint32_t                                     ScratchSpaceBasePointerHigh;
+   uint32_t                                     MaximumNumberofThreads;
+   uint32_t                                     NumberofURBEntries;
+#define     Maintainingtheexistingtimestampstate               0
+#define     Resettingrelativetimerandlatchingtheglobaltimestamp       1
+   uint32_t                                     ResetGatewayTimer;
+#define     MaintainingOpenGatewayForwardMsgCloseGatewayprotocollegacymode       0
+#define     BypassingOpenGatewayCloseGatewayprotocol           1
+   uint32_t                                     BypassGatewayControl;
+   uint32_t                                     SliceDisable;
+   uint32_t                                     URBEntryAllocationSize;
+   uint32_t                                     CURBEAllocationSize;
+#define     Scoreboarddisabled                                 0
+#define     Scoreboardenabled                                  1
+   uint32_t                                     ScoreboardEnable;
+#define     StallingScoreboard                                 0
+#define     NonStallingScoreboard                              1
+   uint32_t                                     ScoreboardType;
+   uint32_t                                     ScoreboardMask;
+   uint32_t                                     Scoreboard3DeltaY;
+   uint32_t                                     Scoreboard3DeltaX;
+   uint32_t                                     Scoreboard2DeltaY;
+   uint32_t                                     Scoreboard2DeltaX;
+   uint32_t                                     Scoreboard1DeltaY;
+   uint32_t                                     Scoreboard1DeltaX;
+   uint32_t                                     Scoreboard0DeltaY;
+   uint32_t                                     Scoreboard0DeltaX;
+   uint32_t                                     Scoreboard7DeltaY;
+   uint32_t                                     Scoreboard7DeltaX;
+   uint32_t                                     Scoreboard6DeltaY;
+   uint32_t                                     Scoreboard6DeltaX;
+   uint32_t                                     Scoreboard5DeltaY;
+   uint32_t                                     Scoreboard5DeltaX;
+   uint32_t                                     Scoreboard4DeltaY;
+   uint32_t                                     Scoreboard4DeltaX;
+};
+
+static inline void
+GEN8_MEDIA_VFE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN8_MEDIA_VFE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->Pipeline, 27, 28) |
+      __gen_field(values->MediaCommandOpcode, 24, 26) |
+      __gen_field(values->SubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->ScratchSpaceBasePointer, 10, 31) |
+      __gen_field(values->StackSize, 4, 7) |
+      __gen_field(values->PerThreadScratchSpace, 0, 3) |
+      0;
+
+   dw[2] =
+      __gen_offset(values->ScratchSpaceBasePointerHigh, 0, 15) |
+      0;
+
+   dw[3] =
+      __gen_field(values->MaximumNumberofThreads, 16, 31) |
+      __gen_field(values->NumberofURBEntries, 8, 15) |
+      __gen_field(values->ResetGatewayTimer, 7, 7) |
+      __gen_field(values->BypassGatewayControl, 6, 6) |
+      0;
+
+   dw[4] =
+      __gen_field(values->SliceDisable, 0, 1) |
+      0;
+
+   dw[5] =
+      __gen_field(values->URBEntryAllocationSize, 16, 31) |
+      __gen_field(values->CURBEAllocationSize, 0, 15) |
+      0;
+
+   dw[6] =
+      __gen_field(values->ScoreboardEnable, 31, 31) |
+      __gen_field(values->ScoreboardType, 30, 30) |
+      __gen_field(values->ScoreboardMask, 0, 7) |
+      0;
+
+   dw[7] =
+      __gen_field(values->Scoreboard3DeltaY, 28, 31) |
+      __gen_field(values->Scoreboard3DeltaX, 24, 27) |
+      __gen_field(values->Scoreboard2DeltaY, 20, 23) |
+      __gen_field(values->Scoreboard2DeltaX, 16, 19) |
+      __gen_field(values->Scoreboard1DeltaY, 12, 15) |
+      __gen_field(values->Scoreboard1DeltaX, 8, 11) |
+      __gen_field(values->Scoreboard0DeltaY, 4, 7) |
+      __gen_field(values->Scoreboard0DeltaX, 0, 3) |
+      0;
+
+   dw[8] =
+      __gen_field(values->Scoreboard7DeltaY, 28, 31) |
+      __gen_field(values->Scoreboard7DeltaX, 24, 27) |
+      __gen_field(values->Scoreboard6DeltaY, 20, 23) |
+      __gen_field(values->Scoreboard6DeltaX, 16, 19) |
+      __gen_field(values->Scoreboard5DeltaY, 12, 15) |
+      __gen_field(values->Scoreboard5DeltaX, 8, 11) |
+      __gen_field(values->Scoreboard4DeltaY, 4, 7) |
+      __gen_field(values->Scoreboard4DeltaX, 0, 3) |
+      0;
+
+}
+
+#define GEN8_MI_ARB_CHECK_length_bias 0x00000001
+#define GEN8_MI_ARB_CHECK_header                \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  5
+
+#define GEN8_MI_ARB_CHECK_length 0x00000001
+
+struct GEN8_MI_ARB_CHECK {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN8_MI_ARB_CHECK_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_MI_ARB_CHECK * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN8_MI_BATCH_BUFFER_END_length_bias 0x00000001
+#define GEN8_MI_BATCH_BUFFER_END_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 10
+
+#define GEN8_MI_BATCH_BUFFER_END_length 0x00000001
+
+struct GEN8_MI_BATCH_BUFFER_END {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN8_MI_BATCH_BUFFER_END_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_MI_BATCH_BUFFER_END * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN8_MI_BATCH_BUFFER_START_length_bias 0x00000002
+#define GEN8_MI_BATCH_BUFFER_START_header       \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 49,                  \
+   .DwordLength          =  1
+
+#define GEN8_MI_BATCH_BUFFER_START_length 0x00000003
+
+struct GEN8_MI_BATCH_BUFFER_START {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     _1stlevelbatch                                     0
+#define     _2ndlevelbatch                                     1
+   uint32_t                                     _2ndLevelBatchBuffer;
+   bool                                         AddOffsetEnable;
+   uint32_t                                     PredicationEnable;
+   bool                                         ResourceStreamerEnable;
+#define     ASI_GGTT                                           0
+#define     ASI_PPGTT                                          1
+   uint32_t                                     AddressSpaceIndicator;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           BatchBufferStartAddress;
+};
+
+static inline void
+GEN8_MI_BATCH_BUFFER_START_pack(__gen_user_data *data, void * restrict dst,
+                                const struct GEN8_MI_BATCH_BUFFER_START * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->_2ndLevelBatchBuffer, 22, 22) |
+      __gen_field(values->AddOffsetEnable, 16, 16) |
+      __gen_field(values->PredicationEnable, 15, 15) |
+      __gen_field(values->ResourceStreamerEnable, 10, 10) |
+      __gen_field(values->AddressSpaceIndicator, 8, 8) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->BatchBufferStartAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+}
+
+#define GEN8_MI_CLFLUSH_length_bias 0x00000002
+#define GEN8_MI_CLFLUSH_header                  \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 39
+
+#define GEN8_MI_CLFLUSH_length 0x00000000
+
+struct GEN8_MI_CLFLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           PageBaseAddress;
+   uint32_t                                     StartingCachelineOffset;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_MI_CLFLUSH_pack(__gen_user_data *data, void * restrict dst,
+                     const struct GEN8_MI_CLFLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->DwordLength, 0, 9) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->StartingCachelineOffset, 6, 11) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->PageBaseAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_MI_CONDITIONAL_BATCH_BUFFER_END_length_bias 0x00000002
+#define GEN8_MI_CONDITIONAL_BATCH_BUFFER_END_header\
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 54,                  \
+   .UseGlobalGTT         =  0,                  \
+   .CompareSemaphore     =  0,                  \
+   .DwordLength          =  1
+
+#define GEN8_MI_CONDITIONAL_BATCH_BUFFER_END_length 0x00000003
+
+struct GEN8_MI_CONDITIONAL_BATCH_BUFFER_END {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     UseGlobalGTT;
+   uint32_t                                     CompareSemaphore;
+   uint32_t                                     DwordLength;
+   uint32_t                                     CompareDataDword;
+   __gen_address_type                           CompareAddress;
+};
+
+static inline void
+GEN8_MI_CONDITIONAL_BATCH_BUFFER_END_pack(__gen_user_data *data, void * restrict dst,
+                                          const struct GEN8_MI_CONDITIONAL_BATCH_BUFFER_END * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->CompareSemaphore, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->CompareDataDword, 0, 31) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->CompareAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+}
+
+#define GEN8_MI_COPY_MEM_MEM_length_bias 0x00000002
+#define GEN8_MI_COPY_MEM_MEM_header             \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 46,                  \
+   .DwordLength          =  3
+
+#define GEN8_MI_COPY_MEM_MEM_length 0x00000005
+
+struct GEN8_MI_COPY_MEM_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTTSource;
+#define     PerProcessGraphicsAddress                          0
+#define     GlobalGraphicsAddress                              1
+   uint32_t                                     UseGlobalGTTDestination;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           DestinationMemoryAddress;
+   __gen_address_type                           SourceMemoryAddress;
+};
+
+static inline void
+GEN8_MI_COPY_MEM_MEM_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN8_MI_COPY_MEM_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTTSource, 22, 22) |
+      __gen_field(values->UseGlobalGTTDestination, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->DestinationMemoryAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   uint32_t dw3 =
+      0;
+
+   uint64_t qw3 =
+      __gen_combine_address(data, &dw[3], values->SourceMemoryAddress, dw3);
+
+   dw[3] = qw3;
+   dw[4] = qw3 >> 32;
+
+}
+
+#define GEN8_MI_LOAD_REGISTER_IMM_length_bias 0x00000002
+#define GEN8_MI_LOAD_REGISTER_IMM_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 34,                  \
+   .DwordLength          =  1
+
+#define GEN8_MI_LOAD_REGISTER_IMM_length 0x00000003
+
+struct GEN8_MI_LOAD_REGISTER_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     ByteWriteDisables;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterOffset;
+   uint32_t                                     DataDWord;
+};
+
+static inline void
+GEN8_MI_LOAD_REGISTER_IMM_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_MI_LOAD_REGISTER_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ByteWriteDisables, 8, 11) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterOffset, 2, 22) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DataDWord, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MI_LOAD_REGISTER_MEM_length_bias 0x00000002
+#define GEN8_MI_LOAD_REGISTER_MEM_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 41,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_LOAD_REGISTER_MEM_length 0x00000004
+
+struct GEN8_MI_LOAD_REGISTER_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   uint32_t                                     AsyncModeEnable;
+   uint32_t                                     DwordLength;
+   uint32_t                                     RegisterAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN8_MI_LOAD_REGISTER_MEM_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_MI_LOAD_REGISTER_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->AsyncModeEnable, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->RegisterAddress, 2, 22) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+}
+
+#define GEN8_MI_LOAD_SCAN_LINES_EXCL_length_bias 0x00000002
+#define GEN8_MI_LOAD_SCAN_LINES_EXCL_header     \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 19,                  \
+   .DwordLength          =  0
+
+#define GEN8_MI_LOAD_SCAN_LINES_EXCL_length 0x00000002
+
+struct GEN8_MI_LOAD_SCAN_LINES_EXCL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     DisplayPlaneA                                      0
+#define     DisplayPlaneB                                      1
+#define     DisplayPlaneC                                      4
+   uint32_t                                     DisplayPlaneSelect;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StartScanLineNumber;
+   uint32_t                                     EndScanLineNumber;
+};
+
+static inline void
+GEN8_MI_LOAD_SCAN_LINES_EXCL_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN8_MI_LOAD_SCAN_LINES_EXCL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPlaneSelect, 19, 21) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StartScanLineNumber, 16, 28) |
+      __gen_field(values->EndScanLineNumber, 0, 12) |
+      0;
+
+}
+
+#define GEN8_MI_LOAD_SCAN_LINES_INCL_length_bias 0x00000002
+#define GEN8_MI_LOAD_SCAN_LINES_INCL_header     \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 18,                  \
+   .DwordLength          =  0
+
+#define GEN8_MI_LOAD_SCAN_LINES_INCL_length 0x00000002
+
+struct GEN8_MI_LOAD_SCAN_LINES_INCL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     DisplayPlaneA                                      0
+#define     DisplayPlaneB                                      1
+#define     DisplayPlaneC                                      4
+   uint32_t                                     DisplayPlaneSelect;
+#define     NeverForward                                       0
+#define     AlwaysForward                                      1
+#define     ConditionallyForward                               2
+   bool                                         ScanLineEventDoneForward;
+   uint32_t                                     DwordLength;
+   uint32_t                                     StartScanLineNumber;
+   uint32_t                                     EndScanLineNumber;
+};
+
+static inline void
+GEN8_MI_LOAD_SCAN_LINES_INCL_pack(__gen_user_data *data, void * restrict dst,
+                                  const struct GEN8_MI_LOAD_SCAN_LINES_INCL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPlaneSelect, 19, 21) |
+      __gen_field(values->ScanLineEventDoneForward, 17, 18) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->StartScanLineNumber, 16, 28) |
+      __gen_field(values->EndScanLineNumber, 0, 12) |
+      0;
+
+}
+
+#define GEN8_MI_LOAD_URB_MEM_length_bias 0x00000002
+#define GEN8_MI_LOAD_URB_MEM_header             \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 44,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_LOAD_URB_MEM_length 0x00000004
+
+struct GEN8_MI_LOAD_URB_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN8_MI_LOAD_URB_MEM_pack(__gen_user_data *data, void * restrict dst,
+                          const struct GEN8_MI_LOAD_URB_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBAddress, 2, 14) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+}
+
+#define GEN8_MI_MATH_length_bias 0x00000002
+#define GEN8_MI_MATH_header                     \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 26
+
+#define GEN8_MI_MATH_length 0x00000000
+
+struct GEN8_MI_MATH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     ALUINSTRUCTION1;
+   uint32_t                                     ALUINSTRUCTION2;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_MI_MATH_pack(__gen_user_data *data, void * restrict dst,
+                  const struct GEN8_MI_MATH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 5) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ALUINSTRUCTION1, 0, 31) |
+      0;
+
+   dw[2] =
+      __gen_field(values->ALUINSTRUCTION2, 0, 31) |
+      0;
+
+   /* variable length fields follow */
+}
+
+#define GEN8_MI_NOOP_length_bias 0x00000001
+#define GEN8_MI_NOOP_header                     \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  0
+
+#define GEN8_MI_NOOP_length 0x00000001
+
+struct GEN8_MI_NOOP {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         IdentificationNumberRegisterWriteEnable;
+   uint32_t                                     IdentificationNumber;
+};
+
+static inline void
+GEN8_MI_NOOP_pack(__gen_user_data *data, void * restrict dst,
+                  const struct GEN8_MI_NOOP * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->IdentificationNumberRegisterWriteEnable, 22, 22) |
+      __gen_field(values->IdentificationNumber, 0, 21) |
+      0;
+
+}
+
+#define GEN8_MI_PREDICATE_length_bias 0x00000001
+#define GEN8_MI_PREDICATE_header                \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 12
+
+#define GEN8_MI_PREDICATE_length 0x00000001
+
+struct GEN8_MI_PREDICATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     LOAD_KEEP                                          0
+#define     LOAD_LOAD                                          2
+#define     LOAD_LOADINV                                       3
+   uint32_t                                     LoadOperation;
+#define     COMBINE_SET                                        0
+#define     COMBINE_AND                                        1
+#define     COMBINE_OR                                         2
+#define     COMBINE_XOR                                        3
+   uint32_t                                     CombineOperation;
+#define     COMPARE_SRCS_EQUAL                                 2
+#define     COMPARE_DELTAS_EQUAL                               3
+   uint32_t                                     CompareOperation;
+};
+
+static inline void
+GEN8_MI_PREDICATE_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_MI_PREDICATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->LoadOperation, 6, 7) |
+      __gen_field(values->CombineOperation, 3, 4) |
+      __gen_field(values->CompareOperation, 0, 1) |
+      0;
+
+}
+
+#define GEN8_MI_REPORT_HEAD_length_bias 0x00000001
+#define GEN8_MI_REPORT_HEAD_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  7
+
+#define GEN8_MI_REPORT_HEAD_length 0x00000001
+
+struct GEN8_MI_REPORT_HEAD {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN8_MI_REPORT_HEAD_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_MI_REPORT_HEAD * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN8_MI_RS_CONTEXT_length_bias 0x00000001
+#define GEN8_MI_RS_CONTEXT_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 15
+
+#define GEN8_MI_RS_CONTEXT_length 0x00000001
+
+struct GEN8_MI_RS_CONTEXT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     RS_RESTORE                                         0
+#define     RS_SAVE                                            1
+   uint32_t                                     ResourceStreamerSave;
+};
+
+static inline void
+GEN8_MI_RS_CONTEXT_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN8_MI_RS_CONTEXT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ResourceStreamerSave, 0, 0) |
+      0;
+
+}
+
+#define GEN8_MI_RS_CONTROL_length_bias 0x00000001
+#define GEN8_MI_RS_CONTROL_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  6
+
+#define GEN8_MI_RS_CONTROL_length 0x00000001
+
+struct GEN8_MI_RS_CONTROL {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     RS_STOP                                            0
+#define     RS_START                                           1
+   uint32_t                                     ResourceStreamerControl;
+};
+
+static inline void
+GEN8_MI_RS_CONTROL_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN8_MI_RS_CONTROL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->ResourceStreamerControl, 0, 0) |
+      0;
+
+}
+
+#define GEN8_MI_RS_STORE_DATA_IMM_length_bias 0x00000002
+#define GEN8_MI_RS_STORE_DATA_IMM_header        \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 43,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_RS_STORE_DATA_IMM_length 0x00000004
+
+struct GEN8_MI_RS_STORE_DATA_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           DestinationAddress;
+   uint32_t                                     CoreModeEnable;
+   uint32_t                                     DataDWord0;
+};
+
+static inline void
+GEN8_MI_RS_STORE_DATA_IMM_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_MI_RS_STORE_DATA_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->CoreModeEnable, 0, 0) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->DestinationAddress, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MI_SET_CONTEXT_length_bias 0x00000002
+#define GEN8_MI_SET_CONTEXT_header              \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 24,                  \
+   .DwordLength          =  0
+
+#define GEN8_MI_SET_CONTEXT_length 0x00000002
+
+struct GEN8_MI_SET_CONTEXT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           LogicalContextAddress;
+   uint32_t                                     ReservedMustbe1;
+   bool                                         CoreModeEnable;
+   bool                                         ResourceStreamerStateSaveEnable;
+   bool                                         ResourceStreamerStateRestoreEnable;
+   uint32_t                                     ForceRestore;
+   uint32_t                                     RestoreInhibit;
+};
+
+static inline void
+GEN8_MI_SET_CONTEXT_pack(__gen_user_data *data, void * restrict dst,
+                         const struct GEN8_MI_SET_CONTEXT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->ReservedMustbe1, 8, 8) |
+      __gen_field(values->CoreModeEnable, 4, 4) |
+      __gen_field(values->ResourceStreamerStateSaveEnable, 3, 3) |
+      __gen_field(values->ResourceStreamerStateRestoreEnable, 2, 2) |
+      __gen_field(values->ForceRestore, 1, 1) |
+      __gen_field(values->RestoreInhibit, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->LogicalContextAddress, dw1);
+
+}
+
+#define GEN8_MI_SET_PREDICATE_length_bias 0x00000001
+#define GEN8_MI_SET_PREDICATE_header            \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  1
+
+#define GEN8_MI_SET_PREDICATE_length 0x00000001
+
+struct GEN8_MI_SET_PREDICATE {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+#define     NOOPNever                                          0
+#define     NOOPonResult2clear                                 1
+#define     NOOPonResult2set                                   2
+#define     NOOPonResultclear                                  3
+#define     NOOPonResultset                                    4
+#define     Executewhenonesliceenabled                         5
+#define     Executewhentwoslicesareenabled                     6
+#define     Executewhenthreeslicesareenabled                   7
+#define     NOOPAlways                                        15
+   uint32_t                                     PREDICATEENABLE;
+};
+
+static inline void
+GEN8_MI_SET_PREDICATE_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_MI_SET_PREDICATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->PREDICATEENABLE, 0, 3) |
+      0;
+
+}
+
+#define GEN8_MI_STORE_DATA_IMM_length_bias 0x00000002
+#define GEN8_MI_STORE_DATA_IMM_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 32,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_STORE_DATA_IMM_length 0x00000004
+
+struct GEN8_MI_STORE_DATA_IMM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         UseGlobalGTT;
+   bool                                         StoreQword;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           Address;
+   uint32_t                                     CoreModeEnable;
+   uint32_t                                     DataDWord0;
+   uint32_t                                     DataDWord1;
+};
+
+static inline void
+GEN8_MI_STORE_DATA_IMM_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_MI_STORE_DATA_IMM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UseGlobalGTT, 22, 22) |
+      __gen_field(values->StoreQword, 21, 21) |
+      __gen_field(values->DwordLength, 0, 9) |
+      0;
+
+   uint32_t dw1 =
+      __gen_field(values->CoreModeEnable, 0, 0) |
+      0;
+
+   uint64_t qw1 =
+      __gen_combine_address(data, &dw[1], values->Address, dw1);
+
+   dw[1] = qw1;
+   dw[2] = qw1 >> 32;
+
+   dw[3] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+   dw[4] =
+      __gen_field(values->DataDWord1, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MI_STORE_DATA_INDEX_length_bias 0x00000002
+#define GEN8_MI_STORE_DATA_INDEX_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 33,                  \
+   .DwordLength          =  1
+
+#define GEN8_MI_STORE_DATA_INDEX_length 0x00000003
+
+struct GEN8_MI_STORE_DATA_INDEX {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     UsePerProcessHardwareStatusPage;
+   uint32_t                                     DwordLength;
+   uint32_t                                     Offset;
+   uint32_t                                     DataDWord0;
+   uint32_t                                     DataDWord1;
+};
+
+static inline void
+GEN8_MI_STORE_DATA_INDEX_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_MI_STORE_DATA_INDEX * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->UsePerProcessHardwareStatusPage, 21, 21) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Offset, 2, 11) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DataDWord0, 0, 31) |
+      0;
+
+   dw[3] =
+      __gen_field(values->DataDWord1, 0, 31) |
+      0;
+
+}
+
+#define GEN8_MI_STORE_URB_MEM_length_bias 0x00000002
+#define GEN8_MI_STORE_URB_MEM_header            \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 45,                  \
+   .DwordLength          =  2
+
+#define GEN8_MI_STORE_URB_MEM_length 0x00000004
+
+struct GEN8_MI_STORE_URB_MEM {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBAddress;
+   __gen_address_type                           MemoryAddress;
+};
+
+static inline void
+GEN8_MI_STORE_URB_MEM_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_MI_STORE_URB_MEM * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBAddress, 2, 14) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->MemoryAddress, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+}
+
+#define GEN8_MI_SUSPEND_FLUSH_length_bias 0x00000001
+#define GEN8_MI_SUSPEND_FLUSH_header            \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 11
+
+#define GEN8_MI_SUSPEND_FLUSH_length 0x00000001
+
+struct GEN8_MI_SUSPEND_FLUSH {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         SuspendFlush;
+};
+
+static inline void
+GEN8_MI_SUSPEND_FLUSH_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_MI_SUSPEND_FLUSH * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->SuspendFlush, 0, 0) |
+      0;
+
+}
+
+#define GEN8_MI_TOPOLOGY_FILTER_length_bias 0x00000001
+#define GEN8_MI_TOPOLOGY_FILTER_header          \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 13
+
+#define GEN8_MI_TOPOLOGY_FILTER_length 0x00000001
+
+struct GEN8_MI_TOPOLOGY_FILTER {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     TopologyFilterValue;
+};
+
+static inline void
+GEN8_MI_TOPOLOGY_FILTER_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN8_MI_TOPOLOGY_FILTER * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->TopologyFilterValue, 0, 5) |
+      0;
+
+}
+
+#define GEN8_MI_UPDATE_GTT_length_bias 0x00000002
+#define GEN8_MI_UPDATE_GTT_header               \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 35
+
+#define GEN8_MI_UPDATE_GTT_length 0x00000000
+
+struct GEN8_MI_UPDATE_GTT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   __gen_address_type                           EntryAddress;
+   /* variable length fields follow */
+};
+
+static inline void
+GEN8_MI_UPDATE_GTT_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN8_MI_UPDATE_GTT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 9) |
+      0;
+
+   uint32_t dw1 =
+      0;
+
+   dw[1] =
+      __gen_combine_address(data, &dw[1], values->EntryAddress, dw1);
+
+   /* variable length fields follow */
+}
+
+#define GEN8_MI_URB_ATOMIC_ALLOC_length_bias 0x00000001
+#define GEN8_MI_URB_ATOMIC_ALLOC_header         \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  9
+
+#define GEN8_MI_URB_ATOMIC_ALLOC_length 0x00000001
+
+struct GEN8_MI_URB_ATOMIC_ALLOC {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     URBAtomicStorageOffset;
+   uint32_t                                     URBAtomicStorageSize;
+};
+
+static inline void
+GEN8_MI_URB_ATOMIC_ALLOC_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_MI_URB_ATOMIC_ALLOC * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->URBAtomicStorageOffset, 12, 19) |
+      __gen_field(values->URBAtomicStorageSize, 0, 8) |
+      0;
+
+}
+
+#define GEN8_MI_URB_CLEAR_length_bias 0x00000002
+#define GEN8_MI_URB_CLEAR_header                \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      = 25,                  \
+   .DwordLength          =  0
+
+#define GEN8_MI_URB_CLEAR_length 0x00000002
+
+struct GEN8_MI_URB_CLEAR {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   uint32_t                                     DwordLength;
+   uint32_t                                     URBClearLength;
+   uint32_t                                     URBAddress;
+};
+
+static inline void
+GEN8_MI_URB_CLEAR_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_MI_URB_CLEAR * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->URBClearLength, 16, 29) |
+      __gen_offset(values->URBAddress, 0, 14) |
+      0;
+
+}
+
+#define GEN8_MI_USER_INTERRUPT_length_bias 0x00000001
+#define GEN8_MI_USER_INTERRUPT_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  2
+
+#define GEN8_MI_USER_INTERRUPT_length 0x00000001
+
+struct GEN8_MI_USER_INTERRUPT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+};
+
+static inline void
+GEN8_MI_USER_INTERRUPT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_MI_USER_INTERRUPT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      0;
+
+}
+
+#define GEN8_MI_WAIT_FOR_EVENT_length_bias 0x00000001
+#define GEN8_MI_WAIT_FOR_EVENT_header           \
+   .CommandType          =  0,                  \
+   .MICommandOpcode      =  3
+
+#define GEN8_MI_WAIT_FOR_EVENT_length 0x00000001
+
+struct GEN8_MI_WAIT_FOR_EVENT {
+   uint32_t                                     CommandType;
+   uint32_t                                     MICommandOpcode;
+   bool                                         DisplayPipeCVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteCFlipPendingWaitEnable;
+   bool                                         DisplayPlaneCFlipPendingWaitEnable;
+   bool                                         DisplayPipeCScanLineWaitEnable;
+   bool                                         DisplayPipeBVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteBFlipPendingWaitEnable;
+   bool                                         DisplayPlaneBFlipPendingWaitEnable;
+   bool                                         DisplayPipeBScanLineWaitEnable;
+   bool                                         DisplayPipeAVerticalBlankWaitEnable;
+   bool                                         DisplaySpriteAFlipPendingWaitEnable;
+   bool                                         DisplayPlaneAFlipPendingWaitEnable;
+   bool                                         DisplayPipeAScanLineWaitEnable;
+};
+
+static inline void
+GEN8_MI_WAIT_FOR_EVENT_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_MI_WAIT_FOR_EVENT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->MICommandOpcode, 23, 28) |
+      __gen_field(values->DisplayPipeCVerticalBlankWaitEnable, 21, 21) |
+      __gen_field(values->DisplaySpriteCFlipPendingWaitEnable, 20, 20) |
+      __gen_field(values->DisplayPlaneCFlipPendingWaitEnable, 15, 15) |
+      __gen_field(values->DisplayPipeCScanLineWaitEnable, 14, 14) |
+      __gen_field(values->DisplayPipeBVerticalBlankWaitEnable, 11, 11) |
+      __gen_field(values->DisplaySpriteBFlipPendingWaitEnable, 10, 10) |
+      __gen_field(values->DisplayPlaneBFlipPendingWaitEnable, 9, 9) |
+      __gen_field(values->DisplayPipeBScanLineWaitEnable, 8, 8) |
+      __gen_field(values->DisplayPipeAVerticalBlankWaitEnable, 3, 3) |
+      __gen_field(values->DisplaySpriteAFlipPendingWaitEnable, 2, 2) |
+      __gen_field(values->DisplayPlaneAFlipPendingWaitEnable, 1, 1) |
+      __gen_field(values->DisplayPipeAScanLineWaitEnable, 0, 0) |
+      0;
+
+}
+
+#define GEN8_PIPE_CONTROL_length_bias 0x00000002
+#define GEN8_PIPE_CONTROL_header                \
+   .CommandType          =  3,                  \
+   .CommandSubType       =  3,                  \
+   ._3DCommandOpcode     =  2,                  \
+   ._3DCommandSubOpcode  =  0,                  \
+   .DwordLength          =  4
+
+#define GEN8_PIPE_CONTROL_length 0x00000006
+
+struct GEN8_PIPE_CONTROL {
+   uint32_t                                     CommandType;
+   uint32_t                                     CommandSubType;
+   uint32_t                                     _3DCommandOpcode;
+   uint32_t                                     _3DCommandSubOpcode;
+   uint32_t                                     DwordLength;
+#define     DAT_PPGTT                                          0
+#define     DAT_GGTT                                           1
+   uint32_t                                     DestinationAddressType;
+#define     NoLRIOperation                                     0
+#define     MMIOWriteImmediateData                             1
+   uint32_t                                     LRIPostSyncOperation;
+   uint32_t                                     StoreDataIndex;
+   uint32_t                                     CommandStreamerStallEnable;
+#define     DontReset                                          0
+#define     Reset                                              1
+   uint32_t                                     GlobalSnapshotCountReset;
+   uint32_t                                     TLBInvalidate;
+   bool                                         GenericMediaStateClear;
+#define     NoWrite                                            0
+#define     WriteImmediateData                                 1
+#define     WritePSDepthCount                                  2
+#define     WriteTimestamp                                     3
+   uint32_t                                     PostSyncOperation;
+   bool                                         DepthStallEnable;
+#define     DisableFlush                                       0
+#define     EnableFlush                                        1
+   bool                                         RenderTargetCacheFlushEnable;
+   bool                                         InstructionCacheInvalidateEnable;
+   bool                                         TextureCacheInvalidationEnable;
+   bool                                         IndirectStatePointersDisable;
+   bool                                         NotifyEnable;
+   bool                                         PipeControlFlushEnable;
+   bool                                         DCFlushEnable;
+   bool                                         VFCacheInvalidationEnable;
+   bool                                         ConstantCacheInvalidationEnable;
+   bool                                         StateCacheInvalidationEnable;
+   bool                                         StallAtPixelScoreboard;
+#define     FlushDisabled                                      0
+#define     FlushEnabled                                       1
+   bool                                         DepthCacheFlushEnable;
+   __gen_address_type                           Address;
+   uint64_t                                     ImmediateData;
+};
+
+static inline void
+GEN8_PIPE_CONTROL_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_PIPE_CONTROL * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->CommandType, 29, 31) |
+      __gen_field(values->CommandSubType, 27, 28) |
+      __gen_field(values->_3DCommandOpcode, 24, 26) |
+      __gen_field(values->_3DCommandSubOpcode, 16, 23) |
+      __gen_field(values->DwordLength, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->DestinationAddressType, 24, 24) |
+      __gen_field(values->LRIPostSyncOperation, 23, 23) |
+      __gen_field(values->StoreDataIndex, 21, 21) |
+      __gen_field(values->CommandStreamerStallEnable, 20, 20) |
+      __gen_field(values->GlobalSnapshotCountReset, 19, 19) |
+      __gen_field(values->TLBInvalidate, 18, 18) |
+      __gen_field(values->GenericMediaStateClear, 16, 16) |
+      __gen_field(values->PostSyncOperation, 14, 15) |
+      __gen_field(values->DepthStallEnable, 13, 13) |
+      __gen_field(values->RenderTargetCacheFlushEnable, 12, 12) |
+      __gen_field(values->InstructionCacheInvalidateEnable, 11, 11) |
+      __gen_field(values->TextureCacheInvalidationEnable, 10, 10) |
+      __gen_field(values->IndirectStatePointersDisable, 9, 9) |
+      __gen_field(values->NotifyEnable, 8, 8) |
+      __gen_field(values->PipeControlFlushEnable, 7, 7) |
+      __gen_field(values->DCFlushEnable, 5, 5) |
+      __gen_field(values->VFCacheInvalidationEnable, 4, 4) |
+      __gen_field(values->ConstantCacheInvalidationEnable, 3, 3) |
+      __gen_field(values->StateCacheInvalidationEnable, 2, 2) |
+      __gen_field(values->StallAtPixelScoreboard, 1, 1) |
+      __gen_field(values->DepthCacheFlushEnable, 0, 0) |
+      0;
+
+   uint32_t dw2 =
+      0;
+
+   uint64_t qw2 =
+      __gen_combine_address(data, &dw[2], values->Address, dw2);
+
+   dw[2] = qw2;
+   dw[3] = qw2 >> 32;
+
+   uint64_t qw4 =
+      __gen_field(values->ImmediateData, 0, 63) |
+      0;
+
+   dw[4] = qw4;
+   dw[5] = qw4 >> 32;
+
+}
+
+#define GEN8_SCISSOR_RECT_length 0x00000002
+
+struct GEN8_SCISSOR_RECT {
+   uint32_t                                     ScissorRectangleYMin;
+   uint32_t                                     ScissorRectangleXMin;
+   uint32_t                                     ScissorRectangleYMax;
+   uint32_t                                     ScissorRectangleXMax;
+};
+
+static inline void
+GEN8_SCISSOR_RECT_pack(__gen_user_data *data, void * restrict dst,
+                       const struct GEN8_SCISSOR_RECT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->ScissorRectangleYMin, 16, 31) |
+      __gen_field(values->ScissorRectangleXMin, 0, 15) |
+      0;
+
+   dw[1] =
+      __gen_field(values->ScissorRectangleYMax, 16, 31) |
+      __gen_field(values->ScissorRectangleXMax, 0, 15) |
+      0;
+
+}
+
+#define GEN8_SF_CLIP_VIEWPORT_length 0x00000010
+
+struct GEN8_SF_CLIP_VIEWPORT {
+   float                                        ViewportMatrixElementm00;
+   float                                        ViewportMatrixElementm11;
+   float                                        ViewportMatrixElementm22;
+   float                                        ViewportMatrixElementm30;
+   float                                        ViewportMatrixElementm31;
+   float                                        ViewportMatrixElementm32;
+   float                                        XMinClipGuardband;
+   float                                        XMaxClipGuardband;
+   float                                        YMinClipGuardband;
+   float                                        YMaxClipGuardband;
+   float                                        XMinViewPort;
+   float                                        XMaxViewPort;
+   float                                        YMinViewPort;
+   float                                        YMaxViewPort;
+};
+
+static inline void
+GEN8_SF_CLIP_VIEWPORT_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_SF_CLIP_VIEWPORT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->ViewportMatrixElementm00) |
+      0;
+
+   dw[1] =
+      __gen_float(values->ViewportMatrixElementm11) |
+      0;
+
+   dw[2] =
+      __gen_float(values->ViewportMatrixElementm22) |
+      0;
+
+   dw[3] =
+      __gen_float(values->ViewportMatrixElementm30) |
+      0;
+
+   dw[4] =
+      __gen_float(values->ViewportMatrixElementm31) |
+      0;
+
+   dw[5] =
+      __gen_float(values->ViewportMatrixElementm32) |
+      0;
+
+   dw[6] =
+      0;
+
+   dw[7] =
+      0;
+
+   dw[8] =
+      __gen_float(values->XMinClipGuardband) |
+      0;
+
+   dw[9] =
+      __gen_float(values->XMaxClipGuardband) |
+      0;
+
+   dw[10] =
+      __gen_float(values->YMinClipGuardband) |
+      0;
+
+   dw[11] =
+      __gen_float(values->YMaxClipGuardband) |
+      0;
+
+   dw[12] =
+      __gen_float(values->XMinViewPort) |
+      0;
+
+   dw[13] =
+      __gen_float(values->XMaxViewPort) |
+      0;
+
+   dw[14] =
+      __gen_float(values->YMinViewPort) |
+      0;
+
+   dw[15] =
+      __gen_float(values->YMaxViewPort) |
+      0;
+
+}
+
+#define GEN8_BLEND_STATE_length 0x00000011
+
+#define GEN8_BLEND_STATE_ENTRY_length 0x00000002
+
+struct GEN8_BLEND_STATE_ENTRY {
+   bool                                         LogicOpEnable;
+   uint32_t                                     LogicOpFunction;
+   uint32_t                                     PreBlendSourceOnlyClampEnable;
+#define     COLORCLAMP_UNORM                                   0
+#define     COLORCLAMP_SNORM                                   1
+#define     COLORCLAMP_RTFORMAT                                2
+   uint32_t                                     ColorClampRange;
+   bool                                         PreBlendColorClampEnable;
+   bool                                         PostBlendColorClampEnable;
+   bool                                         ColorBufferBlendEnable;
+   uint32_t                                     SourceBlendFactor;
+   uint32_t                                     DestinationBlendFactor;
+   uint32_t                                     ColorBlendFunction;
+   uint32_t                                     SourceAlphaBlendFactor;
+   uint32_t                                     DestinationAlphaBlendFactor;
+   uint32_t                                     AlphaBlendFunction;
+   bool                                         WriteDisableAlpha;
+   bool                                         WriteDisableRed;
+   bool                                         WriteDisableGreen;
+   bool                                         WriteDisableBlue;
+};
+
+static inline void
+GEN8_BLEND_STATE_ENTRY_pack(__gen_user_data *data, void * restrict dst,
+                            const struct GEN8_BLEND_STATE_ENTRY * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   uint64_t qw0 =
+      __gen_field(values->LogicOpEnable, 63, 63) |
+      __gen_field(values->LogicOpFunction, 59, 62) |
+      __gen_field(values->PreBlendSourceOnlyClampEnable, 36, 36) |
+      __gen_field(values->ColorClampRange, 34, 35) |
+      __gen_field(values->PreBlendColorClampEnable, 33, 33) |
+      __gen_field(values->PostBlendColorClampEnable, 32, 32) |
+      __gen_field(values->ColorBufferBlendEnable, 31, 31) |
+      __gen_field(values->SourceBlendFactor, 26, 30) |
+      __gen_field(values->DestinationBlendFactor, 21, 25) |
+      __gen_field(values->ColorBlendFunction, 18, 20) |
+      __gen_field(values->SourceAlphaBlendFactor, 13, 17) |
+      __gen_field(values->DestinationAlphaBlendFactor, 8, 12) |
+      __gen_field(values->AlphaBlendFunction, 5, 7) |
+      __gen_field(values->WriteDisableAlpha, 3, 3) |
+      __gen_field(values->WriteDisableRed, 2, 2) |
+      __gen_field(values->WriteDisableGreen, 1, 1) |
+      __gen_field(values->WriteDisableBlue, 0, 0) |
+      0;
+
+   dw[0] = qw0;
+   dw[1] = qw0 >> 32;
+
+}
+
+struct GEN8_BLEND_STATE {
+   bool                                         AlphaToCoverageEnable;
+   bool                                         IndependentAlphaBlendEnable;
+   bool                                         AlphaToOneEnable;
+   bool                                         AlphaToCoverageDitherEnable;
+   bool                                         AlphaTestEnable;
+   uint32_t                                     AlphaTestFunction;
+   bool                                         ColorDitherEnable;
+   uint32_t                                     XDitherOffset;
+   uint32_t                                     YDitherOffset;
+   struct GEN8_BLEND_STATE_ENTRY                Entry[8];
+};
+
+static inline void
+GEN8_BLEND_STATE_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN8_BLEND_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->AlphaToCoverageEnable, 31, 31) |
+      __gen_field(values->IndependentAlphaBlendEnable, 30, 30) |
+      __gen_field(values->AlphaToOneEnable, 29, 29) |
+      __gen_field(values->AlphaToCoverageDitherEnable, 28, 28) |
+      __gen_field(values->AlphaTestEnable, 27, 27) |
+      __gen_field(values->AlphaTestFunction, 24, 26) |
+      __gen_field(values->ColorDitherEnable, 23, 23) |
+      __gen_field(values->XDitherOffset, 21, 22) |
+      __gen_field(values->YDitherOffset, 19, 20) |
+      0;
+
+   for (uint32_t i = 0, j = 1; i < 8; i++, j += 2)
+      GEN8_BLEND_STATE_ENTRY_pack(data, &dw[j], &values->Entry[i]);
+}
+
+#define GEN8_CC_VIEWPORT_length 0x00000002
+
+struct GEN8_CC_VIEWPORT {
+   float                                        MinimumDepth;
+   float                                        MaximumDepth;
+};
+
+static inline void
+GEN8_CC_VIEWPORT_pack(__gen_user_data *data, void * restrict dst,
+                      const struct GEN8_CC_VIEWPORT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_float(values->MinimumDepth) |
+      0;
+
+   dw[1] =
+      __gen_float(values->MaximumDepth) |
+      0;
+
+}
+
+#define GEN8_COLOR_CALC_STATE_length 0x00000006
+
+struct GEN8_COLOR_CALC_STATE {
+   uint32_t                                     StencilReferenceValue;
+   uint32_t                                     BackFaceStencilReferenceValue;
+#define     Cancelled                                          0
+#define     NotCancelled                                       1
+   uint32_t                                     RoundDisableFunctionDisable;
+#define     ALPHATEST_UNORM8                                   0
+#define     ALPHATEST_FLOAT32                                  1
+   uint32_t                                     AlphaTestFormat;
+   uint32_t                                     AlphaReferenceValueAsUNORM8;
+   float                                        AlphaReferenceValueAsFLOAT32;
+   float                                        BlendConstantColorRed;
+   float                                        BlendConstantColorGreen;
+   float                                        BlendConstantColorBlue;
+   float                                        BlendConstantColorAlpha;
+};
+
+static inline void
+GEN8_COLOR_CALC_STATE_pack(__gen_user_data *data, void * restrict dst,
+                           const struct GEN8_COLOR_CALC_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->StencilReferenceValue, 24, 31) |
+      __gen_field(values->BackFaceStencilReferenceValue, 16, 23) |
+      __gen_field(values->RoundDisableFunctionDisable, 15, 15) |
+      __gen_field(values->AlphaTestFormat, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_field(values->AlphaReferenceValueAsUNORM8, 0, 31) |
+      __gen_float(values->AlphaReferenceValueAsFLOAT32) |
+      0;
+
+   dw[2] =
+      __gen_float(values->BlendConstantColorRed) |
+      0;
+
+   dw[3] =
+      __gen_float(values->BlendConstantColorGreen) |
+      0;
+
+   dw[4] =
+      __gen_float(values->BlendConstantColorBlue) |
+      0;
+
+   dw[5] =
+      __gen_float(values->BlendConstantColorAlpha) |
+      0;
+
+}
+
+#define GEN8_BLACK_LEVEL_CORRECTION_STATE__DW7576_length 0x00000002
+
+struct GEN8_BLACK_LEVEL_CORRECTION_STATE__DW7576 {
+   uint32_t                                     BlackPointOffsetR;
+   uint32_t                                     BlackPointOffsetG;
+   uint32_t                                     BlackPointOffsetB;
+};
+
+static inline void
+GEN8_BLACK_LEVEL_CORRECTION_STATE__DW7576_pack(__gen_user_data *data, void * restrict dst,
+                                               const struct GEN8_BLACK_LEVEL_CORRECTION_STATE__DW7576 * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->BlackPointOffsetR, 0, 12) |
+      0;
+
+   dw[1] =
+      __gen_field(values->BlackPointOffsetG, 13, 25) |
+      __gen_field(values->BlackPointOffsetB, 0, 12) |
+      0;
+
+}
+
+#define GEN8_INTERFACE_DESCRIPTOR_DATA_length 0x00000008
+
+struct GEN8_INTERFACE_DESCRIPTOR_DATA {
+   uint32_t                                     KernelStartPointer;
+   uint32_t                                     KernelStartPointerHigh;
+#define     Ftz                                                0
+#define     SetByKernel                                        1
+   uint32_t                                     DenormMode;
+#define     Multiple                                           0
+#define     Single                                             1
+   uint32_t                                     SingleProgramFlow;
+#define     NormalPriority                                     0
+#define     HighPriority                                       1
+   uint32_t                                     ThreadPriority;
+#define     IEEE754                                            0
+#define     Alternate                                          1
+   uint32_t                                     FloatingPointMode;
+   bool                                         IllegalOpcodeExceptionEnable;
+   bool                                         MaskStackExceptionEnable;
+   bool                                         SoftwareExceptionEnable;
+   uint32_t                                     SamplerStatePointer;
+#define     Nosamplersused                                     0
+#define     Between1and4samplersused                           1
+#define     Between5and8samplersused                           2
+#define     Between9and12samplersused                          3
+#define     Between13and16samplersused                         4
+   uint32_t                                     SamplerCount;
+   uint32_t                                     BindingTablePointer;
+   uint32_t                                     BindingTableEntryCount;
+   uint32_t                                     ConstantIndirectURBEntryReadLength;
+   uint32_t                                     ConstantURBEntryReadOffset;
+#define     RTNE                                               0
+#define     RU                                                 1
+#define     RD                                                 2
+#define     RTZ                                                3
+   uint32_t                                     RoundingMode;
+   bool                                         BarrierEnable;
+#define     Encodes0k                                          0
+#define     Encodes4k                                          1
+#define     Encodes8k                                          2
+#define     Encodes16k                                         4
+#define     Encodes32k                                         8
+#define     Encodes64k                                        16
+   uint32_t                                     SharedLocalMemorySize;
+   uint32_t                                     NumberofThreadsinGPGPUThreadGroup;
+   uint32_t                                     CrossThreadConstantDataReadLength;
+};
+
+static inline void
+GEN8_INTERFACE_DESCRIPTOR_DATA_pack(__gen_user_data *data, void * restrict dst,
+                                    const struct GEN8_INTERFACE_DESCRIPTOR_DATA * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->KernelStartPointer, 6, 31) |
+      0;
+
+   dw[1] =
+      __gen_offset(values->KernelStartPointerHigh, 0, 15) |
+      0;
+
+   dw[2] =
+      __gen_field(values->DenormMode, 19, 19) |
+      __gen_field(values->SingleProgramFlow, 18, 18) |
+      __gen_field(values->ThreadPriority, 17, 17) |
+      __gen_field(values->FloatingPointMode, 16, 16) |
+      __gen_field(values->IllegalOpcodeExceptionEnable, 13, 13) |
+      __gen_field(values->MaskStackExceptionEnable, 11, 11) |
+      __gen_field(values->SoftwareExceptionEnable, 7, 7) |
+      0;
+
+   dw[3] =
+      __gen_offset(values->SamplerStatePointer, 5, 31) |
+      __gen_field(values->SamplerCount, 2, 4) |
+      0;
+
+   dw[4] =
+      __gen_offset(values->BindingTablePointer, 5, 15) |
+      __gen_field(values->BindingTableEntryCount, 0, 4) |
+      0;
+
+   dw[5] =
+      __gen_field(values->ConstantIndirectURBEntryReadLength, 16, 31) |
+      __gen_field(values->ConstantURBEntryReadOffset, 0, 15) |
+      0;
+
+   dw[6] =
+      __gen_field(values->RoundingMode, 22, 23) |
+      __gen_field(values->BarrierEnable, 21, 21) |
+      __gen_field(values->SharedLocalMemorySize, 16, 20) |
+      __gen_field(values->NumberofThreadsinGPGPUThreadGroup, 0, 9) |
+      0;
+
+   dw[7] =
+      __gen_field(values->CrossThreadConstantDataReadLength, 0, 7) |
+      0;
+
+}
+
+#define GEN8_BINDING_TABLE_STATE_length 0x00000001
+
+struct GEN8_BINDING_TABLE_STATE {
+   uint32_t                                     SurfaceStatePointer;
+};
+
+static inline void
+GEN8_BINDING_TABLE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                              const struct GEN8_BINDING_TABLE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_offset(values->SurfaceStatePointer, 6, 31) |
+      0;
+
+}
+
+#define GEN8_RENDER_SURFACE_STATE_length 0x00000010
+
+struct GEN8_RENDER_SURFACE_STATE {
+#define     SURFTYPE_1D                                        0
+#define     SURFTYPE_2D                                        1
+#define     SURFTYPE_3D                                        2
+#define     SURFTYPE_CUBE                                      3
+#define     SURFTYPE_BUFFER                                    4
+#define     SURFTYPE_STRBUF                                    5
+#define     SURFTYPE_NULL                                      7
+   uint32_t                                     SurfaceType;
+   bool                                         SurfaceArray;
+   uint32_t                                     SurfaceFormat;
+#define     VALIGN4                                            1
+#define     VALIGN8                                            2
+#define     VALIGN16                                           3
+   uint32_t                                     SurfaceVerticalAlignment;
+#define     HALIGN4                                            1
+#define     HALIGN8                                            2
+#define     HALIGN16                                           3
+   uint32_t                                     SurfaceHorizontalAlignment;
+#define     LINEAR                                             0
+#define     WMAJOR                                             1
+#define     XMAJOR                                             2
+#define     YMAJOR                                             3
+   uint32_t                                     TileMode;
+   uint32_t                                     VerticalLineStride;
+   uint32_t                                     VerticalLineStrideOffset;
+   bool                                         SamplerL2BypassModeDisable;
+#define     WriteOnlyCache                                     0
+#define     ReadWriteCache                                     1
+   uint32_t                                     RenderCacheReadWriteMode;
+#define     NORMAL_MODE                                        0
+#define     PROGRESSIVE_FRAME                                  2
+#define     INTERLACED_FRAME                                   3
+   uint32_t                                     MediaBoundaryPixelMode;
+   bool                                         CubeFaceEnablePositiveZ;
+   bool                                         CubeFaceEnableNegativeZ;
+   bool                                         CubeFaceEnablePositiveY;
+   bool                                         CubeFaceEnableNegativeY;
+   bool                                         CubeFaceEnablePositiveX;
+   bool                                         CubeFaceEnableNegativeX;
+   struct GEN8_MEMORY_OBJECT_CONTROL_STATE      MemoryObjectControlState;
+   float                                        BaseMipLevel;
+   uint32_t                                     SurfaceQPitch;
+   uint32_t                                     Height;
+   uint32_t                                     Width;
+   uint32_t                                     Depth;
+   uint32_t                                     SurfacePitch;
+#define     _0DEG                                              0
+#define     _90DEG                                             1
+#define     _270DEG                                            3
+   uint32_t                                     RenderTargetAndSampleUnormRotation;
+   uint32_t                                     MinimumArrayElement;
+   uint32_t                                     RenderTargetViewExtent;
+#define     MSS                                                0
+#define     DEPTH_STENCIL                                      1
+   uint32_t                                     MultisampledSurfaceStorageFormat;
+#define     MULTISAMPLECOUNT_1                                 0
+#define     MULTISAMPLECOUNT_2                                 1
+#define     MULTISAMPLECOUNT_4                                 2
+#define     MULTISAMPLECOUNT_8                                 3
+   uint32_t                                     NumberofMultisamples;
+   uint32_t                                     MultisamplePositionPaletteIndex;
+   uint32_t                                     XOffset;
+   uint32_t                                     YOffset;
+   bool                                         EWADisableForCube;
+#define     GPUcoherent                                        0
+#define     IAcoherent                                         1
+   uint32_t                                     CoherencyType;
+   uint32_t                                     SurfaceMinLOD;
+   uint32_t                                     MIPCountLOD;
+   uint32_t                                     AuxiliarySurfaceQPitch;
+   uint32_t                                     AuxiliarySurfacePitch;
+#define     AUX_NONE                                           0
+#define     AUX_MCS                                            1
+#define     AUX_APPEND                                         2
+#define     AUX_HIZ                                            3
+   uint32_t                                     AuxiliarySurfaceMode;
+   bool                                         SeparateUVPlaneEnable;
+   uint32_t                                     XOffsetforUorUVPlane;
+   uint32_t                                     YOffsetforUorUVPlane;
+   uint32_t                                     RedClearColor;
+   uint32_t                                     GreenClearColor;
+   uint32_t                                     BlueClearColor;
+   uint32_t                                     AlphaClearColor;
+   uint32_t                                     ShaderChannelSelectRed;
+   uint32_t                                     ShaderChannelSelectGreen;
+   uint32_t                                     ShaderChannelSelectBlue;
+   uint32_t                                     ShaderChannelSelectAlpha;
+   float                                        ResourceMinLOD;
+   __gen_address_type                           SurfaceBaseAddress;
+   uint32_t                                     XOffsetforVPlane;
+   uint32_t                                     YOffsetforVPlane;
+   uint32_t                                     AuxiliaryTableIndexforMediaCompressedSurface;
+   __gen_address_type                           AuxiliarySurfaceBaseAddress;
+};
+
+static inline void
+GEN8_RENDER_SURFACE_STATE_pack(__gen_user_data *data, void * restrict dst,
+                               const struct GEN8_RENDER_SURFACE_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->SurfaceType, 29, 31) |
+      __gen_field(values->SurfaceArray, 28, 28) |
+      __gen_field(values->SurfaceFormat, 18, 26) |
+      __gen_field(values->SurfaceVerticalAlignment, 16, 17) |
+      __gen_field(values->SurfaceHorizontalAlignment, 14, 15) |
+      __gen_field(values->TileMode, 12, 13) |
+      __gen_field(values->VerticalLineStride, 11, 11) |
+      __gen_field(values->VerticalLineStrideOffset, 10, 10) |
+      __gen_field(values->SamplerL2BypassModeDisable, 9, 9) |
+      __gen_field(values->RenderCacheReadWriteMode, 8, 8) |
+      __gen_field(values->MediaBoundaryPixelMode, 6, 7) |
+      __gen_field(values->CubeFaceEnablePositiveZ, 0, 0) |
+      __gen_field(values->CubeFaceEnableNegativeZ, 1, 1) |
+      __gen_field(values->CubeFaceEnablePositiveY, 2, 2) |
+      __gen_field(values->CubeFaceEnableNegativeY, 3, 3) |
+      __gen_field(values->CubeFaceEnablePositiveX, 4, 4) |
+      __gen_field(values->CubeFaceEnableNegativeX, 5, 5) |
+      0;
+
+   uint32_t dw_MemoryObjectControlState;
+   GEN8_MEMORY_OBJECT_CONTROL_STATE_pack(data, &dw_MemoryObjectControlState, &values->MemoryObjectControlState);
+   dw[1] =
+      __gen_field(dw_MemoryObjectControlState, 24, 30) |
+      __gen_field(values->BaseMipLevel * (1 << 1), 19, 23) |
+      __gen_field(values->SurfaceQPitch, 0, 14) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Height, 16, 29) |
+      __gen_field(values->Width, 0, 13) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Depth, 21, 31) |
+      __gen_field(values->SurfacePitch, 0, 17) |
+      0;
+
+   dw[4] =
+      __gen_field(values->RenderTargetAndSampleUnormRotation, 29, 30) |
+      __gen_field(values->MinimumArrayElement, 18, 28) |
+      __gen_field(values->RenderTargetViewExtent, 7, 17) |
+      __gen_field(values->MultisampledSurfaceStorageFormat, 6, 6) |
+      __gen_field(values->NumberofMultisamples, 3, 5) |
+      __gen_field(values->MultisamplePositionPaletteIndex, 0, 2) |
+      0;
+
+   dw[5] =
+      __gen_offset(values->XOffset, 25, 31) |
+      __gen_offset(values->YOffset, 21, 23) |
+      __gen_field(values->EWADisableForCube, 20, 20) |
+      __gen_field(values->CoherencyType, 14, 14) |
+      __gen_field(values->SurfaceMinLOD, 4, 7) |
+      __gen_field(values->MIPCountLOD, 0, 3) |
+      0;
+
+   dw[6] =
+      __gen_field(values->AuxiliarySurfaceQPitch, 16, 30) |
+      __gen_field(values->AuxiliarySurfacePitch, 3, 11) |
+      __gen_field(values->AuxiliarySurfaceMode, 0, 2) |
+      __gen_field(values->SeparateUVPlaneEnable, 31, 31) |
+      __gen_field(values->XOffsetforUorUVPlane, 16, 29) |
+      __gen_field(values->YOffsetforUorUVPlane, 0, 13) |
+      0;
+
+   dw[7] =
+      __gen_field(values->RedClearColor, 31, 31) |
+      __gen_field(values->GreenClearColor, 30, 30) |
+      __gen_field(values->BlueClearColor, 29, 29) |
+      __gen_field(values->AlphaClearColor, 28, 28) |
+      __gen_field(values->ShaderChannelSelectRed, 25, 27) |
+      __gen_field(values->ShaderChannelSelectGreen, 22, 24) |
+      __gen_field(values->ShaderChannelSelectBlue, 19, 21) |
+      __gen_field(values->ShaderChannelSelectAlpha, 16, 18) |
+      __gen_field(values->ResourceMinLOD * (1 << 8), 0, 11) |
+      0;
+
+   uint32_t dw8 =
+      0;
+
+   uint64_t qw8 =
+      __gen_combine_address(data, &dw[8], values->SurfaceBaseAddress, dw8);
+
+   dw[8] = qw8;
+   dw[9] = qw8 >> 32;
+
+   uint32_t dw10 =
+      __gen_field(values->XOffsetforVPlane, 48, 61) |
+      __gen_field(values->YOffsetforVPlane, 32, 45) |
+      __gen_field(values->AuxiliaryTableIndexforMediaCompressedSurface, 21, 31) |
+      0;
+
+   uint64_t qw10 =
+      __gen_combine_address(data, &dw[10], values->AuxiliarySurfaceBaseAddress, dw10);
+
+   dw[10] = qw10;
+   dw[11] = qw10 >> 32;
+
+   dw[12] =
+      0;
+
+   dw[13] =
+      0;
+
+   dw[14] =
+      0;
+
+   dw[15] =
+      0;
+
+}
+
+#define GEN8_FILTER_COEFFICIENT_length 0x00000001
+
+struct GEN8_FILTER_COEFFICIENT {
+   uint32_t                                     FilterCoefficient;
+};
+
+static inline void
+GEN8_FILTER_COEFFICIENT_pack(__gen_user_data *data, void * restrict dst,
+                             const struct GEN8_FILTER_COEFFICIENT * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->FilterCoefficient, 0, 7) |
+      0;
+
+}
+
+#define GEN8_SAMPLER_STATE_length 0x00000004
+
+struct GEN8_SAMPLER_STATE {
+   bool                                         SamplerDisable;
+#define     DX10OGL                                            0
+#define     DX9                                                1
+   uint32_t                                     TextureBorderColorMode;
+#define     CLAMP_NONE                                         0
+#define     CLAMP_OGL                                          2
+   uint32_t                                     LODPreClampMode;
+   float                                        BaseMipLevel;
+#define     MIPFILTER_NONE                                     0
+#define     MIPFILTER_NEAREST                                  1
+#define     MIPFILTER_LINEAR                                   3
+   uint32_t                                     MipModeFilter;
+#define     MAPFILTER_NEAREST                                  0
+#define     MAPFILTER_LINEAR                                   1
+#define     MAPFILTER_ANISOTROPIC                              2
+#define     MAPFILTER_MONO                                     6
+   uint32_t                                     MagModeFilter;
+#define     MAPFILTER_NEAREST                                  0
+#define     MAPFILTER_LINEAR                                   1
+#define     MAPFILTER_ANISOTROPIC                              2
+#define     MAPFILTER_MONO                                     6
+   uint32_t                                     MinModeFilter;
+   uint32_t                                     TextureLODBias;
+#define     LEGACY                                             0
+#define     EWAApproximation                                   1
+   uint32_t                                     AnisotropicAlgorithm;
+   float                                        MinLOD;
+   float                                        MaxLOD;
+   bool                                         ChromaKeyEnable;
+   uint32_t                                     ChromaKeyIndex;
+#define     KEYFILTER_KILL_ON_ANY_MATCH                        0
+#define     KEYFILTER_REPLACE_BLACK                            1
+   uint32_t                                     ChromaKeyMode;
+#define     PREFILTEROPALWAYS                                  0
+#define     PREFILTEROPNEVER                                   1
+#define     PREFILTEROPLESS                                    2
+#define     PREFILTEROPEQUAL                                   3
+#define     PREFILTEROPLEQUAL                                  4
+#define     PREFILTEROPGREATER                                 5
+#define     PREFILTEROPNOTEQUAL                                6
+#define     PREFILTEROPGEQUAL                                  7
+   uint32_t                                     ShadowFunction;
+#define     PROGRAMMED                                         0
+#define     OVERRIDE                                           1
+   uint32_t                                     CubeSurfaceControlMode;
+   uint32_t                                     IndirectStatePointer;
+#define     MIPNONE                                            0
+#define     MIPFILTER                                          1
+   uint32_t                                     LODClampMagnificationMode;
+#define     RATIO21                                            0
+#define     RATIO41                                            1
+#define     RATIO61                                            2
+#define     RATIO81                                            3
+#define     RATIO101                                           4
+#define     RATIO121                                           5
+#define     RATIO141                                           6
+#define     RATIO161                                           7
+   uint32_t                                     MaximumAnisotropy;
+   bool                                         RAddressMinFilterRoundingEnable;
+   bool                                         RAddressMagFilterRoundingEnable;
+   bool                                         VAddressMinFilterRoundingEnable;
+   bool                                         VAddressMagFilterRoundingEnable;
+   bool                                         UAddressMinFilterRoundingEnable;
+   bool                                         UAddressMagFilterRoundingEnable;
+#define     FULL                                               0
+#define     HIGH                                               1
+#define     MED                                                2
+#define     LOW                                                3
+   uint32_t                                     TrilinearFilterQuality;
+   bool                                         NonnormalizedCoordinateEnable;
+   uint32_t                                     TCXAddressControlMode;
+   uint32_t                                     TCYAddressControlMode;
+   uint32_t                                     TCZAddressControlMode;
+};
+
+static inline void
+GEN8_SAMPLER_STATE_pack(__gen_user_data *data, void * restrict dst,
+                        const struct GEN8_SAMPLER_STATE * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->SamplerDisable, 31, 31) |
+      __gen_field(values->TextureBorderColorMode, 29, 29) |
+      __gen_field(values->LODPreClampMode, 27, 28) |
+      __gen_field(values->BaseMipLevel * (1 << 1), 22, 26) |
+      __gen_field(values->MipModeFilter, 20, 21) |
+      __gen_field(values->MagModeFilter, 17, 19) |
+      __gen_field(values->MinModeFilter, 14, 16) |
+      __gen_field(values->TextureLODBias, 1, 13) |
+      __gen_field(values->AnisotropicAlgorithm, 0, 0) |
+      0;
+
+   dw[1] =
+      __gen_field(values->MinLOD * (1 << 8), 20, 31) |
+      __gen_field(values->MaxLOD * (1 << 8), 8, 19) |
+      __gen_field(values->ChromaKeyEnable, 7, 7) |
+      __gen_field(values->ChromaKeyIndex, 5, 6) |
+      __gen_field(values->ChromaKeyMode, 4, 4) |
+      __gen_field(values->ShadowFunction, 1, 3) |
+      __gen_field(values->CubeSurfaceControlMode, 0, 0) |
+      0;
+
+   dw[2] =
+      __gen_field(values->IndirectStatePointer, 6, 23) |
+      __gen_field(values->LODClampMagnificationMode, 0, 0) |
+      0;
+
+   dw[3] =
+      __gen_field(values->MaximumAnisotropy, 19, 21) |
+      __gen_field(values->RAddressMinFilterRoundingEnable, 13, 13) |
+      __gen_field(values->RAddressMagFilterRoundingEnable, 14, 14) |
+      __gen_field(values->VAddressMinFilterRoundingEnable, 15, 15) |
+      __gen_field(values->VAddressMagFilterRoundingEnable, 16, 16) |
+      __gen_field(values->UAddressMinFilterRoundingEnable, 17, 17) |
+      __gen_field(values->UAddressMagFilterRoundingEnable, 18, 18) |
+      __gen_field(values->TrilinearFilterQuality, 11, 12) |
+      __gen_field(values->NonnormalizedCoordinateEnable, 10, 10) |
+      __gen_field(values->TCXAddressControlMode, 6, 8) |
+      __gen_field(values->TCYAddressControlMode, 3, 5) |
+      __gen_field(values->TCZAddressControlMode, 0, 2) |
+      0;
+
+}
+
+#define GEN8_SAMPLER_STATE_8X8_AVS_COEFFICIENTS_length 0x00000008
+
+struct GEN8_SAMPLER_STATE_8X8_AVS_COEFFICIENTS {
+   uint32_t                                     Table0YFilterCoefficientn1;
+   uint32_t                                     Table0XFilterCoefficientn1;
+   uint32_t                                     Table0YFilterCoefficientn0;
+   uint32_t                                     Table0XFilterCoefficientn0;
+   uint32_t                                     Table0YFilterCoefficientn3;
+   uint32_t                                     Table0XFilterCoefficientn3;
+   uint32_t                                     Table0YFilterCoefficientn2;
+   uint32_t                                     Table0XFilterCoefficientn2;
+   uint32_t                                     Table0YFilterCoefficientn5;
+   uint32_t                                     Table0XFilterCoefficientn5;
+   uint32_t                                     Table0YFilterCoefficientn4;
+   uint32_t                                     Table0XFilterCoefficientn4;
+   uint32_t                                     Table0YFilterCoefficientn7;
+   uint32_t                                     Table0XFilterCoefficientn7;
+   uint32_t                                     Table0YFilterCoefficientn6;
+   uint32_t                                     Table0XFilterCoefficientn6;
+   uint32_t                                     Table1XFilterCoefficientn3;
+   uint32_t                                     Table1XFilterCoefficientn2;
+   uint32_t                                     Table1XFilterCoefficientn5;
+   uint32_t                                     Table1XFilterCoefficientn4;
+   uint32_t                                     Table1YFilterCoefficientn3;
+   uint32_t                                     Table1YFilterCoefficientn2;
+   uint32_t                                     Table1YFilterCoefficientn5;
+   uint32_t                                     Table1YFilterCoefficientn4;
+};
+
+static inline void
+GEN8_SAMPLER_STATE_8X8_AVS_COEFFICIENTS_pack(__gen_user_data *data, void * restrict dst,
+                                             const struct GEN8_SAMPLER_STATE_8X8_AVS_COEFFICIENTS * restrict values)
+{
+   uint32_t *dw = (uint32_t * restrict) dst;
+
+   dw[0] =
+      __gen_field(values->Table0YFilterCoefficientn1, 24, 31) |
+      __gen_field(values->Table0XFilterCoefficientn1, 16, 23) |
+      __gen_field(values->Table0YFilterCoefficientn0, 8, 15) |
+      __gen_field(values->Table0XFilterCoefficientn0, 0, 7) |
+      0;
+
+   dw[1] =
+      __gen_field(values->Table0YFilterCoefficientn3, 24, 31) |
+      __gen_field(values->Table0XFilterCoefficientn3, 16, 23) |
+      __gen_field(values->Table0YFilterCoefficientn2, 8, 15) |
+      __gen_field(values->Table0XFilterCoefficientn2, 0, 7) |
+      0;
+
+   dw[2] =
+      __gen_field(values->Table0YFilterCoefficientn5, 24, 31) |
+      __gen_field(values->Table0XFilterCoefficientn5, 16, 23) |
+      __gen_field(values->Table0YFilterCoefficientn4, 8, 15) |
+      __gen_field(values->Table0XFilterCoefficientn4, 0, 7) |
+      0;
+
+   dw[3] =
+      __gen_field(values->Table0YFilterCoefficientn7, 24, 31) |
+      __gen_field(values->Table0XFilterCoefficientn7, 16, 23) |
+      __gen_field(values->Table0YFilterCoefficientn6, 8, 15) |
+      __gen_field(values->Table0XFilterCoefficientn6, 0, 7) |
+      0;
+
+   dw[4] =
+      __gen_field(values->Table1XFilterCoefficientn3, 24, 31) |
+      __gen_field(values->Table1XFilterCoefficientn2, 16, 23) |
+      0;
+
+   dw[5] =
+      __gen_field(values->Table1XFilterCoefficientn5, 8, 15) |
+      __gen_field(values->Table1XFilterCoefficientn4, 0, 7) |
+      0;
+
+   dw[6] =
+      __gen_field(values->Table1YFilterCoefficientn3, 24, 31) |
+      __gen_field(values->Table1YFilterCoefficientn2, 16, 23) |
+      0;
+
+   dw[7] =
+      __gen_field(values->Table1YFilterCoefficientn5, 8, 15) |
+      __gen_field(values->Table1YFilterCoefficientn4, 0, 7) |
+      0;
+
+}
+
+/* Enum 3D_Prim_Topo_Type */
+#define     _3DPRIM_POINTLIST                                  1
+#define     _3DPRIM_LINELIST                                   2
+#define     _3DPRIM_LINESTRIP                                  3
+#define     _3DPRIM_TRILIST                                    4
+#define     _3DPRIM_TRISTRIP                                   5
+#define     _3DPRIM_TRIFAN                                     6
+#define     _3DPRIM_QUADLIST                                   7
+#define     _3DPRIM_QUADSTRIP                                  8
+#define     _3DPRIM_LINELIST_ADJ                               9
+#define     _3DPRIM_LINESTRIP_ADJ                             10
+#define     _3DPRIM_TRILIST_ADJ                               11
+#define     _3DPRIM_TRISTRIP_ADJ                              12
+#define     _3DPRIM_TRISTRIP_REVERSE                          13
+#define     _3DPRIM_POLYGON                                   14
+#define     _3DPRIM_RECTLIST                                  15
+#define     _3DPRIM_LINELOOP                                  16
+#define     _3DPRIM_POINTLIST_BF                              17
+#define     _3DPRIM_LINESTRIP_CONT                            18
+#define     _3DPRIM_LINESTRIP_BF                              19
+#define     _3DPRIM_LINESTRIP_CONT_BF                         20
+#define     _3DPRIM_TRIFAN_NOSTIPPLE                          22
+#define     _3DPRIM_PATCHLIST_1                               32
+#define     _3DPRIM_PATCHLIST_2                               33
+#define     _3DPRIM_PATCHLIST_3                               34
+#define     _3DPRIM_PATCHLIST_4                               35
+#define     _3DPRIM_PATCHLIST_5                               36
+#define     _3DPRIM_PATCHLIST_6                               37
+#define     _3DPRIM_PATCHLIST_7                               38
+#define     _3DPRIM_PATCHLIST_8                               39
+#define     _3DPRIM_PATCHLIST_9                               40
+#define     _3DPRIM_PATCHLIST_10                              41
+#define     _3DPRIM_PATCHLIST_11                              42
+#define     _3DPRIM_PATCHLIST_12                              43
+#define     _3DPRIM_PATCHLIST_13                              44
+#define     _3DPRIM_PATCHLIST_14                              45
+#define     _3DPRIM_PATCHLIST_15                              46
+#define     _3DPRIM_PATCHLIST_16                              47
+#define     _3DPRIM_PATCHLIST_17                              48
+#define     _3DPRIM_PATCHLIST_18                              49
+#define     _3DPRIM_PATCHLIST_19                              50
+#define     _3DPRIM_PATCHLIST_20                              51
+#define     _3DPRIM_PATCHLIST_21                              52
+#define     _3DPRIM_PATCHLIST_22                              53
+#define     _3DPRIM_PATCHLIST_23                              54
+#define     _3DPRIM_PATCHLIST_24                              55
+#define     _3DPRIM_PATCHLIST_25                              56
+#define     _3DPRIM_PATCHLIST_26                              57
+#define     _3DPRIM_PATCHLIST_27                              58
+#define     _3DPRIM_PATCHLIST_28                              59
+#define     _3DPRIM_PATCHLIST_29                              60
+#define     _3DPRIM_PATCHLIST_30                              61
+#define     _3DPRIM_PATCHLIST_31                              62
+#define     _3DPRIM_PATCHLIST_32                              63
+
+/* Enum 3D_Vertex_Component_Control */
+#define     VFCOMP_NOSTORE                                     0
+#define     VFCOMP_STORE_SRC                                   1
+#define     VFCOMP_STORE_0                                     2
+#define     VFCOMP_STORE_1_FP                                  3
+#define     VFCOMP_STORE_1_INT                                 4
+#define     VFCOMP_STORE_PID                                   7
+
+/* Enum WRAP_SHORTEST_ENABLE */
+#define     WSE_X                                              1
+#define     WSE_Y                                              2
+#define     WSE_XY                                             3
+#define     WSE_Z                                              4
+#define     WSE_XZ                                             5
+#define     WSE_YZ                                             6
+#define     WSE_XYZ                                            7
+#define     WSE_W                                              8
+#define     WSE_XW                                             9
+#define     WSE_YW                                            10
+#define     WSE_XYW                                           11
+#define     WSE_ZW                                            12
+#define     WSE_XZW                                           13
+#define     WSE_YZW                                           14
+#define     WSE_XYZW                                          15
+
+/* Enum 3D_Stencil_Operation */
+#define     STENCILOP_KEEP                                     0
+#define     STENCILOP_ZERO                                     1
+#define     STENCILOP_REPLACE                                  2
+#define     STENCILOP_INCRSAT                                  3
+#define     STENCILOP_DECRSAT                                  4
+#define     STENCILOP_INCR                                     5
+#define     STENCILOP_DECR                                     6
+#define     STENCILOP_INVERT                                   7
+
+/* Enum 3D_Color_Buffer_Blend_Factor */
+#define     BLENDFACTOR_ONE                                    1
+#define     BLENDFACTOR_SRC_COLOR                              2
+#define     BLENDFACTOR_SRC_ALPHA                              3
+#define     BLENDFACTOR_DST_ALPHA                              4
+#define     BLENDFACTOR_DST_COLOR                              5
+#define     BLENDFACTOR_SRC_ALPHA_SATURATE                     6
+#define     BLENDFACTOR_CONST_COLOR                            7
+#define     BLENDFACTOR_CONST_ALPHA                            8
+#define     BLENDFACTOR_SRC1_COLOR                             9
+#define     BLENDFACTOR_SRC1_ALPHA                            10
+#define     BLENDFACTOR_ZERO                                  17
+#define     BLENDFACTOR_INV_SRC_COLOR                         18
+#define     BLENDFACTOR_INV_SRC_ALPHA                         19
+#define     BLENDFACTOR_INV_DST_ALPHA                         20
+#define     BLENDFACTOR_INV_DST_COLOR                         21
+#define     BLENDFACTOR_INV_CONST_COLOR                       23
+#define     BLENDFACTOR_INV_CONST_ALPHA                       24
+#define     BLENDFACTOR_INV_SRC1_COLOR                        25
+#define     BLENDFACTOR_INV_SRC1_ALPHA                        26
+
+/* Enum 3D_Color_Buffer_Blend_Function */
+#define     BLENDFUNCTION_ADD                                  0
+#define     BLENDFUNCTION_SUBTRACT                             1
+#define     BLENDFUNCTION_REVERSE_SUBTRACT                     2
+#define     BLENDFUNCTION_MIN                                  3
+#define     BLENDFUNCTION_MAX                                  4
+
+/* Enum 3D_Compare_Function */
+#define     COMPAREFUNCTION_ALWAYS                             0
+#define     COMPAREFUNCTION_NEVER                              1
+#define     COMPAREFUNCTION_LESS                               2
+#define     COMPAREFUNCTION_EQUAL                              3
+#define     COMPAREFUNCTION_LEQUAL                             4
+#define     COMPAREFUNCTION_GREATER                            5
+#define     COMPAREFUNCTION_NOTEQUAL                           6
+#define     COMPAREFUNCTION_GEQUAL                             7
+
+/* Enum 3D_Logic_Op_Function */
+#define     LOGICOP_CLEAR                                      0
+#define     LOGICOP_NOR                                        1
+#define     LOGICOP_AND_INVERTED                               2
+#define     LOGICOP_COPY_INVERTED                              3
+#define     LOGICOP_AND_REVERSE                                4
+#define     LOGICOP_INVERT                                     5
+#define     LOGICOP_XOR                                        6
+#define     LOGICOP_NAND                                       7
+#define     LOGICOP_AND                                        8
+#define     LOGICOP_EQUIV                                      9
+#define     LOGICOP_NOOP                                      10
+#define     LOGICOP_OR_INVERTED                               11
+#define     LOGICOP_COPY                                      12
+#define     LOGICOP_OR_REVERSE                                13
+#define     LOGICOP_OR                                        14
+#define     LOGICOP_SET                                       15
+
+/* Enum SURFACE_FORMAT */
+#define     R32G32B32A32_FLOAT                                 0
+#define     R32G32B32A32_SINT                                  1
+#define     R32G32B32A32_UINT                                  2
+#define     R32G32B32A32_UNORM                                 3
+#define     R32G32B32A32_SNORM                                 4
+#define     R64G64_FLOAT                                       5
+#define     R32G32B32X32_FLOAT                                 6
+#define     R32G32B32A32_SSCALED                               7
+#define     R32G32B32A32_USCALED                               8
+#define     R32G32B32A32_SFIXED                               32
+#define     R64G64_PASSTHRU                                   33
+#define     R32G32B32_FLOAT                                   64
+#define     R32G32B32_SINT                                    65
+#define     R32G32B32_UINT                                    66
+#define     R32G32B32_UNORM                                   67
+#define     R32G32B32_SNORM                                   68
+#define     R32G32B32_SSCALED                                 69
+#define     R32G32B32_USCALED                                 70
+#define     R32G32B32_SFIXED                                  80
+#define     R16G16B16A16_UNORM                               128
+#define     R16G16B16A16_SNORM                               129
+#define     R16G16B16A16_SINT                                130
+#define     R16G16B16A16_UINT                                131
+#define     R16G16B16A16_FLOAT                               132
+#define     R32G32_FLOAT                                     133
+#define     R32G32_SINT                                      134
+#define     R32G32_UINT                                      135
+#define     R32_FLOAT_X8X24_TYPELESS                         136
+#define     X32_TYPELESS_G8X24_UINT                          137
+#define     L32A32_FLOAT                                     138
+#define     R32G32_UNORM                                     139
+#define     R32G32_SNORM                                     140
+#define     R64_FLOAT                                        141
+#define     R16G16B16X16_UNORM                               142
+#define     R16G16B16X16_FLOAT                               143
+#define     A32X32_FLOAT                                     144
+#define     L32X32_FLOAT                                     145
+#define     I32X32_FLOAT                                     146
+#define     R16G16B16A16_SSCALED                             147
+#define     R16G16B16A16_USCALED                             148
+#define     R32G32_SSCALED                                   149
+#define     R32G32_USCALED                                   150
+#define     R32G32_SFIXED                                    160
+#define     R64_PASSTHRU                                     161
+#define     B8G8R8A8_UNORM                                   192
+#define     B8G8R8A8_UNORM_SRGB                              193
+#define     R10G10B10A2_UNORM                                194
+#define     R10G10B10A2_UNORM_SRGB                           195
+#define     R10G10B10A2_UINT                                 196
+#define     R10G10B10_SNORM_A2_UNORM                         197
+#define     R8G8B8A8_UNORM                                   199
+#define     R8G8B8A8_UNORM_SRGB                              200
+#define     R8G8B8A8_SNORM                                   201
+#define     R8G8B8A8_SINT                                    202
+#define     R8G8B8A8_UINT                                    203
+#define     R16G16_UNORM                                     204
+#define     R16G16_SNORM                                     205
+#define     R16G16_SINT                                      206
+#define     R16G16_UINT                                      207
+#define     R16G16_FLOAT                                     208
+#define     B10G10R10A2_UNORM                                209
+#define     B10G10R10A2_UNORM_SRGB                           210
+#define     R11G11B10_FLOAT                                  211
+#define     R32_SINT                                         214
+#define     R32_UINT                                         215
+#define     R32_FLOAT                                        216
+#define     R24_UNORM_X8_TYPELESS                            217
+#define     X24_TYPELESS_G8_UINT                             218
+#define     L32_UNORM                                        221
+#define     A32_UNORM                                        222
+#define     L16A16_UNORM                                     223
+#define     I24X8_UNORM                                      224
+#define     L24X8_UNORM                                      225
+#define     A24X8_UNORM                                      226
+#define     I32_FLOAT                                        227
+#define     L32_FLOAT                                        228
+#define     A32_FLOAT                                        229
+#define     X8B8_UNORM_G8R8_SNORM                            230
+#define     A8X8_UNORM_G8R8_SNORM                            231
+#define     B8X8_UNORM_G8R8_SNORM                            232
+#define     B8G8R8X8_UNORM                                   233
+#define     B8G8R8X8_UNORM_SRGB                              234
+#define     R8G8B8X8_UNORM                                   235
+#define     R8G8B8X8_UNORM_SRGB                              236
+#define     R9G9B9E5_SHAREDEXP                               237
+#define     B10G10R10X2_UNORM                                238
+#define     L16A16_FLOAT                                     240
+#define     R32_UNORM                                        241
+#define     R32_SNORM                                        242
+#define     R10G10B10X2_USCALED                              243
+#define     R8G8B8A8_SSCALED                                 244
+#define     R8G8B8A8_USCALED                                 245
+#define     R16G16_SSCALED                                   246
+#define     R16G16_USCALED                                   247
+#define     R32_SSCALED                                      248
+#define     R32_USCALED                                      249
+#define     B5G6R5_UNORM                                     256
+#define     B5G6R5_UNORM_SRGB                                257
+#define     B5G5R5A1_UNORM                                   258
+#define     B5G5R5A1_UNORM_SRGB                              259
+#define     B4G4R4A4_UNORM                                   260
+#define     B4G4R4A4_UNORM_SRGB                              261
+#define     R8G8_UNORM                                       262
+#define     R8G8_SNORM                                       263
+#define     R8G8_SINT                                        264
+#define     R8G8_UINT                                        265
+#define     R16_UNORM                                        266
+#define     R16_SNORM                                        267
+#define     R16_SINT                                         268
+#define     R16_UINT                                         269
+#define     R16_FLOAT                                        270
+#define     A8P8_UNORM_PALETTE0                              271
+#define     A8P8_UNORM_PALETTE1                              272
+#define     I16_UNORM                                        273
+#define     L16_UNORM                                        274
+#define     A16_UNORM                                        275
+#define     L8A8_UNORM                                       276
+#define     I16_FLOAT                                        277
+#define     L16_FLOAT                                        278
+#define     A16_FLOAT                                        279
+#define     L8A8_UNORM_SRGB                                  280
+#define     R5G5_SNORM_B6_UNORM                              281
+#define     B5G5R5X1_UNORM                                   282
+#define     B5G5R5X1_UNORM_SRGB                              283
+#define     R8G8_SSCALED                                     284
+#define     R8G8_USCALED                                     285
+#define     R16_SSCALED                                      286
+#define     R16_USCALED                                      287
+#define     P8A8_UNORM_PALETTE0                              290
+#define     P8A8_UNORM_PALETTE1                              291
+#define     A1B5G5R5_UNORM                                   292
+#define     A4B4G4R4_UNORM                                   293
+#define     L8A8_UINT                                        294
+#define     L8A8_SINT                                        295
+#define     R8_UNORM                                         320
+#define     R8_SNORM                                         321
+#define     R8_SINT                                          322
+#define     R8_UINT                                          323
+#define     A8_UNORM                                         324
+#define     I8_UNORM                                         325
+#define     L8_UNORM                                         326
+#define     P4A4_UNORM_PALETTE0                              327
+#define     A4P4_UNORM_PALETTE0                              328
+#define     R8_SSCALED                                       329
+#define     R8_USCALED                                       330
+#define     P8_UNORM_PALETTE0                                331
+#define     L8_UNORM_SRGB                                    332
+#define     P8_UNORM_PALETTE1                                333
+#define     P4A4_UNORM_PALETTE1                              334
+#define     A4P4_UNORM_PALETTE1                              335
+#define     Y8_UNORM                                         336
+#define     L8_UINT                                          338
+#define     L8_SINT                                          339
+#define     I8_UINT                                          340
+#define     I8_SINT                                          341
+#define     DXT1_RGB_SRGB                                    384
+#define     R1_UNORM                                         385
+#define     YCRCB_NORMAL                                     386
+#define     YCRCB_SWAPUVY                                    387
+#define     P2_UNORM_PALETTE0                                388
+#define     P2_UNORM_PALETTE1                                389
+#define     BC1_UNORM                                        390
+#define     BC2_UNORM                                        391
+#define     BC3_UNORM                                        392
+#define     BC4_UNORM                                        393
+#define     BC5_UNORM                                        394
+#define     BC1_UNORM_SRGB                                   395
+#define     BC2_UNORM_SRGB                                   396
+#define     BC3_UNORM_SRGB                                   397
+#define     MONO8                                            398
+#define     YCRCB_SWAPUV                                     399
+#define     YCRCB_SWAPY                                      400
+#define     DXT1_RGB                                         401
+#define     FXT1                                             402
+#define     R8G8B8_UNORM                                     403
+#define     R8G8B8_SNORM                                     404
+#define     R8G8B8_SSCALED                                   405
+#define     R8G8B8_USCALED                                   406
+#define     R64G64B64A64_FLOAT                               407
+#define     R64G64B64_FLOAT                                  408
+#define     BC4_SNORM                                        409
+#define     BC5_SNORM                                        410
+#define     R16G16B16_FLOAT                                  411
+#define     R16G16B16_UNORM                                  412
+#define     R16G16B16_SNORM                                  413
+#define     R16G16B16_SSCALED                                414
+#define     R16G16B16_USCALED                                415
+#define     BC6H_SF16                                        417
+#define     BC7_UNORM                                        418
+#define     BC7_UNORM_SRGB                                   419
+#define     BC6H_UF16                                        420
+#define     PLANAR_420_8                                     421
+#define     R8G8B8_UNORM_SRGB                                424
+#define     ETC1_RGB8                                        425
+#define     ETC2_RGB8                                        426
+#define     EAC_R11                                          427
+#define     EAC_RG11                                         428
+#define     EAC_SIGNED_R11                                   429
+#define     EAC_SIGNED_RG11                                  430
+#define     ETC2_SRGB8                                       431
+#define     R16G16B16_UINT                                   432
+#define     R16G16B16_SINT                                   433
+#define     R32_SFIXED                                       434
+#define     R10G10B10A2_SNORM                                435
+#define     R10G10B10A2_USCALED                              436
+#define     R10G10B10A2_SSCALED                              437
+#define     R10G10B10A2_SINT                                 438
+#define     B10G10R10A2_SNORM                                439
+#define     B10G10R10A2_USCALED                              440
+#define     B10G10R10A2_SSCALED                              441
+#define     B10G10R10A2_UINT                                 442
+#define     B10G10R10A2_SINT                                 443
+#define     R64G64B64A64_PASSTHRU                            444
+#define     R64G64B64_PASSTHRU                               445
+#define     ETC2_RGB8_PTA                                    448
+#define     ETC2_SRGB8_PTA                                   449
+#define     ETC2_EAC_RGBA8                                   450
+#define     ETC2_EAC_SRGB8_A8                                451
+#define     R8G8B8_UINT                                      456
+#define     R8G8B8_SINT                                      457
+#define     RAW                                              511
+
+/* Enum Shader Channel Select */
+#define     SCS_ZERO                                           0
+#define     SCS_ONE                                            1
+#define     SCS_RED                                            4
+#define     SCS_GREEN                                          5
+#define     SCS_BLUE                                           6
+#define     SCS_ALPHA                                          7
+
+/* Enum Clear Color */
+#define     CC_ZERO                                            0
+#define     CC_ONE                                             1
+
+/* Enum Texture Coordinate Mode */
+#define     TCM_WRAP                                           0
+#define     TCM_MIRROR                                         1
+#define     TCM_CLAMP                                          2
+#define     TCM_CUBE                                           3
+#define     TCM_CLAMP_BORDER                                   4
+#define     TCM_MIRROR_ONCE                                    5
+#define     TCM_HALF_BORDER                                    6
+
diff --git a/src/vulkan/gen8_pipeline.c b/src/vulkan/gen8_pipeline.c
new file mode 100644 (file)
index 0000000..e980452
--- /dev/null
@@ -0,0 +1,664 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static void
+emit_vertex_input(struct anv_pipeline *pipeline,
+                  const VkPipelineVertexInputStateCreateInfo *info)
+{
+   const uint32_t num_dwords = 1 + info->attributeCount * 2;
+   uint32_t *p;
+
+   if (info->attributeCount > 0) {
+      p = anv_batch_emitn(&pipeline->batch, num_dwords,
+                          GEN8_3DSTATE_VERTEX_ELEMENTS);
+   }
+
+   for (uint32_t i = 0; i < info->attributeCount; i++) {
+      const VkVertexInputAttributeDescription *desc =
+         &info->pVertexAttributeDescriptions[i];
+      const struct anv_format *format = anv_format_for_vk_format(desc->format);
+
+      struct GEN8_VERTEX_ELEMENT_STATE element = {
+         .VertexBufferIndex = desc->binding,
+         .Valid = true,
+         .SourceElementFormat = format->surface_format,
+         .EdgeFlagEnable = false,
+         .SourceElementOffset = desc->offsetInBytes,
+         .Component0Control = VFCOMP_STORE_SRC,
+         .Component1Control = format->num_channels >= 2 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
+         .Component2Control = format->num_channels >= 3 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
+         .Component3Control = format->num_channels >= 4 ? VFCOMP_STORE_SRC : VFCOMP_STORE_1_FP
+      };
+      GEN8_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + i * 2], &element);
+
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_INSTANCING,
+                     .InstancingEnable = pipeline->instancing_enable[desc->binding],
+                     .VertexElementIndex = i,
+                     /* Vulkan so far doesn't have an instance divisor, so
+                      * this is always 1 (ignored if not instancing). */
+                     .InstanceDataStepRate = 1);
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_SGVS,
+                  .VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
+                  .VertexIDComponentNumber = 2,
+                  .VertexIDElementOffset = info->bindingCount,
+                  .InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
+                  .InstanceIDComponentNumber = 3,
+                  .InstanceIDElementOffset = info->bindingCount);
+}
+
+static void
+emit_ia_state(struct anv_pipeline *pipeline,
+              const VkPipelineInputAssemblyStateCreateInfo *info,
+              const struct anv_graphics_pipeline_create_info *extra)
+{
+   struct GEN8_3DSTATE_VF vf = {
+      GEN8_3DSTATE_VF_header,
+      .IndexedDrawCutIndexEnable = pipeline->primitive_restart
+   };
+   GEN8_3DSTATE_VF_pack(NULL, pipeline->gen8.vf, &vf);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_TOPOLOGY,
+                  .PrimitiveTopologyType = pipeline->topology);
+}
+
+static void
+emit_rs_state(struct anv_pipeline *pipeline,
+              const VkPipelineRasterStateCreateInfo *info,
+              const struct anv_graphics_pipeline_create_info *extra)
+{
+   static const uint32_t vk_to_gen_cullmode[] = {
+      [VK_CULL_MODE_NONE]                       = CULLMODE_NONE,
+      [VK_CULL_MODE_FRONT]                      = CULLMODE_FRONT,
+      [VK_CULL_MODE_BACK]                       = CULLMODE_BACK,
+      [VK_CULL_MODE_FRONT_AND_BACK]             = CULLMODE_BOTH
+   };
+
+   static const uint32_t vk_to_gen_fillmode[] = {
+      [VK_FILL_MODE_POINTS]                     = RASTER_POINT,
+      [VK_FILL_MODE_WIREFRAME]                  = RASTER_WIREFRAME,
+      [VK_FILL_MODE_SOLID]                      = RASTER_SOLID
+   };
+
+   static const uint32_t vk_to_gen_front_face[] = {
+      [VK_FRONT_FACE_CCW]                       = CounterClockwise,
+      [VK_FRONT_FACE_CW]                        = Clockwise
+   };
+
+   struct GEN8_3DSTATE_SF sf = {
+      GEN8_3DSTATE_SF_header,
+      .ViewportTransformEnable = !(extra && extra->disable_viewport),
+      .TriangleStripListProvokingVertexSelect = 0,
+      .LineStripListProvokingVertexSelect = 0,
+      .TriangleFanProvokingVertexSelect = 0,
+      .PointWidthSource = pipeline->writes_point_size ? Vertex : State,
+      .PointWidth = 1.0,
+   };
+
+   /* FINISHME: VkBool32 rasterizerDiscardEnable; */
+
+   GEN8_3DSTATE_SF_pack(NULL, pipeline->gen8.sf, &sf);
+
+   struct GEN8_3DSTATE_RASTER raster = {
+      GEN8_3DSTATE_RASTER_header,
+      .FrontWinding = vk_to_gen_front_face[info->frontFace],
+      .CullMode = vk_to_gen_cullmode[info->cullMode],
+      .FrontFaceFillMode = vk_to_gen_fillmode[info->fillMode],
+      .BackFaceFillMode = vk_to_gen_fillmode[info->fillMode],
+      .ScissorRectangleEnable = !(extra && extra->disable_scissor),
+      .ViewportZClipTestEnable = info->depthClipEnable
+   };
+
+   GEN8_3DSTATE_RASTER_pack(NULL, pipeline->gen8.raster, &raster);
+}
+
+static void
+emit_cb_state(struct anv_pipeline *pipeline,
+              const VkPipelineColorBlendStateCreateInfo *info)
+{
+   struct anv_device *device = pipeline->device;
+
+   static const uint32_t vk_to_gen_logic_op[] = {
+      [VK_LOGIC_OP_COPY]                        = LOGICOP_COPY,
+      [VK_LOGIC_OP_CLEAR]                       = LOGICOP_CLEAR,
+      [VK_LOGIC_OP_AND]                         = LOGICOP_AND,
+      [VK_LOGIC_OP_AND_REVERSE]                 = LOGICOP_AND_REVERSE,
+      [VK_LOGIC_OP_AND_INVERTED]                = LOGICOP_AND_INVERTED,
+      [VK_LOGIC_OP_NOOP]                        = LOGICOP_NOOP,
+      [VK_LOGIC_OP_XOR]                         = LOGICOP_XOR,
+      [VK_LOGIC_OP_OR]                          = LOGICOP_OR,
+      [VK_LOGIC_OP_NOR]                         = LOGICOP_NOR,
+      [VK_LOGIC_OP_EQUIV]                       = LOGICOP_EQUIV,
+      [VK_LOGIC_OP_INVERT]                      = LOGICOP_INVERT,
+      [VK_LOGIC_OP_OR_REVERSE]                  = LOGICOP_OR_REVERSE,
+      [VK_LOGIC_OP_COPY_INVERTED]               = LOGICOP_COPY_INVERTED,
+      [VK_LOGIC_OP_OR_INVERTED]                 = LOGICOP_OR_INVERTED,
+      [VK_LOGIC_OP_NAND]                        = LOGICOP_NAND,
+      [VK_LOGIC_OP_SET]                         = LOGICOP_SET,
+   };
+
+   static const uint32_t vk_to_gen_blend[] = {
+      [VK_BLEND_ZERO]                           = BLENDFACTOR_ZERO,
+      [VK_BLEND_ONE]                            = BLENDFACTOR_ONE,
+      [VK_BLEND_SRC_COLOR]                      = BLENDFACTOR_SRC_COLOR,
+      [VK_BLEND_ONE_MINUS_SRC_COLOR]            = BLENDFACTOR_INV_SRC_COLOR,
+      [VK_BLEND_DEST_COLOR]                     = BLENDFACTOR_DST_COLOR,
+      [VK_BLEND_ONE_MINUS_DEST_COLOR]           = BLENDFACTOR_INV_DST_COLOR,
+      [VK_BLEND_SRC_ALPHA]                      = BLENDFACTOR_SRC_ALPHA,
+      [VK_BLEND_ONE_MINUS_SRC_ALPHA]            = BLENDFACTOR_INV_SRC_ALPHA,
+      [VK_BLEND_DEST_ALPHA]                     = BLENDFACTOR_DST_ALPHA,
+      [VK_BLEND_ONE_MINUS_DEST_ALPHA]           = BLENDFACTOR_INV_DST_ALPHA,
+      [VK_BLEND_CONSTANT_COLOR]                 = BLENDFACTOR_CONST_COLOR,
+      [VK_BLEND_ONE_MINUS_CONSTANT_COLOR]       = BLENDFACTOR_INV_CONST_COLOR,
+      [VK_BLEND_CONSTANT_ALPHA]                 = BLENDFACTOR_CONST_ALPHA,
+      [VK_BLEND_ONE_MINUS_CONSTANT_ALPHA]       = BLENDFACTOR_INV_CONST_ALPHA,
+      [VK_BLEND_SRC_ALPHA_SATURATE]             = BLENDFACTOR_SRC_ALPHA_SATURATE,
+      [VK_BLEND_SRC1_COLOR]                     = BLENDFACTOR_SRC1_COLOR,
+      [VK_BLEND_ONE_MINUS_SRC1_COLOR]           = BLENDFACTOR_INV_SRC1_COLOR,
+      [VK_BLEND_SRC1_ALPHA]                     = BLENDFACTOR_SRC1_ALPHA,
+      [VK_BLEND_ONE_MINUS_SRC1_ALPHA]           = BLENDFACTOR_INV_SRC1_ALPHA,
+   };
+
+   static const uint32_t vk_to_gen_blend_op[] = {
+      [VK_BLEND_OP_ADD]                         = BLENDFUNCTION_ADD,
+      [VK_BLEND_OP_SUBTRACT]                    = BLENDFUNCTION_SUBTRACT,
+      [VK_BLEND_OP_REVERSE_SUBTRACT]            = BLENDFUNCTION_REVERSE_SUBTRACT,
+      [VK_BLEND_OP_MIN]                         = BLENDFUNCTION_MIN,
+      [VK_BLEND_OP_MAX]                         = BLENDFUNCTION_MAX,
+   };
+
+   uint32_t num_dwords = GEN8_BLEND_STATE_length;
+   pipeline->blend_state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+   struct GEN8_BLEND_STATE blend_state = {
+      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
+   };
+
+   for (uint32_t i = 0; i < info->attachmentCount; i++) {
+      const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[i];
+
+      blend_state.Entry[i] = (struct GEN8_BLEND_STATE_ENTRY) {
+         .LogicOpEnable = info->logicOpEnable,
+         .LogicOpFunction = vk_to_gen_logic_op[info->logicOp],
+         .ColorBufferBlendEnable = a->blendEnable,
+         .PreBlendSourceOnlyClampEnable = false,
+         .PreBlendColorClampEnable = false,
+         .PostBlendColorClampEnable = false,
+         .SourceBlendFactor = vk_to_gen_blend[a->srcBlendColor],
+         .DestinationBlendFactor = vk_to_gen_blend[a->destBlendColor],
+         .ColorBlendFunction = vk_to_gen_blend_op[a->blendOpColor],
+         .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcBlendAlpha],
+         .DestinationAlphaBlendFactor = vk_to_gen_blend[a->destBlendAlpha],
+         .AlphaBlendFunction = vk_to_gen_blend_op[a->blendOpAlpha],
+         .WriteDisableAlpha = !(a->channelWriteMask & VK_CHANNEL_A_BIT),
+         .WriteDisableRed = !(a->channelWriteMask & VK_CHANNEL_R_BIT),
+         .WriteDisableGreen = !(a->channelWriteMask & VK_CHANNEL_G_BIT),
+         .WriteDisableBlue = !(a->channelWriteMask & VK_CHANNEL_B_BIT),
+      };
+   }
+
+   GEN8_BLEND_STATE_pack(NULL, pipeline->blend_state.map, &blend_state);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_BLEND_STATE_POINTERS,
+                  .BlendStatePointer = pipeline->blend_state.offset,
+                  .BlendStatePointerValid = true);
+}
+
+static const uint32_t vk_to_gen_compare_op[] = {
+   [VK_COMPARE_OP_NEVER]                        = COMPAREFUNCTION_NEVER,
+   [VK_COMPARE_OP_LESS]                         = COMPAREFUNCTION_LESS,
+   [VK_COMPARE_OP_EQUAL]                        = COMPAREFUNCTION_EQUAL,
+   [VK_COMPARE_OP_LESS_EQUAL]                   = COMPAREFUNCTION_LEQUAL,
+   [VK_COMPARE_OP_GREATER]                      = COMPAREFUNCTION_GREATER,
+   [VK_COMPARE_OP_NOT_EQUAL]                    = COMPAREFUNCTION_NOTEQUAL,
+   [VK_COMPARE_OP_GREATER_EQUAL]                = COMPAREFUNCTION_GEQUAL,
+   [VK_COMPARE_OP_ALWAYS]                       = COMPAREFUNCTION_ALWAYS,
+};
+
+static const uint32_t vk_to_gen_stencil_op[] = {
+   [VK_STENCIL_OP_KEEP]                         = STENCILOP_KEEP,
+   [VK_STENCIL_OP_ZERO]                         = STENCILOP_ZERO,
+   [VK_STENCIL_OP_REPLACE]                      = STENCILOP_REPLACE,
+   [VK_STENCIL_OP_INC_CLAMP]                    = STENCILOP_INCRSAT,
+   [VK_STENCIL_OP_DEC_CLAMP]                    = STENCILOP_DECRSAT,
+   [VK_STENCIL_OP_INVERT]                       = STENCILOP_INVERT,
+   [VK_STENCIL_OP_INC_WRAP]                     = STENCILOP_INCR,
+   [VK_STENCIL_OP_DEC_WRAP]                     = STENCILOP_DECR,
+};
+
+static void
+emit_ds_state(struct anv_pipeline *pipeline,
+              const VkPipelineDepthStencilStateCreateInfo *info)
+{
+   if (info == NULL) {
+      /* We're going to OR this together with the dynamic state.  We need
+       * to make sure it's initialized to something useful.
+       */
+      memset(pipeline->gen8.wm_depth_stencil, 0,
+             sizeof(pipeline->gen8.wm_depth_stencil));
+      return;
+   }
+
+   /* VkBool32 depthBoundsTestEnable; // optional (depth_bounds_test) */
+
+   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+      .DepthTestEnable = info->depthTestEnable,
+      .DepthBufferWriteEnable = info->depthWriteEnable,
+      .DepthTestFunction = vk_to_gen_compare_op[info->depthCompareOp],
+      .DoubleSidedStencilEnable = true,
+
+      .StencilTestEnable = info->stencilTestEnable,
+      .StencilFailOp = vk_to_gen_stencil_op[info->front.stencilFailOp],
+      .StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.stencilPassOp],
+      .StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.stencilDepthFailOp],
+      .StencilTestFunction = vk_to_gen_compare_op[info->front.stencilCompareOp],
+      .BackfaceStencilFailOp = vk_to_gen_stencil_op[info->back.stencilFailOp],
+      .BackfaceStencilPassDepthPassOp = vk_to_gen_stencil_op[info->back.stencilPassOp],
+      .BackfaceStencilPassDepthFailOp =vk_to_gen_stencil_op[info->back.stencilDepthFailOp],
+      .BackfaceStencilTestFunction = vk_to_gen_compare_op[info->back.stencilCompareOp],
+   };
+
+   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, pipeline->gen8.wm_depth_stencil, &wm_depth_stencil);
+}
+
+VkResult
+gen8_graphics_pipeline_create(
+    VkDevice                                    _device,
+    const VkGraphicsPipelineCreateInfo*         pCreateInfo,
+    const struct anv_graphics_pipeline_create_info *extra,
+    VkPipeline*                                 pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_pipeline *pipeline;
+   VkResult result;
+   uint32_t offset, length;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
+
+   pipeline = anv_device_alloc(device, sizeof(*pipeline), 8,
+                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pipeline == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   result = anv_pipeline_init(pipeline, device, pCreateInfo, extra);
+   if (result != VK_SUCCESS)
+      return result;
+
+   /* FIXME: The compiler dead-codes FS inputs when we don't have a VS, so we
+    * hard code this to num_attributes - 2. This is because the attributes
+    * include VUE header and position, which aren't counted as varying
+    * inputs. */
+   if (pipeline->vs_simd8 == NO_KERNEL) {
+      pipeline->wm_prog_data.num_varying_inputs =
+         pCreateInfo->pVertexInputState->attributeCount - 2;
+   }
+
+   assert(pCreateInfo->pVertexInputState);
+   emit_vertex_input(pipeline, pCreateInfo->pVertexInputState);
+   assert(pCreateInfo->pInputAssemblyState);
+   emit_ia_state(pipeline, pCreateInfo->pInputAssemblyState, extra);
+   assert(pCreateInfo->pRasterState);
+   emit_rs_state(pipeline, pCreateInfo->pRasterState, extra);
+   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
+   emit_cb_state(pipeline, pCreateInfo->pColorBlendState);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_STATISTICS,
+                   .StatisticsEnable = true);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_HS, .Enable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_TE, .TEEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_DS, .FunctionEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_STREAMOUT, .SOFunctionEnable = false);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
+                  .ConstantBufferOffset = 0,
+                  .ConstantBufferSize = 4);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
+                  .ConstantBufferOffset = 4,
+                  .ConstantBufferSize = 4);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
+                  .ConstantBufferOffset = 8,
+                  .ConstantBufferSize = 4);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_WM_CHROMAKEY,
+                  .ChromaKeyKillEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_CLIP,
+                  .ClipEnable = true,
+                  .ViewportXYClipTestEnable = !(extra && extra->disable_viewport),
+                  .MinimumPointWidth = 0.125,
+                  .MaximumPointWidth = 255.875);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_WM,
+                  .StatisticsEnable = true,
+                  .LineEndCapAntialiasingRegionWidth = _05pixels,
+                  .LineAntialiasingRegionWidth = _10pixels,
+                  .EarlyDepthStencilControl = NORMAL,
+                  .ForceThreadDispatchEnable = NORMAL,
+                  .PointRasterizationRule = RASTRULE_UPPER_RIGHT,
+                  .BarycentricInterpolationMode =
+                     pipeline->wm_prog_data.barycentric_interp_modes);
+
+   uint32_t samples = 1;
+   uint32_t log2_samples = __builtin_ffs(samples) - 1;
+   bool enable_sampling = samples > 1 ? true : false;
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_MULTISAMPLE,
+                  .PixelPositionOffsetEnable = enable_sampling,
+                  .PixelLocation = CENTER,
+                  .NumberofMultisamples = log2_samples);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SAMPLE_MASK,
+                  .SampleMask = 0xffff);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_VS,
+                  .VSURBStartingAddress = pipeline->urb.vs_start,
+                  .VSURBEntryAllocationSize = pipeline->urb.vs_size - 1,
+                  .VSNumberofURBEntries = pipeline->urb.nr_vs_entries);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_GS,
+                  .GSURBStartingAddress = pipeline->urb.gs_start,
+                  .GSURBEntryAllocationSize = pipeline->urb.gs_size - 1,
+                  .GSNumberofURBEntries = pipeline->urb.nr_gs_entries);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_HS,
+                  .HSURBStartingAddress = pipeline->urb.vs_start,
+                  .HSURBEntryAllocationSize = 0,
+                  .HSNumberofURBEntries = 0);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_DS,
+                  .DSURBStartingAddress = pipeline->urb.vs_start,
+                  .DSURBEntryAllocationSize = 0,
+                  .DSNumberofURBEntries = 0);
+
+   const struct brw_gs_prog_data *gs_prog_data = &pipeline->gs_prog_data;
+   offset = 1;
+   length = (gs_prog_data->base.vue_map.num_slots + 1) / 2 - offset;
+
+   if (pipeline->gs_vec4 == NO_KERNEL)
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_GS, .Enable = false);
+   else
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_GS,
+                     .SingleProgramFlow = false,
+                     .KernelStartPointer = pipeline->gs_vec4,
+                     .VectorMaskEnable = Dmask,
+                     .SamplerCount = 0,
+                     .BindingTableEntryCount = 0,
+                     .ExpectedVertexCount = pipeline->gs_vertex_count,
+
+                     .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_GEOMETRY],
+                     .PerThreadScratchSpace = ffs(gs_prog_data->base.base.total_scratch / 2048),
+
+                     .OutputVertexSize = gs_prog_data->output_vertex_size_hwords * 2 - 1,
+                     .OutputTopology = gs_prog_data->output_topology,
+                     .VertexURBEntryReadLength = gs_prog_data->base.urb_read_length,
+                     .DispatchGRFStartRegisterForURBData =
+                        gs_prog_data->base.base.dispatch_grf_start_reg,
+
+                     .MaximumNumberofThreads = device->info.max_gs_threads / 2 - 1,
+                     .ControlDataHeaderSize = gs_prog_data->control_data_header_size_hwords,
+                     .DispatchMode = gs_prog_data->base.dispatch_mode,
+                     .StatisticsEnable = true,
+                     .IncludePrimitiveID = gs_prog_data->include_primitive_id,
+                     .ReorderMode = TRAILING,
+                     .Enable = true,
+
+                     .ControlDataFormat = gs_prog_data->control_data_format,
+
+                     .StaticOutput = gs_prog_data->static_vertex_count >= 0,
+                     .StaticOutputVertexCount =
+                        gs_prog_data->static_vertex_count >= 0 ?
+                        gs_prog_data->static_vertex_count : 0,
+
+                     /* FIXME: mesa sets this based on ctx->Transform.ClipPlanesEnabled:
+                      * UserClipDistanceClipTestEnableBitmask_3DSTATE_GS(v)
+                      * UserClipDistanceCullTestEnableBitmask(v)
+                      */
+
+                     .VertexURBEntryOutputReadOffset = offset,
+                     .VertexURBEntryOutputLength = length);
+
+   const struct brw_vue_prog_data *vue_prog_data = &pipeline->vs_prog_data.base;
+   /* Skip the VUE header and position slots */
+   offset = 1;
+   length = (vue_prog_data->vue_map.num_slots + 1) / 2 - offset;
+
+   if (pipeline->vs_simd8 == NO_KERNEL || (extra && extra->disable_vs))
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VS,
+                     .FunctionEnable = false,
+                     /* Even if VS is disabled, SBE still gets the amount of
+                      * vertex data to read from this field. */
+                     .VertexURBEntryOutputReadOffset = offset,
+                     .VertexURBEntryOutputLength = length);
+   else
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VS,
+                     .KernelStartPointer = pipeline->vs_simd8,
+                     .SingleVertexDispatch = Multiple,
+                     .VectorMaskEnable = Dmask,
+                     .SamplerCount = 0,
+                     .BindingTableEntryCount =
+                     vue_prog_data->base.binding_table.size_bytes / 4,
+                     .ThreadDispatchPriority = Normal,
+                     .FloatingPointMode = IEEE754,
+                     .IllegalOpcodeExceptionEnable = false,
+                     .AccessesUAV = false,
+                     .SoftwareExceptionEnable = false,
+
+                     .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_VERTEX],
+                     .PerThreadScratchSpace = ffs(vue_prog_data->base.total_scratch / 2048),
+
+                     .DispatchGRFStartRegisterForURBData =
+                     vue_prog_data->base.dispatch_grf_start_reg,
+                     .VertexURBEntryReadLength = vue_prog_data->urb_read_length,
+                     .VertexURBEntryReadOffset = 0,
+
+                     .MaximumNumberofThreads = device->info.max_vs_threads - 1,
+                     .StatisticsEnable = false,
+                     .SIMD8DispatchEnable = true,
+                     .VertexCacheDisable = false,
+                     .FunctionEnable = true,
+
+                     .VertexURBEntryOutputReadOffset = offset,
+                     .VertexURBEntryOutputLength = length,
+                     .UserClipDistanceClipTestEnableBitmask = 0,
+                     .UserClipDistanceCullTestEnableBitmask = 0);
+
+   const struct brw_wm_prog_data *wm_prog_data = &pipeline->wm_prog_data;
+
+   /* TODO: We should clean this up.  Among other things, this is mostly
+    * shared with other gens.
+    */
+   const struct brw_vue_map *fs_input_map;
+   if (pipeline->gs_vec4 == NO_KERNEL)
+      fs_input_map = &vue_prog_data->vue_map;
+   else
+      fs_input_map = &gs_prog_data->base.vue_map;
+
+   struct GEN8_3DSTATE_SBE_SWIZ swiz = {
+      GEN8_3DSTATE_SBE_SWIZ_header,
+   };
+
+   int max_source_attr = 0;
+   for (int attr = 0; attr < VARYING_SLOT_MAX; attr++) {
+      int input_index = wm_prog_data->urb_setup[attr];
+
+      if (input_index < 0)
+        continue;
+
+      /* We have to subtract two slots to accout for the URB entry output
+       * read offset in the VS and GS stages.
+       */
+      int source_attr = fs_input_map->varying_to_slot[attr] - 2;
+      max_source_attr = MAX2(max_source_attr, source_attr);
+
+      if (input_index >= 16)
+        continue;
+
+      swiz.Attribute[input_index].SourceAttribute = source_attr;
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SBE,
+                  .AttributeSwizzleEnable = true,
+                  .ForceVertexURBEntryReadLength = false,
+                  .ForceVertexURBEntryReadOffset = false,
+                  .VertexURBEntryReadLength = DIV_ROUND_UP(max_source_attr + 1, 2),
+                  .PointSpriteTextureCoordinateOrigin = UPPERLEFT,
+                  .NumberofSFOutputAttributes =
+                     wm_prog_data->num_varying_inputs);
+
+   uint32_t *dw = anv_batch_emit_dwords(&pipeline->batch,
+                                        GEN8_3DSTATE_SBE_SWIZ_length);
+   GEN8_3DSTATE_SBE_SWIZ_pack(&pipeline->batch, dw, &swiz);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS,
+                  .KernelStartPointer0 = pipeline->ps_ksp0,
+
+                  .SingleProgramFlow = false,
+                  .VectorMaskEnable = true,
+                  .SamplerCount = 1,
+
+                  .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_FRAGMENT],
+                  .PerThreadScratchSpace = ffs(wm_prog_data->base.total_scratch / 2048),
+
+                  .MaximumNumberofThreadsPerPSD = 64 - 2,
+                  .PositionXYOffsetSelect = wm_prog_data->uses_pos_offset ?
+                     POSOFFSET_SAMPLE: POSOFFSET_NONE,
+                  .PushConstantEnable = wm_prog_data->base.nr_params > 0,
+                  ._8PixelDispatchEnable = pipeline->ps_simd8 != NO_KERNEL,
+                  ._16PixelDispatchEnable = pipeline->ps_simd16 != NO_KERNEL,
+                  ._32PixelDispatchEnable = false,
+
+                  .DispatchGRFStartRegisterForConstantSetupData0 = pipeline->ps_grf_start0,
+                  .DispatchGRFStartRegisterForConstantSetupData1 = 0,
+                  .DispatchGRFStartRegisterForConstantSetupData2 = pipeline->ps_grf_start2,
+
+                  .KernelStartPointer1 = 0,
+                  .KernelStartPointer2 = pipeline->ps_ksp2);
+
+   bool per_sample_ps = false;
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS_EXTRA,
+                  .PixelShaderValid = true,
+                  .PixelShaderKillsPixel = wm_prog_data->uses_kill,
+                  .PixelShaderComputedDepthMode = wm_prog_data->computed_depth_mode,
+                  .AttributeEnable = wm_prog_data->num_varying_inputs > 0,
+                  .oMaskPresenttoRenderTarget = wm_prog_data->uses_omask,
+                  .PixelShaderIsPerSample = per_sample_ps);
+
+   *pPipeline = anv_pipeline_to_handle(pipeline);
+
+   return VK_SUCCESS;
+}
+
+VkResult gen8_compute_pipeline_create(
+    VkDevice                                    _device,
+    const VkComputePipelineCreateInfo*          pCreateInfo,
+    VkPipeline*                                 pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_pipeline *pipeline;
+   VkResult result;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
+
+   pipeline = anv_device_alloc(device, sizeof(*pipeline), 8,
+                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pipeline == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   pipeline->device = device;
+   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
+
+   pipeline->blend_state.map = NULL;
+
+   result = anv_reloc_list_init(&pipeline->batch_relocs, device);
+   if (result != VK_SUCCESS) {
+      anv_device_free(device, pipeline);
+      return result;
+   }
+   pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
+   pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
+   pipeline->batch.relocs = &pipeline->batch_relocs;
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   /* When we free the pipeline, we detect stages based on the NULL status
+    * of various prog_data pointers.  Make them NULL by default.
+    */
+   memset(pipeline->prog_data, 0, sizeof(pipeline->prog_data));
+   memset(pipeline->scratch_start, 0, sizeof(pipeline->scratch_start));
+
+   pipeline->vs_simd8 = NO_KERNEL;
+   pipeline->vs_vec4 = NO_KERNEL;
+   pipeline->gs_vec4 = NO_KERNEL;
+
+   pipeline->active_stages = 0;
+   pipeline->total_scratch = 0;
+
+   assert(pCreateInfo->stage.stage == VK_SHADER_STAGE_COMPUTE);
+   ANV_FROM_HANDLE(anv_shader, shader,  pCreateInfo->stage.shader);
+   anv_pipeline_compile_cs(pipeline, pCreateInfo, shader);
+
+   pipeline->use_repclear = false;
+
+   const struct brw_cs_prog_data *cs_prog_data = &pipeline->cs_prog_data;
+
+   anv_batch_emit(&pipeline->batch, GEN8_MEDIA_VFE_STATE,
+                  .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_COMPUTE],
+                  .PerThreadScratchSpace = ffs(cs_prog_data->base.total_scratch / 2048),
+                  .ScratchSpaceBasePointerHigh = 0,
+                  .StackSize = 0,
+
+                  .MaximumNumberofThreads = device->info.max_cs_threads - 1,
+                  .NumberofURBEntries = 2,
+                  .ResetGatewayTimer = true,
+                  .BypassGatewayControl = true,
+                  .URBEntryAllocationSize = 2,
+                  .CURBEAllocationSize = 0);
+
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+   uint32_t group_size = prog_data->local_size[0] *
+      prog_data->local_size[1] * prog_data->local_size[2];
+   pipeline->cs_thread_width_max = DIV_ROUND_UP(group_size, prog_data->simd_size);
+   uint32_t remainder = group_size & (prog_data->simd_size - 1);
+
+   if (remainder > 0)
+      pipeline->cs_right_mask = ~0u >> (32 - remainder);
+   else
+      pipeline->cs_right_mask = ~0u >> (32 - prog_data->simd_size);
+
+
+   *pPipeline = anv_pipeline_to_handle(pipeline);
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/gen8_state.c b/src/vulkan/gen8_state.c
new file mode 100644 (file)
index 0000000..6eb65e6
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+void
+gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
+                               uint32_t offset, uint32_t range, uint32_t stride)
+{
+   uint32_t num_elements = range / stride;
+
+   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = SURFTYPE_BUFFER,
+      .SurfaceArray = false,
+      .SurfaceFormat = format->surface_format,
+      .SurfaceVerticalAlignment = VALIGN4,
+      .SurfaceHorizontalAlignment = HALIGN4,
+      .TileMode = LINEAR,
+      .SamplerL2BypassModeDisable = true,
+      .RenderCacheReadWriteMode = WriteOnlyCache,
+      .MemoryObjectControlState = GEN8_MOCS,
+      .Height = ((num_elements - 1) >> 7) & 0x3fff,
+      .Width = (num_elements - 1) & 0x7f,
+      .Depth = ((num_elements - 1) >> 21) & 0x3f,
+      .SurfacePitch = stride - 1,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .ShaderChannelSelectRed = SCS_RED,
+      .ShaderChannelSelectGreen = SCS_GREEN,
+      .ShaderChannelSelectBlue = SCS_BLUE,
+      .ShaderChannelSelectAlpha = SCS_ALPHA,
+      /* FIXME: We assume that the image must be bound at this time. */
+      .SurfaceBaseAddress = { NULL, offset },
+   };
+
+   GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
+}
+
+static const uint8_t anv_halign[] = {
+    [4] = HALIGN4,
+    [8] = HALIGN8,
+    [16] = HALIGN16,
+};
+
+static const uint8_t anv_valign[] = {
+    [4] = VALIGN4,
+    [8] = VALIGN8,
+    [16] = VALIGN16,
+};
+
+static struct anv_state
+gen8_alloc_surface_state(struct anv_device *device,
+                         struct anv_cmd_buffer *cmd_buffer)
+{
+      if (cmd_buffer) {
+         return anv_cmd_buffer_alloc_surface_state(cmd_buffer);
+      } else {
+         return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+      }
+}
+
+void
+gen8_image_view_init(struct anv_image_view *iview,
+                     struct anv_device *device,
+                     const VkImageViewCreateInfo* pCreateInfo,
+                     struct anv_cmd_buffer *cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+
+   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+
+   struct anv_surface *surface =
+      anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
+
+   uint32_t depth = 1; /* RENDER_SURFACE_STATE::Depth */
+   uint32_t rt_view_extent = 1; /* RENDER_SURFACE_STATE::RenderTargetViewExtent */
+
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   iview->image = image;
+   iview->bo = image->bo;
+   iview->offset = image->offset + surface->offset;
+   iview->format = format_info;
+
+   iview->extent = (VkExtent3D) {
+      .width = anv_minify(image->extent.width, range->baseMipLevel),
+      .height = anv_minify(image->extent.height, range->baseMipLevel),
+      .depth = anv_minify(image->extent.depth, range->baseMipLevel),
+   };
+
+   switch (image->type) {
+   case VK_IMAGE_TYPE_1D:
+   case VK_IMAGE_TYPE_2D:
+      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
+       *
+       *    For SURFTYPE_1D, 2D, and CUBE: The range of this field is reduced
+       *    by one for each increase from zero of Minimum Array Element. For
+       *    example, if Minimum Array Element is set to 1024 on a 2D surface,
+       *    the range of this field is reduced to [0,1023].
+       */
+      depth = range->arraySize;
+
+      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
+       *
+       *    For Render Target and Typed Dataport 1D and 2D Surfaces:
+       *    This field must be set to the same value as the Depth field.
+       */
+      rt_view_extent = depth;
+      break;
+   case VK_IMAGE_TYPE_3D:
+      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
+       *
+       *    If the volume texture is MIP-mapped, this field specifies the
+       *    depth of the base MIP level.
+       */
+      depth = image->extent.depth;
+
+      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
+       *
+       *    For Render Target and Typed Dataport 3D Surfaces: This field
+       *    indicates the extent of the accessible 'R' coordinates minus 1 on
+       *    the LOD currently being rendered to.
+       */
+      rt_view_extent = iview->extent.depth;
+      break;
+   default:
+      unreachable(!"bad VkImageType");
+   }
+
+   static const uint32_t vk_to_gen_swizzle[] = {
+      [VK_CHANNEL_SWIZZLE_ZERO]                 = SCS_ZERO,
+      [VK_CHANNEL_SWIZZLE_ONE]                  = SCS_ONE,
+      [VK_CHANNEL_SWIZZLE_R]                    = SCS_RED,
+      [VK_CHANNEL_SWIZZLE_G]                    = SCS_GREEN,
+      [VK_CHANNEL_SWIZZLE_B]                    = SCS_BLUE,
+      [VK_CHANNEL_SWIZZLE_A]                    = SCS_ALPHA
+   };
+
+   static const uint8_t isl_to_gen_tiling[] = {
+      [ISL_TILING_LINEAR]  = LINEAR,
+      [ISL_TILING_X]       = XMAJOR,
+      [ISL_TILING_Y]       = YMAJOR,
+      [ISL_TILING_Yf]      = YMAJOR,
+      [ISL_TILING_Ys]      = YMAJOR,
+      [ISL_TILING_W]       = WMAJOR,
+   };
+
+   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = image->surface_type,
+      .SurfaceArray = image->array_size > 1,
+      .SurfaceFormat = format_info->surface_format,
+      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
+      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
+      .TileMode = isl_to_gen_tiling[surface->tiling],
+      .VerticalLineStride = 0,
+      .VerticalLineStrideOffset = 0,
+      .SamplerL2BypassModeDisable = true,
+      .RenderCacheReadWriteMode = WriteOnlyCache,
+      .MemoryObjectControlState = GEN8_MOCS,
+
+      /* The driver sets BaseMipLevel in SAMPLER_STATE, not here in
+       * RENDER_SURFACE_STATE. The Broadwell PRM says "it is illegal to have
+       * both Base Mip Level fields nonzero".
+       */
+      .BaseMipLevel = 0.0,
+
+      .SurfaceQPitch = surface->qpitch >> 2,
+      .Height = image->extent.height - 1,
+      .Width = image->extent.width - 1,
+      .Depth = depth - 1,
+      .SurfacePitch = surface->stride - 1,
+      .RenderTargetViewExtent = rt_view_extent - 1,
+      .MinimumArrayElement = range->baseArrayLayer,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .XOffset = 0,
+      .YOffset = 0,
+
+      .MIPCountLOD = 0, /* TEMPLATE */
+      .SurfaceMinLOD = 0, /* TEMPLATE */
+
+      .AuxiliarySurfaceMode = AUX_NONE,
+      .RedClearColor = 0,
+      .GreenClearColor = 0,
+      .BlueClearColor = 0,
+      .AlphaClearColor = 0,
+      .ShaderChannelSelectRed = vk_to_gen_swizzle[pCreateInfo->channels.r],
+      .ShaderChannelSelectGreen = vk_to_gen_swizzle[pCreateInfo->channels.g],
+      .ShaderChannelSelectBlue = vk_to_gen_swizzle[pCreateInfo->channels.b],
+      .ShaderChannelSelectAlpha = vk_to_gen_swizzle[pCreateInfo->channels.a],
+      .ResourceMinLOD = 0.0,
+      .SurfaceBaseAddress = { NULL, iview->offset },
+   };
+
+   if (image->needs_nonrt_surface_state) {
+      iview->nonrt_surface_state =
+         gen8_alloc_surface_state(device, cmd_buffer);
+
+      /* For non render target surfaces, the hardware interprets field
+       * MIPCount/LOD as MIPCount.  The range of levels accessible by the
+       * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
+       */
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->mipLevels - 1;
+
+      GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->nonrt_surface_state.map,
+                                     &surface_state);
+   }
+
+   if (image->needs_color_rt_surface_state) {
+      iview->color_rt_surface_state =
+         gen8_alloc_surface_state(device, cmd_buffer);
+
+      /* For render target surfaces, the hardware interprets field
+       * MIPCount/LOD as LOD. The Broadwell PRM says:
+       *
+       *    MIPCountLOD defines the LOD that will be rendered into.
+       *    SurfaceMinLOD is ignored.
+       */
+      surface_state.MIPCountLOD = range->baseMipLevel;
+      surface_state.SurfaceMinLOD = 0;
+
+      GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->color_rt_surface_state.map,
+                                     &surface_state);
+   }
+}
+
+VkResult gen8_CreateSampler(
+    VkDevice                                    _device,
+    const VkSamplerCreateInfo*                  pCreateInfo,
+    VkSampler*                                  pSampler)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_sampler *sampler;
+   uint32_t mag_filter, min_filter, max_anisotropy;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+
+   sampler = anv_device_alloc(device, sizeof(*sampler), 8,
+                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!sampler)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   static const uint32_t vk_to_gen_tex_filter[] = {
+      [VK_TEX_FILTER_NEAREST]                   = MAPFILTER_NEAREST,
+      [VK_TEX_FILTER_LINEAR]                    = MAPFILTER_LINEAR
+   };
+
+   static const uint32_t vk_to_gen_mipmap_mode[] = {
+      [VK_TEX_MIPMAP_MODE_BASE]                 = MIPFILTER_NONE,
+      [VK_TEX_MIPMAP_MODE_NEAREST]              = MIPFILTER_NEAREST,
+      [VK_TEX_MIPMAP_MODE_LINEAR]               = MIPFILTER_LINEAR
+   };
+
+   static const uint32_t vk_to_gen_tex_address[] = {
+      [VK_TEX_ADDRESS_MODE_WRAP]                = TCM_WRAP,
+      [VK_TEX_ADDRESS_MODE_MIRROR]              = TCM_MIRROR,
+      [VK_TEX_ADDRESS_MODE_CLAMP]               = TCM_CLAMP,
+      [VK_TEX_ADDRESS_MODE_MIRROR_ONCE]         = TCM_MIRROR_ONCE,
+      [VK_TEX_ADDRESS_MODE_CLAMP_BORDER]        = TCM_CLAMP_BORDER,
+   };
+
+   static const uint32_t vk_to_gen_compare_op[] = {
+      [VK_COMPARE_OP_NEVER]                     = PREFILTEROPNEVER,
+      [VK_COMPARE_OP_LESS]                      = PREFILTEROPLESS,
+      [VK_COMPARE_OP_EQUAL]                     = PREFILTEROPEQUAL,
+      [VK_COMPARE_OP_LESS_EQUAL]                = PREFILTEROPLEQUAL,
+      [VK_COMPARE_OP_GREATER]                   = PREFILTEROPGREATER,
+      [VK_COMPARE_OP_NOT_EQUAL]                 = PREFILTEROPNOTEQUAL,
+      [VK_COMPARE_OP_GREATER_EQUAL]             = PREFILTEROPGEQUAL,
+      [VK_COMPARE_OP_ALWAYS]                    = PREFILTEROPALWAYS,
+   };
+
+   if (pCreateInfo->maxAnisotropy > 1) {
+      mag_filter = MAPFILTER_ANISOTROPIC;
+      min_filter = MAPFILTER_ANISOTROPIC;
+      max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
+   } else {
+      mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
+      min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
+      max_anisotropy = RATIO21;
+   }
+
+   struct GEN8_SAMPLER_STATE sampler_state = {
+      .SamplerDisable = false,
+      .TextureBorderColorMode = DX10OGL,
+      .LODPreClampMode = 0,
+      .BaseMipLevel = 0.0,
+      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
+      .MagModeFilter = mag_filter,
+      .MinModeFilter = min_filter,
+      .TextureLODBias = pCreateInfo->mipLodBias * 256,
+      .AnisotropicAlgorithm = EWAApproximation,
+      .MinLOD = pCreateInfo->minLod,
+      .MaxLOD = pCreateInfo->maxLod,
+      .ChromaKeyEnable = 0,
+      .ChromaKeyIndex = 0,
+      .ChromaKeyMode = 0,
+      .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
+      .CubeSurfaceControlMode = 0,
+
+      .IndirectStatePointer =
+         device->border_colors.offset +
+         pCreateInfo->borderColor * sizeof(float) * 4,
+
+      .LODClampMagnificationMode = MIPNONE,
+      .MaximumAnisotropy = max_anisotropy,
+      .RAddressMinFilterRoundingEnable = 0,
+      .RAddressMagFilterRoundingEnable = 0,
+      .VAddressMinFilterRoundingEnable = 0,
+      .VAddressMagFilterRoundingEnable = 0,
+      .UAddressMinFilterRoundingEnable = 0,
+      .UAddressMagFilterRoundingEnable = 0,
+      .TrilinearFilterQuality = 0,
+      .NonnormalizedCoordinateEnable = pCreateInfo->unnormalizedCoordinates,
+      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeU],
+      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeV],
+      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressModeW],
+   };
+
+   GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
+
+   *pSampler = anv_sampler_to_handle(sampler);
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/isl.c b/src/vulkan/isl.c
new file mode 100644 (file)
index 0000000..ebfd2bf
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2015 Intel Corporation
+ *
+ *  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 (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ *  IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "mesa/main/imports.h"
+
+#include "isl.h"
+
+/**
+ * Log base 2, rounding towards zero.
+ */
+static inline uint32_t
+isl_log2u(uint32_t n)
+{
+   assert(n != 0);
+   return 31 - __builtin_clz(n);
+}
+
+void
+isl_device_init(struct isl_device *dev,
+                const struct brw_device_info *info)
+{
+   dev->info = info;
+}
+
+/**
+ * The returned extent's units are (width=bytes, height=rows).
+ */
+void
+isl_tiling_get_extent(const struct isl_device *dev,
+                      enum isl_tiling tiling,
+                      uint32_t cpp,
+                      struct isl_extent2d *e)
+{
+   static const struct isl_extent2d legacy_extents[] = {
+      [ISL_TILING_LINEAR]  = {   1,   1 },
+      [ISL_TILING_X]       = { 512,   8 },
+      [ISL_TILING_Y]       = { 128,  32 },
+      [ISL_TILING_W]       = { 128,  32 },
+   };
+
+   static const struct isl_extent2d yf_extents[] = {
+      /*cpp*/
+      /* 1*/ [0] = {   64, 64 },
+      /* 2*/ [1] = {  128, 32 },
+      /* 4*/ [2] = {  128, 32 },
+      /* 8*/ [3] = {  256, 16 },
+      /*16*/ [4] = {  256, 16 },
+   };
+
+   assert(cpp > 0);
+
+   switch (tiling) {
+   case ISL_TILING_LINEAR:
+   case ISL_TILING_X:
+   case ISL_TILING_Y:
+   case ISL_TILING_W:
+      *e = legacy_extents[tiling];
+      return;
+   case ISL_TILING_Yf:
+   case ISL_TILING_Ys:
+      assert(_mesa_is_pow_two(cpp));
+      *e = yf_extents[isl_log2u(cpp)];
+      if (tiling == ISL_TILING_Ys) {
+         e->width *= 4;
+         e->height *= 4;
+      }
+      return;
+   }
+}
diff --git a/src/vulkan/isl.h b/src/vulkan/isl.h
new file mode 100644 (file)
index 0000000..fb0b6f4
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+/**
+ * @file
+ * @brief Intel Surface Layout
+ */
+
+#pragma once
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct brw_device_info;
+
+/**
+ * WARNING: These values differ from the hardware enum values, which are
+ * unstable across hardware generations.
+ */
+enum isl_tiling {
+   ISL_TILING_LINEAR,
+   ISL_TILING_W,
+   ISL_TILING_X,
+   ISL_TILING_Y, /**< Legacy Y tiling */
+   ISL_TILING_Yf,
+   ISL_TILING_Ys,
+};
+
+/**
+ * Hardware enumeration SURFACE_FORMAT.
+ *
+ * For the official list, see Broadwell PRM: Volume 2b: Command Reference:
+ * Enumerations: SURFACE_FORMAT.
+ */
+enum isl_format {
+   ISL_FORMAT_R32G32B32A32_FLOAT =                               0,
+   ISL_FORMAT_R32G32B32A32_SINT =                                1,
+   ISL_FORMAT_R32G32B32A32_UINT =                                2,
+   ISL_FORMAT_R32G32B32A32_UNORM =                               3,
+   ISL_FORMAT_R32G32B32A32_SNORM =                               4,
+   ISL_FORMAT_R64G64_FLOAT =                                     5,
+   ISL_FORMAT_R32G32B32X32_FLOAT =                               6,
+   ISL_FORMAT_R32G32B32A32_SSCALED =                             7,
+   ISL_FORMAT_R32G32B32A32_USCALED =                             8,
+   ISL_FORMAT_R32G32B32A32_SFIXED =                             32,
+   ISL_FORMAT_R64G64_PASSTHRU =                                 33,
+   ISL_FORMAT_R32G32B32_FLOAT =                                 64,
+   ISL_FORMAT_R32G32B32_SINT =                                  65,
+   ISL_FORMAT_R32G32B32_UINT =                                  66,
+   ISL_FORMAT_R32G32B32_UNORM =                                 67,
+   ISL_FORMAT_R32G32B32_SNORM =                                 68,
+   ISL_FORMAT_R32G32B32_SSCALED =                               69,
+   ISL_FORMAT_R32G32B32_USCALED =                               70,
+   ISL_FORMAT_R32G32B32_SFIXED =                                80,
+   ISL_FORMAT_R16G16B16A16_UNORM =                             128,
+   ISL_FORMAT_R16G16B16A16_SNORM =                             129,
+   ISL_FORMAT_R16G16B16A16_SINT =                              130,
+   ISL_FORMAT_R16G16B16A16_UINT =                              131,
+   ISL_FORMAT_R16G16B16A16_FLOAT =                             132,
+   ISL_FORMAT_R32G32_FLOAT =                                   133,
+   ISL_FORMAT_R32G32_SINT =                                    134,
+   ISL_FORMAT_R32G32_UINT =                                    135,
+   ISL_FORMAT_R32_FLOAT_X8X24_TYPELESS =                       136,
+   ISL_FORMAT_X32_TYPELESS_G8X24_UINT =                        137,
+   ISL_FORMAT_L32A32_FLOAT =                                   138,
+   ISL_FORMAT_R32G32_UNORM =                                   139,
+   ISL_FORMAT_R32G32_SNORM =                                   140,
+   ISL_FORMAT_R64_FLOAT =                                      141,
+   ISL_FORMAT_R16G16B16X16_UNORM =                             142,
+   ISL_FORMAT_R16G16B16X16_FLOAT =                             143,
+   ISL_FORMAT_A32X32_FLOAT =                                   144,
+   ISL_FORMAT_L32X32_FLOAT =                                   145,
+   ISL_FORMAT_I32X32_FLOAT =                                   146,
+   ISL_FORMAT_R16G16B16A16_SSCALED =                           147,
+   ISL_FORMAT_R16G16B16A16_USCALED =                           148,
+   ISL_FORMAT_R32G32_SSCALED =                                 149,
+   ISL_FORMAT_R32G32_USCALED =                                 150,
+   ISL_FORMAT_R32G32_SFIXED =                                  160,
+   ISL_FORMAT_R64_PASSTHRU =                                   161,
+   ISL_FORMAT_B8G8R8A8_UNORM =                                 192,
+   ISL_FORMAT_B8G8R8A8_UNORM_SRGB =                            193,
+   ISL_FORMAT_R10G10B10A2_UNORM =                              194,
+   ISL_FORMAT_R10G10B10A2_UNORM_SRGB =                         195,
+   ISL_FORMAT_R10G10B10A2_UINT =                               196,
+   ISL_FORMAT_R10G10B10_SNORM_A2_UNORM =                       197,
+   ISL_FORMAT_R8G8B8A8_UNORM =                                 199,
+   ISL_FORMAT_R8G8B8A8_UNORM_SRGB =                            200,
+   ISL_FORMAT_R8G8B8A8_SNORM =                                 201,
+   ISL_FORMAT_R8G8B8A8_SINT =                                  202,
+   ISL_FORMAT_R8G8B8A8_UINT =                                  203,
+   ISL_FORMAT_R16G16_UNORM =                                   204,
+   ISL_FORMAT_R16G16_SNORM =                                   205,
+   ISL_FORMAT_R16G16_SINT =                                    206,
+   ISL_FORMAT_R16G16_UINT =                                    207,
+   ISL_FORMAT_R16G16_FLOAT =                                   208,
+   ISL_FORMAT_B10G10R10A2_UNORM =                              209,
+   ISL_FORMAT_B10G10R10A2_UNORM_SRGB =                         210,
+   ISL_FORMAT_R11G11B10_FLOAT =                                211,
+   ISL_FORMAT_R32_SINT =                                       214,
+   ISL_FORMAT_R32_UINT =                                       215,
+   ISL_FORMAT_R32_FLOAT =                                      216,
+   ISL_FORMAT_R24_UNORM_X8_TYPELESS =                          217,
+   ISL_FORMAT_X24_TYPELESS_G8_UINT =                           218,
+   ISL_FORMAT_L32_UNORM =                                      221,
+   ISL_FORMAT_A32_UNORM =                                      222,
+   ISL_FORMAT_L16A16_UNORM =                                   223,
+   ISL_FORMAT_I24X8_UNORM =                                    224,
+   ISL_FORMAT_L24X8_UNORM =                                    225,
+   ISL_FORMAT_A24X8_UNORM =                                    226,
+   ISL_FORMAT_I32_FLOAT =                                      227,
+   ISL_FORMAT_L32_FLOAT =                                      228,
+   ISL_FORMAT_A32_FLOAT =                                      229,
+   ISL_FORMAT_X8B8_UNORM_G8R8_SNORM =                          230,
+   ISL_FORMAT_A8X8_UNORM_G8R8_SNORM =                          231,
+   ISL_FORMAT_B8X8_UNORM_G8R8_SNORM =                          232,
+   ISL_FORMAT_B8G8R8X8_UNORM =                                 233,
+   ISL_FORMAT_B8G8R8X8_UNORM_SRGB =                            234,
+   ISL_FORMAT_R8G8B8X8_UNORM =                                 235,
+   ISL_FORMAT_R8G8B8X8_UNORM_SRGB =                            236,
+   ISL_FORMAT_R9G9B9E5_SHAREDEXP =                             237,
+   ISL_FORMAT_B10G10R10X2_UNORM =                              238,
+   ISL_FORMAT_L16A16_FLOAT =                                   240,
+   ISL_FORMAT_R32_UNORM =                                      241,
+   ISL_FORMAT_R32_SNORM =                                      242,
+   ISL_FORMAT_R10G10B10X2_USCALED =                            243,
+   ISL_FORMAT_R8G8B8A8_SSCALED =                               244,
+   ISL_FORMAT_R8G8B8A8_USCALED =                               245,
+   ISL_FORMAT_R16G16_SSCALED =                                 246,
+   ISL_FORMAT_R16G16_USCALED =                                 247,
+   ISL_FORMAT_R32_SSCALED =                                    248,
+   ISL_FORMAT_R32_USCALED =                                    249,
+   ISL_FORMAT_B5G6R5_UNORM =                                   256,
+   ISL_FORMAT_B5G6R5_UNORM_SRGB =                              257,
+   ISL_FORMAT_B5G5R5A1_UNORM =                                 258,
+   ISL_FORMAT_B5G5R5A1_UNORM_SRGB =                            259,
+   ISL_FORMAT_B4G4R4A4_UNORM =                                 260,
+   ISL_FORMAT_B4G4R4A4_UNORM_SRGB =                            261,
+   ISL_FORMAT_R8G8_UNORM =                                     262,
+   ISL_FORMAT_R8G8_SNORM =                                     263,
+   ISL_FORMAT_R8G8_SINT =                                      264,
+   ISL_FORMAT_R8G8_UINT =                                      265,
+   ISL_FORMAT_R16_UNORM =                                      266,
+   ISL_FORMAT_R16_SNORM =                                      267,
+   ISL_FORMAT_R16_SINT =                                       268,
+   ISL_FORMAT_R16_UINT =                                       269,
+   ISL_FORMAT_R16_FLOAT =                                      270,
+   ISL_FORMAT_A8P8_UNORM_PALETTE0 =                            271,
+   ISL_FORMAT_A8P8_UNORM_PALETTE1 =                            272,
+   ISL_FORMAT_I16_UNORM =                                      273,
+   ISL_FORMAT_L16_UNORM =                                      274,
+   ISL_FORMAT_A16_UNORM =                                      275,
+   ISL_FORMAT_L8A8_UNORM =                                     276,
+   ISL_FORMAT_I16_FLOAT =                                      277,
+   ISL_FORMAT_L16_FLOAT =                                      278,
+   ISL_FORMAT_A16_FLOAT =                                      279,
+   ISL_FORMAT_L8A8_UNORM_SRGB =                                280,
+   ISL_FORMAT_R5G5_SNORM_B6_UNORM =                            281,
+   ISL_FORMAT_B5G5R5X1_UNORM =                                 282,
+   ISL_FORMAT_B5G5R5X1_UNORM_SRGB =                            283,
+   ISL_FORMAT_R8G8_SSCALED =                                   284,
+   ISL_FORMAT_R8G8_USCALED =                                   285,
+   ISL_FORMAT_R16_SSCALED =                                    286,
+   ISL_FORMAT_R16_USCALED =                                    287,
+   ISL_FORMAT_P8A8_UNORM_PALETTE0 =                            290,
+   ISL_FORMAT_P8A8_UNORM_PALETTE1 =                            291,
+   ISL_FORMAT_A1B5G5R5_UNORM =                                 292,
+   ISL_FORMAT_A4B4G4R4_UNORM =                                 293,
+   ISL_FORMAT_L8A8_UINT =                                      294,
+   ISL_FORMAT_L8A8_SINT =                                      295,
+   ISL_FORMAT_R8_UNORM =                                       320,
+   ISL_FORMAT_R8_SNORM =                                       321,
+   ISL_FORMAT_R8_SINT =                                        322,
+   ISL_FORMAT_R8_UINT =                                        323,
+   ISL_FORMAT_A8_UNORM =                                       324,
+   ISL_FORMAT_I8_UNORM =                                       325,
+   ISL_FORMAT_L8_UNORM =                                       326,
+   ISL_FORMAT_P4A4_UNORM_PALETTE0 =                            327,
+   ISL_FORMAT_A4P4_UNORM_PALETTE0 =                            328,
+   ISL_FORMAT_R8_SSCALED =                                     329,
+   ISL_FORMAT_R8_USCALED =                                     330,
+   ISL_FORMAT_P8_UNORM_PALETTE0 =                              331,
+   ISL_FORMAT_L8_UNORM_SRGB =                                  332,
+   ISL_FORMAT_P8_UNORM_PALETTE1 =                              333,
+   ISL_FORMAT_P4A4_UNORM_PALETTE1 =                            334,
+   ISL_FORMAT_A4P4_UNORM_PALETTE1 =                            335,
+   ISL_FORMAT_Y8_UNORM =                                       336,
+   ISL_FORMAT_L8_UINT =                                        338,
+   ISL_FORMAT_L8_SINT =                                        339,
+   ISL_FORMAT_I8_UINT =                                        340,
+   ISL_FORMAT_I8_SINT =                                        341,
+   ISL_FORMAT_DXT1_RGB_SRGB =                                  384,
+   ISL_FORMAT_R1_UNORM =                                       385,
+   ISL_FORMAT_YCRCB_NORMAL =                                   386,
+   ISL_FORMAT_YCRCB_SWAPUVY =                                  387,
+   ISL_FORMAT_P2_UNORM_PALETTE0 =                              388,
+   ISL_FORMAT_P2_UNORM_PALETTE1 =                              389,
+   ISL_FORMAT_BC1_UNORM =                                      390,
+   ISL_FORMAT_BC2_UNORM =                                      391,
+   ISL_FORMAT_BC3_UNORM =                                      392,
+   ISL_FORMAT_BC4_UNORM =                                      393,
+   ISL_FORMAT_BC5_UNORM =                                      394,
+   ISL_FORMAT_BC1_UNORM_SRGB =                                 395,
+   ISL_FORMAT_BC2_UNORM_SRGB =                                 396,
+   ISL_FORMAT_BC3_UNORM_SRGB =                                 397,
+   ISL_FORMAT_MONO8 =                                          398,
+   ISL_FORMAT_YCRCB_SWAPUV =                                   399,
+   ISL_FORMAT_YCRCB_SWAPY =                                    400,
+   ISL_FORMAT_DXT1_RGB =                                       401,
+   ISL_FORMAT_FXT1 =                                           402,
+   ISL_FORMAT_R8G8B8_UNORM =                                   403,
+   ISL_FORMAT_R8G8B8_SNORM =                                   404,
+   ISL_FORMAT_R8G8B8_SSCALED =                                 405,
+   ISL_FORMAT_R8G8B8_USCALED =                                 406,
+   ISL_FORMAT_R64G64B64A64_FLOAT =                             407,
+   ISL_FORMAT_R64G64B64_FLOAT =                                408,
+   ISL_FORMAT_BC4_SNORM =                                      409,
+   ISL_FORMAT_BC5_SNORM =                                      410,
+   ISL_FORMAT_R16G16B16_FLOAT =                                411,
+   ISL_FORMAT_R16G16B16_UNORM =                                412,
+   ISL_FORMAT_R16G16B16_SNORM =                                413,
+   ISL_FORMAT_R16G16B16_SSCALED =                              414,
+   ISL_FORMAT_R16G16B16_USCALED =                              415,
+   ISL_FORMAT_BC6H_SF16 =                                      417,
+   ISL_FORMAT_BC7_UNORM =                                      418,
+   ISL_FORMAT_BC7_UNORM_SRGB =                                 419,
+   ISL_FORMAT_BC6H_UF16 =                                      420,
+   ISL_FORMAT_PLANAR_420_8 =                                   421,
+   ISL_FORMAT_R8G8B8_UNORM_SRGB =                              424,
+   ISL_FORMAT_ETC1_RGB8 =                                      425,
+   ISL_FORMAT_ETC2_RGB8 =                                      426,
+   ISL_FORMAT_EAC_R11 =                                        427,
+   ISL_FORMAT_EAC_RG11 =                                       428,
+   ISL_FORMAT_EAC_SIGNED_R11 =                                 429,
+   ISL_FORMAT_EAC_SIGNED_RG11 =                                430,
+   ISL_FORMAT_ETC2_SRGB8 =                                     431,
+   ISL_FORMAT_R16G16B16_UINT =                                 432,
+   ISL_FORMAT_R16G16B16_SINT =                                 433,
+   ISL_FORMAT_R32_SFIXED =                                     434,
+   ISL_FORMAT_R10G10B10A2_SNORM =                              435,
+   ISL_FORMAT_R10G10B10A2_USCALED =                            436,
+   ISL_FORMAT_R10G10B10A2_SSCALED =                            437,
+   ISL_FORMAT_R10G10B10A2_SINT =                               438,
+   ISL_FORMAT_B10G10R10A2_SNORM =                              439,
+   ISL_FORMAT_B10G10R10A2_USCALED =                            440,
+   ISL_FORMAT_B10G10R10A2_SSCALED =                            441,
+   ISL_FORMAT_B10G10R10A2_UINT =                               442,
+   ISL_FORMAT_B10G10R10A2_SINT =                               443,
+   ISL_FORMAT_R64G64B64A64_PASSTHRU =                          444,
+   ISL_FORMAT_R64G64B64_PASSTHRU =                             445,
+   ISL_FORMAT_ETC2_RGB8_PTA =                                  448,
+   ISL_FORMAT_ETC2_SRGB8_PTA =                                 449,
+   ISL_FORMAT_ETC2_EAC_RGBA8 =                                 450,
+   ISL_FORMAT_ETC2_EAC_SRGB8_A8 =                              451,
+   ISL_FORMAT_R8G8B8_UINT =                                    456,
+   ISL_FORMAT_R8G8B8_SINT =                                    457,
+   ISL_FORMAT_RAW =                                            511,
+
+   /* Hardware doesn't understand this out-of-band value */
+   ISL_FORMAT_UNSUPPORTED =                             UINT16_MAX,
+};
+
+enum isl_base_type {
+   ISL_VOID,
+   ISL_RAW,
+   ISL_UNORM,
+   ISL_SNORM,
+   ISL_UFLOAT,
+   ISL_SFLOAT,
+   ISL_UFIXED,
+   ISL_SFIXED,
+   ISL_UINT,
+   ISL_SINT,
+   ISL_USCALED,
+   ISL_SSCALED,
+};
+
+enum isl_colorspace {
+   ISL_COLORSPACE_NONE = 0,
+   ISL_COLORSPACE_LINEAR,
+   ISL_COLORSPACE_SRGB,
+   ISL_COLORSPACE_YUV,
+};
+
+/**
+ * Texture compression mode
+ */
+enum isl_txc {
+   ISL_TXC_NONE = 0,
+   ISL_TXC_DXT1,
+   ISL_TXC_DXT3,
+   ISL_TXC_DXT5,
+   ISL_TXC_FXT1,
+   ISL_TXC_RGTC1,
+   ISL_TXC_RGTC2,
+   ISL_TXC_BPTC,
+   ISL_TXC_ETC1,
+   ISL_TXC_ETC2,
+};
+
+struct isl_device {
+   const struct brw_device_info *info;
+};
+
+struct isl_extent2d {
+   uint32_t width;
+   uint32_t height;
+};
+
+struct isl_extent3d {
+   uint32_t width;
+   uint32_t height;
+   uint32_t depth;
+};
+
+struct isl_channel_layout {
+   enum isl_base_type type;
+   uint8_t bits; /**< Size in bits */
+};
+
+struct isl_format_layout {
+   enum isl_format format;
+
+   uint16_t bpb; /**< Bits per block */
+   uint8_t bs; /**< Block size, in bytes, rounded towards 0 */
+   uint8_t bw; /**< Block width, in pixels */
+   uint8_t bh; /**< Block height, in pixels */
+   uint8_t bd; /**< Block depth, in pixels */
+
+   struct {
+      struct isl_channel_layout r; /**< Red channel */
+      struct isl_channel_layout g; /**< Green channel */
+      struct isl_channel_layout b; /**< Blue channel */
+      struct isl_channel_layout a; /**< Alpha channel */
+      struct isl_channel_layout l; /**< Luminance channel */
+      struct isl_channel_layout i; /**< Intensity channel */
+      struct isl_channel_layout p; /**< Palette channel */
+   } channels;
+
+   enum isl_colorspace colorspace;
+   enum isl_txc txc;
+};
+
+void
+isl_device_init(struct isl_device *dev,
+                const struct brw_device_info *info);
+
+void
+isl_tiling_get_extent(const struct isl_device *dev,
+                      enum isl_tiling tiling,
+                      uint32_t cpp,
+                      struct isl_extent2d *e);
+
+extern const struct isl_format_layout isl_format_layouts[];
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/vulkan/isl_format_layout.csv b/src/vulkan/isl_format_layout.csv
new file mode 100644 (file)
index 0000000..2a302b0
--- /dev/null
@@ -0,0 +1,287 @@
+# Copyright 2015 Intel Corporation
+#
+# 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 (including the next
+# paragraph) 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.
+
+#
+# @file
+# @brief Layout of all hardware surface formats
+#
+# For the official list, see Broadwell PRM: Volume 2b: Command Reference:
+# Enumerations: SURFACE_FORMAT.
+#
+
+
+# Columns:
+#    name: format name in PRM
+#    bpb: bits per block
+#    bw: block width, in pixels
+#    bh: block height, in pixels
+#    bd: block depth, in pixels
+#    r: red channel, data type and bitwidth
+#    g: green channel
+#    b: blue channel
+#    a: alpha channel
+#    l: luminance channel
+#    i: intensity channel
+#    p: palette channel
+#    space: colorspace
+#    txc: texture compression
+#
+# Data Types:
+#     x: void
+#     r: raw
+#    un: unorm
+#    sn: snorm
+#    uf: ufloat
+#    sf: sfloat
+#    ux: ufixed
+#    sx: sfixed
+#    ui: uint
+#    si: sint
+#    us: uscaled
+#    ss: sscaled
+
+
+# Table is aligned with the Vim commands below, using the Align plugin:
+#     :AlignCtrl lr+ p8000000000000P1
+#     /^# name/,$ Align,
+
+# name                      , bpb, bw, bh, bd,    r,    g,    b,    a,    l,    i,   p,  space,   txc
+R32G32B32A32_FLOAT          , 128,  1,  1,  1, sf32, sf32, sf32, sf32,     ,     ,    , linear,
+R32G32B32A32_SINT           , 128,  1,  1,  1, si32, si32, si32, si32,     ,     ,    , linear,
+R32G32B32A32_UINT           , 128,  1,  1,  1, ui32, ui32, ui32, ui32,     ,     ,    , linear,
+R32G32B32A32_UNORM          , 128,  1,  1,  1, un32, un32, un32, un32,     ,     ,    , linear,
+R32G32B32A32_SNORM          , 128,  1,  1,  1, sn32, sn32, sn32, sn32,     ,     ,    , linear,
+R64G64_FLOAT                , 128,  1,  1,  1, sf64, sf64,     ,     ,     ,     ,    , linear,
+R32G32B32X32_FLOAT          , 128,  1,  1,  1, sf32, sf32, sf32,  x32,     ,     ,    , linear,
+R32G32B32A32_SSCALED        , 128,  1,  1,  1, ss32, ss32, ss32, ss32,     ,     ,    , linear,
+R32G32B32A32_USCALED        , 128,  1,  1,  1, us32, us32, us32, us32,     ,     ,    , linear,
+R32G32B32A32_SFIXED         , 128,  1,  1,  1, sx32, sx32, sx32, sx32,     ,     ,    , linear,
+R64G64_PASSTHRU             , 128,  1,  1,  1,  r64,  r64,     ,     ,     ,     ,    ,       ,
+R32G32B32_FLOAT             ,  96,  1,  1,  1, sf32, sf32, sf32,     ,     ,     ,    , linear,
+R32G32B32_SINT              ,  96,  1,  1,  1, si32, si32, si32,     ,     ,     ,    , linear,
+R32G32B32_UINT              ,  96,  1,  1,  1, ui32, ui32, ui32,     ,     ,     ,    , linear,
+R32G32B32_UNORM             ,  96,  1,  1,  1, un32, un32, un32,     ,     ,     ,    , linear,
+R32G32B32_SNORM             ,  96,  1,  1,  1, sn32, sn32, sn32,     ,     ,     ,    , linear,
+R32G32B32_SSCALED           ,  96,  1,  1,  1, ss32, ss32, ss32,     ,     ,     ,    , linear,
+R32G32B32_USCALED           ,  96,  1,  1,  1, us32, us32, us32,     ,     ,     ,    , linear,
+R32G32B32_SFIXED            ,  96,  1,  1,  1, sx32, sx32, sx32,     ,     ,     ,    , linear,
+R16G16B16A16_UNORM          ,  64,  1,  1,  1, un16, un16, un16, un16,     ,     ,    , linear,
+R16G16B16A16_SNORM          ,  64,  1,  1,  1, sn16, sn16, sn16, sn16,     ,     ,    , linear,
+R16G16B16A16_SINT           ,  64,  1,  1,  1, si16, si16, si16, si16,     ,     ,    , linear,
+R16G16B16A16_UINT           ,  64,  1,  1,  1, ui16, ui16, ui16, ui16,     ,     ,    , linear,
+R16G16B16A16_FLOAT          ,  64,  1,  1,  1, sf16, sf16, sf16, sf16,     ,     ,    , linear,
+R32G32_FLOAT                ,  64,  1,  1,  1, sf32, sf32,     ,     ,     ,     ,    , linear,
+R32G32_SINT                 ,  64,  1,  1,  1, si32, si32,     ,     ,     ,     ,    , linear,
+R32G32_UINT                 ,  64,  1,  1,  1, ui32, ui32,     ,     ,     ,     ,    , linear,
+R32_FLOAT_X8X24_TYPELESS    ,  64,  1,  1,  1, sf32,   x8,  x24,     ,     ,     ,    , linear,
+X32_TYPELESS_G8X24_UINT     ,  64,  1,  1,  1,  x32,  ui8,  x24,     ,     ,     ,    , linear,
+L32A32_FLOAT                ,  64,  1,  1,  1,     ,     ,     , sf32, sf32,     ,    , linear,
+R32G32_UNORM                ,  64,  1,  1,  1, un32, un32,     ,     ,     ,     ,    , linear,
+R32G32_SNORM                ,  64,  1,  1,  1, sn32, sn32,     ,     ,     ,     ,    , linear,
+R64_FLOAT                   ,  64,  1,  1,  1, sf64,     ,     ,     ,     ,     ,    , linear,
+R16G16B16X16_UNORM          ,  64,  1,  1,  1, un16, un16, un16,  x16,     ,     ,    , linear,
+R16G16B16X16_FLOAT          ,  64,  1,  1,  1, sf16, sf16, sf16,  x16,     ,     ,    , linear,
+A32X32_FLOAT                ,  64,  1,  1,  1,     ,     ,     , sf32,  x32,     ,    ,  alpha,
+L32X32_FLOAT                ,  64,  1,  1,  1,     ,     ,     ,  x32, sf32,     ,    , linear,
+I32X32_FLOAT                ,  64,  1,  1,  1,     ,     ,     ,  x32,     , sf32,    , linear,
+R16G16B16A16_SSCALED        ,  64,  1,  1,  1, ss16, ss16, ss16, ss16,     ,     ,    , linear,
+R16G16B16A16_USCALED        ,  64,  1,  1,  1, us16, us16, us16, us16,     ,     ,    , linear,
+R32G32_SSCALED              ,  64,  1,  1,  1, ss32, ss32,     ,     ,     ,     ,    , linear,
+R32G32_USCALED              ,  64,  1,  1,  1, us32, us32,     ,     ,     ,     ,    , linear,
+R32G32_SFIXED               ,  64,  1,  1,  1, sx32, sx32,     ,     ,     ,     ,    , linear,
+R64_PASSTHRU                ,  64,  1,  1,  1,  r64,     ,     ,     ,     ,     ,    ,       ,
+B8G8R8A8_UNORM              ,  32,  1,  1,  1,  un8,  un8,  un8,  un8,     ,     ,    , linear,
+B8G8R8A8_UNORM_SRGB         ,  32,  1,  1,  1,  un8,  un8,  un8,  un8,     ,     ,    ,   srgb,
+R10G10B10A2_UNORM           ,  32,  1,  1,  1, un10, un10, un10,  un2,     ,     ,    , linear,
+R10G10B10A2_UNORM_SRGB      ,  32,  1,  1,  1, un10, un10, un10,  un2,     ,     ,    ,   srgb,
+R10G10B10A2_UINT            ,  32,  1,  1,  1, ui10, ui10, ui10,  ui2,     ,     ,    , linear,
+R10G10B10_SNORM_A2_UNORM    ,  32,  1,  1,  1, sn10, sn10, sn10,  un2,     ,     ,    , linear,
+R8G8B8A8_UNORM              ,  32,  1,  1,  1,  un8,  un8,  un8,  un8,     ,     ,    , linear,
+R8G8B8A8_UNORM_SRGB         ,  32,  1,  1,  1,  un8,  un8,  un8,  un8,     ,     ,    ,   srgb,
+R8G8B8A8_SNORM              ,  32,  1,  1,  1,  sn8,  sn8,  sn8,  sn8,     ,     ,    , linear,
+R8G8B8A8_SINT               ,  32,  1,  1,  1,  si8,  si8,  si8,  si8,     ,     ,    , linear,
+R8G8B8A8_UINT               ,  32,  1,  1,  1,  ui8,  ui8,  ui8,  ui8,     ,     ,    , linear,
+R16G16_UNORM                ,  32,  1,  1,  1, un16, un16,     ,     ,     ,     ,    , linear,
+R16G16_SNORM                ,  32,  1,  1,  1, sn16, sn16,     ,     ,     ,     ,    , linear,
+R16G16_SINT                 ,  32,  1,  1,  1, si16, si16,     ,     ,     ,     ,    , linear,
+R16G16_UINT                 ,  32,  1,  1,  1, ui16, ui16,     ,     ,     ,     ,    , linear,
+R16G16_FLOAT                ,  32,  1,  1,  1, sf16, sf16,     ,     ,     ,     ,    , linear,
+B10G10R10A2_UNORM           ,  32,  1,  1,  1, un10, un10, un10,  un2,     ,     ,    , linear,
+B10G10R10A2_UNORM_SRGB      ,  32,  1,  1,  1, un10, un10, un10,  un2,     ,     ,    ,   srgb,
+R11G11B10_FLOAT             ,  32,  1,  1,  1, sf11, sf11, sf10,     ,     ,     ,    , linear,
+R32_SINT                    ,  32,  1,  1,  1, si32,     ,     ,     ,     ,     ,    , linear,
+R32_UINT                    ,  32,  1,  1,  1, ui32,     ,     ,     ,     ,     ,    , linear,
+R32_FLOAT                   ,  32,  1,  1,  1, sf32,     ,     ,     ,     ,     ,    , linear,
+R24_UNORM_X8_TYPELESS       ,  32,  1,  1,  1, un24,   x8,     ,     ,     ,     ,    , linear,
+X24_TYPELESS_G8_UINT        ,  32,  1,  1,  1,  x24,  ui8,     ,     ,     ,     ,    , linear,
+L32_UNORM                   ,  32,  1,  1,  1,     ,     ,     ,     , un32,     ,    , linear,
+A32_UNORM                   ,  32,  1,  1,  1,     ,     ,     , un32,     ,     ,    ,  alpha,
+L16A16_UNORM                ,  32,  1,  1,  1,     ,     ,     , un16, un16,     ,    , linear,
+I24X8_UNORM                 ,  32,  1,  1,  1,     ,     ,     ,   x8,     , un24,    , linear,
+L24X8_UNORM                 ,  32,  1,  1,  1,     ,     ,     ,   x8, un24,     ,    , linear,
+A24X8_UNORM                 ,  32,  1,  1,  1,     ,     ,     , un24,   x8,     ,    ,  alpha,
+I32_FLOAT                   ,  32,  1,  1,  1,     ,     ,     ,     ,     , sf32,    , linear,
+L32_FLOAT                   ,  32,  1,  1,  1,     ,     ,     ,     , sf32,     ,    , linear,
+A32_FLOAT                   ,  32,  1,  1,  1,     ,     ,     , sf32,     ,     ,    ,  alpha,
+X8B8_UNORM_G8R8_SNORM       ,  32,  1,  1,  1,  sn8,  sn8,  un8,   x8,     ,     ,    , linear,
+A8X8_UNORM_G8R8_SNORM       ,  32,  1,  1,  1,  sn8,  sn8,   x8,  un8,     ,     ,    , linear,
+B8X8_UNORM_G8R8_SNORM       ,  32,  1,  1,  1,  sn8,  sn8,  un8,   x8,     ,     ,    , linear,
+B8G8R8X8_UNORM              ,  32,  1,  1,  1,  un8,  un8,  un8,   x8,     ,     ,    , linear,
+B8G8R8X8_UNORM_SRGB         ,  32,  1,  1,  1,  un8,  un8,  un8,   x8,     ,     ,    ,   srgb,
+R8G8B8X8_UNORM              ,  32,  1,  1,  1,  un8,  un8,  un8,   x8,     ,     ,    , linear,
+R8G8B8X8_UNORM_SRGB         ,  32,  1,  1,  1,  un8,  un8,  un8,   x8,     ,     ,    ,   srgb,
+R9G9B9E5_SHAREDEXP          ,  32,  1,  1,  1,  ui9,  ui9,  ui9,     ,     ,     ,    , linear,
+B10G10R10X2_UNORM           ,  32,  1,  1,  1, un10, un10, un10,   x2,     ,     ,    , linear,
+L16A16_FLOAT                ,  32,  1,  1,  1,     ,     ,     , sf16, sf16,     ,    , linear,
+R32_UNORM                   ,  32,  1,  1,  1, un32,     ,     ,     ,     ,     ,    , linear,
+R32_SNORM                   ,  32,  1,  1,  1, sn32,     ,     ,     ,     ,     ,    , linear,
+R10G10B10X2_USCALED         ,  32,  1,  1,  1, us10, us10, us10,   x2,     ,     ,    , linear,
+R8G8B8A8_SSCALED            ,  32,  1,  1,  1,  ss8,  ss8,  ss8,  ss8,     ,     ,    , linear,
+R8G8B8A8_USCALED            ,  32,  1,  1,  1,  us8,  us8,  us8,  us8,     ,     ,    , linear,
+R16G16_SSCALED              ,  32,  1,  1,  1, ss16,  ss6,     ,     ,     ,     ,    , linear,
+R16G16_USCALED              ,  32,  1,  1,  1, us16, us16,     ,     ,     ,     ,    , linear,
+R32_SSCALED                 ,  32,  1,  1,  1, ss32,     ,     ,     ,     ,     ,    , linear,
+R32_USCALED                 ,  32,  1,  1,  1, us32,     ,     ,     ,     ,     ,    , linear,
+B5G6R5_UNORM                ,  16,  1,  1,  1,  un5,  un6,  un5,     ,     ,     ,    , linear,
+B5G6R5_UNORM_SRGB           ,  16,  1,  1,  1,  un5,  un6,  un5,     ,     ,     ,    ,   srgb,
+B5G5R5A1_UNORM              ,  16,  1,  1,  1,  un5,  un5,  un5,  un1,     ,     ,    , linear,
+B5G5R5A1_UNORM_SRGB         ,  16,  1,  1,  1,  un5,  un5,  un5,  un1,     ,     ,    ,   srgb,
+B4G4R4A4_UNORM              ,  16,  1,  1,  1,  un4,  un4,  un4,  un4,     ,     ,    , linear,
+B4G4R4A4_UNORM_SRGB         ,  16,  1,  1,  1,  un4,  un4,  un4,  un4,     ,     ,    ,   srgb,
+R8G8_UNORM                  ,  16,  1,  1,  1,  un8,  un8,     ,     ,     ,     ,    , linear,
+R8G8_SNORM                  ,  16,  1,  1,  1,  sn8,  sn8,     ,     ,     ,     ,    , linear,
+R8G8_SINT                   ,  16,  1,  1,  1,  si8,  si8,     ,     ,     ,     ,    , linear,
+R8G8_UINT                   ,  16,  1,  1,  1,  ui8,  ui8,     ,     ,     ,     ,    , linear,
+R16_UNORM                   ,  16,  1,  1,  1, un16,     ,     ,     ,     ,     ,    , linear,
+R16_SNORM                   ,  16,  1,  1,  1, sn16,     ,     ,     ,     ,     ,    , linear,
+R16_SINT                    ,  16,  1,  1,  1, si16,     ,     ,     ,     ,     ,    , linear,
+R16_UINT                    ,  16,  1,  1,  1, ui16,     ,     ,     ,     ,     ,    , linear,
+R16_FLOAT                   ,  16,  1,  1,  1, sf16,     ,     ,     ,     ,     ,    , linear,
+A8P8_UNORM_PALETTE0         ,  16,  1,  1,  1,     ,     ,     ,  un8,     ,     , un8, linear,
+A8P8_UNORM_PALETTE1         ,  16,  1,  1,  1,     ,     ,     ,  un8,     ,     , un8, linear,
+I16_UNORM                   ,  16,  1,  1,  1,     ,     ,     ,     ,     , un16,    , linear,
+L16_UNORM                   ,  16,  1,  1,  1,     ,     ,     ,     , un16,     ,    , linear,
+A16_UNORM                   ,  16,  1,  1,  1,     ,     ,     , un16,     ,     ,    ,  alpha,
+L8A8_UNORM                  ,  16,  1,  1,  1,     ,     ,     ,  un8,  un8,     ,    , linear,
+I16_FLOAT                   ,  16,  1,  1,  1,     ,     ,     ,     ,     , sf16,    , linear,
+L16_FLOAT                   ,  16,  1,  1,  1,     ,     ,     ,     , sf16,     ,    , linear,
+A16_FLOAT                   ,  16,  1,  1,  1,     ,     ,     , sf16,     ,     ,    ,  alpha,
+L8A8_UNORM_SRGB             ,  16,  1,  1,  1,     ,     ,     ,  un8,  un8,     ,    ,   srgb,
+R5G5_SNORM_B6_UNORM         ,  16,  1,  1,  1,  sn5,  sn5,  un6,     ,     ,     ,    , linear,
+B5G5R5X1_UNORM              ,  16,  1,  1,  1,  un5,  un5,  un5,   x1,     ,     ,    , linear,
+B5G5R5X1_UNORM_SRGB         ,  16,  1,  1,  1,  un5,  un5,  un5,   x1,     ,     ,    ,   srgb,
+R8G8_SSCALED                ,  16,  1,  1,  1,  ss8,  ss8,     ,     ,     ,     ,    , linear,
+R8G8_USCALED                ,  16,  1,  1,  1,  us8,  us8,     ,     ,     ,     ,    , linear,
+R16_SSCALED                 ,  16,  1,  1,  1, ss16,     ,     ,     ,     ,     ,    , linear,
+R16_USCALED                 ,  16,  1,  1,  1, us16,     ,     ,     ,     ,     ,    , linear,
+P8A8_UNORM_PALETTE0         ,  16,  1,  1,  1,     ,     ,     ,  un8,     ,     , un8, linear,
+P8A8_UNORM_PALETTE1         ,  16,  1,  1,  1,     ,     ,     ,  un8,     ,     , un8, linear,
+A1B5G5R5_UNORM              ,  16,  1,  1,  1,  un5,  un5,  un5,  un1,     ,     ,    , linear,
+A4B4G4R4_UNORM              ,  16,  1,  1,  1,  un4,  un4,  un4,  un4,     ,     ,    , linear,
+L8A8_UINT                   ,  16,  1,  1,  1,     ,     ,     ,  ui8,  ui8,     ,    , linear,
+L8A8_SINT                   ,  16,  1,  1,  1,     ,     ,     ,  si8,  si8,     ,    , linear,
+R8_UNORM                    ,   8,  1,  1,  1,  un8,     ,     ,     ,     ,     ,    , linear,
+R8_SNORM                    ,   8,  1,  1,  1,  sn8,     ,     ,     ,     ,     ,    , linear,
+R8_SINT                     ,   8,  1,  1,  1,  si8,     ,     ,     ,     ,     ,    , linear,
+R8_UINT                     ,   8,  1,  1,  1,  ui8,     ,     ,     ,     ,     ,    , linear,
+A8_UNORM                    ,   8,  1,  1,  1,     ,     ,     ,  un8,     ,     ,    ,  alpha,
+I8_UNORM                    ,   8,  1,  1,  1,     ,     ,     ,     ,     ,  un8,    , linear,
+L8_UNORM                    ,   8,  1,  1,  1,     ,     ,     ,     ,  un8,     ,    , linear,
+P4A4_UNORM_PALETTE0         ,   8,  1,  1,  1,     ,     ,     ,  un4,     ,     , un4, linear,
+A4P4_UNORM_PALETTE0         ,   8,  1,  1,  1,     ,     ,     ,  un4,     ,     , un4, linear,
+R8_SSCALED                  ,   8,  1,  1,  1,  ss8,     ,     ,     ,     ,     ,    , linear,
+R8_USCALED                  ,   8,  1,  1,  1,  us8,     ,     ,     ,     ,     ,    , linear,
+P8_UNORM_PALETTE0           ,   8,  1,  1,  1,     ,     ,     ,     ,     ,     , un8, linear,
+L8_UNORM_SRGB               ,   8,  1,  1,  1,     ,     ,     ,     ,  un8,     ,    , linear,
+P8_UNORM_PALETTE1           ,   8,  1,  1,  1,     ,     ,     ,     ,     ,     , un8, linear,
+P4A4_UNORM_PALETTE1         ,   8,  1,  1,  1,     ,     ,     ,  un4,     ,     , un4, linear,
+A4P4_UNORM_PALETTE1         ,   8,  1,  1,  1,     ,     ,     ,  un4,     ,     , un4, linear,
+Y8_UNORM                    ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,    yuv,
+L8_UINT                     ,   8,  1,  1,  1,     ,     ,     ,     ,  ui8,     ,    , linear,
+L8_SINT                     ,   8,  1,  1,  1,     ,     ,     ,     ,  si8,     ,    , linear,
+I8_UINT                     ,   8,  1,  1,  1,     ,     ,     ,     ,     ,  ui8,    , linear,
+I8_SINT                     ,   8,  1,  1,  1,     ,     ,     ,     ,     ,  si8,    , linear,
+DXT1_RGB_SRGB               ,  64,  4,  4,  1,  un4,  un4,  un4,     ,     ,     ,    ,   srgb,  dxt1
+R1_UNORM                    ,   1,  1,  1,  1,  un1,     ,     ,     ,     ,     ,    , linear,
+YCRCB_NORMAL                ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,    yuv,
+YCRCB_SWAPUVY               ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,    yuv,
+P2_UNORM_PALETTE0           ,   2,  1,  1,  1,     ,     ,     ,     ,     ,     , un2, linear,
+P2_UNORM_PALETTE1           ,   2,  1,  1,  1,     ,     ,     ,     ,     ,     , un2, linear,
+BC1_UNORM                   ,  64,  4,  4,  1,  un4,  un4,  un4,  un4,     ,     ,    , linear,  dxt1
+BC2_UNORM                   , 128,  4,  4,  1,  un4,  un4,  un4,  un4,     ,     ,    , linear,  dxt3
+BC3_UNORM                   , 128,  4,  4,  1,  un4,  un4,  un4,  un4,     ,     ,    , linear,  dxt5
+BC4_UNORM                   ,  64,  4,  4,  1,  un8,     ,     ,     ,     ,     ,    , linear, rgtc1
+BC5_UNORM                   , 128,  4,  4,  1,  un8,  un8,     ,     ,     ,     ,    , linear, rgtc2
+BC1_UNORM_SRGB              ,  64,  4,  4,  1,  un4,  un4,  un4,  un4,     ,     ,    ,   srgb,  dxt1
+BC2_UNORM_SRGB              , 128,  4,  4,  1,  un4,  un4,  un4,  un4,     ,     ,    ,   srgb,  dxt3
+BC3_UNORM_SRGB              , 128,  4,  4,  1,  un4,  un4,  un4,  un4,     ,     ,    ,   srgb,  dxt5
+MONO8                       ,   1,  1,  1,  1,     ,     ,     ,     ,     ,     ,    ,       ,
+YCRCB_SWAPUV                ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,    yuv,
+YCRCB_SWAPY                 ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,    yuv,
+DXT1_RGB                    ,  64,  4,  4,  1,  un4,  un4,  un4,     ,     ,     ,    , linear,  dxt1
+FXT1                        , 128,  8,  4,  1,  un4,  un4,  un4,     ,     ,     ,    , linear,  fxt1
+R8G8B8_UNORM                ,  24,  1,  1,  1,  un8,  un8,  un8,     ,     ,     ,    , linear,
+R8G8B8_SNORM                ,  24,  1,  1,  1,  sn8,  sn8,  sn8,     ,     ,     ,    , linear,
+R8G8B8_SSCALED              ,  24,  1,  1,  1,  ss8,  ss8,  ss8,     ,     ,     ,    , linear,
+R8G8B8_USCALED              ,  24,  1,  1,  1,  us8,  us8,  us8,     ,     ,     ,    , linear,
+R64G64B64A64_FLOAT          , 256,  1,  1,  1, sf64, sf64, sf64, sf64,     ,     ,    , linear,
+R64G64B64_FLOAT             , 196,  1,  1,  1, sf64, sf64, sf64,     ,     ,     ,    , linear,
+BC4_SNORM                   ,  64,  4,  4,  1,  sn8,     ,     ,     ,     ,     ,    , linear, rgtc1
+BC5_SNORM                   , 128,  4,  4,  1,  sn8,  sn8,     ,     ,     ,     ,    , linear, rgtc2
+R16G16B16_FLOAT             ,  48,  1,  1,  1, sf16, sf16, sf16,     ,     ,     ,    , linear,
+R16G16B16_UNORM             ,  48,  1,  1,  1, un16, un16, un16,     ,     ,     ,    , linear,
+R16G16B16_SNORM             ,  48,  1,  1,  1, sn16, sn16, sn16,     ,     ,     ,    , linear,
+R16G16B16_SSCALED           ,  48,  1,  1,  1, ss16, ss16, ss16,     ,     ,     ,    , linear,
+R16G16B16_USCALED           ,  48,  1,  1,  1, us16, us16, us16,     ,     ,     ,    , linear,
+BC6H_SF16                   , 128,  4,  4,  1, sf16, sf16, sf16,     ,     ,     ,    , linear,  bptc
+BC7_UNORM                   , 128,  4,  4,  1,  un8,  un8,  un8,  un8,     ,     ,    , linear,  bptc
+BC7_UNORM_SRGB              , 128,  4,  4,  1,  un8,  un8,  un8,  un8,     ,     ,    ,   srgb,  bptc
+BC6H_UF16                   , 128,  4,  4,  1, uf16, uf16, uf16,     ,     ,     ,    , linear,  bptc
+PLANAR_420_8                ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,    yuv,
+R8G8B8_UNORM_SRGB           ,  24,  1,  1,  1,  un8,  un8,  un8,     ,     ,     ,    ,   srgb,
+ETC1_RGB8                   ,  64,  4,  4,  1,  un8,  un8,  un8,     ,     ,     ,    , linear,  etc1
+ETC2_RGB8                   ,  64,  4,  4,  1,  un8,  un8,  un8,     ,     ,     ,    , linear,  etc2
+EAC_R11                     ,  64,  4,  4,  1, un11,     ,     ,     ,     ,     ,    , linear,  etc2
+EAC_RG11                    , 128,  4,  4,  1, un11, un11,     ,     ,     ,     ,    , linear,  etc2
+EAC_SIGNED_R11              ,  64,  4,  4,  1, sn11,     ,     ,     ,     ,     ,    , linear,  etc2
+EAC_SIGNED_RG11             , 128,  4,  4,  1, sn11, sn11,     ,     ,     ,     ,    , linear,  etc2
+ETC2_SRGB8                  ,  64,  4,  4,  1,  un8,  un8,  un8,     ,     ,     ,    ,   srgb,  etc2
+R16G16B16_UINT              ,  48,  1,  1,  1, ui16, ui16, ui16,     ,     ,     ,    , linear,
+R16G16B16_SINT              ,  48,  1,  1,  1, si16, si16, si16,     ,     ,     ,    , linear,
+R32_SFIXED                  ,  32,  1,  1,  1, sx16,     ,     ,     ,     ,     ,    , linear,
+R10G10B10A2_SNORM           ,  32,  1,  1,  1, sn10, sn10, sn10,  sn2,     ,     ,    , linear,
+R10G10B10A2_USCALED         ,  32,  1,  1,  1, us10, us10, us10,  us2,     ,     ,    , linear,
+R10G10B10A2_SSCALED         ,  32,  1,  1,  1, ss10, ss10, ss10,  ss2,     ,     ,    , linear,
+R10G10B10A2_SINT            ,  32,  1,  1,  1, si10, si10, si10,  si2,     ,     ,    , linear,
+B10G10R10A2_SNORM           ,  32,  1,  1,  1, sn10, sn10, sn10,  sn2,     ,     ,    , linear,
+B10G10R10A2_USCALED         ,  32,  1,  1,  1, us10, us10, us10,  us2,     ,     ,    , linear,
+B10G10R10A2_SSCALED         ,  32,  1,  1,  1, ss10, ss10, ss10,  ss2,     ,     ,    , linear,
+B10G10R10A2_UINT            ,  32,  1,  1,  1, ui10, ui10, ui10,  ui2,     ,     ,    , linear,
+B10G10R10A2_SINT            ,  32,  1,  1,  1, si10, si10, si10,  si2,     ,     ,    , linear,
+R64G64B64A64_PASSTHRU       , 256,  1,  1,  1,  r64,  r64,  r64,  r64,     ,     ,    ,       ,
+R64G64B64_PASSTHRU          , 192,  1,  1,  1,  r64,  r64,  r64,     ,     ,     ,    ,       ,
+ETC2_RGB8_PTA               ,  64,  4,  4,  1,  un8,  un8,  un8,  un1,     ,     ,    , linear,  etc2
+ETC2_SRGB8_PTA              ,  64,  4,  4,  1,  un8,  un8,  un8,  un1,     ,     ,    ,   srgb,  etc2
+ETC2_EAC_RGBA8              , 128,  4,  4,  1,  un8,  un8,  un8,  un8,     ,     ,    , linear,  etc2
+ETC2_EAC_SRGB8_A8           , 128,  4,  4,  1,  un8,  un8,  un8,  un8,     ,     ,    ,   srgb,  etc2
+R8G8B8_UINT                 ,  24,  1,  1,  1,  ui8,  ui8,  ui8,     ,     ,     ,    , linear,
+R8G8B8_SINT                 ,  24,  1,  1,  1,  si8,  si8,  si8,     ,     ,     ,    , linear,
+RAW                         ,   0,  0,  0,  0,     ,     ,     ,     ,     ,     ,    ,       ,
diff --git a/src/vulkan/isl_format_layout_gen.bash b/src/vulkan/isl_format_layout_gen.bash
new file mode 100755 (executable)
index 0000000..2511f29
--- /dev/null
@@ -0,0 +1,128 @@
+#!/usr/bin/env bash
+#
+# Copyright 2015 Intel Corporation
+#
+#  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 (including the next
+#  paragraph) 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.
+
+set -eu
+set -o pipefail
+
+cat <<'EOF'
+/*
+ * Copyright 2015 Intel Corporation
+ *
+ *  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 (including the next
+ *  paragraph) 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 "isl.h"
+
+const struct isl_format_layout
+isl_format_layouts[] = {
+EOF
+
+sed -r '
+# Delete comment lines and empty lines
+/^[[:space:]]*#/d
+/^[[:space:]]*$/d
+
+# Delete spaces
+s/[[:space:]]//g
+
+# Translate formats
+s/^([A-Za-z0-9_]+),*/ISL_FORMAT_\1,/
+
+# Translate data type of channels
+s/\<x([0-9]+),/ISL_VOID@\1,/g
+s/\<r([0-9]+),/ISL_RAW@\1,/g
+s/\<un([0-9]+),/ISL_UNORM@\1,/g
+s/\<sn([0-9]+),/ISL_SNORM@\1,/g
+s/\<uf([0-9]+),/ISL_UFLOAT@\1,/g
+s/\<sf([0-9]+),/ISL_SFLOAT@\1,/g
+s/\<ux([0-9]+),/ISL_UFIXED@\1,/g
+s/\<sx([0-9]+),/ISL_SFIXED@\1,/g
+s/\<ui([0-9]+),/ISL_UINT@\1,/g
+s/\<si([0-9]+),/ISL_SINT@\1,/g
+s/\<us([0-9]+),/ISL_USCALED@\1,/g
+s/\<ss([0-9]+),/ISL_SSCALED@\1,/g
+
+# Translate colorspaces
+# Interpret alpha-only formats as having no colorspace.
+s/\<(linear|srgb|yuv)\>/ISL_COLORSPACE_\1/
+s/\<alpha\>//
+
+# Translate texture compression
+s/\<(dxt|fxt|rgtc|bptc|etc)([0-9]*)\>/ISL_TXC_\1\2/
+' |
+tr 'a-z' 'A-Z' | # Convert to uppersace
+while IFS=, read -r format bpb bw bh bd \
+                    red green blue alpha \
+                    luminance intensity palette \
+                    colorspace txc
+do
+    : ${colorspace:=ISL_COLORSPACE_NONE}
+    : ${txc:=ISL_TXC_NONE}
+
+    cat <<EOF
+   [$format] = {
+      $format,
+      .bs = $((bpb/8)), .bpb = $bpb,
+      .bw = $bw, .bh = $bh, .bd = $bd,
+      .channels = {
+          .r = { $red },
+          .g = { $green },
+          .b = { $blue },
+          .a = { $alpha },
+          .l = { $luminance },
+          .i = { $intensity },
+          .p = { $palette },
+      },
+      .colorspace = $colorspace,
+      .txc = $txc,
+   },
+
+EOF
+done |
+sed -r '
+# Collapse empty channels
+s/\{  \}/{}/
+
+# Split non-empty channels into two members: base type and bit size
+s/@/, /
+'
+
+# Terminate the table
+printf '};\n'
diff --git a/src/vulkan/tests/.gitignore b/src/vulkan/tests/.gitignore
new file mode 100644 (file)
index 0000000..9f4be52
--- /dev/null
@@ -0,0 +1,4 @@
+block_pool
+state_pool
+state_pool_free_list_only
+state_pool_no_free
diff --git a/src/vulkan/tests/Makefile.am b/src/vulkan/tests/Makefile.am
new file mode 100644 (file)
index 0000000..7b15bb0
--- /dev/null
@@ -0,0 +1,45 @@
+# Copyright © 2009 Intel Corporation
+#
+#  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
+#  on the rights to use, copy, modify, merge, publish, distribute, sub
+#  license, and/or sell copies of the Software, and to permit persons to whom
+#  the Software is furnished to do so, subject to the following conditions:
+#
+#  The above copyright notice and this permission notice (including the next
+#  paragraph) 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
+#  ADAM JACKSON 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.
+
+AM_CPPFLAGS = \
+       $(INTEL_CFLAGS) \
+       $(VALGRIND_CFLAGS) \
+       $(DEFINES) \
+       -I$(top_srcdir)/include \
+       -I$(top_srcdir)/src \
+       -I$(top_srcdir)/src/mapi \
+       -I$(top_srcdir)/src/mesa \
+       -I$(top_srcdir)/src/mesa/drivers/dri/common \
+       -I$(top_srcdir)/src/mesa/drivers/dri/i965 \
+       -I$(top_srcdir)/src/gallium/auxiliary \
+       -I$(top_srcdir)/src/gallium/include \
+       -I$(top_srcdir)/src/vulkan
+
+LDADD = \
+       $(top_builddir)/src/vulkan/libvulkan-test.la \
+       $(PTHREAD_LIBS) -lm -lstdc++
+
+check_PROGRAMS = \
+       block_pool_no_free \
+       state_pool_no_free \
+       state_pool_free_list_only \
+       state_pool
+
+TESTS = $(check_PROGRAMS)
diff --git a/src/vulkan/tests/block_pool_no_free.c b/src/vulkan/tests/block_pool_no_free.c
new file mode 100644 (file)
index 0000000..86d1a76
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <pthread.h>
+
+#include "anv_private.h"
+
+#define NUM_THREADS 16
+#define BLOCKS_PER_THREAD 1024
+#define NUM_RUNS 64
+
+struct job {
+   pthread_t thread;
+   unsigned id;
+   struct anv_block_pool *pool;
+   uint32_t blocks[BLOCKS_PER_THREAD];
+   uint32_t back_blocks[BLOCKS_PER_THREAD];
+} jobs[NUM_THREADS];
+
+
+static void *alloc_blocks(void *_job)
+{
+   struct job *job = _job;
+   int32_t block, *data;
+
+   for (unsigned i = 0; i < BLOCKS_PER_THREAD; i++) {
+      block = anv_block_pool_alloc(job->pool);
+      data = job->pool->map + block;
+      *data = block;
+      assert(block >= 0);
+      job->blocks[i] = block;
+
+      block = anv_block_pool_alloc_back(job->pool);
+      data = job->pool->map + block;
+      *data = block;
+      assert(block < 0);
+      job->back_blocks[i] = -block;
+   }
+
+   for (unsigned i = 0; i < BLOCKS_PER_THREAD; i++) {
+      block = job->blocks[i];
+      data = job->pool->map + block;
+      assert(*data == block);
+
+      block = -job->back_blocks[i];
+      data = job->pool->map + block;
+      assert(*data == block);
+   }
+
+   return NULL;
+}
+
+static void validate_monotonic(uint32_t **blocks)
+{
+   /* A list of indices, one per thread */
+   unsigned next[NUM_THREADS];
+   memset(next, 0, sizeof(next));
+
+   int highest = -1;
+   while (true) {
+      /* First, we find which thread has the highest next element */
+      int thread_max = -1;
+      int max_thread_idx = -1;
+      for (unsigned i = 0; i < NUM_THREADS; i++) {
+         if (next[i] >= BLOCKS_PER_THREAD)
+            continue;
+
+         if (thread_max < blocks[i][next[i]]) {
+            thread_max = blocks[i][next[i]];
+            max_thread_idx = i;
+         }
+      }
+
+      /* The only way this can happen is if all of the next[] values are at
+       * BLOCKS_PER_THREAD, in which case, we're done.
+       */
+      if (thread_max == -1)
+         break;
+
+      /* That next element had better be higher than the previous highest */
+      assert(blocks[max_thread_idx][next[max_thread_idx]] > highest);
+
+      highest = blocks[max_thread_idx][next[max_thread_idx]];
+      next[max_thread_idx]++;
+   }
+}
+
+static void run_test()
+{
+   struct anv_device device;
+   struct anv_block_pool pool;
+
+   pthread_mutex_init(&device.mutex, NULL);
+   anv_block_pool_init(&pool, &device, 16);
+
+   for (unsigned i = 0; i < NUM_THREADS; i++) {
+      jobs[i].pool = &pool;
+      jobs[i].id = i;
+      pthread_create(&jobs[i].thread, NULL, alloc_blocks, &jobs[i]);
+   }
+
+   for (unsigned i = 0; i < NUM_THREADS; i++)
+      pthread_join(jobs[i].thread, NULL);
+
+   /* Validate that the block allocations were monotonic */
+   uint32_t *block_ptrs[NUM_THREADS];
+   for (unsigned i = 0; i < NUM_THREADS; i++)
+      block_ptrs[i] = jobs[i].blocks;
+   validate_monotonic(block_ptrs);
+
+   /* Validate that the back block allocations were monotonic */
+   for (unsigned i = 0; i < NUM_THREADS; i++)
+      block_ptrs[i] = jobs[i].back_blocks;
+   validate_monotonic(block_ptrs);
+
+   anv_block_pool_finish(&pool);
+   pthread_mutex_destroy(&device.mutex);
+}
+
+int main(int argc, char **argv)
+{
+   for (unsigned i = 0; i < NUM_RUNS; i++)
+      run_test();
+}
diff --git a/src/vulkan/tests/state_pool.c b/src/vulkan/tests/state_pool.c
new file mode 100644 (file)
index 0000000..878ec19
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <pthread.h>
+
+#include "anv_private.h"
+
+#define NUM_THREADS 8
+#define STATES_PER_THREAD_LOG2 10
+#define STATES_PER_THREAD (1 << STATES_PER_THREAD_LOG2)
+#define NUM_RUNS 64
+
+#include "state_pool_test_helper.h"
+
+int main(int argc, char **argv)
+{
+   struct anv_device device;
+   struct anv_block_pool block_pool;
+   struct anv_state_pool state_pool;
+
+   pthread_mutex_init(&device.mutex, NULL);
+
+   for (unsigned i = 0; i < NUM_RUNS; i++) {
+      anv_block_pool_init(&block_pool, &device, 256);
+      anv_state_pool_init(&state_pool, &block_pool);
+
+      /* Grab one so a zero offset is impossible */
+      anv_state_pool_alloc(&state_pool, 16, 16);
+
+      run_state_pool_test(&state_pool);
+
+      anv_state_pool_finish(&state_pool);
+      anv_block_pool_finish(&block_pool);
+   }
+
+   pthread_mutex_destroy(&device.mutex);
+}
diff --git a/src/vulkan/tests/state_pool_free_list_only.c b/src/vulkan/tests/state_pool_free_list_only.c
new file mode 100644 (file)
index 0000000..2f4eb47
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <pthread.h>
+
+#include "anv_private.h"
+
+#define NUM_THREADS 8
+#define STATES_PER_THREAD_LOG2 12
+#define STATES_PER_THREAD (1 << STATES_PER_THREAD_LOG2)
+
+#include "state_pool_test_helper.h"
+
+int main(int argc, char **argv)
+{
+   struct anv_device device;
+   struct anv_block_pool block_pool;
+   struct anv_state_pool state_pool;
+
+   pthread_mutex_init(&device.mutex, NULL);
+   anv_block_pool_init(&block_pool, &device, 4096);
+   anv_state_pool_init(&state_pool, &block_pool);
+
+   /* Grab one so a zero offset is impossible */
+   anv_state_pool_alloc(&state_pool, 16, 16);
+
+   /* Grab and return enough states that the state pool test below won't
+    * actually ever resize anything.
+    */
+   {
+      struct anv_state states[NUM_THREADS * STATES_PER_THREAD];
+      for (unsigned i = 0; i < NUM_THREADS * STATES_PER_THREAD; i++) {
+         states[i] = anv_state_pool_alloc(&state_pool, 16, 16);
+         assert(states[i].offset != 0);
+      }
+
+      for (unsigned i = 0; i < NUM_THREADS * STATES_PER_THREAD; i++)
+         anv_state_pool_free(&state_pool, states[i]);
+   }
+
+   run_state_pool_test(&state_pool);
+
+   anv_state_pool_finish(&state_pool);
+   anv_block_pool_finish(&block_pool);
+   pthread_mutex_destroy(&device.mutex);
+}
diff --git a/src/vulkan/tests/state_pool_no_free.c b/src/vulkan/tests/state_pool_no_free.c
new file mode 100644 (file)
index 0000000..4b248c2
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <pthread.h>
+
+#include "anv_private.h"
+
+#define NUM_THREADS 16
+#define STATES_PER_THREAD 1024
+#define NUM_RUNS 64
+
+struct job {
+   pthread_t thread;
+   unsigned id;
+   struct anv_state_pool *pool;
+   uint32_t offsets[STATES_PER_THREAD];
+} jobs[NUM_THREADS];
+
+pthread_barrier_t barrier;
+
+static void *alloc_states(void *_job)
+{
+   struct job *job = _job;
+
+   pthread_barrier_wait(&barrier);
+
+   for (unsigned i = 0; i < STATES_PER_THREAD; i++) {
+      struct anv_state state = anv_state_pool_alloc(job->pool, 16, 16);
+      job->offsets[i] = state.offset;
+   }
+
+   return NULL;
+}
+
+static void run_test()
+{
+   struct anv_device device;
+   struct anv_block_pool block_pool;
+   struct anv_state_pool state_pool;
+
+   pthread_mutex_init(&device.mutex, NULL);
+   anv_block_pool_init(&block_pool, &device, 64);
+   anv_state_pool_init(&state_pool, &block_pool);
+
+   pthread_barrier_init(&barrier, NULL, NUM_THREADS);
+
+   for (unsigned i = 0; i < NUM_THREADS; i++) {
+      jobs[i].pool = &state_pool;
+      jobs[i].id = i;
+      pthread_create(&jobs[i].thread, NULL, alloc_states, &jobs[i]);
+   }
+
+   for (unsigned i = 0; i < NUM_THREADS; i++)
+      pthread_join(jobs[i].thread, NULL);
+
+   /* A list of indices, one per thread */
+   unsigned next[NUM_THREADS];
+   memset(next, 0, sizeof(next));
+
+   int highest = -1;
+   while (true) {
+      /* First, we find which thread has the highest next element */
+      int thread_max = -1;
+      int max_thread_idx = -1;
+      for (unsigned i = 0; i < NUM_THREADS; i++) {
+         if (next[i] >= STATES_PER_THREAD)
+            continue;
+
+         if (thread_max < jobs[i].offsets[next[i]]) {
+            thread_max = jobs[i].offsets[next[i]];
+            max_thread_idx = i;
+         }
+      }
+
+      /* The only way this can happen is if all of the next[] values are at
+       * BLOCKS_PER_THREAD, in which case, we're done.
+       */
+      if (thread_max == -1)
+         break;
+
+      /* That next element had better be higher than the previous highest */
+      assert(jobs[max_thread_idx].offsets[next[max_thread_idx]] > highest);
+
+      highest = jobs[max_thread_idx].offsets[next[max_thread_idx]];
+      next[max_thread_idx]++;
+   }
+
+   anv_state_pool_finish(&state_pool);
+   anv_block_pool_finish(&block_pool);
+   pthread_mutex_destroy(&device.mutex);
+}
+
+int main(int argc, char **argv)
+{
+   for (unsigned i = 0; i < NUM_RUNS; i++)
+      run_test();
+}
diff --git a/src/vulkan/tests/state_pool_test_helper.h b/src/vulkan/tests/state_pool_test_helper.h
new file mode 100644 (file)
index 0000000..0e56431
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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 <pthread.h>
+
+struct job {
+   struct anv_state_pool *pool;
+   unsigned id;
+   pthread_t thread;
+} jobs[NUM_THREADS];
+
+pthread_barrier_t barrier;
+
+static void *alloc_states(void *void_job)
+{
+   struct job *job = void_job;
+
+   const unsigned chunk_size = 1 << (job->id % STATES_PER_THREAD_LOG2);
+   const unsigned num_chunks = STATES_PER_THREAD / chunk_size;
+
+   struct anv_state states[chunk_size];
+
+   pthread_barrier_wait(&barrier);
+
+   for (unsigned c = 0; c < num_chunks; c++) {
+      for (unsigned i = 0; i < chunk_size; i++) {
+         states[i] = anv_state_pool_alloc(job->pool, 16, 16);
+         memset(states[i].map, 139, 16);
+         assert(states[i].offset != 0);
+      }
+
+      for (unsigned i = 0; i < chunk_size; i++)
+         anv_state_pool_free(job->pool, states[i]);
+   }
+
+   return NULL;
+}
+
+static void run_state_pool_test(struct anv_state_pool *state_pool)
+{
+   pthread_barrier_init(&barrier, NULL, NUM_THREADS);
+
+   for (unsigned i = 0; i < NUM_THREADS; i++) {
+      jobs[i].pool = state_pool;
+      jobs[i].id = i;
+      pthread_create(&jobs[i].thread, NULL, alloc_states, &jobs[i]);
+   }
+
+   for (unsigned i = 0; i < NUM_THREADS; i++)
+      pthread_join(jobs[i].thread, NULL);
+}