vk: Prefix most filenames with anv
authorChad Versace <chad.versace@intel.com>
Fri, 17 Jul 2015 22:04:27 +0000 (15:04 -0700)
committerChad Versace <chad.versace@intel.com>
Sat, 18 Jul 2015 03:25:38 +0000 (20:25 -0700)
Jason started the task by creating anv_cmd_buffer.c and anv_cmd_emit.c.
This patch finishes the task by renaming all other files except
gen*_pack.h and glsl_scraper.py.

36 files changed:
src/vulkan/.gitignore
src/vulkan/Makefile.am
src/vulkan/allocator.c [deleted file]
src/vulkan/anv_allocator.c [new file with mode: 0644]
src/vulkan/anv_aub.c [new file with mode: 0644]
src/vulkan/anv_aub.h [new file with mode: 0644]
src/vulkan/anv_cmd_buffer.c
src/vulkan/anv_cmd_emit.c
src/vulkan/anv_compiler.cpp [new file with mode: 0644]
src/vulkan/anv_device.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_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_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_x11.c [new file with mode: 0644]
src/vulkan/aub.c [deleted file]
src/vulkan/aub.h [deleted file]
src/vulkan/compiler.cpp [deleted file]
src/vulkan/device.c [deleted file]
src/vulkan/formats.c [deleted file]
src/vulkan/gem.c [deleted file]
src/vulkan/image.c [deleted file]
src/vulkan/intel.c [deleted file]
src/vulkan/meta.c [deleted file]
src/vulkan/pipeline.c [deleted file]
src/vulkan/private.h [deleted file]
src/vulkan/query.c [deleted file]
src/vulkan/util.c [deleted file]
src/vulkan/vk_gen.py [deleted file]
src/vulkan/x11.c [deleted file]

index 617b6d4ebb988f05807728190a7f0a3b5da16f2b..30c614497e5273800aba0b2a701e5a9732be8355 100644 (file)
@@ -1,4 +1,4 @@
 # Generated source files
-/*-spirv.h
-/entrypoints.c
-/entrypoints.h
+/*_spirv.h
+/anv_entrypoints.c
+/anv_entrypoints.h
index 5147f6c69d0be48aa6d1b2e9a19fe2087c94c595..6d1212c532c14bae65bd9499f123b21499d08900 100644 (file)
@@ -53,38 +53,38 @@ libvulkan_la_CFLAGS =                                                       \
 libvulkan_la_CXXFLAGS =                                                        \
        -Wall -Wextra -Wno-unused-parameter -fvisibility=hidden -O0 -g
 
-libvulkan_la_SOURCES =                         \
-       private.h                               \
-       gem.c                                   \
-       device.c                                \
-        anv_cmd_buffer.c                        \
-       anv_cmd_emit.c                          \
-       aub.c                                   \
-       allocator.c                             \
-       util.c                                  \
-       pipeline.c                              \
-       image.c                                 \
-       meta.c                                  \
-       intel.c                                 \
-       entrypoints.c                           \
-       entrypoints.h                           \
-       x11.c                                   \
-       formats.c                               \
-       compiler.cpp                            \
-       query.c
-
-BUILT_SOURCES =                                        \
-       entrypoints.h                           \
-       entrypoints.c                           \
-       meta-spirv.h
-
-entrypoints.h : vk_gen.py $(vulkan_include_HEADERS)
+libvulkan_la_SOURCES =                                  \
+       anv_allocator.c                                 \
+       anv_aub.c                                       \
+       anv_cmd_buffer.c                                \
+       anv_cmd_emit.c                                  \
+       anv_compiler.cpp                                \
+       anv_device.c                                    \
+       anv_entrypoints.c                               \
+       anv_entrypoints.h                               \
+       anv_formats.c                                   \
+       anv_gem.c                                       \
+       anv_image.c                                     \
+       anv_intel.c                                     \
+       anv_meta.c                                      \
+       anv_pipeline.c                                  \
+       anv_private.h                                   \
+       anv_query.c                                     \
+       anv_util.c                                      \
+       anv_x11.c
+
+BUILT_SOURCES =                                         \
+       anv_entrypoints.h                               \
+       anv_entrypoints.c                               \
+       anv_meta_spirv.h
+
+anv_entrypoints.h : anv_entrypoints_gen.py $(vulkan_include_HEADERS)
        $(AM_V_GEN)cat $(vulkan_include_HEADERS) | $(PYTHON2) $< header > $@
 
-entrypoints.c : vk_gen.py $(vulkan_include_HEADERS)
+anv_entrypoints.c : anv_entrypoints_gen.py $(vulkan_include_HEADERS)
        $(AM_V_GEN)cat $(vulkan_include_HEADERS) | $(PYTHON2) $< code > $@
 
-%-spirv.h: %.c glsl_scraper.py
+%_spirv.h: %.c glsl_scraper.py
        $(AM_V_GEN) $(PYTHON2) $(srcdir)/glsl_scraper.py --glsl-only -o $@ $<
 
 CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/vulkan/allocator.c b/src/vulkan/allocator.c
deleted file mode 100644 (file)
index 2d0d255..0000000
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * 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 "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, uint32_t *offset)
-{
-   union anv_free_list current, next, old;
-
-   current = *list;
-   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();
-
-      uint32_t *next_ptr = *map + current.offset;
-      next.offset = VG_NOACCESS_READ(next_ptr);
-      next.count = current.count + 1;
-      old.u64 = __sync_val_compare_and_swap(&list->u64, current.u64, next.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, uint32_t offset)
-{
-   union anv_free_list current, old, new;
-   uint32_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 int
-anv_block_pool_grow(struct anv_block_pool *pool);
-
-void
-anv_block_pool_init(struct anv_block_pool *pool,
-                    struct anv_device *device, uint32_t block_size)
-{
-   assert(is_power_of_two(block_size));
-
-   pool->device = device;
-   pool->bo.gem_handle = 0;
-   pool->bo.offset = 0;
-   pool->size = 0;
-   pool->block_size = block_size;
-   pool->next_block = 0;
-   pool->free_list = ANV_FREE_LIST_EMPTY;
-   anv_vector_init(&pool->mmap_cleanups,
-                   round_to_power_of_two(sizeof(struct anv_mmap_cleanup)), 128);
-
-   /* Immediately grow the pool so we'll have a backing bo. */
-   anv_block_pool_grow(pool);
-}
-
-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);
-}
-
-static int
-anv_block_pool_grow(struct anv_block_pool *pool)
-{
-   size_t size;
-   void *map;
-   int gem_handle;
-   struct anv_mmap_cleanup *cleanup;
-
-   if (pool->size == 0) {
-      size = 32 * pool->block_size;
-   } else {
-      size = pool->size * 2;
-   }
-
-   cleanup = anv_vector_add(&pool->mmap_cleanups);
-   if (!cleanup)
-      return -1;
-   *cleanup = ANV_MMAP_CLEANUP_INIT;
-
-   if (pool->size == 0)
-      pool->fd = memfd_create("block pool", MFD_CLOEXEC);
-
-   if (pool->fd == -1)
-      return -1;
-
-   if (ftruncate(pool->fd, size) == -1)
-      return -1;
-
-   /* First try to see if mremap can grow the map in place. */
-   map = MAP_FAILED;
-   if (pool->size > 0)
-      map = mremap(pool->map, pool->size, size, 0);
-   if (map == MAP_FAILED) {
-      /* 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, 0);
-      cleanup->map = map;
-      cleanup->size = size;
-   }
-   if (map == MAP_FAILED)
-      return -1;
-
-   gem_handle = anv_gem_userptr(pool->device, map, size);
-   if (gem_handle == 0)
-      return -1;
-   cleanup->gem_handle = gem_handle;
-
-   /* Now that we successfull allocated everything, we can write the new
-    * values back into pool. */
-   pool->map = map;
-   pool->bo.gem_handle = gem_handle;
-   pool->bo.size = size;
-   pool->bo.map = map;
-   pool->bo.index = 0;
-
-   /* Write size last and after the memory barrier here. We need the memory
-    * barrier to make sure map and gem_handle are written before other threads
-    * see the new size.  A thread could allocate a block and then go try using
-    * the old pool->map and access out of bounds. */
-
-   __sync_synchronize();
-   pool->size = size;
-
-   return 0;
-}
-
-uint32_t
-anv_block_pool_alloc(struct anv_block_pool *pool)
-{
-   uint32_t offset, block, size;
-
-   /* Try free list first. */
-   if (anv_free_list_pop(&pool->free_list, &pool->map, &offset)) {
-      assert(pool->map);
-      return offset;
-   }
-
- restart:
-   size = pool->size;
-   block = __sync_fetch_and_add(&pool->next_block, pool->block_size);
-   if (block < size) {
-      assert(pool->map);
-      return block;
-   } else if (block == size) {
-      /* We allocated the first block outside the pool, we have to grow it.
-       * pool->next_block acts a mutex: threads who try to allocate now will
-       * get block indexes above the current limit and hit futex_wait
-       * below. */
-      int err = anv_block_pool_grow(pool);
-      assert(err == 0);
-      (void) err;
-      futex_wake(&pool->size, INT_MAX);
-   } else {
-      futex_wait(&pool->size, size);
-      __sync_fetch_and_add(&pool->next_block, -pool->block_size);
-      goto restart;
-   }
-
-   return block;
-}
-
-void
-anv_block_pool_free(struct anv_block_pool *pool, uint32_t offset)
-{
-   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 && 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)
-{
-   uint32_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))
-      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) {
-      new.next = anv_block_pool_alloc(block_pool);
-      new.end = new.next + block_pool->block_size;
-      old.u64 = __sync_fetch_and_add(&pool->block.u64, new.u64 - block.u64);
-      if (old.next != block.next)
-         futex_wake(&pool->block.end, INT_MAX);
-      return new.next;
-   } else {
-      futex_wait(&pool->block.end, block.end);
-      __sync_fetch_and_add(&pool->block.u64, -pool->state_size);
-      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);
-   }
-}
-
-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_MALLOCLIKE_BLOCK(state.map, size, 0, false));
-   return state;
-}
-
-void
-anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state)
-{
-   assert(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_FREELIKE_BLOCK(state.map, 0));
-   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;
-}
-
-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) {
-      sb = stream->block_pool->map + block;
-      next_block = VG_NOACCESS_READ(&sb->next);
-      VG(VALGRIND_FREELIKE_BLOCK(VG_NOACCESS_READ(&sb->_vg_ptr), 0));
-      anv_block_pool_free(stream->block_pool, block);
-      block = next_block;
-   }
-}
-
-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_MALLOCLIKE_BLOCK(vg_ptr, size, 0, false);
-   } else {
-      ptrdiff_t vg_offset = vg_ptr - current_map;
-      assert(vg_offset >= stream->current_block &&
-             vg_offset < stream->end);
-      VALGRIND_RESIZEINPLACE_BLOCK(vg_ptr,
-                                   stream->next - vg_offset,
-                                   (state.offset + size) - vg_offset,
-                                   0);
-   }
-#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;
-}
-
-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);
-
-      /* The anv_gem_m[un]map() functions are also valgrind-safe so they
-       * act as an alloc/free.  In order to avoid a double-free warning, we
-       * need to mark thiss as malloc'd before we unmap it.
-       */
-      VG(VALGRIND_MALLOCLIKE_BLOCK(link_copy.bo.map, pool->bo_size, 0, false));
-
-      anv_gem_munmap(link_copy.bo.map, pool->bo_size);
-      anv_gem_close(pool->device, link_copy.bo.gem_handle);
-      link = link_copy.next;
-   }
-}
-
-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_MALLOCLIKE_BLOCK(bo->map, pool->bo_size, 0, false));
-
-      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);
-   }
-
-   /* We don't need to call VALGRIND_MALLOCLIKE_BLOCK here because gem_mmap
-    * calls it for us.  If we really want to be pedantic we could do a
-    * VALGRIND_FREELIKE_BLOCK right after the mmap, but there's no good
-    * reason.
-    */
-
-   *bo = new_bo;
-   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_FREELIKE_BLOCK(bo->map, 0));
-   anv_ptr_free_list_push(&pool->free_list, link);
-}
diff --git a/src/vulkan/anv_allocator.c b/src/vulkan/anv_allocator.c
new file mode 100644 (file)
index 0000000..d85b919
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+ * 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, uint32_t *offset)
+{
+   union anv_free_list current, next, old;
+
+   current = *list;
+   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();
+
+      uint32_t *next_ptr = *map + current.offset;
+      next.offset = VG_NOACCESS_READ(next_ptr);
+      next.count = current.count + 1;
+      old.u64 = __sync_val_compare_and_swap(&list->u64, current.u64, next.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, uint32_t offset)
+{
+   union anv_free_list current, old, new;
+   uint32_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 int
+anv_block_pool_grow(struct anv_block_pool *pool);
+
+void
+anv_block_pool_init(struct anv_block_pool *pool,
+                    struct anv_device *device, uint32_t block_size)
+{
+   assert(is_power_of_two(block_size));
+
+   pool->device = device;
+   pool->bo.gem_handle = 0;
+   pool->bo.offset = 0;
+   pool->size = 0;
+   pool->block_size = block_size;
+   pool->next_block = 0;
+   pool->free_list = ANV_FREE_LIST_EMPTY;
+   anv_vector_init(&pool->mmap_cleanups,
+                   round_to_power_of_two(sizeof(struct anv_mmap_cleanup)), 128);
+
+   /* Immediately grow the pool so we'll have a backing bo. */
+   anv_block_pool_grow(pool);
+}
+
+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);
+}
+
+static int
+anv_block_pool_grow(struct anv_block_pool *pool)
+{
+   size_t size;
+   void *map;
+   int gem_handle;
+   struct anv_mmap_cleanup *cleanup;
+
+   if (pool->size == 0) {
+      size = 32 * pool->block_size;
+   } else {
+      size = pool->size * 2;
+   }
+
+   cleanup = anv_vector_add(&pool->mmap_cleanups);
+   if (!cleanup)
+      return -1;
+   *cleanup = ANV_MMAP_CLEANUP_INIT;
+
+   if (pool->size == 0)
+      pool->fd = memfd_create("block pool", MFD_CLOEXEC);
+
+   if (pool->fd == -1)
+      return -1;
+
+   if (ftruncate(pool->fd, size) == -1)
+      return -1;
+
+   /* First try to see if mremap can grow the map in place. */
+   map = MAP_FAILED;
+   if (pool->size > 0)
+      map = mremap(pool->map, pool->size, size, 0);
+   if (map == MAP_FAILED) {
+      /* 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, 0);
+      cleanup->map = map;
+      cleanup->size = size;
+   }
+   if (map == MAP_FAILED)
+      return -1;
+
+   gem_handle = anv_gem_userptr(pool->device, map, size);
+   if (gem_handle == 0)
+      return -1;
+   cleanup->gem_handle = gem_handle;
+
+   /* Now that we successfull allocated everything, we can write the new
+    * values back into pool. */
+   pool->map = map;
+   pool->bo.gem_handle = gem_handle;
+   pool->bo.size = size;
+   pool->bo.map = map;
+   pool->bo.index = 0;
+
+   /* Write size last and after the memory barrier here. We need the memory
+    * barrier to make sure map and gem_handle are written before other threads
+    * see the new size.  A thread could allocate a block and then go try using
+    * the old pool->map and access out of bounds. */
+
+   __sync_synchronize();
+   pool->size = size;
+
+   return 0;
+}
+
+uint32_t
+anv_block_pool_alloc(struct anv_block_pool *pool)
+{
+   uint32_t offset, block, size;
+
+   /* Try free list first. */
+   if (anv_free_list_pop(&pool->free_list, &pool->map, &offset)) {
+      assert(pool->map);
+      return offset;
+   }
+
+ restart:
+   size = pool->size;
+   block = __sync_fetch_and_add(&pool->next_block, pool->block_size);
+   if (block < size) {
+      assert(pool->map);
+      return block;
+   } else if (block == size) {
+      /* We allocated the first block outside the pool, we have to grow it.
+       * pool->next_block acts a mutex: threads who try to allocate now will
+       * get block indexes above the current limit and hit futex_wait
+       * below. */
+      int err = anv_block_pool_grow(pool);
+      assert(err == 0);
+      (void) err;
+      futex_wake(&pool->size, INT_MAX);
+   } else {
+      futex_wait(&pool->size, size);
+      __sync_fetch_and_add(&pool->next_block, -pool->block_size);
+      goto restart;
+   }
+
+   return block;
+}
+
+void
+anv_block_pool_free(struct anv_block_pool *pool, uint32_t offset)
+{
+   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 && 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)
+{
+   uint32_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))
+      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) {
+      new.next = anv_block_pool_alloc(block_pool);
+      new.end = new.next + block_pool->block_size;
+      old.u64 = __sync_fetch_and_add(&pool->block.u64, new.u64 - block.u64);
+      if (old.next != block.next)
+         futex_wake(&pool->block.end, INT_MAX);
+      return new.next;
+   } else {
+      futex_wait(&pool->block.end, block.end);
+      __sync_fetch_and_add(&pool->block.u64, -pool->state_size);
+      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);
+   }
+}
+
+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_MALLOCLIKE_BLOCK(state.map, size, 0, false));
+   return state;
+}
+
+void
+anv_state_pool_free(struct anv_state_pool *pool, struct anv_state state)
+{
+   assert(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_FREELIKE_BLOCK(state.map, 0));
+   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;
+}
+
+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) {
+      sb = stream->block_pool->map + block;
+      next_block = VG_NOACCESS_READ(&sb->next);
+      VG(VALGRIND_FREELIKE_BLOCK(VG_NOACCESS_READ(&sb->_vg_ptr), 0));
+      anv_block_pool_free(stream->block_pool, block);
+      block = next_block;
+   }
+}
+
+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_MALLOCLIKE_BLOCK(vg_ptr, size, 0, false);
+   } else {
+      ptrdiff_t vg_offset = vg_ptr - current_map;
+      assert(vg_offset >= stream->current_block &&
+             vg_offset < stream->end);
+      VALGRIND_RESIZEINPLACE_BLOCK(vg_ptr,
+                                   stream->next - vg_offset,
+                                   (state.offset + size) - vg_offset,
+                                   0);
+   }
+#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;
+}
+
+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);
+
+      /* The anv_gem_m[un]map() functions are also valgrind-safe so they
+       * act as an alloc/free.  In order to avoid a double-free warning, we
+       * need to mark thiss as malloc'd before we unmap it.
+       */
+      VG(VALGRIND_MALLOCLIKE_BLOCK(link_copy.bo.map, pool->bo_size, 0, false));
+
+      anv_gem_munmap(link_copy.bo.map, pool->bo_size);
+      anv_gem_close(pool->device, link_copy.bo.gem_handle);
+      link = link_copy.next;
+   }
+}
+
+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_MALLOCLIKE_BLOCK(bo->map, pool->bo_size, 0, false));
+
+      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);
+   }
+
+   /* We don't need to call VALGRIND_MALLOCLIKE_BLOCK here because gem_mmap
+    * calls it for us.  If we really want to be pedantic we could do a
+    * VALGRIND_FREELIKE_BLOCK right after the mmap, but there's no good
+    * reason.
+    */
+
+   *bo = new_bo;
+   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_FREELIKE_BLOCK(bo->map, 0));
+   anv_ptr_free_list_push(&pool->free_list, link);
+}
diff --git a/src/vulkan/anv_aub.c b/src/vulkan/anv_aub.c
new file mode 100644 (file)
index 0000000..97f124a
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <drm.h>
+#include <i915_drm.h>
+
+#include "anv_private.h"
+#include "anv_aub.h"
+
+struct anv_aub_writer {
+   FILE *file;
+   uint32_t offset;
+   int gen;
+};
+
+static void
+aub_out(struct anv_aub_writer *writer, uint32_t data)
+{
+   fwrite(&data, 1, 4, writer->file);
+}
+
+static void
+aub_out_data(struct anv_aub_writer *writer, const void *data, size_t size)
+{
+   fwrite(data, 1, size, writer->file);
+}
+
+static struct anv_aub_writer *
+get_anv_aub_writer(struct anv_device *device)
+{
+   struct anv_aub_writer *writer = device->aub_writer;
+   int entry = 0x200003;
+   int i;
+   int gtt_size = 0x10000;
+   const char *filename;
+
+   if (geteuid() != getuid())
+      return NULL;
+
+   if (writer)
+      return writer;
+
+   writer = malloc(sizeof(*writer));
+   if (writer == NULL)
+      return NULL;
+
+   filename = "intel.aub";
+   writer->gen = device->info.gen;
+   writer->file = fopen(filename, "w+");
+   if (!writer->file) {
+      free(writer);
+      return NULL;
+   }
+
+   /* Start allocating objects from just after the GTT. */
+   writer->offset = gtt_size;
+
+   /* Start with a (required) version packet. */
+   aub_out(writer, CMD_AUB_HEADER | (13 - 2));
+   aub_out(writer,
+           (4 << AUB_HEADER_MAJOR_SHIFT) |
+           (0 << AUB_HEADER_MINOR_SHIFT));
+   for (i = 0; i < 8; i++) {
+      aub_out(writer, 0); /* app name */
+   }
+   aub_out(writer, 0); /* timestamp */
+   aub_out(writer, 0); /* timestamp */
+   aub_out(writer, 0); /* comment len */
+
+   /* Set up the GTT. The max we can handle is 256M */
+   aub_out(writer, CMD_AUB_TRACE_HEADER_BLOCK | ((writer->gen >= 8 ? 6 : 5) - 2));
+   aub_out(writer,
+           AUB_TRACE_MEMTYPE_GTT_ENTRY |
+           AUB_TRACE_TYPE_NOTYPE | AUB_TRACE_OP_DATA_WRITE);
+   aub_out(writer, 0); /* subtype */
+   aub_out(writer, 0); /* offset */
+   aub_out(writer, gtt_size); /* size */
+   if (writer->gen >= 8)
+      aub_out(writer, 0);
+   for (i = 0x000; i < gtt_size; i += 4, entry += 0x1000) {
+      aub_out(writer, entry);
+   }
+
+   return device->aub_writer = writer;
+}
+
+void
+anv_aub_writer_destroy(struct anv_aub_writer *writer)
+{
+   fclose(writer->file);
+   free(writer);
+}
+
+
+/**
+ * Break up large objects into multiple writes.  Otherwise a 128kb VBO
+ * would overflow the 16 bits of size field in the packet header and
+ * everything goes badly after that.
+ */
+static void
+aub_write_trace_block(struct anv_aub_writer *writer, uint32_t type,
+                      void *virtual, uint32_t size, uint32_t gtt_offset)
+{
+   uint32_t block_size;
+   uint32_t offset;
+   uint32_t subtype = 0;
+   static const char null_block[8 * 4096];
+
+   for (offset = 0; offset < size; offset += block_size) {
+      block_size = size - offset;
+
+      if (block_size > 8 * 4096)
+         block_size = 8 * 4096;
+
+      aub_out(writer,
+              CMD_AUB_TRACE_HEADER_BLOCK |
+              ((writer->gen >= 8 ? 6 : 5) - 2));
+      aub_out(writer,
+              AUB_TRACE_MEMTYPE_GTT |
+              type | AUB_TRACE_OP_DATA_WRITE);
+      aub_out(writer, subtype);
+      aub_out(writer, gtt_offset + offset);
+      aub_out(writer, align_u32(block_size, 4));
+      if (writer->gen >= 8)
+         aub_out(writer, 0);
+
+      if (virtual)
+         aub_out_data(writer, (char *) virtual + offset, block_size);
+      else
+         aub_out_data(writer, null_block, block_size);
+
+      /* Pad to a multiple of 4 bytes. */
+      aub_out_data(writer, null_block, -block_size & 3);
+   }
+}
+
+/*
+ * Make a ringbuffer on fly and dump it
+ */
+static void
+aub_build_dump_ringbuffer(struct anv_aub_writer *writer,
+                          uint32_t batch_offset, uint32_t offset,
+                          int ring_flag)
+{
+   uint32_t ringbuffer[4096];
+   int ring = AUB_TRACE_TYPE_RING_PRB0; /* The default ring */
+   int ring_count = 0;
+
+   if (ring_flag == I915_EXEC_BSD)
+      ring = AUB_TRACE_TYPE_RING_PRB1;
+   else if (ring_flag == I915_EXEC_BLT)
+      ring = AUB_TRACE_TYPE_RING_PRB2;
+
+   /* Make a ring buffer to execute our batchbuffer. */
+   memset(ringbuffer, 0, sizeof(ringbuffer));
+   if (writer->gen >= 8) {
+      ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START | (3 - 2);
+      ringbuffer[ring_count++] = batch_offset;
+      ringbuffer[ring_count++] = 0;
+   } else {
+      ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START;
+      ringbuffer[ring_count++] = batch_offset;
+   }
+
+   /* Write out the ring.  This appears to trigger execution of
+    * the ring in the simulator.
+    */
+   aub_out(writer,
+           CMD_AUB_TRACE_HEADER_BLOCK |
+           ((writer->gen >= 8 ? 6 : 5) - 2));
+   aub_out(writer,
+           AUB_TRACE_MEMTYPE_GTT | ring | AUB_TRACE_OP_COMMAND_WRITE);
+   aub_out(writer, 0); /* general/surface subtype */
+   aub_out(writer, offset);
+   aub_out(writer, ring_count * 4);
+   if (writer->gen >= 8)
+      aub_out(writer, 0);
+
+   /* FIXME: Need some flush operations here? */
+   aub_out_data(writer, ringbuffer, ring_count * 4);
+}
+
+struct aub_bo {
+   uint32_t offset;
+   void *map;
+   void *relocated;
+};
+
+static void
+relocate_bo(struct anv_bo *bo, struct drm_i915_gem_relocation_entry *relocs,
+            size_t num_relocs, struct aub_bo *bos)
+{
+   struct aub_bo *aub_bo = &bos[bo->index];
+   struct drm_i915_gem_relocation_entry *reloc;
+   uint32_t *dw;
+
+   aub_bo->relocated = malloc(bo->size);
+   memcpy(aub_bo->relocated, aub_bo->map, bo->size);
+   for (size_t i = 0; i < num_relocs; i++) {
+      reloc = &relocs[i];
+      assert(reloc->offset < bo->size);
+      dw = aub_bo->relocated + reloc->offset;
+      *dw = bos[reloc->target_handle].offset + reloc->delta;
+   }
+}
+
+void
+anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_batch *batch = &cmd_buffer->batch;
+   struct anv_aub_writer *writer;
+   struct anv_bo *bo;
+   uint32_t ring_flag = 0;
+   uint32_t offset;
+   struct aub_bo *aub_bos;
+
+   writer = get_anv_aub_writer(device);
+   if (writer == NULL)
+      return;
+
+   aub_bos = malloc(cmd_buffer->exec2_bo_count * sizeof(aub_bos[0]));
+   offset = writer->offset;
+   for (uint32_t i = 0; i < cmd_buffer->exec2_bo_count; i++) {
+      bo = cmd_buffer->exec2_bos[i];
+      if (bo->map)
+         aub_bos[i].map = bo->map;
+      else
+         aub_bos[i].map = anv_gem_mmap(device, bo->gem_handle, 0, bo->size);
+      aub_bos[i].relocated = aub_bos[i].map;
+      aub_bos[i].offset = offset;
+      offset = align_u32(offset + bo->size + 4095, 4096);
+   }
+
+   struct anv_batch_bo *first_bbo;
+   for (struct anv_batch_bo *bbo = cmd_buffer->last_batch_bo;
+        bbo != NULL; bbo = bbo->prev_batch_bo) {
+      /* Keep stashing the current BO until we get to the beginning */
+      first_bbo = bbo;
+
+      /* Handle relocations for this batch BO */
+      relocate_bo(&bbo->bo, &batch->relocs.relocs[bbo->first_reloc],
+                  bbo->num_relocs, aub_bos);
+   }
+   assert(first_bbo->prev_batch_bo == NULL);
+
+   for (struct anv_batch_bo *bbo = cmd_buffer->surface_batch_bo;
+        bbo != NULL; bbo = bbo->prev_batch_bo) {
+
+      /* Handle relocations for this surface state BO */
+      relocate_bo(&bbo->bo,
+                  &cmd_buffer->surface_relocs.relocs[bbo->first_reloc],
+                  bbo->num_relocs, aub_bos);
+   }
+
+   for (uint32_t i = 0; i < cmd_buffer->exec2_bo_count; i++) {
+      bo = cmd_buffer->exec2_bos[i];
+      if (i == cmd_buffer->exec2_bo_count - 1) {
+         assert(bo == &first_bbo->bo);
+         aub_write_trace_block(writer, AUB_TRACE_TYPE_BATCH,
+                               aub_bos[i].relocated,
+                               first_bbo->length, aub_bos[i].offset);
+      } else {
+         aub_write_trace_block(writer, AUB_TRACE_TYPE_NOTYPE,
+                               aub_bos[i].relocated,
+                               bo->size, aub_bos[i].offset);
+      }
+      if (aub_bos[i].relocated != aub_bos[i].map)
+         free(aub_bos[i].relocated);
+      if (aub_bos[i].map != bo->map)
+         anv_gem_munmap(aub_bos[i].map, bo->size);
+   }
+
+   /* Dump ring buffer */
+   aub_build_dump_ringbuffer(writer, aub_bos[first_bbo->bo.index].offset,
+                             offset, ring_flag);
+
+   free(aub_bos);
+
+   fflush(writer->file);
+}
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 */
index 0d24d0bda028c6ab151e46af234598de46553a8d..4d4dfa9fb53e131aaade09a2e15a8bfc48946db4 100644 (file)
@@ -27,7 +27,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include "private.h"
+#include "anv_private.h"
 
 /** \file anv_cmd_buffer.c
  *
index 6f8788c348131a9a7874eefd0bb193acac23115a..8654c4a0ac734184ad1865ea628a8c28a91ed842 100644 (file)
@@ -27,7 +27,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include "private.h"
+#include "anv_private.h"
 
 /** \file anv_cmd_buffer.c
  *
diff --git a/src/vulkan/anv_compiler.cpp b/src/vulkan/anv_compiler.cpp
new file mode 100644 (file)
index 0000000..a50ecfd
--- /dev/null
@@ -0,0 +1,1209 @@
+/*
+ * 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 <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+#include <brw_context.h>
+#include <brw_wm.h> /* brw_new_shader_program is here */
+#include <brw_nir.h>
+
+#include <brw_vs.h>
+#include <brw_gs.h>
+#include <brw_cs.h>
+
+#include <mesa/main/shaderobj.h>
+#include <mesa/main/fbobject.h>
+#include <mesa/main/context.h>
+#include <mesa/program/program.h>
+#include <glsl/program.h>
+
+/* XXX: We need this to keep symbols in nir.h from conflicting with the
+ * generated GEN command packing headers.  We need to fix *both* to not
+ * define something as generic as LOAD.
+ */
+#undef LOAD
+
+#include <glsl/nir/nir_spirv.h>
+
+#define SPIR_V_MAGIC_NUMBER 0x07230203
+
+static void
+fail_if(int cond, const char *format, ...)
+{
+   va_list args;
+
+   if (!cond)
+      return;
+
+   va_start(args, format);
+   vfprintf(stderr, format, args);
+   va_end(args);
+
+   exit(1);
+}
+
+static VkResult
+set_binding_table_layout(struct brw_stage_prog_data *prog_data,
+                         struct anv_pipeline *pipeline, uint32_t stage)
+{
+   uint32_t bias, count, k, *map;
+   struct anv_pipeline_layout *layout = pipeline->layout;
+
+   /* No layout is valid for shaders that don't bind any resources. */
+   if (pipeline->layout == NULL)
+      return VK_SUCCESS;
+
+   if (stage == VK_SHADER_STAGE_FRAGMENT)
+      bias = MAX_RTS;
+   else
+      bias = 0;
+
+   count = layout->stage[stage].surface_count;
+   prog_data->map_entries =
+      (uint32_t *) malloc(count * sizeof(prog_data->map_entries[0]));
+   if (prog_data->map_entries == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   k = bias;
+   map = prog_data->map_entries;
+   for (uint32_t i = 0; i < layout->num_sets; i++) {
+      prog_data->bind_map[i].index = map;
+      for (uint32_t j = 0; j < layout->set[i].layout->stage[stage].surface_count; j++)
+         *map++ = k++;
+
+      prog_data->bind_map[i].index_count =
+         layout->set[i].layout->stage[stage].surface_count;
+   }
+
+   return VK_SUCCESS;
+}
+
+static void
+brw_vs_populate_key(struct brw_context *brw,
+                    struct brw_vertex_program *vp,
+                    struct brw_vs_prog_key *key)
+{
+   struct gl_context *ctx = &brw->ctx;
+   /* BRW_NEW_VERTEX_PROGRAM */
+   struct gl_program *prog = (struct gl_program *) vp;
+
+   memset(key, 0, sizeof(*key));
+
+   /* Just upload the program verbatim for now.  Always send it all
+    * the inputs it asks for, whether they are varying or not.
+    */
+   key->base.program_string_id = vp->id;
+   brw_setup_vue_key_clip_info(brw, &key->base,
+                               vp->program.Base.UsesClipDistanceOut);
+
+   /* _NEW_POLYGON */
+   if (brw->gen < 6) {
+      key->copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL ||
+                           ctx->Polygon.BackMode != GL_FILL);
+   }
+
+   if (prog->OutputsWritten & (VARYING_BIT_COL0 | VARYING_BIT_COL1 |
+                               VARYING_BIT_BFC0 | VARYING_BIT_BFC1)) {
+      /* _NEW_LIGHT | _NEW_BUFFERS */
+      key->clamp_vertex_color = ctx->Light._ClampVertexColor;
+   }
+
+   /* _NEW_POINT */
+   if (brw->gen < 6 && ctx->Point.PointSprite) {
+      for (int i = 0; i < 8; i++) {
+         if (ctx->Point.CoordReplace[i])
+            key->point_coord_replace |= (1 << i);
+      }
+   }
+
+   /* _NEW_TEXTURE */
+   brw_populate_sampler_prog_key_data(ctx, prog, brw->vs.base.sampler_count,
+                                      &key->base.tex);
+}
+
+static bool
+really_do_vs_prog(struct brw_context *brw,
+                  struct gl_shader_program *prog,
+                  struct brw_vertex_program *vp,
+                  struct brw_vs_prog_key *key, struct anv_pipeline *pipeline)
+{
+   GLuint program_size;
+   const GLuint *program;
+   struct brw_vs_compile c;
+   struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
+   struct brw_stage_prog_data *stage_prog_data = &prog_data->base.base;
+   void *mem_ctx;
+   struct gl_shader *vs = NULL;
+
+   if (prog)
+      vs = prog->_LinkedShaders[MESA_SHADER_VERTEX];
+
+   memset(&c, 0, sizeof(c));
+   memcpy(&c.key, key, sizeof(*key));
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   mem_ctx = ralloc_context(NULL);
+
+   c.vp = vp;
+
+   /* Allocate the references to the uniforms that will end up in the
+    * prog_data associated with the compiled program, and which will be freed
+    * by the state cache.
+    */
+   int param_count;
+   if (vs) {
+      /* We add padding around uniform values below vec4 size, with the worst
+       * case being a float value that gets blown up to a vec4, so be
+       * conservative here.
+       */
+      param_count = vs->num_uniform_components * 4;
+
+   } else {
+      param_count = vp->program.Base.Parameters->NumParameters * 4;
+   }
+   /* vec4_visitor::setup_uniform_clipplane_values() also uploads user clip
+    * planes as uniforms.
+    */
+   param_count += c.key.base.nr_userclip_plane_consts * 4;
+
+   /* Setting nr_params here NOT to the size of the param and pull_param
+    * arrays, but to the number of uniform components vec4_visitor
+    * needs. vec4_visitor::setup_uniforms() will set it back to a proper value.
+    */
+   stage_prog_data->nr_params = ALIGN(param_count, 4) / 4;
+   if (vs) {
+      stage_prog_data->nr_params += vs->num_samplers;
+   }
+
+   GLbitfield64 outputs_written = vp->program.Base.OutputsWritten;
+   prog_data->inputs_read = vp->program.Base.InputsRead;
+
+   if (c.key.copy_edgeflag) {
+      outputs_written |= BITFIELD64_BIT(VARYING_SLOT_EDGE);
+      prog_data->inputs_read |= VERT_BIT_EDGEFLAG;
+   }
+
+   if (brw->gen < 6) {
+      /* Put dummy slots into the VUE for the SF to put the replaced
+       * point sprite coords in.  We shouldn't need these dummy slots,
+       * which take up precious URB space, but it would mean that the SF
+       * doesn't get nice aligned pairs of input coords into output
+       * coords, which would be a pain to handle.
+       */
+      for (int i = 0; i < 8; i++) {
+         if (c.key.point_coord_replace & (1 << i))
+            outputs_written |= BITFIELD64_BIT(VARYING_SLOT_TEX0 + i);
+      }
+
+      /* if back colors are written, allocate slots for front colors too */
+      if (outputs_written & BITFIELD64_BIT(VARYING_SLOT_BFC0))
+         outputs_written |= BITFIELD64_BIT(VARYING_SLOT_COL0);
+      if (outputs_written & BITFIELD64_BIT(VARYING_SLOT_BFC1))
+         outputs_written |= BITFIELD64_BIT(VARYING_SLOT_COL1);
+   }
+
+   /* In order for legacy clipping to work, we need to populate the clip
+    * distance varying slots whenever clipping is enabled, even if the vertex
+    * shader doesn't write to gl_ClipDistance.
+    */
+   if (c.key.base.userclip_active) {
+      outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0);
+      outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1);
+   }
+
+   brw_compute_vue_map(brw->intelScreen->devinfo,
+                       &prog_data->base.vue_map, outputs_written);
+\
+   set_binding_table_layout(&prog_data->base.base, pipeline,
+                            VK_SHADER_STAGE_VERTEX);
+
+   /* Emit GEN4 code.
+    */
+   program = brw_vs_emit(brw, prog, &c, prog_data, mem_ctx, &program_size);
+   if (program == NULL) {
+      ralloc_free(mem_ctx);
+      return false;
+   }
+
+   struct anv_state vs_state = anv_state_stream_alloc(&pipeline->program_stream,
+                                                      program_size, 64);
+   memcpy(vs_state.map, program, program_size);
+
+   pipeline->vs_simd8 = vs_state.offset;
+
+   ralloc_free(mem_ctx);
+
+   return true;
+}
+
+void brw_wm_populate_key(struct brw_context *brw,
+                         struct brw_fragment_program *fp,
+                         struct brw_wm_prog_key *key)
+{
+   struct gl_context *ctx = &brw->ctx;
+   struct gl_program *prog = (struct gl_program *) brw->fragment_program;
+   GLuint lookup = 0;
+   GLuint line_aa;
+   bool program_uses_dfdy = fp->program.UsesDFdy;
+   struct gl_framebuffer draw_buffer;
+   bool multisample_fbo;
+
+   memset(key, 0, sizeof(*key));
+
+   for (int i = 0; i < MAX_SAMPLERS; i++) {
+      /* Assume color sampler, no swizzling. */
+      key->tex.swizzles[i] = SWIZZLE_XYZW;
+   }
+
+   /* A non-zero framebuffer name indicates that the framebuffer was created by
+    * the user rather than the window system. */
+   draw_buffer.Name = 1;
+   draw_buffer.Visual.samples = 1;
+   draw_buffer._NumColorDrawBuffers = 1;
+   draw_buffer._NumColorDrawBuffers = 1;
+   draw_buffer.Width = 400;
+   draw_buffer.Height = 400;
+   ctx->DrawBuffer = &draw_buffer;
+
+   multisample_fbo = ctx->DrawBuffer->Visual.samples > 1;
+
+   /* Build the index for table lookup
+    */
+   if (brw->gen < 6) {
+      /* _NEW_COLOR */
+      if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
+         lookup |= IZ_PS_KILL_ALPHATEST_BIT;
+
+      if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
+         lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
+
+      /* _NEW_DEPTH */
+      if (ctx->Depth.Test)
+         lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
+
+      if (ctx->Depth.Test && ctx->Depth.Mask) /* ?? */
+         lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
+
+      /* _NEW_STENCIL | _NEW_BUFFERS */
+      if (ctx->Stencil._Enabled) {
+         lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
+
+         if (ctx->Stencil.WriteMask[0] ||
+             ctx->Stencil.WriteMask[ctx->Stencil._BackFace])
+            lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
+      }
+      key->iz_lookup = lookup;
+   }
+
+   line_aa = AA_NEVER;
+
+   /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
+   if (ctx->Line.SmoothFlag) {
+      if (brw->reduced_primitive == GL_LINES) {
+         line_aa = AA_ALWAYS;
+      }
+      else if (brw->reduced_primitive == GL_TRIANGLES) {
+         if (ctx->Polygon.FrontMode == GL_LINE) {
+            line_aa = AA_SOMETIMES;
+
+            if (ctx->Polygon.BackMode == GL_LINE ||
+                (ctx->Polygon.CullFlag &&
+                 ctx->Polygon.CullFaceMode == GL_BACK))
+               line_aa = AA_ALWAYS;
+         }
+         else if (ctx->Polygon.BackMode == GL_LINE) {
+            line_aa = AA_SOMETIMES;
+
+            if ((ctx->Polygon.CullFlag &&
+                 ctx->Polygon.CullFaceMode == GL_FRONT))
+               line_aa = AA_ALWAYS;
+         }
+      }
+   }
+
+   key->line_aa = line_aa;
+
+   /* _NEW_HINT */
+   key->high_quality_derivatives =
+      ctx->Hint.FragmentShaderDerivative == GL_NICEST;
+
+   if (brw->gen < 6)
+      key->stats_wm = brw->stats_wm;
+
+   /* _NEW_LIGHT */
+   key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
+
+   /* _NEW_FRAG_CLAMP | _NEW_BUFFERS */
+   key->clamp_fragment_color = ctx->Color._ClampFragmentColor;
+
+   /* _NEW_TEXTURE */
+   brw_populate_sampler_prog_key_data(ctx, prog, brw->wm.base.sampler_count,
+                                      &key->tex);
+
+   /* _NEW_BUFFERS */
+   /*
+    * Include the draw buffer origin and height so that we can calculate
+    * fragment position values relative to the bottom left of the drawable,
+    * from the incoming screen origin relative position we get as part of our
+    * payload.
+    *
+    * This is only needed for the WM_WPOSXY opcode when the fragment program
+    * uses the gl_FragCoord input.
+    *
+    * We could avoid recompiling by including this as a constant referenced by
+    * our program, but if we were to do that it would also be nice to handle
+    * getting that constant updated at batchbuffer submit time (when we
+    * hold the lock and know where the buffer really is) rather than at emit
+    * time when we don't hold the lock and are just guessing.  We could also
+    * just avoid using this as key data if the program doesn't use
+    * fragment.position.
+    *
+    * For DRI2 the origin_x/y will always be (0,0) but we still need the
+    * drawable height in order to invert the Y axis.
+    */
+   if (fp->program.Base.InputsRead & VARYING_BIT_POS) {
+      key->drawable_height = ctx->DrawBuffer->Height;
+   }
+
+   if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
+      key->render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
+   }
+
+   /* _NEW_BUFFERS */
+   key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
+
+   /* _NEW_MULTISAMPLE, _NEW_COLOR, _NEW_BUFFERS */
+   key->replicate_alpha = ctx->DrawBuffer->_NumColorDrawBuffers > 1 &&
+      (ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled);
+
+   /* _NEW_BUFFERS _NEW_MULTISAMPLE */
+   /* Ignore sample qualifier while computing this flag. */
+   key->persample_shading =
+      _mesa_get_min_invocations_per_fragment(ctx, &fp->program, true) > 1;
+   if (key->persample_shading)
+      key->persample_2x = ctx->DrawBuffer->Visual.samples == 2;
+
+   key->compute_pos_offset =
+      _mesa_get_min_invocations_per_fragment(ctx, &fp->program, false) > 1 &&
+      fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_POS;
+
+   key->compute_sample_id =
+      multisample_fbo &&
+      ctx->Multisample.Enabled &&
+      (fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_ID);
+
+   /* BRW_NEW_VUE_MAP_GEOM_OUT */
+   if (brw->gen < 6 || _mesa_bitcount_64(fp->program.Base.InputsRead &
+                                         BRW_FS_VARYING_INPUT_MASK) > 16)
+      key->input_slots_valid = brw->vue_map_geom_out.slots_valid;
+
+
+   /* _NEW_COLOR | _NEW_BUFFERS */
+   /* Pre-gen6, the hardware alpha test always used each render
+    * target's alpha to do alpha test, as opposed to render target 0's alpha
+    * like GL requires.  Fix that by building the alpha test into the
+    * shader, and we'll skip enabling the fixed function alpha test.
+    */
+   if (brw->gen < 6 && ctx->DrawBuffer->_NumColorDrawBuffers > 1 && ctx->Color.AlphaEnabled) {
+      key->alpha_test_func = ctx->Color.AlphaFunc;
+      key->alpha_test_ref = ctx->Color.AlphaRef;
+   }
+
+   /* The unique fragment program ID */
+   key->program_string_id = fp->id;
+
+   ctx->DrawBuffer = NULL;
+}
+
+static uint8_t
+computed_depth_mode(struct gl_fragment_program *fp)
+{
+   if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
+      switch (fp->FragDepthLayout) {
+      case FRAG_DEPTH_LAYOUT_NONE:
+      case FRAG_DEPTH_LAYOUT_ANY:
+         return BRW_PSCDEPTH_ON;
+      case FRAG_DEPTH_LAYOUT_GREATER:
+         return BRW_PSCDEPTH_ON_GE;
+      case FRAG_DEPTH_LAYOUT_LESS:
+         return BRW_PSCDEPTH_ON_LE;
+      case FRAG_DEPTH_LAYOUT_UNCHANGED:
+         return BRW_PSCDEPTH_OFF;
+      }
+   }
+   return BRW_PSCDEPTH_OFF;
+}
+
+static bool
+really_do_wm_prog(struct brw_context *brw,
+                  struct gl_shader_program *prog,
+                  struct brw_fragment_program *fp,
+                  struct brw_wm_prog_key *key, struct anv_pipeline *pipeline)
+{
+   struct gl_context *ctx = &brw->ctx;
+   void *mem_ctx = ralloc_context(NULL);
+   struct brw_wm_prog_data *prog_data = &pipeline->wm_prog_data;
+   struct gl_shader *fs = NULL;
+   unsigned int program_size;
+   const uint32_t *program;
+
+   if (prog)
+      fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
+
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   /* key->alpha_test_func means simulating alpha testing via discards,
+    * so the shader definitely kills pixels.
+    */
+   prog_data->uses_kill = fp->program.UsesKill || key->alpha_test_func;
+
+   prog_data->computed_depth_mode = computed_depth_mode(&fp->program);
+
+   /* Allocate the references to the uniforms that will end up in the
+    * prog_data associated with the compiled program, and which will be freed
+    * by the state cache.
+    */
+   int param_count;
+   if (fs) {
+      param_count = fs->num_uniform_components;
+   } else {
+      param_count = fp->program.Base.Parameters->NumParameters * 4;
+   }
+   /* The backend also sometimes adds params for texture size. */
+   param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
+   prog_data->base.param =
+      rzalloc_array(NULL, const gl_constant_value *, param_count);
+   prog_data->base.pull_param =
+      rzalloc_array(NULL, const gl_constant_value *, param_count);
+   prog_data->base.nr_params = param_count;
+
+   prog_data->barycentric_interp_modes =
+      brw_compute_barycentric_interp_modes(brw, key->flat_shade,
+                                           key->persample_shading,
+                                           &fp->program);
+
+   set_binding_table_layout(&prog_data->base, pipeline,
+                            VK_SHADER_STAGE_FRAGMENT);
+   /* This needs to come after shader time and pull constant entries, but we
+    * don't have those set up now, so just put it after the layout entries.
+    */
+   prog_data->binding_table.render_target_start = 0;
+
+   program = brw_wm_fs_emit(brw, mem_ctx, key, prog_data,
+                            &fp->program, prog, &program_size);
+   if (program == NULL) {
+      ralloc_free(mem_ctx);
+      return false;
+   }
+
+   struct anv_state ps_state = anv_state_stream_alloc(&pipeline->program_stream,
+                                                      program_size, 64);
+   memcpy(ps_state.map, program, program_size);
+
+   if (prog_data->no_8)
+      pipeline->ps_simd8 = NO_KERNEL;
+   else
+      pipeline->ps_simd8 = ps_state.offset;
+
+   if (prog_data->no_8 || prog_data->prog_offset_16) {
+      pipeline->ps_simd16 = ps_state.offset + prog_data->prog_offset_16;
+   } else {
+      pipeline->ps_simd16 = NO_KERNEL;
+   }
+
+   ralloc_free(mem_ctx);
+
+   return true;
+}
+
+static void
+brw_gs_populate_key(struct brw_context *brw,
+                    struct anv_pipeline *pipeline,
+                    struct brw_geometry_program *gp,
+                    struct brw_gs_prog_key *key)
+{
+   struct gl_context *ctx = &brw->ctx;
+   struct brw_stage_state *stage_state = &brw->gs.base;
+   struct gl_program *prog = &gp->program.Base;
+
+   memset(key, 0, sizeof(*key));
+
+   key->base.program_string_id = gp->id;
+   brw_setup_vue_key_clip_info(brw, &key->base,
+                               gp->program.Base.UsesClipDistanceOut);
+
+   /* _NEW_TEXTURE */
+   brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
+                                      &key->base.tex);
+
+   struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
+
+   /* BRW_NEW_VUE_MAP_VS */
+   key->input_varyings = prog_data->base.vue_map.slots_valid;
+}
+
+static bool
+really_do_gs_prog(struct brw_context *brw,
+                  struct gl_shader_program *prog,
+                  struct brw_geometry_program *gp,
+                  struct brw_gs_prog_key *key, struct anv_pipeline *pipeline)
+{
+   struct brw_gs_compile_output output;
+
+   /* FIXME: We pass the bind map to the compile in the output struct. Need
+    * something better. */
+   set_binding_table_layout(&output.prog_data.base.base,
+                            pipeline, VK_SHADER_STAGE_GEOMETRY);
+
+   brw_compile_gs_prog(brw, prog, gp, key, &output);
+
+   struct anv_state gs_state = anv_state_stream_alloc(&pipeline->program_stream,
+                                                      output.program_size, 64);
+   memcpy(gs_state.map, output.program, output.program_size);
+
+   pipeline->gs_vec4 = gs_state.offset;
+   pipeline->gs_vertex_count = gp->program.VerticesIn;
+
+   ralloc_free(output.mem_ctx);
+
+   return true;
+}
+
+static bool
+brw_codegen_cs_prog(struct brw_context *brw,
+                    struct gl_shader_program *prog,
+                    struct brw_compute_program *cp,
+                    struct brw_cs_prog_key *key, struct anv_pipeline *pipeline)
+{
+   struct gl_context *ctx = &brw->ctx;
+   const GLuint *program;
+   void *mem_ctx = ralloc_context(NULL);
+   GLuint program_size;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+
+   struct gl_shader *cs = prog->_LinkedShaders[MESA_SHADER_COMPUTE];
+   assert (cs);
+
+   memset(prog_data, 0, sizeof(*prog_data));
+
+   set_binding_table_layout(&prog_data->base, pipeline, VK_SHADER_STAGE_COMPUTE);
+
+   /* Allocate the references to the uniforms that will end up in the
+    * prog_data associated with the compiled program, and which will be freed
+    * by the state cache.
+    */
+   int param_count = cs->num_uniform_components;
+
+   /* The backend also sometimes adds params for texture size. */
+   param_count += 2 * ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
+   prog_data->base.param =
+      rzalloc_array(NULL, const gl_constant_value *, param_count);
+   prog_data->base.pull_param =
+      rzalloc_array(NULL, const gl_constant_value *, param_count);
+   prog_data->base.nr_params = param_count;
+
+   program = brw_cs_emit(brw, mem_ctx, key, prog_data,
+                         &cp->program, prog, &program_size);
+   if (program == NULL) {
+      ralloc_free(mem_ctx);
+      return false;
+   }
+
+   if (unlikely(INTEL_DEBUG & DEBUG_CS))
+      fprintf(stderr, "\n");
+
+   struct anv_state cs_state = anv_state_stream_alloc(&pipeline->program_stream,
+                                                      program_size, 64);
+   memcpy(cs_state.map, program, program_size);
+
+   pipeline->cs_simd = cs_state.offset;
+
+   ralloc_free(mem_ctx);
+
+   return true;
+}
+
+static void
+brw_cs_populate_key(struct brw_context *brw,
+                    struct brw_compute_program *bcp, struct brw_cs_prog_key *key)
+{
+   memset(key, 0, sizeof(*key));
+
+   /* The unique compute program ID */
+   key->program_string_id = bcp->id;
+}
+
+static void
+fail_on_compile_error(int status, const char *msg)
+{
+   int source, line, column;
+   char error[256];
+
+   if (status)
+      return;
+
+   if (sscanf(msg, "%d:%d(%d): error: %255[^\n]", &source, &line, &column, error) == 4)
+      fail_if(!status, "%d:%s\n", line, error);
+   else
+      fail_if(!status, "%s\n", msg);
+}
+
+struct anv_compiler {
+   struct anv_device *device;
+   struct intel_screen *screen;
+   struct brw_context *brw;
+   struct gl_pipeline_object pipeline;
+};
+
+extern "C" {
+
+struct anv_compiler *
+anv_compiler_create(struct anv_device *device)
+{
+   const struct brw_device_info *devinfo = &device->info;
+   struct anv_compiler *compiler;
+   struct gl_context *ctx;
+
+   compiler = rzalloc(NULL, struct anv_compiler);
+   if (compiler == NULL)
+      return NULL;
+
+   compiler->screen = rzalloc(compiler, struct intel_screen);
+   if (compiler->screen == NULL)
+      goto fail;
+
+   compiler->brw = rzalloc(compiler, struct brw_context);
+   if (compiler->brw == NULL)
+      goto fail;
+
+   compiler->device = device;
+
+   compiler->brw->optionCache.info = NULL;
+   compiler->brw->bufmgr = NULL;
+   compiler->brw->gen = devinfo->gen;
+   compiler->brw->is_g4x = devinfo->is_g4x;
+   compiler->brw->is_baytrail = devinfo->is_baytrail;
+   compiler->brw->is_haswell = devinfo->is_haswell;
+   compiler->brw->is_cherryview = devinfo->is_cherryview;
+
+   /* We need this at least for CS, which will check brw->max_cs_threads
+    * against the work group size. */
+   compiler->brw->max_vs_threads = devinfo->max_vs_threads;
+   compiler->brw->max_hs_threads = devinfo->max_hs_threads;
+   compiler->brw->max_ds_threads = devinfo->max_ds_threads;
+   compiler->brw->max_gs_threads = devinfo->max_gs_threads;
+   compiler->brw->max_wm_threads = devinfo->max_wm_threads;
+   compiler->brw->max_cs_threads = devinfo->max_cs_threads;
+   compiler->brw->urb.size = devinfo->urb.size;
+   compiler->brw->urb.min_vs_entries = devinfo->urb.min_vs_entries;
+   compiler->brw->urb.max_vs_entries = devinfo->urb.max_vs_entries;
+   compiler->brw->urb.max_hs_entries = devinfo->urb.max_hs_entries;
+   compiler->brw->urb.max_ds_entries = devinfo->urb.max_ds_entries;
+   compiler->brw->urb.max_gs_entries = devinfo->urb.max_gs_entries;
+
+   compiler->brw->intelScreen = compiler->screen;
+   compiler->screen->devinfo = &device->info;
+
+   brw_process_intel_debug_variable(compiler->screen);
+
+   compiler->screen->compiler = brw_compiler_create(compiler, &device->info);
+
+   ctx = &compiler->brw->ctx;
+   _mesa_init_shader_object_functions(&ctx->Driver);
+
+   _mesa_init_constants(&ctx->Const, API_OPENGL_CORE);
+
+   brw_initialize_context_constants(compiler->brw);
+
+   intelInitExtensions(ctx);
+
+   /* Set dd::NewShader */
+   brwInitFragProgFuncs(&ctx->Driver);
+
+   ctx->_Shader = &compiler->pipeline;
+
+   compiler->brw->precompile = false;
+
+   return compiler;
+
+ fail:
+   ralloc_free(compiler);
+   return NULL;
+}
+
+void
+anv_compiler_destroy(struct anv_compiler *compiler)
+{
+   _mesa_free_errors_data(&compiler->brw->ctx);
+   ralloc_free(compiler);
+}
+
+/* From gen7_urb.c */
+
+/* FIXME: Add to struct intel_device_info */
+
+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->vs_simd8 != NO_KERNEL;
+   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->gs_vec4 != NO_KERNEL;
+   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 const struct {
+   uint32_t token;
+   gl_shader_stage stage;
+   const char *name;
+} stage_info[] = {
+   { GL_VERTEX_SHADER, MESA_SHADER_VERTEX, "vertex" },
+   { GL_TESS_CONTROL_SHADER, (gl_shader_stage)-1,"tess control" },
+   { GL_TESS_EVALUATION_SHADER, (gl_shader_stage)-1, "tess evaluation" },
+   { GL_GEOMETRY_SHADER, MESA_SHADER_GEOMETRY, "geometry" },
+   { GL_FRAGMENT_SHADER, MESA_SHADER_FRAGMENT, "fragment" },
+   { GL_COMPUTE_SHADER, MESA_SHADER_COMPUTE, "compute" },
+};
+
+struct spirv_header{
+   uint32_t magic;
+   uint32_t version;
+   uint32_t gen_magic;
+};
+
+static const char *
+src_as_glsl(const char *data)
+{
+   const struct spirv_header *as_spirv = (const struct spirv_header *)data;
+
+   /* Check alignment */
+   if ((intptr_t)data & 0x3) {
+      return data;
+   }
+
+   if (as_spirv->magic == SPIR_V_MAGIC_NUMBER) {
+      /* LunarG back-door */
+      if (as_spirv->version == 0)
+         return data + 12;
+      else
+         return NULL;
+   } else {
+      return data;
+   }
+}
+
+static void
+anv_compile_shader_glsl(struct anv_compiler *compiler,
+                   struct gl_shader_program *program,
+                   struct anv_pipeline *pipeline, uint32_t stage)
+{
+   struct brw_context *brw = compiler->brw;
+   struct gl_shader *shader;
+   int name = 0;
+
+   shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
+   fail_if(shader == NULL, "failed to create %s shader\n", stage_info[stage].name);
+
+   shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->module->data));
+   _mesa_glsl_compile_shader(&brw->ctx, shader, false, false);
+   fail_on_compile_error(shader->CompileStatus, shader->InfoLog);
+
+   program->Shaders[program->NumShaders] = shader;
+   program->NumShaders++;
+}
+
+static void
+setup_nir_io(struct gl_program *prog,
+             nir_shader *shader)
+{
+   foreach_list_typed(nir_variable, var, node, &shader->inputs) {
+      prog->InputsRead |= BITFIELD64_BIT(var->data.location);
+   }
+
+   foreach_list_typed(nir_variable, var, node, &shader->outputs) {
+      prog->OutputsWritten |= BITFIELD64_BIT(var->data.location);
+   }
+}
+
+static void
+anv_compile_shader_spirv(struct anv_compiler *compiler,
+                         struct gl_shader_program *program,
+                         struct anv_pipeline *pipeline, uint32_t stage)
+{
+   struct brw_context *brw = compiler->brw;
+   struct anv_shader *shader = pipeline->shaders[stage];
+   struct gl_shader *mesa_shader;
+   int name = 0;
+
+   mesa_shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
+   fail_if(mesa_shader == NULL,
+           "failed to create %s shader\n", stage_info[stage].name);
+
+   switch (stage) {
+   case VK_SHADER_STAGE_VERTEX:
+      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_vertex_program)->program.Base;
+      break;
+   case VK_SHADER_STAGE_GEOMETRY:
+      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_geometry_program)->program.Base;
+      break;
+   case VK_SHADER_STAGE_FRAGMENT:
+      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_fragment_program)->program.Base;
+      break;
+   case VK_SHADER_STAGE_COMPUTE:
+      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_compute_program)->program.Base;
+      break;
+   }
+
+   mesa_shader->Program->Parameters =
+      rzalloc(mesa_shader, struct gl_program_parameter_list);
+
+   mesa_shader->Type = stage_info[stage].token;
+   mesa_shader->Stage = stage_info[stage].stage;
+
+   assert(shader->module->size % 4 == 0);
+
+   struct gl_shader_compiler_options *glsl_options =
+      &compiler->screen->compiler->glsl_compiler_options[stage_info[stage].stage];
+
+   mesa_shader->Program->nir =
+      spirv_to_nir((uint32_t *)shader->module->data, shader->module->size / 4,
+                   glsl_options->NirOptions);
+   nir_validate_shader(mesa_shader->Program->nir);
+
+   brw_process_nir(mesa_shader->Program->nir,
+                   compiler->screen->devinfo,
+                   NULL, mesa_shader->Stage);
+
+   setup_nir_io(mesa_shader->Program, mesa_shader->Program->nir);
+
+   fail_if(mesa_shader->Program->nir == NULL,
+           "failed to translate SPIR-V to NIR\n");
+
+   program->Shaders[program->NumShaders] = mesa_shader;
+   program->NumShaders++;
+}
+
+static void
+add_compiled_stage(struct anv_pipeline *pipeline, uint32_t 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];
+}
+
+int
+anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
+{
+   struct gl_shader_program *program;
+   int name = 0;
+   struct brw_context *brw = compiler->brw;
+
+   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));
+
+   brw->use_rep_send = pipeline->use_repclear;
+   brw->no_simd8 = pipeline->use_repclear;
+
+   program = brw->ctx.Driver.NewShaderProgram(name);
+   program->Shaders = (struct gl_shader **)
+      calloc(VK_SHADER_STAGE_NUM, sizeof(struct gl_shader *));
+   fail_if(program == NULL || program->Shaders == NULL,
+           "failed to create program\n");
+
+   bool all_spirv = true;
+   for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
+      if (pipeline->shaders[i] == NULL)
+         continue;
+
+      /* You need at least this much for "void main() { }" anyway */
+      assert(pipeline->shaders[i]->module->size >= 12);
+
+      if (src_as_glsl(pipeline->shaders[i]->module->data)) {
+         all_spirv = false;
+         break;
+      }
+
+      assert(pipeline->shaders[i]->module->size % 4 == 0);
+   }
+
+   if (all_spirv) {
+      for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
+         if (pipeline->shaders[i])
+            anv_compile_shader_spirv(compiler, program, pipeline, i);
+      }
+
+      for (unsigned i = 0; i < program->NumShaders; i++) {
+         struct gl_shader *shader = program->Shaders[i];
+         program->_LinkedShaders[shader->Stage] = shader;
+      }
+   } else {
+      for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
+         if (pipeline->shaders[i])
+            anv_compile_shader_glsl(compiler, program, pipeline, i);
+      }
+
+      _mesa_glsl_link_shader(&brw->ctx, program);
+      fail_on_compile_error(program->LinkStatus,
+                            program->InfoLog);
+   }
+
+   bool success;
+   pipeline->active_stages = 0;
+   pipeline->total_scratch = 0;
+
+   if (pipeline->shaders[VK_SHADER_STAGE_VERTEX]) {
+      struct brw_vs_prog_key vs_key;
+      struct gl_vertex_program *vp = (struct gl_vertex_program *)
+         program->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
+      struct brw_vertex_program *bvp = brw_vertex_program(vp);
+
+      brw_vs_populate_key(brw, bvp, &vs_key);
+
+      success = really_do_vs_prog(brw, program, bvp, &vs_key, pipeline);
+      fail_if(!success, "do_wm_prog failed\n");
+      add_compiled_stage(pipeline, VK_SHADER_STAGE_VERTEX,
+                         &pipeline->vs_prog_data.base.base);
+
+      if (vp->Base.OutputsWritten & VARYING_SLOT_PSIZ)
+         pipeline->writes_point_size = true;
+   } else {
+      memset(&pipeline->vs_prog_data, 0, sizeof(pipeline->vs_prog_data));
+      pipeline->vs_simd8 = NO_KERNEL;
+   }
+
+
+   if (pipeline->shaders[VK_SHADER_STAGE_GEOMETRY]) {
+      struct brw_gs_prog_key gs_key;
+      struct gl_geometry_program *gp = (struct gl_geometry_program *)
+         program->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
+      struct brw_geometry_program *bgp = brw_geometry_program(gp);
+
+      brw_gs_populate_key(brw, pipeline, bgp, &gs_key);
+
+      success = really_do_gs_prog(brw, program, bgp, &gs_key, pipeline);
+      fail_if(!success, "do_gs_prog failed\n");
+      add_compiled_stage(pipeline, VK_SHADER_STAGE_GEOMETRY,
+                         &pipeline->gs_prog_data.base.base);
+
+      if (gp->Base.OutputsWritten & VARYING_SLOT_PSIZ)
+         pipeline->writes_point_size = true;
+   } else {
+      pipeline->gs_vec4 = NO_KERNEL;
+   }
+
+   if (pipeline->shaders[VK_SHADER_STAGE_FRAGMENT]) {
+      struct brw_wm_prog_key wm_key;
+      struct gl_fragment_program *fp = (struct gl_fragment_program *)
+         program->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
+      struct brw_fragment_program *bfp = brw_fragment_program(fp);
+
+      brw_wm_populate_key(brw, bfp, &wm_key);
+
+      success = really_do_wm_prog(brw, program, bfp, &wm_key, pipeline);
+      fail_if(!success, "do_wm_prog failed\n");
+      add_compiled_stage(pipeline, VK_SHADER_STAGE_FRAGMENT,
+                         &pipeline->wm_prog_data.base);
+   }
+
+   if (pipeline->shaders[VK_SHADER_STAGE_COMPUTE]) {
+      struct brw_cs_prog_key cs_key;
+      struct gl_compute_program *cp = (struct gl_compute_program *)
+         program->_LinkedShaders[MESA_SHADER_COMPUTE]->Program;
+      struct brw_compute_program *bcp = brw_compute_program(cp);
+
+      brw_cs_populate_key(brw, bcp, &cs_key);
+
+      success = brw_codegen_cs_prog(brw, program, bcp, &cs_key, pipeline);
+      fail_if(!success, "brw_codegen_cs_prog failed\n");
+      add_compiled_stage(pipeline, VK_SHADER_STAGE_COMPUTE,
+                         &pipeline->cs_prog_data.base);
+   }
+
+   /* XXX: Deleting the shader is broken with our current SPIR-V hacks.  We
+    * need to fix this ASAP.
+    */
+   if (!all_spirv)
+      brw->ctx.Driver.DeleteShaderProgram(&brw->ctx, program);
+
+   struct anv_device *device = compiler->device;
+   while (device->scratch_block_pool.bo.size < pipeline->total_scratch)
+      anv_block_pool_alloc(&device->scratch_block_pool);
+
+   gen7_compute_urb_partition(pipeline);
+
+   return 0;
+}
+
+/* This badly named function frees the struct anv_pipeline data that the compiler
+ * allocates.  Currently just the prog_data structs.
+ */
+void
+anv_compiler_free(struct anv_pipeline *pipeline)
+{
+   for (uint32_t stage = 0; stage < VK_SHADER_STAGE_NUM; stage++) {
+      if (pipeline->prog_data[stage]) {
+         free(pipeline->prog_data[stage]->map_entries);
+         ralloc_free(pipeline->prog_data[stage]->param);
+         ralloc_free(pipeline->prog_data[stage]->pull_param);
+      }
+   }
+}
+
+}
diff --git a/src/vulkan/anv_device.c b/src/vulkan/anv_device.c
new file mode 100644 (file)
index 0000000..1847303
--- /dev/null
@@ -0,0 +1,2390 @@
+/*
+ * 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"
+
+static int
+anv_env_get_int(const char *name)
+{
+   const char *val = getenv(name);
+
+   if (!val)
+      return 0;
+
+   return strtol(val, NULL, 0);
+}
+
+static void
+anv_physical_device_finish(struct anv_physical_device *device)
+{
+   if (device->fd >= 0)
+      close(device->fd);
+}
+
+static VkResult
+anv_physical_device_init(struct anv_physical_device *device,
+                         struct anv_instance *instance,
+                         const char *path)
+{
+   device->fd = open(path, O_RDWR | O_CLOEXEC);
+   if (device->fd < 0)
+      return vk_error(VK_ERROR_UNAVAILABLE);
+
+   device->instance = instance;
+   device->path = path;
+   
+   device->chipset_id = anv_env_get_int("INTEL_DEVID_OVERRIDE");
+   device->no_hw = false;
+   if (device->chipset_id) {
+      /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */
+      device->no_hw = true;
+   } else {
+      device->chipset_id = anv_gem_get_param(device->fd, I915_PARAM_CHIPSET_ID);
+   }
+   if (!device->chipset_id)
+      goto fail;
+
+   device->name = brw_get_device_name(device->chipset_id);
+   device->info = brw_get_device_info(device->chipset_id, -1);
+   if (!device->info)
+      goto fail;
+   
+   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_WAIT_TIMEOUT))
+      goto fail;
+
+   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_EXECBUF2))
+      goto fail;
+
+   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_LLC))
+      goto fail;
+
+   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_EXEC_CONSTANTS))
+      goto fail;
+   
+   return VK_SUCCESS;
+   
+fail:
+   anv_physical_device_finish(device);
+   return vk_error(VK_ERROR_UNAVAILABLE);
+}
+
+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
+};
+
+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->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->pAllocUserData = alloc_callbacks->pUserData;
+   instance->pfnAlloc = alloc_callbacks->pfnAlloc;
+   instance->pfnFree = alloc_callbacks->pfnFree;
+   instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
+   instance->physicalDeviceCount = 0;
+
+   *pInstance = anv_instance_to_handle(instance);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyInstance(
+    VkInstance                                  _instance)
+{
+   ANV_FROM_HANDLE(anv_instance, instance, _instance);
+
+   if (instance->physicalDeviceCount > 0) {
+      anv_physical_device_finish(&instance->physicalDevice);
+   }
+
+   instance->pfnFree(instance->pAllocUserData, instance);
+
+   return VK_SUCCESS;
+}
+
+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_SUCCESS)
+         return result;
+
+      instance->physicalDeviceCount = 1;
+   }
+
+   /* 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,
+      .instancedDrawIndirect                    = true,
+      .depthClip                                = false,
+      .depthBiasClamp                           = false,
+      .fillModeNonSolid                         = true,
+      .depthBounds                              = false,
+      .wideLines                                = true,
+      .largePoints                              = true,
+      .textureCompressionETC2                   = true,
+      .textureCompressionASTC_LDR               = true,
+      .textureCompressionBC                     = true,
+      .pipelineStatisticsQuery                  = true,
+      .vertexSideEffects                        = false,
+      .tessellationSideEffects                  = false,
+      .geometrySideEffects                      = false,
+      .fragmentSideEffects                      = false,
+      .shaderTessellationPointSize              = false,
+      .shaderGeometryPointSize                  = true,
+      .shaderTextureGatherExtended              = true,
+      .shaderStorageImageExtendedFormats        = false,
+      .shaderStorageImageMultisample            = false,
+      .shaderStorageBufferArrayConstantIndexing = false,
+      .shaderStorageImageArrayConstantIndexing  = false,
+      .shaderUniformBufferArrayDynamicIndexing  = true,
+      .shaderSampledImageArrayDynamicIndexing   = false,
+      .shaderStorageBufferArrayDynamicIndexing  = false,
+      .shaderStorageImageArrayDynamicIndexing   = false,
+      .shaderClipDistance                       = false,
+      .shaderCullDistance                       = false,
+      .shaderFloat64                            = false,
+      .shaderInt64                              = false,
+      .shaderFloat16                            = false,
+      .shaderInt16                              = false,
+   };
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceLimits(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceLimits*                     pLimits)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   const struct brw_device_info *devinfo = physical_device->info;
+
+   anv_finishme("Get correct values for PhysicalDeviceLimits");
+
+   *pLimits = (VkPhysicalDeviceLimits) {
+      .maxImageDimension1D                      = (1 << 14),
+      .maxImageDimension2D                      = (1 << 14),
+      .maxImageDimension3D                      = (1 << 10),
+      .maxImageDimensionCube                    = (1 << 14),
+      .maxImageArrayLayers                      = (1 << 10),
+      .maxTexelBufferSize                       = (1 << 14),
+      .maxUniformBufferSize                     = UINT32_MAX,
+      .maxStorageBufferSize                     = UINT32_MAX,
+      .maxPushConstantsSize                     = 128,
+      .maxMemoryAllocationCount                 = UINT32_MAX,
+      .bufferImageGranularity                   = 64, /* A cache line */
+      .maxBoundDescriptorSets                   = MAX_SETS,
+      .maxDescriptorSets                        = UINT32_MAX,
+      .maxPerStageDescriptorSamplers            = 64,
+      .maxPerStageDescriptorUniformBuffers      = 64,
+      .maxPerStageDescriptorStorageBuffers      = 64,
+      .maxPerStageDescriptorSampledImages       = 64,
+      .maxPerStageDescriptorStorageImages       = 64,
+      .maxDescriptorSetSamplers                 = 256,
+      .maxDescriptorSetUniformBuffers           = 256,
+      .maxDescriptorSetStorageBuffers           = 256,
+      .maxDescriptorSetSampledImages            = 256,
+      .maxDescriptorSetStorageImages            = 256,
+      .maxVertexInputAttributes                 = 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                             = 16,
+      .maxDynamicViewportStates                 = UINT32_MAX,
+      .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),
+   };
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkPhysicalDeviceProperties*                 pProperties)
+{
+   ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
+
+   *pProperties = (VkPhysicalDeviceProperties) {
+      .apiVersion = 1,
+      .driverVersion = 1,
+      .vendorId = 0x8086,
+      .deviceId = pdevice->chipset_id,
+      .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
+   };
+
+   strcpy(pProperties->deviceName, pdevice->name);
+   snprintf((char *)pProperties->pipelineCacheUUID, VK_UUID_LENGTH,
+            "anv-%s", MESA_GIT_SHA1 + 4);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceQueueCount(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t*                                   pCount)
+{
+   *pCount = 1;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceQueueProperties(
+    VkPhysicalDevice                            physicalDevice,
+    uint32_t                                    count,
+    VkPhysicalDeviceQueueProperties*            pQueueProperties)
+{
+   assert(count == 1);
+
+   *pQueueProperties = (VkPhysicalDeviceQueueProperties) {
+      .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);
+
+   size_t aperture_size;
+   size_t heap_size;
+
+   if (anv_gem_get_aperture(physical_device, &aperture_size) == -1)
+      return vk_error(VK_ERROR_UNAVAILABLE);
+
+   /* Reserve some wiggle room for the driver by exposing only 75% of the
+    * aperture to the heap.
+    */
+   heap_size = 3 * 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,
+   };
+
+   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 void
+parse_debug_flags(struct anv_device *device)
+{
+   const char *debug, *p, *end;
+
+   debug = getenv("INTEL_DEBUG");
+   device->dump_aub = false;
+   if (debug) {
+      for (p = debug; *p; p = end + 1) {
+         end = strchrnul(p, ',');
+         if (end - p == 3 && memcmp(p, "aub", 3) == 0)
+            device->dump_aub = true;
+         if (end - p == 5 && memcmp(p, "no_hw", 5) == 0)
+            device->no_hw = true;
+         if (*end == '\0')
+            break;
+      }
+   }
+}
+
+static VkResult
+anv_queue_init(struct anv_device *device, struct anv_queue *queue)
+{
+   queue->device = device;
+   queue->pool = &device->surface_state_pool;
+
+   queue->completed_serial = anv_state_pool_alloc(queue->pool, 4, 4);
+   if (queue->completed_serial.map == NULL)
+      return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+
+   *(uint32_t *)queue->completed_serial.map = 0;
+   queue->next_serial = 1;
+
+   return VK_SUCCESS;
+}
+
+static void
+anv_queue_finish(struct anv_queue *queue)
+{
+#ifdef HAVE_VALGRIND
+   /* This gets torn down with the device so we only need to do this if
+    * valgrind is present.
+    */
+   anv_state_pool_free(queue->pool, queue->completed_serial);
+#endif
+}
+
+static void
+anv_device_init_border_colors(struct anv_device *device)
+{
+   static const VkClearColorValue border_colors[] = {
+      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .f32 = { 0.0, 0.0, 0.0, 0.0 } },
+      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =       { .f32 = { 0.0, 0.0, 0.0, 1.0 } },
+      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =       { .f32 = { 1.0, 1.0, 1.0, 1.0 } },
+      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =    { .u32 = { 0, 0, 0, 0 } },
+      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =         { .u32 = { 0, 0, 0, 1 } },
+      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =         { .u32 = { 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));
+}
+
+static const uint32_t BATCH_SIZE = 8192;
+
+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);
+
+   device = instance->pfnAlloc(instance->pAllocUserData,
+                               sizeof(*device), 8,
+                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!device)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   device->no_hw = physical_device->no_hw;
+   parse_debug_flags(device);
+
+   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;
+
+   anv_bo_pool_init(&device->batch_bo_pool, device, 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, 2048);
+   anv_block_pool_init(&device->surface_state_block_pool, device, 2048);
+
+   anv_state_pool_init(&device->surface_state_pool,
+                       &device->surface_state_block_pool);
+
+   anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
+
+   device->info = *physical_device->info;
+
+   device->compiler = anv_compiler_create(device);
+   device->aub_writer = NULL;
+
+   pthread_mutex_init(&device->mutex, NULL);
+
+   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_UNAVAILABLE);
+}
+
+VkResult anv_DestroyDevice(
+    VkDevice                                    _device)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   anv_compiler_destroy(device->compiler);
+
+   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_bo_pool_finish(&device->batch_bo_pool);
+   anv_block_pool_finish(&device->dynamic_state_block_pool);
+   anv_block_pool_finish(&device->instruction_block_pool);
+   anv_block_pool_finish(&device->surface_state_block_pool);
+
+   close(device->fd);
+
+   if (device->aub_writer)
+      anv_aub_writer_destroy(device->aub_writer);
+
+   anv_device_free(device, device);
+
+   return VK_SUCCESS;
+}
+
+static const VkExtensionProperties global_extensions[] = {
+   {
+      .extName = "VK_WSI_LunarG",
+      .specVersion = 3
+   }
+};
+
+VkResult anv_GetGlobalExtensionProperties(
+    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_GetPhysicalDeviceExtensionProperties(
+    VkPhysicalDevice                            physicalDevice,
+    const char*                                 pLayerName,
+    uint32_t*                                   pCount,
+    VkExtensionProperties*                      pProperties)
+{
+   if (pProperties == NULL) {
+      *pCount = 0;
+      return VK_SUCCESS;
+   }
+
+   /* None supported at this time */
+   return vk_error(VK_ERROR_INVALID_EXTENSION);
+}
+
+VkResult anv_GetGlobalLayerProperties(
+    uint32_t*                                   pCount,
+    VkLayerProperties*                          pProperties)
+{
+   if (pProperties == NULL) {
+      *pCount = 0;
+      return VK_SUCCESS;
+   }
+
+   /* None supported at this time */
+   return vk_error(VK_ERROR_INVALID_LAYER);
+}
+
+VkResult anv_GetPhysicalDeviceLayerProperties(
+    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_INVALID_LAYER);
+}
+
+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]);
+
+      if (device->dump_aub)
+         anv_cmd_buffer_dump(cmd_buffer);
+
+      if (!device->no_hw) {
+         ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf);
+         if (ret != 0)
+            return vk_error(VK_ERROR_UNKNOWN);
+
+         if (fence) {
+            ret = anv_gem_execbuffer(device, &fence->execbuf);
+            if (ret != 0)
+               return vk_error(VK_ERROR_UNKNOWN);
+         }
+
+         for (uint32_t i = 0; i < cmd_buffer->exec2_bo_count; i++)
+            cmd_buffer->exec2_bos[i]->offset = cmd_buffer->exec2_objects[i].offset;
+      } else {
+         *(uint32_t *)queue->completed_serial.map = cmd_buffer->serial;
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_QueueWaitIdle(
+    VkQueue                                     _queue)
+{
+   ANV_FROM_HANDLE(anv_queue, queue, _queue);
+
+   return vkDeviceWaitIdle(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, GEN8_MI_BATCH_BUFFER_END);
+   anv_batch_emit(&batch, GEN8_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;
+
+   if (!device->no_hw) {
+      ret = anv_gem_execbuffer(device, &execbuf);
+      if (ret != 0) {
+         result = vk_error(VK_ERROR_UNKNOWN);
+         goto fail;
+      }
+
+      timeout = INT64_MAX;
+      ret = anv_gem_wait(device, bo->gem_handle, &timeout);
+      if (ret != 0) {
+         result = vk_error(VK_ERROR_UNKNOWN);
+         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 device->instance->pfnAlloc(device->instance->pAllocUserData,
+                                     size,
+                                     alignment,
+                                     allocType);
+}
+
+void
+anv_device_free(struct anv_device *             device,
+                void *                          mem)
+{
+   if (mem == NULL)
+      return;
+
+   return device->instance->pfnFree(device->instance->pAllocUserData,
+                                    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);
+
+   if (pAllocInfo->memoryTypeIndex != 0) {
+      /* We support exactly one memory heap. */
+      return vk_error(VK_ERROR_INVALID_VALUE);
+   }
+
+   /* 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;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+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;
+}
+
+VkResult anv_UnmapMemory(
+    VkDevice                                    _device,
+    VkDeviceMemory                              _mem)
+{
+   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
+
+   anv_gem_munmap(mem->map, mem->map_size);
+
+   return VK_SUCCESS;
+}
+
+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, GEN8_MI_BATCH_BUFFER_END);
+   anv_batch_emit(&batch, GEN8_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;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+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);
+   int64_t t = timeout;
+   int ret;
+
+   /* FIXME: handle !waitAll */
+
+   for (uint32_t i = 0; i < fenceCount; i++) {
+      ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
+      ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
+      if (ret == -1 && errno == ETIME)
+         return VK_TIMEOUT;
+      else if (ret == -1)
+         return vk_error(VK_ERROR_UNKNOWN);
+   }
+
+   return VK_SUCCESS;
+}
+
+// Queue semaphore functions
+
+VkResult anv_CreateSemaphore(
+    VkDevice                                    device,
+    const VkSemaphoreCreateInfo*                pCreateInfo,
+    VkSemaphore*                                pSemaphore)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_DestroySemaphore(
+    VkDevice                                    device,
+    VkSemaphore                                 semaphore)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+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);
+}
+
+VkResult anv_DestroyEvent(
+    VkDevice                                    device,
+    VkEvent                                     event)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+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;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+// Buffer view functions
+
+void
+anv_fill_buffer_surface_state(void *state, VkFormat format,
+                              uint32_t offset, uint32_t range)
+{
+   const struct anv_format *info;
+
+   info = anv_format_for_vk_format(format);
+   /* This assumes RGBA float format. */
+   uint32_t stride = 4;
+   uint32_t num_elements = range / stride;
+
+   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = SURFTYPE_BUFFER,
+      .SurfaceArray = false,
+      .SurfaceFormat = info->surface_format,
+      .SurfaceVerticalAlignment = VALIGN4,
+      .SurfaceHorizontalAlignment = HALIGN4,
+      .TileMode = LINEAR,
+      .VerticalLineStride = 0,
+      .VerticalLineStrideOffset = 0,
+      .SamplerL2BypassModeDisable = true,
+      .RenderCacheReadWriteMode = WriteOnlyCache,
+      .MemoryObjectControlState = GEN8_MOCS,
+      .BaseMipLevel = 0.0,
+      .SurfaceQPitch = 0,
+      .Height = (num_elements >> 7) & 0x3fff,
+      .Width = num_elements & 0x7f,
+      .Depth = (num_elements >> 21) & 0x3f,
+      .SurfacePitch = stride - 1,
+      .MinimumArrayElement = 0,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .XOffset = 0,
+      .YOffset = 0,
+      .SurfaceMinLOD = 0,
+      .MIPCountLOD = 0,
+      .AuxiliarySurfaceMode = AUX_NONE,
+      .RedClearColor = 0,
+      .GreenClearColor = 0,
+      .BlueClearColor = 0,
+      .AlphaClearColor = 0,
+      .ShaderChannelSelectRed = SCS_RED,
+      .ShaderChannelSelectGreen = SCS_GREEN,
+      .ShaderChannelSelectBlue = SCS_BLUE,
+      .ShaderChannelSelectAlpha = SCS_ALPHA,
+      .ResourceMinLOD = 0.0,
+      /* FIXME: We assume that the image must be bound at this time. */
+      .SurfaceBaseAddress = { NULL, offset },
+   };
+
+   GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
+}
+
+VkResult anv_CreateBufferView(
+    VkDevice                                    _device,
+    const VkBufferViewCreateInfo*               pCreateInfo,
+    VkBufferView*                               pView)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
+   struct anv_buffer_view *bview;
+   struct anv_surface_view *view;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
+
+   bview = anv_device_alloc(device, sizeof(*view), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (bview == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   view = &bview->view;
+   view->bo = buffer->bo;
+   view->offset = buffer->offset + pCreateInfo->offset;
+   view->surface_state =
+      anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+   view->format = pCreateInfo->format;
+   view->range = pCreateInfo->range;
+
+   anv_fill_buffer_surface_state(view->surface_state.map,
+                                 pCreateInfo->format,
+                                 view->offset, pCreateInfo->range);
+
+   *pView = anv_buffer_view_to_handle(bview);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyBufferView(
+    VkDevice                                    _device,
+    VkBufferView                                _bview)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_buffer_view, bview, _bview);
+
+   anv_surface_view_fini(device, &bview->view);
+   anv_device_free(device, bview);
+
+   return VK_SUCCESS;
+}
+
+// Sampler functions
+
+VkResult anv_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_WRAP]                     = TCM_WRAP,
+      [VK_TEX_ADDRESS_MIRROR]                   = TCM_MIRROR,
+      [VK_TEX_ADDRESS_CLAMP]                    = TCM_CLAMP,
+      [VK_TEX_ADDRESS_MIRROR_ONCE]              = TCM_MIRROR_ONCE,
+      [VK_TEX_ADDRESS_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 = 0,
+      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
+      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
+      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
+   };
+
+   GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
+
+   *pSampler = anv_sampler_to_handle(sampler);
+
+   return VK_SUCCESS;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+// 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;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
+
+   uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
+   uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
+   uint32_t num_dynamic_buffers = 0;
+   uint32_t count = 0;
+   uint32_t stages = 0;
+   uint32_t s;
+
+   for (uint32_t i = 0; i < pCreateInfo->count; i++) {
+      switch (pCreateInfo->pBinding[i].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
+            sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
+         break;
+      default:
+         break;
+      }
+
+      switch (pCreateInfo->pBinding[i].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[i].stageFlags)
+            surface_count[s] += pCreateInfo->pBinding[i].arraySize;
+         break;
+      default:
+         break;
+      }
+
+      switch (pCreateInfo->pBinding[i].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+         num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
+         break;
+      default:
+         break;
+      }
+
+      stages |= pCreateInfo->pBinding[i].stageFlags;
+      count += pCreateInfo->pBinding[i].arraySize;
+   }
+
+   uint32_t sampler_total = 0;
+   uint32_t surface_total = 0;
+   for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+      sampler_total += sampler_count[s];
+      surface_total += surface_count[s];
+   }
+
+   size_t size = sizeof(*set_layout) +
+      (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
+   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);
+
+   set_layout->num_dynamic_buffers = num_dynamic_buffers;
+   set_layout->count = count;
+   set_layout->shader_stages = stages;
+
+   struct anv_descriptor_slot *p = set_layout->entries;
+   struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
+   struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
+   for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+      set_layout->stage[s].surface_count = surface_count[s];
+      set_layout->stage[s].surface_start = surface[s] = p;
+      p += surface_count[s];
+      set_layout->stage[s].sampler_count = sampler_count[s];
+      set_layout->stage[s].sampler_start = sampler[s] = p;
+      p += sampler_count[s];
+   }
+
+   uint32_t descriptor = 0;
+   int8_t dynamic_slot = 0;
+   bool is_dynamic;
+   for (uint32_t i = 0; i < pCreateInfo->count; i++) {
+      switch (pCreateInfo->pBinding[i].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
+            for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
+               sampler[s]->index = descriptor + j;
+               sampler[s]->dynamic_slot = -1;
+               sampler[s]++;
+            }
+         break;
+      default:
+         break;
+      }
+
+      switch (pCreateInfo->pBinding[i].descriptorType) {
+      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+         is_dynamic = true;
+         break;
+      default:
+         is_dynamic = false;
+         break;
+      }
+
+      switch (pCreateInfo->pBinding[i].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[i].stageFlags)
+            for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
+               surface[s]->index = descriptor + j;
+               if (is_dynamic)
+                  surface[s]->dynamic_slot = dynamic_slot + j;
+               else
+                  surface[s]->dynamic_slot = -1;
+               surface[s]++;
+            }
+         break;
+      default:
+         break;
+      }
+
+      if (is_dynamic)
+         dynamic_slot += pCreateInfo->pBinding[i].arraySize;
+
+      descriptor += pCreateInfo->pBinding[i].arraySize;
+   }
+
+   *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
+
+   return VK_SUCCESS;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_CreateDescriptorPool(
+    VkDevice                                    device,
+    VkDescriptorPoolUsage                       poolUsage,
+    uint32_t                                    maxSets,
+    const VkDescriptorPoolCreateInfo*           pCreateInfo,
+    VkDescriptorPool*                           pDescriptorPool)
+{
+   anv_finishme("VkDescriptorPool is a stub");
+   pDescriptorPool->handle = 1;
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyDescriptorPool(
+    VkDevice                                    _device,
+    VkDescriptorPool                            _pool)
+{
+   anv_finishme("VkDescriptorPool is a stub: free the pool's descriptor sets");
+   return VK_SUCCESS;
+}
+
+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->count * 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);
+
+   *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,
+    uint32_t*                                   pCount)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   VkResult result;
+   struct anv_descriptor_set *set;
+
+   for (uint32_t 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) {
+         *pCount = i;
+         return result;
+      }
+
+      pDescriptorSets[i] = anv_descriptor_set_to_handle(set);
+   }
+
+   *pCount = count;
+
+   return VK_SUCCESS;
+}
+
+VkResult 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);
+
+      switch (write->descriptorType) {
+      case VK_DESCRIPTOR_TYPE_SAMPLER:
+      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+         for (uint32_t j = 0; j < write->count; j++) {
+            set->descriptors[write->destBinding + j].sampler =
+               anv_sampler_from_handle(write->pDescriptors[j].sampler);
+         }
+
+         if (write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
+            break;
+
+         /* fallthrough */
+
+      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);
+            set->descriptors[write->destBinding + j].view = &iview->view;
+         }
+         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++) {
+            ANV_FROM_HANDLE(anv_buffer_view, bview,
+                            write->pDescriptors[j].bufferView);
+            set->descriptors[write->destBinding + j].view = &bview->view;
+         }
+
+      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];
+      }
+   }
+
+   return VK_SUCCESS;
+}
+
+// State object functions
+
+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;
+}
+
+VkResult anv_CreateDynamicViewportState(
+    VkDevice                                    _device,
+    const VkDynamicViewportStateCreateInfo*     pCreateInfo,
+    VkDynamicViewportState*                     pState)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_dynamic_vp_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   unsigned count = pCreateInfo->viewportAndScissorCount;
+   state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
+                                            count * 64, 64);
+   state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
+                                       count * 8, 32);
+   state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
+                                         count * 32, 32);
+
+   for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
+      const VkViewport *vp = &pCreateInfo->pViewports[i];
+      const VkRect2D *s = &pCreateInfo->pScissors[i];
+
+      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 GEN8_CC_VIEWPORT cc_viewport = {
+         .MinimumDepth = vp->minDepth,
+         .MaximumDepth = vp->maxDepth
+      };
+
+      /* 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 GEN8_SCISSOR_RECT empty_scissor = {
+         .ScissorRectangleYMin = 1,
+         .ScissorRectangleXMin = 1,
+         .ScissorRectangleYMax = 0,
+         .ScissorRectangleXMax = 0
+      };
+
+      const int max = 0xffff;
+      struct GEN8_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)
+      };
+
+      GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
+      GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
+
+      if (s->extent.width <= 0 || s->extent.height <= 0) {
+         GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
+      } else {
+         GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
+      }
+   }
+
+   *pState = anv_dynamic_vp_state_to_handle(state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyDynamicViewportState(
+    VkDevice                                    _device,
+    VkDynamicViewportState                      _vp_state)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, _vp_state);
+
+   anv_state_pool_free(&device->dynamic_state_pool, vp_state->sf_clip_vp);
+   anv_state_pool_free(&device->dynamic_state_pool, vp_state->cc_vp);
+   anv_state_pool_free(&device->dynamic_state_pool, vp_state->scissor);
+
+   anv_device_free(device, vp_state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_CreateDynamicRasterState(
+    VkDevice                                    _device,
+    const VkDynamicRasterStateCreateInfo*       pCreateInfo,
+    VkDynamicRasterState*                       pState)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_dynamic_rs_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct GEN8_3DSTATE_SF sf = {
+      GEN8_3DSTATE_SF_header,
+      .LineWidth = pCreateInfo->lineWidth,
+   };
+
+   GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
+
+   bool enable_bias = pCreateInfo->depthBias != 0.0f ||
+      pCreateInfo->slopeScaledDepthBias != 0.0f;
+   struct GEN8_3DSTATE_RASTER raster = {
+      .GlobalDepthOffsetEnableSolid = enable_bias,
+      .GlobalDepthOffsetEnableWireframe = enable_bias,
+      .GlobalDepthOffsetEnablePoint = enable_bias,
+      .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
+      .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
+      .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
+   };
+
+   GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
+
+   *pState = anv_dynamic_rs_state_to_handle(state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyDynamicRasterState(
+    VkDevice                                    _device,
+    VkDynamicRasterState                        _rs_state)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, _rs_state);
+
+   anv_device_free(device, rs_state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_CreateDynamicColorBlendState(
+    VkDevice                                    _device,
+    const VkDynamicColorBlendStateCreateInfo*   pCreateInfo,
+    VkDynamicColorBlendState*                   pState)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_dynamic_cb_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct GEN8_COLOR_CALC_STATE color_calc_state = {
+      .BlendConstantColorRed = pCreateInfo->blendConst[0],
+      .BlendConstantColorGreen = pCreateInfo->blendConst[1],
+      .BlendConstantColorBlue = pCreateInfo->blendConst[2],
+      .BlendConstantColorAlpha = pCreateInfo->blendConst[3]
+   };
+
+   GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
+
+   *pState = anv_dynamic_cb_state_to_handle(state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyDynamicColorBlendState(
+    VkDevice                                    _device,
+    VkDynamicColorBlendState                    _cb_state)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, _cb_state);
+
+   anv_device_free(device, cb_state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_CreateDynamicDepthStencilState(
+    VkDevice                                    _device,
+    const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
+    VkDynamicDepthStencilState*                 pState)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_dynamic_ds_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+      GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
+
+      /* Is this what we need to do? */
+      .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
+
+      .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
+      .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
+
+      .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
+      .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
+   };
+
+   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
+                                      &wm_depth_stencil);
+
+   struct GEN8_COLOR_CALC_STATE color_calc_state = {
+      .StencilReferenceValue = pCreateInfo->stencilFrontRef,
+      .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
+   };
+
+   GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
+
+   *pState = anv_dynamic_ds_state_to_handle(state);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyDynamicDepthStencilState(
+    VkDevice                                    _device,
+    VkDynamicDepthStencilState                  _ds_state)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, _ds_state);
+
+   anv_device_free(device, ds_state);
+
+   return VK_SUCCESS;
+}
+
+// Command buffer functions
+
+VkResult anv_CreateCommandPool(
+    VkDevice                                    device,
+    const VkCmdPoolCreateInfo*                  pCreateInfo,
+    VkCmdPool*                                  pCmdPool)
+{
+   pCmdPool->handle = 7;
+
+   stub_return(VK_SUCCESS);
+}
+
+VkResult anv_DestroyCommandPool(
+    VkDevice                                    device,
+    VkCmdPool                                   cmdPool)
+{
+   stub_return(VK_SUCCESS);
+}
+
+VkResult anv_ResetCommandPool(
+    VkDevice                                    device,
+    VkCmdPool                                   cmdPool,
+    VkCmdPoolResetFlags                         flags)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+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_attachment_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++) {
+      ANV_FROM_HANDLE(anv_attachment_view, view,
+                      pCreateInfo->pAttachments[i].view);
+
+      framebuffer->attachments[i] = view;
+   }
+
+   framebuffer->width = pCreateInfo->width;
+   framebuffer->height = pCreateInfo->height;
+   framebuffer->layers = pCreateInfo->layers;
+
+   anv_CreateDynamicViewportState(anv_device_to_handle(device),
+      &(VkDynamicViewportStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO,
+         .viewportAndScissorCount = 1,
+         .pViewports = (VkViewport[]) {
+            {
+               .originX = 0,
+               .originY = 0,
+               .width = pCreateInfo->width,
+               .height = pCreateInfo->height,
+               .minDepth = 0,
+               .maxDepth = 1
+            },
+         },
+         .pScissors = (VkRect2D[]) {
+            { {  0,  0 },
+              { pCreateInfo->width, pCreateInfo->height } },
+         }
+      },
+      &framebuffer->vp_state);
+
+   *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyFramebuffer(
+    VkDevice                                    _device,
+    VkFramebuffer                               _fb)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
+
+   anv_DestroyDynamicViewportState(anv_device_to_handle(device),
+                                   fb->vp_state);
+   anv_device_free(device, fb);
+
+   return VK_SUCCESS;
+}
+
+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;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
+
+   size = sizeof(*pass) +
+      pCreateInfo->subpassCount * sizeof(struct anv_subpass);
+   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;
+
+   size = pCreateInfo->attachmentCount * sizeof(*pass->attachments);
+   pass->attachments = anv_device_alloc(device, size, 8,
+                                        VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      pass->attachments[i].format = pCreateInfo->pAttachments[i].format;
+      pass->attachments[i].samples = pCreateInfo->pAttachments[i].samples;
+      pass->attachments[i].load_op = pCreateInfo->pAttachments[i].loadOp;
+      pass->attachments[i].stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
+      // pass->attachments[i].store_op = pCreateInfo->pAttachments[i].storeOp;
+      // pass->attachments[i].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->inputAttachments[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->colorAttachments[j].attachment;
+         }
+      }
+
+      if (desc->resolveAttachments) {
+         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->resolveAttachments[j].attachment;
+         }
+      }
+
+      subpass->depth_stencil_attachment = desc->depthStencilAttachment.attachment;
+   }
+
+   *pRenderPass = anv_render_pass_to_handle(pass);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_DestroyRenderPass(
+    VkDevice                                    _device,
+    VkRenderPass                                _pass)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
+
+   anv_device_free(device, pass->attachments);
+
+   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);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetRenderAreaGranularity(
+    VkDevice                                    device,
+    VkRenderPass                                renderPass,
+    VkExtent2D*                                 pGranularity)
+{
+   *pGranularity = (VkExtent2D) { 1, 1 };
+
+   return VK_SUCCESS;
+}
+
+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_entrypoints_gen.py b/src/vulkan/anv_entrypoints_gen.py
new file mode 100644 (file)
index 0000000..96c4884
--- /dev/null
@@ -0,0 +1,269 @@
+# 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:
+    for type, name, args, num, h in entrypoints:
+        print "%s anv_%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;
+   void *function;
+   void *validate;
+};
+
+/* 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.
+ */
+"""
+
+for type, name, args, num, h in entrypoints:
+    print "%s anv_validate_%s%s __attribute__ ((weak));" % (type, name, args)
+
+# 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, anv_%s, anv_validate_%s }," % (offsets[num], h, name, 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 void * __attribute__ ((noinline))
+resolve_entrypoint(uint32_t index)
+{
+   if (enable_validate && entrypoints[index].validate)
+      return entrypoints[index].validate;
+
+   return entrypoints[index].function;
+}
+"""
+
+# 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 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 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..3cbcff5
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * 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"
+
+#define UNSUPPORTED 0xffff
+
+#define fmt(__vk_fmt, ...) \
+   [__vk_fmt] = { .name = #__vk_fmt, __VA_ARGS__ }
+
+static const struct anv_format anv_formats[] = {
+   fmt(VK_FORMAT_UNDEFINED,               RAW,                    .cpp = 1,   .num_channels = 1),
+   fmt(VK_FORMAT_R4G4_UNORM,              UNSUPPORTED),
+   fmt(VK_FORMAT_R4G4_USCALED,            UNSUPPORTED),
+   fmt(VK_FORMAT_R4G4B4A4_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_R4G4B4A4_USCALED,        UNSUPPORTED),
+   fmt(VK_FORMAT_R5G6B5_UNORM,            UNSUPPORTED),
+   fmt(VK_FORMAT_R5G6B5_USCALED,          UNSUPPORTED),
+   fmt(VK_FORMAT_R5G5B5A1_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_R5G5B5A1_USCALED,        UNSUPPORTED),
+   fmt(VK_FORMAT_R8_UNORM,                R8_UNORM,               .cpp = 1,   .num_channels = 1),
+   fmt(VK_FORMAT_R8_SNORM,                R8_SNORM,               .cpp = 1,   .num_channels = 1,),
+   fmt(VK_FORMAT_R8_USCALED,              R8_USCALED,             .cpp = 1,   .num_channels = 1),
+   fmt(VK_FORMAT_R8_SSCALED,              R8_SSCALED,             .cpp = 1,   .num_channels = 1),
+   fmt(VK_FORMAT_R8_UINT,                 R8_UINT,                .cpp = 1,   .num_channels = 1),
+   fmt(VK_FORMAT_R8_SINT,                 R8_SINT,                .cpp = 1,   .num_channels = 1),
+   fmt(VK_FORMAT_R8_SRGB,                 UNSUPPORTED),
+   fmt(VK_FORMAT_R8G8_UNORM,              R8G8_UNORM,             .cpp = 2,   .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SNORM,              R8G8_SNORM,             .cpp = 2,   .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_USCALED,            R8G8_USCALED,           .cpp = 2,   .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SSCALED,            R8G8_SSCALED,           .cpp = 2,   .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_UINT,               R8G8_UINT,              .cpp = 2,   .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SINT,               R8G8_SINT,              .cpp = 2,   .num_channels = 2),
+   fmt(VK_FORMAT_R8G8_SRGB,               UNSUPPORTED), /* L8A8_UNORM_SRGB */
+   fmt(VK_FORMAT_R8G8B8_UNORM,            R8G8B8X8_UNORM,         .cpp = 3,   .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SNORM,            R8G8B8_SNORM,           .cpp = 3,   .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_USCALED,          R8G8B8_USCALED,         .cpp = 3,   .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SSCALED,          R8G8B8_SSCALED,         .cpp = 3,   .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_UINT,             R8G8B8_UINT,            .cpp = 3,   .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SINT,             R8G8B8_SINT,            .cpp = 3,   .num_channels = 3),
+   fmt(VK_FORMAT_R8G8B8_SRGB,             UNSUPPORTED), /* B8G8R8A8_UNORM_SRGB */
+   fmt(VK_FORMAT_R8G8B8A8_UNORM,          R8G8B8A8_UNORM,         .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SNORM,          R8G8B8A8_SNORM,         .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_USCALED,        R8G8B8A8_USCALED,       .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SSCALED,        R8G8B8A8_SSCALED,       .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_UINT,           R8G8B8A8_UINT,          .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SINT,           R8G8B8A8_SINT,          .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R8G8B8A8_SRGB,           R8G8B8A8_UNORM_SRGB,    .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_UNORM,       R10G10B10A2_UNORM,      .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_SNORM,       R10G10B10A2_SNORM,      .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_USCALED,     R10G10B10A2_USCALED,    .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_SSCALED,     R10G10B10A2_SSCALED,    .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_UINT,        R10G10B10A2_UINT,       .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R10G10B10A2_SINT,        R10G10B10A2_SINT,       .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_R16_UNORM,               R16_UNORM,              .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16_SNORM,               R16_SNORM,              .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16_USCALED,             R16_USCALED,            .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16_SSCALED,             R16_SSCALED,            .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16_UINT,                R16_UINT,               .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16_SINT,                R16_SINT,               .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16_SFLOAT,              R16_FLOAT,              .cpp = 2,   .num_channels = 1),
+   fmt(VK_FORMAT_R16G16_UNORM,            R16G16_UNORM,           .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SNORM,            R16G16_SNORM,           .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_USCALED,          R16G16_USCALED,         .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SSCALED,          R16G16_SSCALED,         .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_UINT,             R16G16_UINT,            .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SINT,             R16G16_SINT,            .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16_SFLOAT,           R16G16_FLOAT,           .cpp = 4,   .num_channels = 2),
+   fmt(VK_FORMAT_R16G16B16_UNORM,         R16G16B16_UNORM,        .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SNORM,         R16G16B16_SNORM,        .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_USCALED,       R16G16B16_USCALED,      .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SSCALED,       R16G16B16_SSCALED,      .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_UINT,          R16G16B16_UINT,         .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SINT,          R16G16B16_SINT,         .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16_SFLOAT,        R16G16B16_FLOAT,        .cpp = 6,   .num_channels = 3),
+   fmt(VK_FORMAT_R16G16B16A16_UNORM,      R16G16B16A16_UNORM,     .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SNORM,      R16G16B16A16_SNORM,     .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_USCALED,    R16G16B16A16_USCALED,   .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SSCALED,    R16G16B16A16_SSCALED,   .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_UINT,       R16G16B16A16_UINT,      .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SINT,       R16G16B16A16_SINT,      .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R16G16B16A16_SFLOAT,     R16G16B16A16_FLOAT,     .cpp = 8,   .num_channels = 4),
+   fmt(VK_FORMAT_R32_UINT,                R32_UINT,               .cpp = 4,   .num_channels = 1,),
+   fmt(VK_FORMAT_R32_SINT,                R32_SINT,               .cpp = 4,   .num_channels = 1,),
+   fmt(VK_FORMAT_R32_SFLOAT,              R32_FLOAT,              .cpp = 4,   .num_channels = 1,),
+   fmt(VK_FORMAT_R32G32_UINT,             R32G32_UINT,            .cpp = 8,   .num_channels = 2,),
+   fmt(VK_FORMAT_R32G32_SINT,             R32G32_SINT,            .cpp = 8,   .num_channels = 2,),
+   fmt(VK_FORMAT_R32G32_SFLOAT,           R32G32_FLOAT,           .cpp = 8,   .num_channels = 2,),
+   fmt(VK_FORMAT_R32G32B32_UINT,          R32G32B32_UINT,         .cpp = 12,  .num_channels = 3,),
+   fmt(VK_FORMAT_R32G32B32_SINT,          R32G32B32_SINT,         .cpp = 12,  .num_channels = 3,),
+   fmt(VK_FORMAT_R32G32B32_SFLOAT,        R32G32B32_FLOAT,        .cpp = 12,  .num_channels = 3,),
+   fmt(VK_FORMAT_R32G32B32A32_UINT,       R32G32B32A32_UINT,      .cpp = 16,  .num_channels = 4,),
+   fmt(VK_FORMAT_R32G32B32A32_SINT,       R32G32B32A32_SINT,      .cpp = 16,  .num_channels = 4,),
+   fmt(VK_FORMAT_R32G32B32A32_SFLOAT,     R32G32B32A32_FLOAT,     .cpp = 16,  .num_channels = 4,),
+   fmt(VK_FORMAT_R64_SFLOAT,              R64_FLOAT,              .cpp = 8,   .num_channels = 1),
+   fmt(VK_FORMAT_R64G64_SFLOAT,           R64G64_FLOAT,           .cpp = 16,  .num_channels = 2),
+   fmt(VK_FORMAT_R64G64B64_SFLOAT,        R64G64B64_FLOAT,        .cpp = 24,  .num_channels = 3),
+   fmt(VK_FORMAT_R64G64B64A64_SFLOAT,     R64G64B64A64_FLOAT,     .cpp = 32,  .num_channels = 4),
+   fmt(VK_FORMAT_R11G11B10_UFLOAT,        R11G11B10_FLOAT,        .cpp = 4,   .num_channels = 3),
+   fmt(VK_FORMAT_R9G9B9E5_UFLOAT,         R9G9B9E5_SHAREDEXP,     .cpp = 4,   .num_channels = 3),
+
+   fmt(VK_FORMAT_D16_UNORM,               R16_UNORM,              .cpp = 2,   .num_channels = 1, .depth_format = D16_UNORM),
+   fmt(VK_FORMAT_D24_UNORM,               R24_UNORM_X8_TYPELESS,  .cpp = 4,   .num_channels = 1, .depth_format = D24_UNORM_X8_UINT),
+   fmt(VK_FORMAT_D32_SFLOAT,              R32_FLOAT,              .cpp = 4,   .num_channels = 1, .depth_format = D32_FLOAT),
+   fmt(VK_FORMAT_S8_UINT,                 R8_UINT,                .cpp = 1,   .num_channels = 1,                                       .has_stencil = true),
+   fmt(VK_FORMAT_D16_UNORM_S8_UINT,       R16_UNORM,              .cpp = 2,   .num_channels = 2, .depth_format = D16_UNORM,            .has_stencil = true),
+   fmt(VK_FORMAT_D24_UNORM_S8_UINT,       R24_UNORM_X8_TYPELESS,  .cpp = 4,   .num_channels = 2, .depth_format = D24_UNORM_X8_UINT,    .has_stencil = true),
+   fmt(VK_FORMAT_D32_SFLOAT_S8_UINT,      R32_FLOAT,              .cpp = 4,   .num_channels = 2, .depth_format = D32_FLOAT,            .has_stencil = true),
+
+   fmt(VK_FORMAT_BC1_RGB_UNORM,           UNSUPPORTED),
+   fmt(VK_FORMAT_BC1_RGB_SRGB,            UNSUPPORTED),
+   fmt(VK_FORMAT_BC1_RGBA_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_BC1_RGBA_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_BC2_UNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC2_SRGB,                UNSUPPORTED),
+   fmt(VK_FORMAT_BC3_UNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC3_SRGB,                UNSUPPORTED),
+   fmt(VK_FORMAT_BC4_UNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC4_SNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC5_UNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC5_SNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC6H_UFLOAT,             UNSUPPORTED),
+   fmt(VK_FORMAT_BC6H_SFLOAT,             UNSUPPORTED),
+   fmt(VK_FORMAT_BC7_UNORM,               UNSUPPORTED),
+   fmt(VK_FORMAT_BC7_SRGB,                UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8_UNORM,       UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8_SRGB,        UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8A1_UNORM,     UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8A1_SRGB,      UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8A8_UNORM,     UNSUPPORTED),
+   fmt(VK_FORMAT_ETC2_R8G8B8A8_SRGB,      UNSUPPORTED),
+   fmt(VK_FORMAT_EAC_R11_UNORM,           UNSUPPORTED),
+   fmt(VK_FORMAT_EAC_R11_SNORM,           UNSUPPORTED),
+   fmt(VK_FORMAT_EAC_R11G11_UNORM,        UNSUPPORTED),
+   fmt(VK_FORMAT_EAC_R11G11_SNORM,        UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_4x4_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_4x4_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x4_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x4_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x5_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_5x5_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x5_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x5_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x6_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_6x6_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x5_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x5_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x6_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x6_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x8_UNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_8x8_SRGB,           UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x5_UNORM,         UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x5_SRGB,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x6_UNORM,         UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x6_SRGB,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x8_UNORM,         UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x8_SRGB,          UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x10_UNORM,        UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_10x10_SRGB,         UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x10_UNORM,        UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x10_SRGB,         UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x12_UNORM,        UNSUPPORTED),
+   fmt(VK_FORMAT_ASTC_12x12_SRGB,         UNSUPPORTED),
+   fmt(VK_FORMAT_B4G4R4A4_UNORM,          B4G4R4A4_UNORM,         .cpp = 2,   .num_channels = 4),
+   fmt(VK_FORMAT_B5G5R5A1_UNORM,          B5G5R5A1_UNORM,         .cpp = 2,   .num_channels = 4),
+   fmt(VK_FORMAT_B5G6R5_UNORM,            B5G6R5_UNORM,           .cpp = 2,   .num_channels = 3),
+   fmt(VK_FORMAT_B5G6R5_USCALED,          UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_UNORM,            UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SNORM,            UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_USCALED,          UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SSCALED,          UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_UINT,             UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SINT,             UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8_SRGB,             UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_UNORM,          B8G8R8A8_UNORM,         .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B8G8R8A8_SNORM,          UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_USCALED,        UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_SSCALED,        UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_UINT,           UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_SINT,           UNSUPPORTED),
+   fmt(VK_FORMAT_B8G8R8A8_SRGB,           B8G8R8A8_UNORM_SRGB,    .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_UNORM,       B10G10R10A2_UNORM,      .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_SNORM,       B10G10R10A2_SNORM,      .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_USCALED,     B10G10R10A2_USCALED,    .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_SSCALED,     B10G10R10A2_SSCALED,    .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_UINT,        B10G10R10A2_UINT,       .cpp = 4,   .num_channels = 4),
+   fmt(VK_FORMAT_B10G10R10A2_SINT,        B10G10R10A2_SINT,       .cpp = 4,   .num_channels = 4)
+};
+
+#undef fmt
+
+const struct anv_format *
+anv_format_for_vk_format(VkFormat format)
+{
+   return &anv_formats[format];
+}
+
+bool
+anv_is_vk_format_depth_or_stencil(VkFormat format)
+{
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(format);
+
+   if (format_info->depth_format != UNSUPPORTED &&
+       format_info->depth_format != 0)
+      return true;
+
+   return format_info->has_stencil;
+}
+
+// Format capabilities
+
+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;
+};
+
+extern const struct surface_format_info surface_formats[];
+
+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);
+}
+
+VkResult anv_GetPhysicalDeviceFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    _format,
+    VkFormatProperties*                         pFormatProperties)
+{
+   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
+   const struct surface_format_info *info;
+   int gen;
+
+   const struct anv_format *format = anv_format_for_vk_format(_format);
+   if (format == NULL)
+      return vk_error(VK_ERROR_INVALID_VALUE);
+
+   gen = physical_device->info->gen * 10;
+   if (physical_device->info->is_haswell)
+      gen += 5;
+
+   if (format->surface_format == UNSUPPORTED)
+      goto unsupported;
+
+   info = &surface_formats[format->surface_format];
+   if (!info->exists)
+      goto unsupported;
+
+   uint32_t linear = 0, tiled = 0;
+   if (info->sampling <= gen) {
+      linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
+      tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
+   }
+   if (info->render_target <= gen) {
+      linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
+      tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
+   }
+   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;
+   }
+
+   pFormatProperties->linearTilingFeatures = linear;
+   pFormatProperties->optimalTilingFeatures = tiled;
+
+   return VK_SUCCESS;
+
+ unsupported:
+   pFormatProperties->linearTilingFeatures = 0;
+   pFormatProperties->optimalTilingFeatures = 0;
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetPhysicalDeviceImageFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkImageType                                 type,
+    VkImageTiling                               tiling,
+    VkImageUsageFlags                           usage,
+    VkImageFormatProperties*                    pImageFormatProperties)
+{
+   /* TODO: We should do something here. Chad? */
+   stub_return(VK_UNSUPPORTED);
+}
+
+VkResult anv_GetPhysicalDeviceSparseImageFormatProperties(
+    VkPhysicalDevice                            physicalDevice,
+    VkFormat                                    format,
+    VkImageType                                 type,
+    uint32_t                                    samples,
+    VkImageUsageFlags                           usage,
+    VkImageTiling                               tiling,
+    uint32_t*                                   pNumProperties,
+    VkSparseImageFormatProperties*              pProperties)
+{
+   stub_return(VK_UNSUPPORTED);
+}
diff --git a/src/vulkan/anv_gem.c b/src/vulkan/anv_gem.c
new file mode 100644 (file)
index 0000000..4ce857e
--- /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(struct anv_physical_device *physical_dev, uint64_t *size)
+{
+   struct drm_i915_gem_get_aperture aperture;
+   int ret;
+
+   VG_CLEAR(aperture);
+   ret = anv_ioctl(physical_dev->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_image.c b/src/vulkan/anv_image.c
new file mode 100644 (file)
index 0000000..21099cb
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * 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"
+
+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* */
+};
+
+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
+};
+
+static const struct anv_surf_type_limits {
+   int32_t width;
+   int32_t height;
+   int32_t depth;
+} anv_surf_type_limits[] = {
+   [SURFTYPE_1D]     = {16384,       0,   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 {
+   uint32_t width;
+   uint32_t height;
+
+   /**
+    * 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[] = {
+   [LINEAR] = {   1,  1,   64 },
+   [XMAJOR] = { 512,  8, 4096 },
+   [YMAJOR] = { 128, 32, 4096 },
+   [WMAJOR] = { 128, 32, 4096 },
+};
+
+static uint32_t
+anv_image_choose_tile_mode(const struct anv_image_create_info *anv_info)
+{
+   if (anv_info->force_tile_mode)
+      return anv_info->tile_mode;
+
+   if (anv_info->vk_info->format == VK_FORMAT_S8_UINT)
+      return WMAJOR;
+
+   switch (anv_info->vk_info->tiling) {
+   case VK_IMAGE_TILING_LINEAR:
+      return LINEAR;
+   case VK_IMAGE_TILING_OPTIMAL:
+      return YMAJOR;
+   default:
+      assert(!"bad VKImageTiling");
+      return LINEAR;
+   }
+}
+
+static VkResult
+anv_image_make_surface(const struct anv_image_create_info *create_info,
+                       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 uint8_t tile_mode = anv_image_choose_tile_mode(create_info);
+
+   const struct anv_tile_info *tile_info =
+       &anv_tile_info_table[tile_mode];
+
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(create_info->vk_info->format);
+
+   const uint32_t i = 4; /* FINISHME: Stop hardcoding subimage alignment */
+   const uint32_t j = 4; /* FINISHME: Stop hardcoding subimage alignment */
+   const uint32_t w0 = align_u32(extent->width, i);
+   const uint32_t h0 = align_u32(extent->height, j);
+
+   uint16_t qpitch;
+   uint32_t mt_width;
+   uint32_t mt_height;
+
+   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);
+
+      qpitch = h0 + h1 + 11 * j;
+      mt_width = MAX(w0, w1 + w2);
+      mt_height = array_size * qpitch;
+   }
+
+   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));
+
+   const uint32_t stride = align_u32(mt_width * format_info->cpp,
+                                     tile_info->width);
+   const uint32_t size = stride * align_u32(mt_height, tile_info->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,
+      .tile_mode = tile_mode,
+      .qpitch = qpitch,
+      .h_align = i,
+      .v_align = j,
+   };
+
+   return VK_SUCCESS;
+}
+
+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);
+
+   /* XXX: We don't handle any of these */
+   anv_assert(pCreateInfo->imageType == VK_IMAGE_TYPE_2D);
+   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];
+
+   if (extent->width > limits->width ||
+       extent->height > limits->height ||
+       extent->depth > limits->depth) {
+      /* TODO(chadv): What is the correct error? */
+      anv_loge("image extent is too large");
+      return vk_error(VK_ERROR_INVALID_MEMORY_SIZE);
+   }
+
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   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 = pCreateInfo->format;
+   image->levels = pCreateInfo->mipLevels;
+   image->array_size = pCreateInfo->arraySize;
+   image->surf_type = surf_type;
+
+   if (likely(!format_info->has_stencil || format_info->depth_format)) {
+      /* The image's primary surface is a color or depth surface. */
+      r = anv_image_make_surface(create_info, &image->size, &image->alignment,
+                                 &image->primary_surface);
+      if (r != VK_SUCCESS)
+         goto fail;
+   }
+
+   if (format_info->has_stencil) {
+      /* From the GPU's perspective, the depth buffer and stencil buffer are
+       * separate buffers.  From Vulkan's perspective, though, depth and
+       * stencil reside in the same image.  To satisfy Vulkan and the GPU, we
+       * place the depth and stencil buffers in the same bo.
+       */
+      VkImageCreateInfo stencil_info = *pCreateInfo;
+      stencil_info.format = VK_FORMAT_S8_UINT;
+
+      r = anv_image_make_surface(
+            &(struct anv_image_create_info) {
+               .vk_info = &stencil_info,
+            },
+            &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);
+}
+
+VkResult
+anv_DestroyImage(VkDevice _device, VkImage _image)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   anv_device_free(device, anv_image_from_handle(_image));
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetImageSubresourceLayout(
+    VkDevice                                    device,
+    VkImage                                     image,
+    const VkImageSubresource*                   pSubresource,
+    VkSubresourceLayout*                        pLayout)
+{
+   stub_return(VK_UNSUPPORTED);
+}
+
+void
+anv_surface_view_fini(struct anv_device *device,
+                      struct anv_surface_view *view)
+{
+   anv_state_pool_free(&device->surface_state_pool, view->surface_state);
+}
+
+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;
+   struct anv_surface_view *view = &iview->view;
+   struct anv_surface *surface;
+
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   const struct anv_image_view_info *view_type_info
+      = &anv_image_view_info_table[pCreateInfo->viewType];
+
+   if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
+      anv_finishme("non-2D image views");
+
+   switch (pCreateInfo->subresourceRange.aspect) {
+   case VK_IMAGE_ASPECT_STENCIL:
+      anv_finishme("stencil image views");
+      abort();
+      break;
+   case VK_IMAGE_ASPECT_DEPTH:
+   case VK_IMAGE_ASPECT_COLOR:
+      view->offset = image->offset;
+      surface = &image->primary_surface;
+      break;
+   default:
+      unreachable("");
+      break;
+   }
+
+   view->bo = image->bo;
+   view->offset = image->offset + surface->offset;
+   view->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;
+   }
+
+   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
+   };
+
+   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = view_type_info->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 = surface->tile_mode,
+      .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,
+      .MinimumArrayElement = range->baseArraySlice,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .XOffset = 0,
+      .YOffset = 0,
+
+      /* For sampler surfaces, the hardware interprets field MIPCount/LOD as
+       * MIPCount.  The range of levels accessible by the sampler engine is
+       * [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
+       */
+      .MIPCountLOD = range->mipLevels - 1,
+      .SurfaceMinLOD = range->baseMipLevel,
+
+      .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, view->offset },
+   };
+
+   if (cmd_buffer) {
+      view->surface_state =
+         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
+   } else {
+      view->surface_state =
+         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+   }
+
+   GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
+}
+
+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;
+   const struct anv_format *image_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);
+   image_format_info = anv_format_for_vk_format(image->format);
+   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->aspect >= VK_IMAGE_ASPECT_BEGIN_RANGE);
+   assert(subresource->aspect <= VK_IMAGE_ASPECT_END_RANGE);
+   assert(subresource->mipLevels > 0);
+   assert(subresource->arraySize > 0);
+   assert(subresource->baseMipLevel < image->levels);
+   assert(subresource->baseMipLevel + subresource->mipLevels <= image->levels);
+   assert(subresource->baseArraySlice < image->array_size);
+   assert(subresource->baseArraySlice + subresource->arraySize <= image->array_size);
+   assert(pView);
+
+   if (view_info->is_cube) {
+      assert(subresource->baseArraySlice % 6 == 0);
+      assert(subresource->arraySize % 6 == 0);
+   }
+
+   /* Validate format. */
+   switch (subresource->aspect) {
+   case VK_IMAGE_ASPECT_COLOR:
+      assert(!image_format_info->depth_format);
+      assert(!image_format_info->has_stencil);
+      assert(!view_format_info->depth_format);
+      assert(!view_format_info->has_stencil);
+      assert(view_format_info->cpp == image_format_info->cpp);
+      break;
+   case VK_IMAGE_ASPECT_DEPTH:
+      assert(image_format_info->depth_format);
+      assert(view_format_info->depth_format);
+      assert(view_format_info->cpp == image_format_info->cpp);
+      break;
+   case VK_IMAGE_ASPECT_STENCIL:
+      /* FINISHME: Is it legal to have an R8 view of S8? */
+      assert(image_format_info->has_stencil);
+      assert(view_format_info->has_stencil);
+      break;
+   default:
+      assert(!"bad VkImageAspect");
+      break;
+   }
+
+   return anv_CreateImageView(_device, pCreateInfo, pView);
+}
+
+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;
+}
+
+VkResult
+anv_DestroyImageView(VkDevice _device, VkImageView _iview)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_image_view, iview, _iview);
+
+   anv_surface_view_fini(device, &iview->view);
+   anv_device_free(device, iview);
+
+   return VK_SUCCESS;
+}
+
+void
+anv_color_attachment_view_init(struct anv_color_attachment_view *aview,
+                               struct anv_device *device,
+                               const VkAttachmentViewCreateInfo* pCreateInfo,
+                               struct anv_cmd_buffer *cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   struct anv_surface_view *view = &aview->view;
+   struct anv_surface *surface = &image->primary_surface;
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   aview->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_COLOR;
+
+   anv_assert(pCreateInfo->arraySize > 0);
+   anv_assert(pCreateInfo->mipLevel < image->levels);
+   anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size);
+
+   view->bo = image->bo;
+   view->offset = image->offset + surface->offset;
+   view->format = pCreateInfo->format;
+
+   aview->base.extent = (VkExtent3D) {
+      .width = anv_minify(image->extent.width, pCreateInfo->mipLevel),
+      .height = anv_minify(image->extent.height, pCreateInfo->mipLevel),
+      .depth = anv_minify(image->extent.depth, pCreateInfo->mipLevel),
+   };
+
+   uint32_t depth = 1;
+   if (pCreateInfo->arraySize > 1) {
+      depth = pCreateInfo->arraySize;
+   } else if (image->extent.depth > 1) {
+      depth = image->extent.depth;
+   }
+
+   if (cmd_buffer) {
+      view->surface_state =
+         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
+   } else {
+      view->surface_state =
+         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+   }
+
+   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = SURFTYPE_2D,
+      .SurfaceArray = image->array_size > 1,
+      .SurfaceFormat = format_info->surface_format,
+      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
+      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
+      .TileMode = surface->tile_mode,
+      .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,
+      .MinimumArrayElement = pCreateInfo->baseArraySlice,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .XOffset = 0,
+      .YOffset = 0,
+
+      /* 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.
+       */
+      .SurfaceMinLOD = 0,
+      .MIPCountLOD = pCreateInfo->mipLevel,
+
+      .AuxiliarySurfaceMode = AUX_NONE,
+      .RedClearColor = 0,
+      .GreenClearColor = 0,
+      .BlueClearColor = 0,
+      .AlphaClearColor = 0,
+      .ShaderChannelSelectRed = SCS_RED,
+      .ShaderChannelSelectGreen = SCS_GREEN,
+      .ShaderChannelSelectBlue = SCS_BLUE,
+      .ShaderChannelSelectAlpha = SCS_ALPHA,
+      .ResourceMinLOD = 0.0,
+      .SurfaceBaseAddress = { NULL, view->offset },
+   };
+
+   GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
+}
+
+static void
+anv_depth_stencil_view_init(struct anv_depth_stencil_view *view,
+                            const VkAttachmentViewCreateInfo *pCreateInfo)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   struct anv_surface *depth_surface = &image->primary_surface;
+   struct anv_surface *stencil_surface = &image->stencil_surface;
+   const struct anv_format *format =
+      anv_format_for_vk_format(image->format);
+
+   view->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL;
+
+   /* XXX: We don't handle any of these */
+   anv_assert(pCreateInfo->mipLevel == 0);
+   anv_assert(pCreateInfo->baseArraySlice == 0);
+   anv_assert(pCreateInfo->arraySize == 1);
+
+   view->bo = image->bo;
+
+   view->depth_stride = depth_surface->stride;
+   view->depth_offset = image->offset + depth_surface->offset;
+   view->depth_format = format->depth_format;
+   view->depth_qpitch = 0; /* FINISHME: QPitch */
+
+   view->stencil_stride = stencil_surface->stride;
+   view->stencil_offset = image->offset + stencil_surface->offset;
+   view->stencil_qpitch = 0; /* FINISHME: QPitch */
+}
+
+VkResult
+anv_CreateAttachmentView(VkDevice _device,
+                         const VkAttachmentViewCreateInfo *pCreateInfo,
+                         VkAttachmentView *pView)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO);
+
+   if (anv_is_vk_format_depth_or_stencil(pCreateInfo->format)) {
+      struct anv_depth_stencil_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_depth_stencil_view_init(view, pCreateInfo);
+
+      *pView = anv_attachment_view_to_handle(&view->base);
+   } else {
+      struct anv_color_attachment_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_color_attachment_view_init(view, device, pCreateInfo, NULL);
+
+      *pView = anv_attachment_view_to_handle(&view->base);
+   }
+
+   return VK_SUCCESS;
+}
+
+VkResult
+anv_DestroyAttachmentView(VkDevice _device, VkAttachmentView _view)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_attachment_view, view, _view);
+
+   if (view->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_COLOR) {
+      struct anv_color_attachment_view *aview =
+         (struct anv_color_attachment_view *)view;
+
+      anv_surface_view_fini(device, &aview->view);
+   }
+
+   anv_device_free(device, view);
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/anv_intel.c b/src/vulkan/anv_intel.c
new file mode 100644 (file)
index 0000000..9fc06ae
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+   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;
+   }
+
+   *image = (struct anv_image) {
+      .bo = &mem->bo,
+      .offset = 0,
+      .type = VK_IMAGE_TYPE_2D,
+      .extent = pCreateInfo->extent,
+      .size = mem->bo.size,
+
+      .primary_surface = {
+         .offset = 0,
+         .stride = pCreateInfo->strideInBytes,
+         .tile_mode = XMAJOR,
+      },
+   };
+
+   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..f262915
--- /dev/null
@@ -0,0 +1,1449 @@
+/*
+ * 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 "anv_meta_spirv.h"
+
+static void
+anv_device_init_meta_clear_state(struct anv_device *device)
+{
+   /* We don't use a vertex shader for clearing, but instead build and pass
+    * the VUEs directly to the rasterization backend.
+    */
+   VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT,
+      out vec4 f_color;
+      flat in vec4 v_color;
+      void main()
+      {
+         f_color = v_color;
+      }
+   );
+
+   VkShader fs;
+   anv_CreateShader(anv_device_to_handle(device),
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = fsm,
+         .pName = "main",
+      }, &fs);
+
+   /* We use instanced rendering to clear multiple render targets. We have two
+    * vertex buffers: the first vertex buffer holds per-vertex data and
+    * provides the vertices for the clear rectangle. The second one holds
+    * per-instance data, which consists of the VUE header (which selects the
+    * layer) and the color (Vulkan supports per-RT clear colors).
+    */
+   VkPipelineVertexInputStateCreateInfo vi_create_info = {
+      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
+      .bindingCount = 2,
+      .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
+         {
+            .binding = 0,
+            .strideInBytes = 8,
+            .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
+         },
+         {
+            .binding = 1,
+            .strideInBytes = 32,
+            .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
+         },
+      },
+      .attributeCount = 3,
+      .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
+         {
+            /* VUE Header */
+            .location = 0,
+            .binding = 1,
+            .format = VK_FORMAT_R32G32B32A32_UINT,
+            .offsetInBytes = 0
+         },
+         {
+            /* Position */
+            .location = 1,
+            .binding = 0,
+            .format = VK_FORMAT_R32G32_SFLOAT,
+            .offsetInBytes = 0
+         },
+         {
+            /* Color */
+            .location = 2,
+            .binding = 1,
+            .format = VK_FORMAT_R32G32B32A32_SFLOAT,
+            .offsetInBytes = 16
+         }
+      }
+   };
+
+   anv_pipeline_create(anv_device_to_handle(device),
+      &(VkGraphicsPipelineCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
+         .stageCount = 1,
+         .pStages = &(VkPipelineShaderStageCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+            .stage = VK_SHADER_STAGE_FRAGMENT,
+            .shader = fs,
+            .pSpecializationInfo = NULL,
+         },
+         .pVertexInputState = &vi_create_info,
+         .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+            .primitiveRestartEnable = false,
+         },
+         .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
+         },
+         .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 },
+            }
+         },
+         .flags = 0,
+      },
+      &(struct anv_pipeline_create_info) {
+         .use_repclear = true,
+         .disable_viewport = true,
+         .use_rectlist = true
+      },
+      &device->meta_state.clear.pipeline);
+
+   anv_DestroyShader(anv_device_to_handle(device), fs);
+}
+
+#define NUM_VB_USED 2
+struct anv_saved_state {
+   struct anv_vertex_binding old_vertex_bindings[NUM_VB_USED];
+   struct anv_descriptor_set *old_descriptor_set0;
+   struct anv_pipeline *old_pipeline;
+   VkDynamicColorBlendState cb_state;
+};
+
+static void
+anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
+                    struct anv_saved_state *state)
+{
+   state->old_pipeline = cmd_buffer->state.pipeline;
+   state->old_descriptor_set0 = cmd_buffer->state.descriptors[0].set;
+   memcpy(state->old_vertex_bindings, cmd_buffer->state.vertex_bindings,
+          sizeof(state->old_vertex_bindings));
+}
+
+static void
+anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer,
+                       const struct anv_saved_state *state)
+{
+   cmd_buffer->state.pipeline = state->old_pipeline;
+   cmd_buffer->state.descriptors[0].set = 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 << NUM_VB_USED) - 1;
+   cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
+   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_VERTEX_BIT;
+}
+
+struct vue_header {
+   uint32_t Reserved;
+   uint32_t RTAIndex;
+   uint32_t ViewportIndex;
+   float PointWidth;
+};
+
+struct clear_instance_data {
+   struct vue_header vue_header;
+   VkClearColorValue color;
+};
+
+static void
+meta_emit_clear(struct anv_cmd_buffer *cmd_buffer,
+                int num_instances,
+                struct clear_instance_data *instance_data)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   struct anv_state state;
+   uint32_t size;
+
+   const float vertex_data[] = {
+      /* Rect-list coordinates */
+            0.0,        0.0,
+      fb->width,        0.0,
+      fb->width, fb->height,
+
+      /* Align to 16 bytes */
+            0.0,        0.0,
+   };
+
+   size = sizeof(vertex_data) + num_instances * sizeof(*instance_data);
+   state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 16);
+
+   /* Copy in the vertex and instance data */
+   memcpy(state.map, vertex_data, sizeof(vertex_data));
+   memcpy(state.map + sizeof(vertex_data), instance_data,
+          num_instances * sizeof(*instance_data));
+
+   struct anv_buffer vertex_buffer = {
+      .device = cmd_buffer->device,
+      .size = size,
+      .bo = &device->surface_state_block_pool.bo,
+      .offset = 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(vertex_data)
+      });
+
+   if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.clear.pipeline))
+      anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
+                          VK_PIPELINE_BIND_POINT_GRAPHICS,
+                          device->meta_state.clear.pipeline);
+
+   /* We don't need anything here, only set if not already set. */
+   if (cmd_buffer->state.rs_state == NULL)
+      anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                    device->meta_state.shared.rs_state);
+
+   if (cmd_buffer->state.vp_state == NULL)
+      anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                      cmd_buffer->state.framebuffer->vp_state);
+
+   if (cmd_buffer->state.ds_state == NULL)
+      anv_CmdBindDynamicDepthStencilState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                          device->meta_state.shared.ds_state);
+
+   if (cmd_buffer->state.cb_state == NULL)
+      anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                        device->meta_state.shared.cb_state);
+
+   anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, num_instances);
+}
+
+void
+anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
+                                 struct anv_render_pass *pass,
+                                 const VkClearValue *clear_values)
+{
+   struct anv_saved_state saved_state;
+
+   int num_clear_layers = 0;
+   for (uint32_t i = 0; i < pass->attachment_count; i++) {
+      if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
+         if (anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) {
+            anv_finishme("Can't clear depth-stencil yet");
+            continue;
+         }
+         num_clear_layers++;
+      }
+   }
+
+   if (num_clear_layers == 0)
+      return;
+
+   struct clear_instance_data instance_data[num_clear_layers];
+   uint32_t color_attachments[num_clear_layers];
+
+   int layer = 0;
+   for (uint32_t i = 0; i < pass->attachment_count; i++) {
+      if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR &&
+          !anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) {
+         instance_data[layer] = (struct clear_instance_data) {
+            .vue_header = {
+               .RTAIndex = i,
+               .ViewportIndex = 0,
+               .PointWidth = 0.0
+            },
+            .color = clear_values[i].color,
+         };
+         color_attachments[layer] = i;
+         layer++;
+      }
+   }
+
+   anv_cmd_buffer_save(cmd_buffer, &saved_state);
+
+   struct anv_subpass subpass = {
+      .input_count = 0,
+      .color_count = num_clear_layers,
+      .color_attachments = color_attachments,
+      .depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
+   };
+
+   anv_cmd_buffer_begin_subpass(cmd_buffer, &subpass);
+
+   meta_emit_clear(cmd_buffer, num_clear_layers, instance_data);
+
+   /* Restore API state */
+   anv_cmd_buffer_restore(cmd_buffer, &saved_state);
+}
+
+static void
+anv_device_init_meta_blit_state(struct anv_device *device)
+{
+   /* 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.
+    */
+   VkShaderModule vsm = GLSL_VK_SHADER_MODULE(device, VERTEX,
+      in vec2 a_pos;
+      in vec2 a_tex_coord;
+      out vec4 v_tex_coord;
+      void main()
+      {
+         v_tex_coord = vec4(a_tex_coord, 0, 1);
+         gl_Position = vec4(a_pos, 0, 1);
+      }
+   );
+
+   VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT,
+      out vec4 f_color;
+      in vec4 v_tex_coord;
+      layout(set = 0, binding = 0) uniform sampler2D u_tex;
+      void main()
+      {
+         f_color = texture(u_tex, v_tex_coord.xy);
+      }
+   );
+
+   VkShader vs;
+   anv_CreateShader(anv_device_to_handle(device),
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = vsm,
+         .pName = "main",
+      }, &vs);
+
+   VkShader fs;
+   anv_CreateShader(anv_device_to_handle(device),
+      &(VkShaderCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
+         .module = fsm,
+         .pName = "main",
+      }, &fs);
+
+   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 = 16,
+            .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_R32G32_SFLOAT,
+            .offsetInBytes = 8
+         }
+      }
+   };
+
+   VkDescriptorSetLayoutCreateInfo ds_layout_info = {
+      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+      .count = 1,
+      .pBinding = (VkDescriptorSetLayoutBinding[]) {
+         {
+            .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
+            .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);
+
+   anv_pipeline_create(anv_device_to_handle(device),
+      &(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,
+               .pSpecializationInfo = NULL
+            }, {
+               .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
+               .stage = VK_SHADER_STAGE_FRAGMENT,
+               .shader = fs,
+               .pSpecializationInfo = NULL
+            },
+         },
+         .pVertexInputState = &vi_create_info,
+         .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
+            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+            .primitiveRestartEnable = false,
+         },
+         .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
+         },
+         .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 },
+            }
+         },
+         .flags = 0,
+         .layout = device->meta_state.blit.pipeline_layout,
+      },
+      &(struct anv_pipeline_create_info) {
+         .use_repclear = false,
+         .disable_viewport = true,
+         .disable_scissor = true,
+         .disable_vs = true,
+         .use_rectlist = true
+      },
+      &device->meta_state.blit.pipeline);
+
+   anv_DestroyShader(anv_device_to_handle(device), vs);
+   anv_DestroyShader(anv_device_to_handle(device), fs);
+}
+
+static void
+meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
+                  struct anv_saved_state *saved_state)
+{
+   struct anv_device *device = cmd_buffer->device;
+
+   anv_cmd_buffer_save(cmd_buffer, saved_state);
+
+   if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.blit.pipeline))
+      anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
+                          VK_PIPELINE_BIND_POINT_GRAPHICS,
+                          device->meta_state.blit.pipeline);
+
+   /* We don't need anything here, only set if not already set. */
+   if (cmd_buffer->state.rs_state == NULL)
+      anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                    device->meta_state.shared.rs_state);
+   if (cmd_buffer->state.ds_state == NULL)
+      anv_CmdBindDynamicDepthStencilState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                          device->meta_state.shared.ds_state);
+
+   saved_state->cb_state = anv_dynamic_cb_state_to_handle(cmd_buffer->state.cb_state);
+   anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                     device->meta_state.shared.cb_state);
+}
+
+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_view *src,
+               VkOffset3D src_offset,
+               VkExtent3D src_extent,
+               struct anv_color_attachment_view *dest,
+               VkOffset3D dest_offset,
+               VkExtent3D dest_extent)
+{
+   struct anv_device *device = cmd_buffer->device;
+   VkDescriptorPool dummy_desc_pool = { .handle = 1 };
+
+   struct blit_vb_data {
+      float pos[2];
+      float tex_coord[2];
+   } *vb_data;
+
+   unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
+
+   struct anv_state vb_state =
+      anv_state_stream_alloc(&cmd_buffer->surface_state_stream, vb_size, 16);
+   memset(vb_state.map, 0, sizeof(struct vue_header));
+   vb_data = vb_state.map + sizeof(struct 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->extent.width,
+         (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
+      },
+   };
+
+   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->extent.width,
+         (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
+      },
+   };
+
+   vb_data[2] = (struct blit_vb_data) {
+      .pos = {
+         dest_offset.x,
+         dest_offset.y,
+      },
+      .tex_coord = {
+         (float)src_offset.x / (float)src->extent.width,
+         (float)src_offset.y / (float)src->extent.height,
+      },
+   };
+
+   struct anv_buffer vertex_buffer = {
+      .device = device,
+      .size = vb_size,
+      .bo = &device->surface_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 vue_header),
+      });
+
+   uint32_t count;
+   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, &count);
+   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_SAMPLED_IMAGE,
+            .pDescriptors = (VkDescriptorInfo[]) {
+               {
+                  .imageView = anv_image_view_to_handle(src),
+                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL
+               },
+            }
+         }
+      }, 0, NULL);
+
+   VkFramebuffer fb;
+   anv_CreateFramebuffer(anv_device_to_handle(device),
+      &(VkFramebufferCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+         .attachmentCount = 1,
+         .pAttachments = (VkAttachmentBindInfo[]) {
+            {
+               .view = anv_attachment_view_to_handle(&dest->base),
+               .layout = VK_IMAGE_LAYOUT_GENERAL
+            }
+         },
+         .width = dest->base.extent.width,
+         .height = dest->base.extent.height,
+         .layers = 1
+      }, &fb);
+
+   VkRenderPass pass;
+   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 = dest->view.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,
+            .colorAttachments = &(VkAttachmentReference) {
+               .attachment = 0,
+               .layout = VK_IMAGE_LAYOUT_GENERAL,
+            },
+            .resolveAttachments = NULL,
+            .depthStencilAttachment = (VkAttachmentReference) {
+               .attachment = VK_ATTACHMENT_UNUSED,
+               .layout = VK_IMAGE_LAYOUT_GENERAL,
+            },
+            .preserveCount = 1,
+            .preserveAttachments = &(VkAttachmentReference) {
+               .attachment = 0,
+               .layout = VK_IMAGE_LAYOUT_GENERAL,
+            },
+         },
+         .dependencyCount = 0,
+      }, &pass);
+
+   anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
+      &(VkRenderPassBeginInfo) {
+         .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+         .renderPass = pass,
+         .framebuffer = fb,
+         .renderArea = {
+            .offset = { dest_offset.x, dest_offset.y },
+            .extent = { dest_extent.width, dest_extent.height },
+         },
+         .attachmentCount = 1,
+         .pAttachmentClearValues = NULL,
+      }, VK_RENDER_PASS_CONTENTS_INLINE);
+
+   anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                   anv_framebuffer_from_handle(fb)->vp_state);
+
+   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_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, 1);
+
+   anv_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_DestroyFramebuffer(anv_device_to_handle(device), fb);
+   anv_DestroyRenderPass(anv_device_to_handle(device), pass);
+}
+
+static void
+meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
+                 const struct anv_saved_state *saved_state)
+{
+   anv_cmd_buffer_restore(cmd_buffer, saved_state);
+   anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
+                                     saved_state->cb_state);
+}
+
+static VkFormat
+vk_format_for_cpp(int cpp)
+{
+   switch (cpp) {
+   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 cpp");
+   }
+}
+
+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 = VK_IMAGE_USAGE_SAMPLED_BIT,
+      .flags = 0,
+   };
+
+   VkImage src_image, dest_image;
+   anv_CreateImage(vk_device, &image_info, &src_image);
+   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_view;
+   anv_image_view_init(&src_view, 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 = {
+            .aspect = VK_IMAGE_ASPECT_COLOR,
+            .baseMipLevel = 0,
+            .mipLevels = 1,
+            .baseArraySlice = 0,
+            .arraySize = 1
+         },
+      },
+      cmd_buffer);
+
+   struct anv_color_attachment_view dest_view;
+   anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
+      &(VkAttachmentViewCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+         .image = dest_image,
+         .format = copy_format,
+         .mipLevel = 0,
+         .baseArraySlice = 0,
+         .arraySize = 1,
+      },
+      cmd_buffer);
+
+   meta_emit_blit(cmd_buffer,
+                  &src_view,
+                  (VkOffset3D) { 0, 0, 0 },
+                  (VkExtent3D) { width, height, 1 },
+                  &dest_view,
+                  (VkOffset3D) { 0, 0, 0 },
+                  (VkExtent3D) { width, height, 1 });
+
+   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_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 cpp = 16;
+
+      int fs = ffs(src_offset) - 1;
+      if (fs != -1)
+         cpp = MIN2(cpp, 1 << fs);
+      assert(src_offset % cpp == 0);
+
+      fs = ffs(dest_offset) - 1;
+      if (fs != -1)
+         cpp = MIN2(cpp, 1 << fs);
+      assert(dest_offset % cpp == 0);
+
+      fs = ffs(pRegions[r].copySize) - 1;
+      if (fs != -1)
+         cpp = MIN2(cpp, 1 << fs);
+      assert(pRegions[r].copySize % cpp == 0);
+
+      VkFormat copy_format = vk_format_for_cpp(cpp);
+
+      /* 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 * cpp;
+      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 * cpp);
+      assert(height < max_surface_dim);
+      if (height != 0) {
+         uint64_t rect_copy_size = height * max_surface_dim * cpp;
+         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 / cpp, 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);
+
+   struct anv_saved_state saved_state;
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      struct anv_image_view src_view;
+      anv_image_view_init(&src_view, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = src_image->format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspect = pRegions[r].srcSubresource.aspect,
+               .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      struct anv_color_attachment_view dest_view;
+      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
+         &(VkAttachmentViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+            .image = destImage,
+            .format = src_image->format,
+            .mipLevel = pRegions[r].destSubresource.mipLevel,
+            .baseArraySlice = pRegions[r].destSubresource.arraySlice,
+            .arraySize = 1,
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     &src_view,
+                     pRegions[r].srcOffset,
+                     pRegions[r].extent,
+                     &dest_view,
+                     pRegions[r].destOffset,
+                     pRegions[r].extent);
+   }
+
+   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);
+
+   struct anv_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_view;
+      anv_image_view_init(&src_view, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = src_image->format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspect = pRegions[r].srcSubresource.aspect,
+               .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      struct anv_color_attachment_view dest_view;
+      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
+         &(VkAttachmentViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+            .image = destImage,
+            .format = dest_image->format,
+            .mipLevel = pRegions[r].destSubresource.mipLevel,
+            .baseArraySlice = pRegions[r].destSubresource.arraySlice,
+            .arraySize = 1,
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     &src_view,
+                     pRegions[r].srcOffset,
+                     pRegions[r].srcExtent,
+                     &dest_view,
+                     pRegions[r].destOffset,
+                     pRegions[r].destExtent);
+   }
+
+   meta_finish_blit(cmd_buffer, &saved_state);
+}
+
+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_buffer, src_buffer, srcBuffer);
+   ANV_FROM_HANDLE(anv_image, dest_image, destImage);
+   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+   struct anv_saved_state saved_state;
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      if (pRegions[r].bufferRowLength != 0)
+         anv_finishme("bufferRowLength not supported in CopyBufferToImage");
+      if (pRegions[r].bufferImageHeight != 0)
+         anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
+
+      VkImage srcImage;
+      anv_CreateImage(vk_device,
+         &(VkImageCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+            .imageType = VK_IMAGE_TYPE_2D,
+            .format = dest_image->format,
+            .extent = {
+               .width = pRegions[r].imageExtent.width,
+               .height = pRegions[r].imageExtent.height,
+               .depth = 1,
+            },
+            .mipLevels = 1,
+            .arraySize = 1,
+            .samples = 1,
+            .tiling = VK_IMAGE_TILING_LINEAR,
+            .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
+            .flags = 0,
+         }, &srcImage);
+
+      ANV_FROM_HANDLE(anv_image, src_image, srcImage);
+
+      /* 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.
+       */
+      src_image->bo = src_buffer->bo;
+      src_image->offset = src_buffer->offset + pRegions[r].bufferOffset;
+
+      struct anv_image_view src_view;
+      anv_image_view_init(&src_view, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = anv_image_to_handle(src_image),
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = dest_image->format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspect = pRegions[r].imageSubresource.aspect,
+               .baseMipLevel = 0,
+               .mipLevels = 1,
+               .baseArraySlice = 0,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      struct anv_color_attachment_view dest_view;
+      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
+         &(VkAttachmentViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+            .image = anv_image_to_handle(dest_image),
+            .format = dest_image->format,
+            .mipLevel = pRegions[r].imageSubresource.mipLevel,
+            .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
+            .arraySize = 1,
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     &src_view,
+                     (VkOffset3D) { 0, 0, 0 },
+                     pRegions[r].imageExtent,
+                     &dest_view,
+                     pRegions[r].imageOffset,
+                     pRegions[r].imageExtent);
+
+      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);
+   ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
+   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
+   struct anv_saved_state saved_state;
+
+   meta_prepare_blit(cmd_buffer, &saved_state);
+
+   for (unsigned r = 0; r < regionCount; r++) {
+      if (pRegions[r].bufferRowLength != 0)
+         anv_finishme("bufferRowLength not supported in CopyBufferToImage");
+      if (pRegions[r].bufferImageHeight != 0)
+         anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
+
+      struct anv_image_view src_view;
+      anv_image_view_init(&src_view, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+            .image = srcImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
+            .format = src_image->format,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspect = pRegions[r].imageSubresource.aspect,
+               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
+               .arraySize = 1
+            },
+         },
+         cmd_buffer);
+
+      VkImage destImage;
+      anv_CreateImage(vk_device,
+         &(VkImageCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+            .imageType = VK_IMAGE_TYPE_2D,
+            .format = src_image->format,
+            .extent = {
+               .width = pRegions[r].imageExtent.width,
+               .height = pRegions[r].imageExtent.height,
+               .depth = 1,
+            },
+            .mipLevels = 1,
+            .arraySize = 1,
+            .samples = 1,
+            .tiling = VK_IMAGE_TILING_LINEAR,
+            .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
+            .flags = 0,
+         }, &destImage);
+
+      ANV_FROM_HANDLE(anv_image, dest_image, destImage);
+
+      /* 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.
+       */
+      dest_image->bo = dest_buffer->bo;
+      dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset;
+
+      struct anv_color_attachment_view dest_view;
+      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
+         &(VkAttachmentViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+            .image = destImage,
+            .format = src_image->format,
+            .mipLevel = 0,
+            .baseArraySlice = 0,
+            .arraySize = 1,
+         },
+         cmd_buffer);
+
+      meta_emit_blit(cmd_buffer,
+                     &src_view,
+                     pRegions[r].imageOffset,
+                     pRegions[r].imageExtent,
+                     &dest_view,
+                     (VkOffset3D) { 0, 0, 0 },
+                     pRegions[r].imageExtent);
+
+      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_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_saved_state saved_state;
+
+   anv_cmd_buffer_save(cmd_buffer, &saved_state);
+
+   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_color_attachment_view view;
+            anv_color_attachment_view_init(&view, cmd_buffer->device,
+               &(VkAttachmentViewCreateInfo) {
+                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+                  .image = _image,
+                  .format = image->format,
+                  .mipLevel = pRanges[r].baseMipLevel + l,
+                  .baseArraySlice = pRanges[r].baseArraySlice + 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 = (VkAttachmentBindInfo[]) {
+                     {
+                        .view = anv_attachment_view_to_handle(&view.base),
+                        .layout = VK_IMAGE_LAYOUT_GENERAL
+                     }
+                  },
+                  .width = view.base.extent.width,
+                  .height = view.base.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 = view.view.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,
+                     .colorAttachments = &(VkAttachmentReference) {
+                        .attachment = 0,
+                        .layout = VK_IMAGE_LAYOUT_GENERAL,
+                     },
+                     .resolveAttachments = NULL,
+                     .depthStencilAttachment = (VkAttachmentReference) {
+                        .attachment = VK_ATTACHMENT_UNUSED,
+                        .layout = VK_IMAGE_LAYOUT_GENERAL,
+                     },
+                     .preserveCount = 1,
+                     .preserveAttachments = &(VkAttachmentReference) {
+                        .attachment = 0,
+                        .layout = VK_IMAGE_LAYOUT_GENERAL,
+                     },
+                  },
+                  .dependencyCount = 0,
+               }, &pass);
+
+            anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
+               &(VkRenderPassBeginInfo) {
+                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+                  .renderArea = {
+                     .offset = { 0, 0, },
+                     .extent = {
+                        .width = view.base.extent.width,
+                        .height = view.base.extent.height,
+                     },
+                  },
+                  .renderPass = pass,
+                  .framebuffer = fb,
+                  .attachmentCount = 1,
+                  .pAttachmentClearValues = NULL,
+               }, VK_RENDER_PASS_CONTENTS_INLINE);
+
+            struct clear_instance_data instance_data = {
+               .vue_header = {
+                  .RTAIndex = 0,
+                  .ViewportIndex = 0,
+                  .PointWidth = 0.0
+               },
+               .color = *pColor,
+            };
+
+            meta_emit_clear(cmd_buffer, 1, &instance_data);
+
+            anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
+         }
+      }
+   }
+
+   /* Restore API state */
+   anv_cmd_buffer_restore(cmd_buffer, &saved_state);
+}
+
+void anv_CmdClearDepthStencilImage(
+    VkCmdBuffer                                 cmdBuffer,
+    VkImage                                     image,
+    VkImageLayout                               imageLayout,
+    float                                       depth,
+    uint32_t                                    stencil,
+    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                          imageAspectMask,
+    VkImageLayout                               imageLayout,
+    float                                       depth,
+    uint32_t                                    stencil,
+    uint32_t                                    rectCount,
+    const VkRect3D*                             pRects)
+{
+   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);
+
+   anv_CreateDynamicRasterState(anv_device_to_handle(device),
+      &(VkDynamicRasterStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO,
+      },
+      &device->meta_state.shared.rs_state);
+
+   anv_CreateDynamicColorBlendState(anv_device_to_handle(device),
+      &(VkDynamicColorBlendStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO
+      },
+      &device->meta_state.shared.cb_state);
+
+   anv_CreateDynamicDepthStencilState(anv_device_to_handle(device),
+      &(VkDynamicDepthStencilStateCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO
+      },
+      &device->meta_state.shared.ds_state);
+}
+
+void
+anv_device_finish_meta(struct anv_device *device)
+{
+   /* Clear */
+   anv_DestroyPipeline(anv_device_to_handle(device),
+                       device->meta_state.clear.pipeline);
+
+   /* Blit */
+   anv_DestroyPipeline(anv_device_to_handle(device),
+                       device->meta_state.blit.pipeline);
+   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);
+
+   /* Shared */
+   anv_DestroyDynamicRasterState(anv_device_to_handle(device),
+                                 device->meta_state.shared.rs_state);
+   anv_DestroyDynamicColorBlendState(anv_device_to_handle(device),
+                                     device->meta_state.shared.cb_state);
+   anv_DestroyDynamicDepthStencilState(anv_device_to_handle(device),
+                                       device->meta_state.shared.ds_state);
+}
diff --git a/src/vulkan/anv_pipeline.c b/src/vulkan/anv_pipeline.c
new file mode 100644 (file)
index 0000000..817b644
--- /dev/null
@@ -0,0 +1,950 @@
+/*
+ * 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"
+
+// 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->size = pCreateInfo->codeSize;
+   memcpy(module->data, pCreateInfo->pCode, module->size);
+
+   *pShaderModule = anv_shader_module_to_handle(module);
+
+   return VK_SUCCESS;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+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);
+
+   size_t name_len = strlen(pCreateInfo->pName);
+
+   if (strcmp(pCreateInfo->pName, "main") != 0) {
+      anv_finishme("Multiple shaders per module not really supported");
+   }
+
+   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, pCreateInfo->pName, name_len + 1);
+
+   *pShader = anv_shader_to_handle(shader);
+
+   return VK_SUCCESS;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+
+VkResult anv_CreatePipelineCache(
+    VkDevice                                    device,
+    const VkPipelineCacheCreateInfo*            pCreateInfo,
+    VkPipelineCache*                            pPipelineCache)
+{
+   pPipelineCache->handle = 1;
+
+   stub_return(VK_SUCCESS);
+}
+
+VkResult anv_DestroyPipelineCache(
+    VkDevice                                    _device,
+    VkPipelineCache                             _cache)
+{
+   /* VkPipelineCache is a dummy object. */
+   return VK_SUCCESS;
+}
+
+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);
+}
+
+// Pipeline functions
+
+static void
+emit_vertex_input(struct anv_pipeline *pipeline,
+                  const VkPipelineVertexInputStateCreateInfo *info)
+{
+   const uint32_t num_dwords = 1 + info->attributeCount * 2;
+   uint32_t *p;
+   bool instancing_enable[32];
+
+   pipeline->vb_used = 0;
+   for (uint32_t i = 0; i < info->bindingCount; i++) {
+      const VkVertexInputBindingDescription *desc =
+         &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:
+         instancing_enable[desc->binding] = false;
+         break;
+      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
+         instancing_enable[desc->binding] = true;
+         break;
+      }
+   }
+
+   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 = 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_pipeline_create_info *extra)
+{
+   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
+   };
+   uint32_t topology = vk_to_gen_primitive_type[info->topology];
+
+   if (extra && extra->use_rectlist)
+      topology = _3DPRIM_RECTLIST;
+
+   struct GEN8_3DSTATE_VF vf = {
+      GEN8_3DSTATE_VF_header,
+      .IndexedDrawCutIndexEnable = info->primitiveRestartEnable,
+   };
+   GEN8_3DSTATE_VF_pack(NULL, pipeline->state_vf, &vf);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_TOPOLOGY,
+                  .PrimitiveTopologyType = topology);
+}
+
+static void
+emit_rs_state(struct anv_pipeline *pipeline,
+              const VkPipelineRasterStateCreateInfo *info,
+              const struct anv_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->state_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->state_raster, &raster);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SBE,
+                  .ForceVertexURBEntryReadLength = false,
+                  .ForceVertexURBEntryReadOffset = false,
+                  .PointSpriteTextureCoordinateOrigin = UPPERLEFT,
+                  .NumberofSFOutputAttributes =
+                     pipeline->wm_prog_data.num_varying_inputs);
+
+}
+
+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 = 1 + info->attachmentCount * 2;
+   pipeline->blend_state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+   struct GEN8_BLEND_STATE blend_state = {
+      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
+   };
+
+   uint32_t *state = pipeline->blend_state.map;
+   GEN8_BLEND_STATE_pack(NULL, state, &blend_state);
+
+   for (uint32_t i = 0; i < info->attachmentCount; i++) {
+      const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[i];
+
+      struct GEN8_BLEND_STATE_ENTRY 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_ENTRY_pack(NULL, state + i * 2 + 1, &entry);
+   }
+
+   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]                         = 0,
+   [VK_STENCIL_OP_ZERO]                         = 0,
+   [VK_STENCIL_OP_REPLACE]                      = 0,
+   [VK_STENCIL_OP_INC_CLAMP]                    = 0,
+   [VK_STENCIL_OP_DEC_CLAMP]                    = 0,
+   [VK_STENCIL_OP_INVERT]                       = 0,
+   [VK_STENCIL_OP_INC_WRAP]                     = 0,
+   [VK_STENCIL_OP_DEC_WRAP]                     = 0
+};
+
+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->state_wm_depth_stencil, 0,
+             sizeof(pipeline->state_wm_depth_stencil));
+      return;
+   }
+
+   /* VkBool32 depthBoundsEnable;          // 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->state_wm_depth_stencil, &wm_depth_stencil);
+}
+
+VkResult
+anv_pipeline_create(
+    VkDevice                                    _device,
+    const VkGraphicsPipelineCreateInfo*         pCreateInfo,
+    const struct anv_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);
+
+   pipeline->device = device;
+   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
+   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+
+   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);
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
+      pipeline->shaders[pCreateInfo->pStages[i].stage] =
+         anv_shader_from_handle(pCreateInfo->pStages[i].shader);
+   }
+
+   if (pCreateInfo->pTessellationState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
+   if (pCreateInfo->pViewportState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
+   if (pCreateInfo->pMultisampleState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
+
+   pipeline->use_repclear = extra && extra->use_repclear;
+
+   anv_compiler_run(device->compiler, pipeline);
+
+   /* 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_SBE_SWIZ);
+   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 = Vmask,
+                     .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,
+                     .ControlDataHeaderSize = gs_prog_data->control_data_header_size_hwords,
+                     //pipeline->gs_prog_data.dispatch_mode |
+                     .StatisticsEnable = true,
+                     .IncludePrimitiveID = gs_prog_data->include_primitive_id,
+                     .ReorderMode = TRAILING,
+                     .Enable = true,
+
+                     .ControlDataFormat = gs_prog_data->control_data_format,
+
+                     /* 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,
+                     .VertexURBEntryOutputReadOffset = 1,
+                     /* Even if VS is disabled, SBE still gets the amount of
+                      * vertex data to read from this field. We use attribute
+                      * count - 1, as we don't count the VUE header here. */
+                     .VertexURBEntryOutputLength =
+                        DIV_ROUND_UP(pCreateInfo->pVertexInputState->attributeCount - 1, 2));
+   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;
+   uint32_t ksp0, ksp2, grf_start0, grf_start2;
+
+   ksp2 = 0;
+   grf_start2 = 0;
+   if (pipeline->ps_simd8 != NO_KERNEL) {
+      ksp0 = pipeline->ps_simd8;
+      grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
+      if (pipeline->ps_simd16 != NO_KERNEL) {
+         ksp2 = pipeline->ps_simd16;
+         grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
+      }
+   } else if (pipeline->ps_simd16 != NO_KERNEL) {
+      ksp0 = pipeline->ps_simd16;
+      grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
+   } else {
+      unreachable("no ps shader");
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS,
+                  .KernelStartPointer0 = 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 = grf_start0,
+                  .DispatchGRFStartRegisterForConstantSetupData1 = 0,
+                  .DispatchGRFStartRegisterForConstantSetupData2 = grf_start2,
+
+                  .KernelStartPointer1 = 0,
+                  .KernelStartPointer2 = 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 anv_DestroyPipeline(
+    VkDevice                                    _device,
+    VkPipeline                                  _pipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
+
+   anv_compiler_free(pipeline);
+   anv_reloc_list_finish(&pipeline->batch.relocs, pipeline->device);
+   anv_state_stream_finish(&pipeline->program_stream);
+   anv_state_pool_free(&device->dynamic_state_pool, pipeline->blend_state);
+   anv_device_free(pipeline->device, pipeline);
+
+   return VK_SUCCESS;
+}
+
+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_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);
+   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);
+
+   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);
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+
+   pipeline->shaders[VK_SHADER_STAGE_COMPUTE] =
+      anv_shader_from_handle(pCreateInfo->cs.shader);
+
+   pipeline->use_repclear = false;
+
+   anv_compiler_run(device->compiler, pipeline);
+
+   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_FRAGMENT],
+                  .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;
+}
+
+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 *layout;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
+
+   layout = anv_device_alloc(device, sizeof(*layout), 8,
+                             VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (layout == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   layout->num_sets = pCreateInfo->descriptorSetCount;
+
+   uint32_t surface_start[VK_SHADER_STAGE_NUM] = { 0, };
+   uint32_t sampler_start[VK_SHADER_STAGE_NUM] = { 0, };
+
+   for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+      layout->stage[s].surface_count = 0;
+      layout->stage[s].sampler_count = 0;
+   }
+
+   for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
+      ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
+                      pCreateInfo->pSetLayouts[i]);
+
+      layout->set[i].layout = set_layout;
+      for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
+         layout->set[i].surface_start[s] = surface_start[s];
+         surface_start[s] += set_layout->stage[s].surface_count;
+         layout->set[i].sampler_start[s] = sampler_start[s];
+         sampler_start[s] += set_layout->stage[s].sampler_count;
+
+         layout->stage[s].surface_count += set_layout->stage[s].surface_count;
+         layout->stage[s].sampler_count += set_layout->stage[s].sampler_count;
+      }
+   }
+
+   *pPipelineLayout = anv_pipeline_layout_to_handle(layout);
+
+   return VK_SUCCESS;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/anv_private.h b/src/vulkan/anv_private.h
new file mode 100644 (file)
index 0000000..be24b51
--- /dev/null
@@ -0,0 +1,1081 @@
+/*
+ * 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"
+
+#define VK_PROTOTYPES
+#include <vulkan/vulkan.h>
+#include <vulkan/vulkan_intel.h>
+#include <vulkan/vk_wsi_lunarg.h>
+
+#include "anv_entrypoints.h"
+
+#include "brw_context.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#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 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.
+ */
+
+static inline VkResult
+vk_error(VkResult error)
+{
+#ifdef DEBUG
+   fprintf(stderr, "vk_error: %x\n", error);
+#endif
+
+   return error;
+}
+
+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
+
+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_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;
+   uint32_t index;
+   uint64_t offset;
+   uint64_t size;
+
+   /* This field is here for the benefit of the aub dumper.  It can (and for
+    * userptr bos it must) be set to the cpu map of the buffer.  Destroying
+    * the bo won't clean up the mmap, it's still the responsibility of the bo
+    * user to do that. */
+   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 {
+      uint32_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_pool {
+   struct anv_device *device;
+
+   struct anv_bo bo;
+   void *map;
+   int fd;
+   uint32_t size;
+
+   /**
+    * 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;
+
+   uint32_t next_block;
+   union anv_free_list free_list;
+};
+
+struct anv_block_state {
+   union {
+      struct {
+         uint32_t next;
+         uint32_t end;
+      };
+      uint64_t u64;
+   };
+};
+
+struct anv_state {
+   uint32_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);
+uint32_t anv_block_pool_alloc(struct anv_block_pool *pool);
+void anv_block_pool_free(struct anv_block_pool *pool, uint32_t offset);
+void anv_state_pool_init(struct anv_state_pool *pool,
+                         struct anv_block_pool *block_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);
+
+struct anv_physical_device {
+    struct anv_instance *                       instance;
+    uint32_t                                    chipset_id;
+    bool                                        no_hw;
+    const char *                                path;
+    const char *                                name;
+    const struct brw_device_info *              info;
+    int                                         fd;
+};
+
+struct anv_instance {
+    void *                                      pAllocUserData;
+    PFN_vkAllocFunction                         pfnAlloc;
+    PFN_vkFreeFunction                          pfnFree;
+    uint32_t                                    apiVersion;
+    uint32_t                                    physicalDeviceCount;
+    struct anv_physical_device                  physicalDevice;
+};
+
+struct anv_meta_state {
+   struct {
+      VkPipeline                                pipeline;
+   } clear;
+
+   struct {
+      VkPipeline                                pipeline;
+      VkPipelineLayout                          pipeline_layout;
+      VkDescriptorSetLayout                     ds_layout;
+   } blit;
+
+   struct {
+      VkDynamicRasterState                      rs_state;
+      VkDynamicColorBlendState                  cb_state;
+      VkDynamicDepthStencilState                ds_state;
+   } shared;
+};
+
+struct anv_queue {
+    struct anv_device *                         device;
+
+    struct anv_state_pool *                     pool;
+
+    /**
+     * Serial number of the most recently completed batch executed on the
+     * engine.
+     */
+    struct anv_state                            completed_serial;
+
+    /**
+     * The next batch submitted to the engine will be assigned this serial
+     * number.
+     */
+    uint32_t                                    next_serial;
+
+    uint32_t                                    last_collected_serial;
+};
+
+struct anv_device {
+    struct anv_instance *                       instance;
+    uint32_t                                    chipset_id;
+    struct brw_device_info                      info;
+    int                                         context_id;
+    int                                         fd;
+    bool                                        no_hw;
+    bool                                        dump_aub;
+
+    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_meta_state                       meta_state;
+
+    struct anv_state                            border_colors;
+
+    struct anv_queue                            queue;
+
+    struct anv_block_pool                       scratch_block_pool;
+
+    struct anv_compiler *                       compiler;
+    struct anv_aub_writer *                     aub_writer;
+    pthread_mutex_t                             mutex;
+};
+
+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(struct anv_physical_device *physical_dev, 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 {
+   struct anv_bo                                bo;
+
+   /* Bytes actually consumed in this batch BO */
+   size_t                                       length;
+
+   /* These offsets reference the per-batch reloc list */
+   size_t                                       first_reloc;
+   size_t                                       num_relocs;
+
+   struct anv_batch_bo *                        prev_batch_bo;
+};
+
+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 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 {                            \
+      struct cmd __template = {                                         \
+         cmd ## _header,                                                \
+         __VA_ARGS__                                                    \
+      };                                                                \
+      void *__dst = anv_batch_emit_dwords(batch, cmd ## _length);       \
+      cmd ## _pack(batch, __dst, &__template);                          \
+   } while (0)
+
+#define anv_batch_emitn(batch, n, cmd, ...) ({          \
+      struct cmd __template = {                         \
+         cmd ## _header,                                \
+        .DwordLength = n - cmd ## _length_bias,         \
+         __VA_ARGS__                                    \
+      };                                                \
+      void *__dst = anv_batch_emit_dwords(batch, n);    \
+      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)
+
+#define GEN8_MOCS {                                     \
+      .MemoryTypeLLCeLLCCacheabilityControl = WB,       \
+      .TargetCache = L3DefertoPATforLLCeLLCselection,   \
+      .AgeforQUADLRU = 0                                \
+   }
+
+struct anv_device_memory {
+   struct anv_bo                                bo;
+   VkDeviceSize                                 map_size;
+   void *                                       map;
+};
+
+struct anv_dynamic_vp_state {
+   struct anv_state sf_clip_vp;
+   struct anv_state cc_vp;
+   struct anv_state scissor;
+};
+
+struct anv_dynamic_rs_state {
+   uint32_t state_sf[GEN8_3DSTATE_SF_length];
+   uint32_t state_raster[GEN8_3DSTATE_RASTER_length];
+};
+
+struct anv_dynamic_ds_state {
+   uint32_t state_wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
+   uint32_t state_color_calc[GEN8_COLOR_CALC_STATE_length];
+};
+
+struct anv_dynamic_cb_state {
+   uint32_t state_color_calc[GEN8_COLOR_CALC_STATE_length];
+
+};
+
+struct anv_descriptor_slot {
+   int8_t dynamic_slot;
+   uint8_t index;
+};
+
+struct anv_descriptor_set_layout {
+   struct {
+      uint32_t surface_count;
+      struct anv_descriptor_slot *surface_start;
+      uint32_t sampler_count;
+      struct anv_descriptor_slot *sampler_start;
+   } stage[VK_SHADER_STAGE_NUM];
+
+   uint32_t count;
+   uint32_t num_dynamic_buffers;
+   uint32_t shader_stages;
+   struct anv_descriptor_slot entries[0];
+};
+
+struct anv_descriptor {
+   struct anv_sampler *sampler;
+   struct anv_surface_view *view;
+};
+
+struct anv_descriptor_set {
+   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
+
+struct anv_pipeline_layout {
+   struct {
+      struct anv_descriptor_set_layout *layout;
+      uint32_t surface_start[VK_SHADER_STAGE_NUM];
+      uint32_t sampler_start[VK_SHADER_STAGE_NUM];
+   } set[MAX_SETS];
+
+   uint32_t num_sets;
+
+   struct {
+      uint32_t surface_count;
+      uint32_t sampler_count;
+   } stage[VK_SHADER_STAGE_NUM];
+};
+
+struct anv_buffer {
+   struct anv_device *                          device;
+   VkDeviceSize                                 size;
+
+   /* Set when bound */
+   struct anv_bo *                              bo;
+   VkDeviceSize                                 offset;   
+};
+
+#define ANV_CMD_BUFFER_PIPELINE_DIRTY           (1 << 0)
+#define ANV_CMD_BUFFER_RS_DIRTY                 (1 << 2)
+#define ANV_CMD_BUFFER_DS_DIRTY                 (1 << 3)
+#define ANV_CMD_BUFFER_CB_DIRTY                 (1 << 4)
+#define ANV_CMD_BUFFER_VP_DIRTY                 (1 << 5)
+#define ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY       (1 << 6)
+
+struct anv_vertex_binding {
+   struct anv_buffer *                          buffer;
+   VkDeviceSize                                 offset;
+};
+
+struct anv_descriptor_set_binding {
+   struct anv_descriptor_set *                  set;
+   uint32_t                                     dynamic_offsets[128];
+};
+
+/** State required while building cmd buffer */
+struct anv_cmd_state {
+   uint32_t                                     current_pipeline;
+   uint32_t                                     vb_dirty;
+   uint32_t                                     dirty;
+   uint32_t                                     compute_dirty;
+   uint32_t                                     descriptors_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;
+   struct anv_dynamic_rs_state *                rs_state;
+   struct anv_dynamic_ds_state *                ds_state;
+   struct anv_dynamic_vp_state *                vp_state;
+   struct anv_dynamic_cb_state *                cb_state;
+   uint32_t                                     state_vf[GEN8_3DSTATE_VF_length];
+   struct anv_vertex_binding                    vertex_bindings[MAX_VBS];
+   struct anv_descriptor_set_binding            descriptors[MAX_SETS];
+};
+
+VkResult anv_cmd_state_init(struct anv_cmd_state *state);
+void anv_cmd_state_fini(struct anv_cmd_state *state);
+
+struct anv_cmd_buffer {
+   struct anv_device *                          device;
+
+   struct drm_i915_gem_execbuffer2              execbuf;
+   struct drm_i915_gem_exec_object2 *           exec2_objects;
+   uint32_t                                     exec2_bo_count;
+   struct anv_bo **                             exec2_bos;
+   uint32_t                                     exec2_array_length;
+   bool                                         need_reloc;
+   uint32_t                                     serial;
+
+   struct anv_batch                             batch;
+   struct anv_batch_bo *                        last_batch_bo;
+   struct anv_batch_bo *                        surface_batch_bo;
+   uint32_t                                     surface_next;
+   struct anv_reloc_list                        surface_relocs;
+   struct anv_state_stream                      surface_state_stream;
+   struct anv_state_stream                      dynamic_state_stream;
+
+   struct anv_cmd_state                         state;
+};
+
+struct anv_state
+anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer,
+                                   uint32_t size, uint32_t alignment);
+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_surface_state_bo(struct anv_cmd_buffer *cmd_buffer);
+
+void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
+
+void anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                  struct anv_subpass *subpass);
+
+void anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
+                                      struct anv_render_pass *pass,
+                                      const VkClearValue *clear_values);
+
+void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
+void anv_aub_writer_destroy(struct anv_aub_writer *writer);
+
+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 anv_shader_module {
+   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[256];
+   struct anv_shader *                          shaders[VK_SHADER_STAGE_NUM];
+   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;
+
+   uint32_t                                     active_stages;
+   struct anv_state_stream                      program_stream;
+   struct anv_state                             blend_state;
+   uint32_t                                     vs_simd8;
+   uint32_t                                     ps_simd8;
+   uint32_t                                     ps_simd16;
+   uint32_t                                     gs_vec4;
+   uint32_t                                     gs_vertex_count;
+   uint32_t                                     cs_simd;
+
+   uint32_t                                     vb_used;
+   uint32_t                                     binding_stride[MAX_VBS];
+
+   uint32_t                                     state_sf[GEN8_3DSTATE_SF_length];
+   uint32_t                                     state_vf[GEN8_3DSTATE_VF_length];
+   uint32_t                                     state_raster[GEN8_3DSTATE_RASTER_length];
+   uint32_t                                     state_wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
+
+   uint32_t                                     cs_thread_width_max;
+   uint32_t                                     cs_right_mask;
+};
+
+struct anv_pipeline_create_info {
+   bool                                         use_repclear;
+   bool                                         disable_viewport;
+   bool                                         disable_scissor;
+   bool                                         disable_vs;
+   bool                                         use_rectlist;
+};
+
+VkResult
+anv_pipeline_create(VkDevice device,
+                    const VkGraphicsPipelineCreateInfo *pCreateInfo,
+                    const struct anv_pipeline_create_info *extra,
+                    VkPipeline *pPipeline);
+
+struct anv_compiler *anv_compiler_create(struct anv_device *device);
+void anv_compiler_destroy(struct anv_compiler *compiler);
+int anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline);
+void anv_compiler_free(struct anv_pipeline *pipeline);
+
+struct anv_format {
+   const char *name;
+   uint16_t surface_format; /**< RENDER_SURFACE_STATE.SurfaceFormat */
+   uint8_t cpp; /**< Bytes-per-pixel of anv_format::surface_format. */
+   uint8_t num_channels;
+   uint16_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
+   bool has_stencil;
+};
+
+const struct anv_format *
+anv_format_for_vk_format(VkFormat format);
+bool anv_is_vk_format_depth_or_stencil(VkFormat format);
+
+/**
+ * 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 */
+   /** \} */
+
+   uint8_t tile_mode; /**< RENDER_SURFACE_STATE.TileMode */
+};
+
+struct anv_image {
+   VkImageType type;
+   VkExtent3D extent;
+   VkFormat format;
+   uint32_t levels;
+   uint32_t array_size;
+
+   VkDeviceSize size;
+   uint32_t alignment;
+
+   /* Set when bound */
+   struct anv_bo *bo;
+   VkDeviceSize offset;
+
+   struct anv_swap_chain *swap_chain;
+
+   /** RENDER_SURFACE_STATE.SurfaceType */
+   uint8_t surf_type;
+
+   /** Primary surface is either color or depth. */
+   struct anv_surface primary_surface;
+
+   /** Stencil surface is optional. */
+   struct anv_surface stencil_surface;
+};
+
+struct anv_surface_view {
+   struct anv_state surface_state; /**< RENDER_SURFACE_STATE */
+   struct anv_bo *bo;
+   uint32_t offset; /**< VkBufferCreateInfo::offset */
+   uint32_t range; /**< VkBufferCreateInfo::range */
+   VkFormat format; /**< VkBufferCreateInfo::format */
+};
+
+struct anv_buffer_view {
+   struct anv_surface_view view;
+};
+
+struct anv_image_view {
+   struct anv_surface_view view;
+   VkExtent3D extent;
+};
+
+enum anv_attachment_view_type {
+   ANV_ATTACHMENT_VIEW_TYPE_COLOR,
+   ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL,
+};
+
+struct anv_attachment_view {
+   enum anv_attachment_view_type attachment_type;
+   VkExtent3D extent;
+};
+
+struct anv_color_attachment_view {
+   struct anv_attachment_view base;
+   struct anv_surface_view view;
+};
+
+struct anv_depth_stencil_view {
+   struct anv_attachment_view base;
+
+   struct anv_bo *bo;
+
+   uint32_t depth_offset; /**< Offset into bo. */
+   uint32_t depth_stride; /**< 3DSTATE_DEPTH_BUFFER.SurfacePitch */
+   uint32_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
+   uint16_t depth_qpitch; /**< 3DSTATE_DEPTH_BUFFER.SurfaceQPitch */
+
+   uint32_t stencil_offset; /**< Offset into bo. */
+   uint32_t stencil_stride; /**< 3DSTATE_STENCIL_BUFFER.SurfacePitch */
+   uint16_t stencil_qpitch; /**< 3DSTATE_STENCIL_BUFFER.SurfaceQPitch */
+};
+
+struct anv_image_create_info {
+   const VkImageCreateInfo *vk_info;
+   bool force_tile_mode;
+   uint8_t tile_mode;
+};
+
+VkResult anv_image_create(VkDevice _device,
+                          const struct anv_image_create_info *info,
+                          VkImage *pImage);
+
+void anv_image_view_init(struct anv_image_view *view,
+                         struct anv_device *device,
+                         const VkImageViewCreateInfo* pCreateInfo,
+                         struct anv_cmd_buffer *cmd_buffer);
+
+void anv_color_attachment_view_init(struct anv_color_attachment_view *view,
+                                    struct anv_device *device,
+                                    const VkAttachmentViewCreateInfo* pCreateInfo,
+                                    struct anv_cmd_buffer *cmd_buffer);
+void anv_fill_buffer_surface_state(void *state, VkFormat format,
+                                   uint32_t offset, uint32_t range);
+
+void anv_surface_view_fini(struct anv_device *device,
+                           struct anv_surface_view *view);
+
+struct anv_sampler {
+   uint32_t state[4];
+};
+
+struct anv_framebuffer {
+   uint32_t                                     width;
+   uint32_t                                     height;
+   uint32_t                                     layers;
+
+   /* Viewport for clears */
+   VkDynamicViewportState                       vp_state;
+
+   uint32_t                                     attachment_count;
+   const struct anv_attachment_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 {
+   VkFormat                                     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];
+};
+
+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);
+
+#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_HANDLE_CASTS(anv_swap_chain, VkSwapChainWSI);
+
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_attachment_view, VkAttachmentView)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer, VkBuffer)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, VkBufferView);
+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_dynamic_cb_state, VkDynamicColorBlendState)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_dynamic_ds_state, VkDynamicDepthStencilState)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_dynamic_rs_state, VkDynamicRasterState)
+ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_dynamic_vp_state, VkDynamicViewportState)
+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..d7903ee
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * 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"
+
+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;
+};
+
+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;
+}
+
+VkResult 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);
+
+   return VK_SUCCESS;
+}
+
+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)
+         return vk_error(VK_ERROR_UNKNOWN);
+   }
+
+   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;
+}
+
+static void
+anv_batch_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 anv_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:
+      anv_batch_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 anv_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:
+      anv_batch_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("");
+   }
+}
+
+void anv_CmdResetQueryPool(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount)
+{
+   stub();
+}
+
+#define TIMESTAMP 0x2358
+
+void anv_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 anv_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;
+   }
+}
diff --git a/src/vulkan/anv_util.c b/src/vulkan/anv_util.c
new file mode 100644 (file)
index 0000000..8203566
--- /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 <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();
+}
+
+int
+anv_vector_init(struct anv_vector *vector, uint32_t element_size, uint32_t size)
+{
+   assert(is_power_of_two(size));
+   assert(element_size < size && 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_x11.c b/src/vulkan/anv_x11.c
new file mode 100644 (file)
index 0000000..9ffce8d
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * 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 <xcb/xcb.h>
+#include <xcb/dri3.h>
+#include <xcb/present.h>
+
+static const VkFormat formats[] = {
+   VK_FORMAT_B5G6R5_UNORM,
+   VK_FORMAT_B8G8R8A8_UNORM,
+   VK_FORMAT_B8G8R8A8_SRGB,
+};
+
+VkResult anv_GetDisplayInfoWSI(
+    VkDisplayWSI                            display,
+    VkDisplayInfoTypeWSI                    infoType,
+    size_t*                                 pDataSize,
+    void*                                   pData)
+{
+   VkDisplayFormatPropertiesWSI *properties = pData;
+   size_t size;
+
+   if (pDataSize == NULL)
+      return VK_ERROR_INVALID_POINTER;
+
+   switch (infoType) {
+   case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI:
+      size = sizeof(properties[0]) * ARRAY_SIZE(formats);
+
+      if (pData == NULL) {
+         *pDataSize = size;
+         return VK_SUCCESS;
+      }
+
+      if (*pDataSize < size)
+         return vk_error(VK_ERROR_INVALID_VALUE);
+
+      *pDataSize = size;
+
+      for (uint32_t i = 0; i < ARRAY_SIZE(formats); i++)
+         properties[i].swapChainFormat = formats[i];
+
+      return VK_SUCCESS;
+
+   default:
+      return VK_UNSUPPORTED;
+   }
+}
+
+struct anv_swap_chain {
+   struct anv_device *                          device;
+   xcb_connection_t *                           conn;
+   xcb_window_t                                 window;
+   xcb_gc_t                                     gc;
+   VkExtent2D                                   extent;
+   uint32_t                                     count;
+   struct {
+      struct anv_image *                        image;
+      struct anv_device_memory *                memory;
+      xcb_pixmap_t                              pixmap;
+   }                                            images[0];
+};
+
+VkResult anv_CreateSwapChainWSI(
+    VkDevice                                _device,
+    const VkSwapChainCreateInfoWSI*         pCreateInfo,
+    VkSwapChainWSI*                         pSwapChain)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+
+   struct anv_swap_chain *chain;
+   xcb_void_cookie_t cookie;
+   VkResult result;
+   size_t size;
+   int ret;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI);
+
+   size = sizeof(*chain) + pCreateInfo->imageCount * 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->device = device;
+   chain->conn = (xcb_connection_t *) pCreateInfo->pNativeWindowSystemHandle;
+   chain->window = (xcb_window_t) (uintptr_t) pCreateInfo->pNativeWindowHandle;
+   chain->count = pCreateInfo->imageCount;
+   chain->extent = pCreateInfo->imageExtent;
+
+   for (uint32_t i = 0; i < chain->count; i++) {
+      VkDeviceMemory memory_h;
+      VkImage image_h;
+      struct anv_image *image;
+      struct anv_surface *surface;
+      struct anv_device_memory *memory;
+
+      anv_image_create(_device,
+         &(struct anv_image_create_info) {
+            .force_tile_mode = true,
+            .tile_mode = XMAJOR,
+            .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);
+      surface = &image->primary_surface;
+
+      anv_AllocMemory(_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);
+
+      ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
+                               surface->stride, I915_TILING_X);
+      if (ret) {
+         result = vk_error(VK_ERROR_UNKNOWN);
+         goto fail;
+      }
+
+      int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle);
+      if (fd == -1) {
+         result = vk_error(VK_ERROR_UNKNOWN);
+         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;
+      image->swap_chain = chain;
+
+      xcb_discard_reply(chain->conn, cookie.sequence);
+   }
+
+   chain->gc = xcb_generate_id(chain->conn);
+   if (!chain->gc) {
+      result = vk_error(VK_ERROR_UNKNOWN);
+      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);
+
+   *pSwapChain = anv_swap_chain_to_handle(chain);
+
+   return VK_SUCCESS;
+
+ fail:
+   return result;
+}
+
+VkResult anv_DestroySwapChainWSI(
+    VkSwapChainWSI                          _chain)
+{
+   ANV_FROM_HANDLE(anv_swap_chain, chain, _chain);
+
+   anv_device_free(chain->device, chain);
+
+   return VK_SUCCESS;
+}
+
+VkResult anv_GetSwapChainInfoWSI(
+    VkSwapChainWSI                          _chain,
+    VkSwapChainInfoTypeWSI                  infoType,
+    size_t*                                 pDataSize,
+    void*                                   pData)
+{
+   ANV_FROM_HANDLE(anv_swap_chain, chain, _chain);
+
+   VkSwapChainImageInfoWSI *images;
+   size_t size;
+
+   switch (infoType) {
+   case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI:
+      size = sizeof(*images) * chain->count;
+      if (pData && *pDataSize < size)
+         return VK_ERROR_INVALID_VALUE;
+
+      *pDataSize = size;
+      if (!pData)
+         return VK_SUCCESS;
+
+      images = pData;
+      for (uint32_t i = 0; i < chain->count; i++) {
+         images[i].image = anv_image_to_handle(chain->images[i].image);
+         images[i].memory = anv_device_memory_to_handle(chain->images[i].memory);
+      }
+
+      return VK_SUCCESS;
+
+   default:
+      return VK_UNSUPPORTED;
+   }
+}
+
+VkResult anv_QueuePresentWSI(
+    VkQueue                                 queue_,
+    const VkPresentInfoWSI*                 pPresentInfo)
+{
+   ANV_FROM_HANDLE(anv_image, image, pPresentInfo->image);
+
+   struct anv_swap_chain *chain = image->swap_chain;
+   xcb_void_cookie_t cookie;
+   xcb_pixmap_t pixmap;
+
+   assert(pPresentInfo->sType == VK_STRUCTURE_TYPE_PRESENT_INFO_WSI);
+
+   if (chain == NULL)
+      return vk_error(VK_ERROR_INVALID_VALUE);
+
+   pixmap = XCB_NONE;
+   for (uint32_t i = 0; i < chain->count; i++) {
+      if (image == chain->images[i].image) {
+         pixmap = chain->images[i].pixmap;
+         break;
+      }
+   }
+
+   if (pixmap == XCB_NONE)
+      return vk_error(VK_ERROR_INVALID_VALUE);
+
+   cookie = xcb_copy_area(chain->conn,
+                          pixmap,
+                          chain->window,
+                          chain->gc,
+                          0, 0,
+                          0, 0,
+                          chain->extent.width,
+                          chain->extent.height);
+   xcb_discard_reply(chain->conn, cookie.sequence);
+
+   xcb_flush(chain->conn);
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/aub.c b/src/vulkan/aub.c
deleted file mode 100644 (file)
index c33defd..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <drm.h>
-#include <i915_drm.h>
-
-#include "private.h"
-#include "aub.h"
-
-struct anv_aub_writer {
-   FILE *file;
-   uint32_t offset;
-   int gen;
-};
-
-static void
-aub_out(struct anv_aub_writer *writer, uint32_t data)
-{
-   fwrite(&data, 1, 4, writer->file);
-}
-
-static void
-aub_out_data(struct anv_aub_writer *writer, const void *data, size_t size)
-{
-   fwrite(data, 1, size, writer->file);
-}
-
-static struct anv_aub_writer *
-get_anv_aub_writer(struct anv_device *device)
-{
-   struct anv_aub_writer *writer = device->aub_writer;
-   int entry = 0x200003;
-   int i;
-   int gtt_size = 0x10000;
-   const char *filename;
-
-   if (geteuid() != getuid())
-      return NULL;
-
-   if (writer)
-      return writer;
-
-   writer = malloc(sizeof(*writer));
-   if (writer == NULL)
-      return NULL;
-
-   filename = "intel.aub";
-   writer->gen = device->info.gen;
-   writer->file = fopen(filename, "w+");
-   if (!writer->file) {
-      free(writer);
-      return NULL;
-   }
-
-   /* Start allocating objects from just after the GTT. */
-   writer->offset = gtt_size;
-
-   /* Start with a (required) version packet. */
-   aub_out(writer, CMD_AUB_HEADER | (13 - 2));
-   aub_out(writer,
-           (4 << AUB_HEADER_MAJOR_SHIFT) |
-           (0 << AUB_HEADER_MINOR_SHIFT));
-   for (i = 0; i < 8; i++) {
-      aub_out(writer, 0); /* app name */
-   }
-   aub_out(writer, 0); /* timestamp */
-   aub_out(writer, 0); /* timestamp */
-   aub_out(writer, 0); /* comment len */
-
-   /* Set up the GTT. The max we can handle is 256M */
-   aub_out(writer, CMD_AUB_TRACE_HEADER_BLOCK | ((writer->gen >= 8 ? 6 : 5) - 2));
-   aub_out(writer,
-           AUB_TRACE_MEMTYPE_GTT_ENTRY |
-           AUB_TRACE_TYPE_NOTYPE | AUB_TRACE_OP_DATA_WRITE);
-   aub_out(writer, 0); /* subtype */
-   aub_out(writer, 0); /* offset */
-   aub_out(writer, gtt_size); /* size */
-   if (writer->gen >= 8)
-      aub_out(writer, 0);
-   for (i = 0x000; i < gtt_size; i += 4, entry += 0x1000) {
-      aub_out(writer, entry);
-   }
-
-   return device->aub_writer = writer;
-}
-
-void
-anv_aub_writer_destroy(struct anv_aub_writer *writer)
-{
-   fclose(writer->file);
-   free(writer);
-}
-
-
-/**
- * Break up large objects into multiple writes.  Otherwise a 128kb VBO
- * would overflow the 16 bits of size field in the packet header and
- * everything goes badly after that.
- */
-static void
-aub_write_trace_block(struct anv_aub_writer *writer, uint32_t type,
-                      void *virtual, uint32_t size, uint32_t gtt_offset)
-{
-   uint32_t block_size;
-   uint32_t offset;
-   uint32_t subtype = 0;
-   static const char null_block[8 * 4096];
-
-   for (offset = 0; offset < size; offset += block_size) {
-      block_size = size - offset;
-
-      if (block_size > 8 * 4096)
-         block_size = 8 * 4096;
-
-      aub_out(writer,
-              CMD_AUB_TRACE_HEADER_BLOCK |
-              ((writer->gen >= 8 ? 6 : 5) - 2));
-      aub_out(writer,
-              AUB_TRACE_MEMTYPE_GTT |
-              type | AUB_TRACE_OP_DATA_WRITE);
-      aub_out(writer, subtype);
-      aub_out(writer, gtt_offset + offset);
-      aub_out(writer, align_u32(block_size, 4));
-      if (writer->gen >= 8)
-         aub_out(writer, 0);
-
-      if (virtual)
-         aub_out_data(writer, (char *) virtual + offset, block_size);
-      else
-         aub_out_data(writer, null_block, block_size);
-
-      /* Pad to a multiple of 4 bytes. */
-      aub_out_data(writer, null_block, -block_size & 3);
-   }
-}
-
-/*
- * Make a ringbuffer on fly and dump it
- */
-static void
-aub_build_dump_ringbuffer(struct anv_aub_writer *writer,
-                          uint32_t batch_offset, uint32_t offset,
-                          int ring_flag)
-{
-   uint32_t ringbuffer[4096];
-   int ring = AUB_TRACE_TYPE_RING_PRB0; /* The default ring */
-   int ring_count = 0;
-
-   if (ring_flag == I915_EXEC_BSD)
-      ring = AUB_TRACE_TYPE_RING_PRB1;
-   else if (ring_flag == I915_EXEC_BLT)
-      ring = AUB_TRACE_TYPE_RING_PRB2;
-
-   /* Make a ring buffer to execute our batchbuffer. */
-   memset(ringbuffer, 0, sizeof(ringbuffer));
-   if (writer->gen >= 8) {
-      ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START | (3 - 2);
-      ringbuffer[ring_count++] = batch_offset;
-      ringbuffer[ring_count++] = 0;
-   } else {
-      ringbuffer[ring_count++] = AUB_MI_BATCH_BUFFER_START;
-      ringbuffer[ring_count++] = batch_offset;
-   }
-
-   /* Write out the ring.  This appears to trigger execution of
-    * the ring in the simulator.
-    */
-   aub_out(writer,
-           CMD_AUB_TRACE_HEADER_BLOCK |
-           ((writer->gen >= 8 ? 6 : 5) - 2));
-   aub_out(writer,
-           AUB_TRACE_MEMTYPE_GTT | ring | AUB_TRACE_OP_COMMAND_WRITE);
-   aub_out(writer, 0); /* general/surface subtype */
-   aub_out(writer, offset);
-   aub_out(writer, ring_count * 4);
-   if (writer->gen >= 8)
-      aub_out(writer, 0);
-
-   /* FIXME: Need some flush operations here? */
-   aub_out_data(writer, ringbuffer, ring_count * 4);
-}
-
-struct aub_bo {
-   uint32_t offset;
-   void *map;
-   void *relocated;
-};
-
-static void
-relocate_bo(struct anv_bo *bo, struct drm_i915_gem_relocation_entry *relocs,
-            size_t num_relocs, struct aub_bo *bos)
-{
-   struct aub_bo *aub_bo = &bos[bo->index];
-   struct drm_i915_gem_relocation_entry *reloc;
-   uint32_t *dw;
-
-   aub_bo->relocated = malloc(bo->size);
-   memcpy(aub_bo->relocated, aub_bo->map, bo->size);
-   for (size_t i = 0; i < num_relocs; i++) {
-      reloc = &relocs[i];
-      assert(reloc->offset < bo->size);
-      dw = aub_bo->relocated + reloc->offset;
-      *dw = bos[reloc->target_handle].offset + reloc->delta;
-   }
-}
-
-void
-anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_device *device = cmd_buffer->device;
-   struct anv_batch *batch = &cmd_buffer->batch;
-   struct anv_aub_writer *writer;
-   struct anv_bo *bo;
-   uint32_t ring_flag = 0;
-   uint32_t offset;
-   struct aub_bo *aub_bos;
-
-   writer = get_anv_aub_writer(device);
-   if (writer == NULL)
-      return;
-
-   aub_bos = malloc(cmd_buffer->exec2_bo_count * sizeof(aub_bos[0]));
-   offset = writer->offset;
-   for (uint32_t i = 0; i < cmd_buffer->exec2_bo_count; i++) {
-      bo = cmd_buffer->exec2_bos[i];
-      if (bo->map)
-         aub_bos[i].map = bo->map;
-      else
-         aub_bos[i].map = anv_gem_mmap(device, bo->gem_handle, 0, bo->size);
-      aub_bos[i].relocated = aub_bos[i].map;
-      aub_bos[i].offset = offset;
-      offset = align_u32(offset + bo->size + 4095, 4096);
-   }
-
-   struct anv_batch_bo *first_bbo;
-   for (struct anv_batch_bo *bbo = cmd_buffer->last_batch_bo;
-        bbo != NULL; bbo = bbo->prev_batch_bo) {
-      /* Keep stashing the current BO until we get to the beginning */
-      first_bbo = bbo;
-
-      /* Handle relocations for this batch BO */
-      relocate_bo(&bbo->bo, &batch->relocs.relocs[bbo->first_reloc],
-                  bbo->num_relocs, aub_bos);
-   }
-   assert(first_bbo->prev_batch_bo == NULL);
-
-   for (struct anv_batch_bo *bbo = cmd_buffer->surface_batch_bo;
-        bbo != NULL; bbo = bbo->prev_batch_bo) {
-
-      /* Handle relocations for this surface state BO */
-      relocate_bo(&bbo->bo,
-                  &cmd_buffer->surface_relocs.relocs[bbo->first_reloc],
-                  bbo->num_relocs, aub_bos);
-   }
-
-   for (uint32_t i = 0; i < cmd_buffer->exec2_bo_count; i++) {
-      bo = cmd_buffer->exec2_bos[i];
-      if (i == cmd_buffer->exec2_bo_count - 1) {
-         assert(bo == &first_bbo->bo);
-         aub_write_trace_block(writer, AUB_TRACE_TYPE_BATCH,
-                               aub_bos[i].relocated,
-                               first_bbo->length, aub_bos[i].offset);
-      } else {
-         aub_write_trace_block(writer, AUB_TRACE_TYPE_NOTYPE,
-                               aub_bos[i].relocated,
-                               bo->size, aub_bos[i].offset);
-      }
-      if (aub_bos[i].relocated != aub_bos[i].map)
-         free(aub_bos[i].relocated);
-      if (aub_bos[i].map != bo->map)
-         anv_gem_munmap(aub_bos[i].map, bo->size);
-   }
-
-   /* Dump ring buffer */
-   aub_build_dump_ringbuffer(writer, aub_bos[first_bbo->bo.index].offset,
-                             offset, ring_flag);
-
-   free(aub_bos);
-
-   fflush(writer->file);
-}
diff --git a/src/vulkan/aub.h b/src/vulkan/aub.h
deleted file mode 100644 (file)
index 7a67712..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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/compiler.cpp b/src/vulkan/compiler.cpp
deleted file mode 100644 (file)
index 9152de6..0000000
+++ /dev/null
@@ -1,1209 +0,0 @@
-/*
- * 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 <sys/stat.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "private.h"
-
-#include <brw_context.h>
-#include <brw_wm.h> /* brw_new_shader_program is here */
-#include <brw_nir.h>
-
-#include <brw_vs.h>
-#include <brw_gs.h>
-#include <brw_cs.h>
-
-#include <mesa/main/shaderobj.h>
-#include <mesa/main/fbobject.h>
-#include <mesa/main/context.h>
-#include <mesa/program/program.h>
-#include <glsl/program.h>
-
-/* XXX: We need this to keep symbols in nir.h from conflicting with the
- * generated GEN command packing headers.  We need to fix *both* to not
- * define something as generic as LOAD.
- */
-#undef LOAD
-
-#include <glsl/nir/nir_spirv.h>
-
-#define SPIR_V_MAGIC_NUMBER 0x07230203
-
-static void
-fail_if(int cond, const char *format, ...)
-{
-   va_list args;
-
-   if (!cond)
-      return;
-
-   va_start(args, format);
-   vfprintf(stderr, format, args);
-   va_end(args);
-
-   exit(1);
-}
-
-static VkResult
-set_binding_table_layout(struct brw_stage_prog_data *prog_data,
-                         struct anv_pipeline *pipeline, uint32_t stage)
-{
-   uint32_t bias, count, k, *map;
-   struct anv_pipeline_layout *layout = pipeline->layout;
-
-   /* No layout is valid for shaders that don't bind any resources. */
-   if (pipeline->layout == NULL)
-      return VK_SUCCESS;
-
-   if (stage == VK_SHADER_STAGE_FRAGMENT)
-      bias = MAX_RTS;
-   else
-      bias = 0;
-
-   count = layout->stage[stage].surface_count;
-   prog_data->map_entries =
-      (uint32_t *) malloc(count * sizeof(prog_data->map_entries[0]));
-   if (prog_data->map_entries == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   k = bias;
-   map = prog_data->map_entries;
-   for (uint32_t i = 0; i < layout->num_sets; i++) {
-      prog_data->bind_map[i].index = map;
-      for (uint32_t j = 0; j < layout->set[i].layout->stage[stage].surface_count; j++)
-         *map++ = k++;
-
-      prog_data->bind_map[i].index_count =
-         layout->set[i].layout->stage[stage].surface_count;
-   }
-
-   return VK_SUCCESS;
-}
-
-static void
-brw_vs_populate_key(struct brw_context *brw,
-                    struct brw_vertex_program *vp,
-                    struct brw_vs_prog_key *key)
-{
-   struct gl_context *ctx = &brw->ctx;
-   /* BRW_NEW_VERTEX_PROGRAM */
-   struct gl_program *prog = (struct gl_program *) vp;
-
-   memset(key, 0, sizeof(*key));
-
-   /* Just upload the program verbatim for now.  Always send it all
-    * the inputs it asks for, whether they are varying or not.
-    */
-   key->base.program_string_id = vp->id;
-   brw_setup_vue_key_clip_info(brw, &key->base,
-                               vp->program.Base.UsesClipDistanceOut);
-
-   /* _NEW_POLYGON */
-   if (brw->gen < 6) {
-      key->copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL ||
-                           ctx->Polygon.BackMode != GL_FILL);
-   }
-
-   if (prog->OutputsWritten & (VARYING_BIT_COL0 | VARYING_BIT_COL1 |
-                               VARYING_BIT_BFC0 | VARYING_BIT_BFC1)) {
-      /* _NEW_LIGHT | _NEW_BUFFERS */
-      key->clamp_vertex_color = ctx->Light._ClampVertexColor;
-   }
-
-   /* _NEW_POINT */
-   if (brw->gen < 6 && ctx->Point.PointSprite) {
-      for (int i = 0; i < 8; i++) {
-         if (ctx->Point.CoordReplace[i])
-            key->point_coord_replace |= (1 << i);
-      }
-   }
-
-   /* _NEW_TEXTURE */
-   brw_populate_sampler_prog_key_data(ctx, prog, brw->vs.base.sampler_count,
-                                      &key->base.tex);
-}
-
-static bool
-really_do_vs_prog(struct brw_context *brw,
-                  struct gl_shader_program *prog,
-                  struct brw_vertex_program *vp,
-                  struct brw_vs_prog_key *key, struct anv_pipeline *pipeline)
-{
-   GLuint program_size;
-   const GLuint *program;
-   struct brw_vs_compile c;
-   struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
-   struct brw_stage_prog_data *stage_prog_data = &prog_data->base.base;
-   void *mem_ctx;
-   struct gl_shader *vs = NULL;
-
-   if (prog)
-      vs = prog->_LinkedShaders[MESA_SHADER_VERTEX];
-
-   memset(&c, 0, sizeof(c));
-   memcpy(&c.key, key, sizeof(*key));
-   memset(prog_data, 0, sizeof(*prog_data));
-
-   mem_ctx = ralloc_context(NULL);
-
-   c.vp = vp;
-
-   /* Allocate the references to the uniforms that will end up in the
-    * prog_data associated with the compiled program, and which will be freed
-    * by the state cache.
-    */
-   int param_count;
-   if (vs) {
-      /* We add padding around uniform values below vec4 size, with the worst
-       * case being a float value that gets blown up to a vec4, so be
-       * conservative here.
-       */
-      param_count = vs->num_uniform_components * 4;
-
-   } else {
-      param_count = vp->program.Base.Parameters->NumParameters * 4;
-   }
-   /* vec4_visitor::setup_uniform_clipplane_values() also uploads user clip
-    * planes as uniforms.
-    */
-   param_count += c.key.base.nr_userclip_plane_consts * 4;
-
-   /* Setting nr_params here NOT to the size of the param and pull_param
-    * arrays, but to the number of uniform components vec4_visitor
-    * needs. vec4_visitor::setup_uniforms() will set it back to a proper value.
-    */
-   stage_prog_data->nr_params = ALIGN(param_count, 4) / 4;
-   if (vs) {
-      stage_prog_data->nr_params += vs->num_samplers;
-   }
-
-   GLbitfield64 outputs_written = vp->program.Base.OutputsWritten;
-   prog_data->inputs_read = vp->program.Base.InputsRead;
-
-   if (c.key.copy_edgeflag) {
-      outputs_written |= BITFIELD64_BIT(VARYING_SLOT_EDGE);
-      prog_data->inputs_read |= VERT_BIT_EDGEFLAG;
-   }
-
-   if (brw->gen < 6) {
-      /* Put dummy slots into the VUE for the SF to put the replaced
-       * point sprite coords in.  We shouldn't need these dummy slots,
-       * which take up precious URB space, but it would mean that the SF
-       * doesn't get nice aligned pairs of input coords into output
-       * coords, which would be a pain to handle.
-       */
-      for (int i = 0; i < 8; i++) {
-         if (c.key.point_coord_replace & (1 << i))
-            outputs_written |= BITFIELD64_BIT(VARYING_SLOT_TEX0 + i);
-      }
-
-      /* if back colors are written, allocate slots for front colors too */
-      if (outputs_written & BITFIELD64_BIT(VARYING_SLOT_BFC0))
-         outputs_written |= BITFIELD64_BIT(VARYING_SLOT_COL0);
-      if (outputs_written & BITFIELD64_BIT(VARYING_SLOT_BFC1))
-         outputs_written |= BITFIELD64_BIT(VARYING_SLOT_COL1);
-   }
-
-   /* In order for legacy clipping to work, we need to populate the clip
-    * distance varying slots whenever clipping is enabled, even if the vertex
-    * shader doesn't write to gl_ClipDistance.
-    */
-   if (c.key.base.userclip_active) {
-      outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST0);
-      outputs_written |= BITFIELD64_BIT(VARYING_SLOT_CLIP_DIST1);
-   }
-
-   brw_compute_vue_map(brw->intelScreen->devinfo,
-                       &prog_data->base.vue_map, outputs_written);
-\
-   set_binding_table_layout(&prog_data->base.base, pipeline,
-                            VK_SHADER_STAGE_VERTEX);
-
-   /* Emit GEN4 code.
-    */
-   program = brw_vs_emit(brw, prog, &c, prog_data, mem_ctx, &program_size);
-   if (program == NULL) {
-      ralloc_free(mem_ctx);
-      return false;
-   }
-
-   struct anv_state vs_state = anv_state_stream_alloc(&pipeline->program_stream,
-                                                      program_size, 64);
-   memcpy(vs_state.map, program, program_size);
-
-   pipeline->vs_simd8 = vs_state.offset;
-
-   ralloc_free(mem_ctx);
-
-   return true;
-}
-
-void brw_wm_populate_key(struct brw_context *brw,
-                         struct brw_fragment_program *fp,
-                         struct brw_wm_prog_key *key)
-{
-   struct gl_context *ctx = &brw->ctx;
-   struct gl_program *prog = (struct gl_program *) brw->fragment_program;
-   GLuint lookup = 0;
-   GLuint line_aa;
-   bool program_uses_dfdy = fp->program.UsesDFdy;
-   struct gl_framebuffer draw_buffer;
-   bool multisample_fbo;
-
-   memset(key, 0, sizeof(*key));
-
-   for (int i = 0; i < MAX_SAMPLERS; i++) {
-      /* Assume color sampler, no swizzling. */
-      key->tex.swizzles[i] = SWIZZLE_XYZW;
-   }
-
-   /* A non-zero framebuffer name indicates that the framebuffer was created by
-    * the user rather than the window system. */
-   draw_buffer.Name = 1;
-   draw_buffer.Visual.samples = 1;
-   draw_buffer._NumColorDrawBuffers = 1;
-   draw_buffer._NumColorDrawBuffers = 1;
-   draw_buffer.Width = 400;
-   draw_buffer.Height = 400;
-   ctx->DrawBuffer = &draw_buffer;
-
-   multisample_fbo = ctx->DrawBuffer->Visual.samples > 1;
-
-   /* Build the index for table lookup
-    */
-   if (brw->gen < 6) {
-      /* _NEW_COLOR */
-      if (fp->program.UsesKill || ctx->Color.AlphaEnabled)
-         lookup |= IZ_PS_KILL_ALPHATEST_BIT;
-
-      if (fp->program.Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH))
-         lookup |= IZ_PS_COMPUTES_DEPTH_BIT;
-
-      /* _NEW_DEPTH */
-      if (ctx->Depth.Test)
-         lookup |= IZ_DEPTH_TEST_ENABLE_BIT;
-
-      if (ctx->Depth.Test && ctx->Depth.Mask) /* ?? */
-         lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
-
-      /* _NEW_STENCIL | _NEW_BUFFERS */
-      if (ctx->Stencil._Enabled) {
-         lookup |= IZ_STENCIL_TEST_ENABLE_BIT;
-
-         if (ctx->Stencil.WriteMask[0] ||
-             ctx->Stencil.WriteMask[ctx->Stencil._BackFace])
-            lookup |= IZ_STENCIL_WRITE_ENABLE_BIT;
-      }
-      key->iz_lookup = lookup;
-   }
-
-   line_aa = AA_NEVER;
-
-   /* _NEW_LINE, _NEW_POLYGON, BRW_NEW_REDUCED_PRIMITIVE */
-   if (ctx->Line.SmoothFlag) {
-      if (brw->reduced_primitive == GL_LINES) {
-         line_aa = AA_ALWAYS;
-      }
-      else if (brw->reduced_primitive == GL_TRIANGLES) {
-         if (ctx->Polygon.FrontMode == GL_LINE) {
-            line_aa = AA_SOMETIMES;
-
-            if (ctx->Polygon.BackMode == GL_LINE ||
-                (ctx->Polygon.CullFlag &&
-                 ctx->Polygon.CullFaceMode == GL_BACK))
-               line_aa = AA_ALWAYS;
-         }
-         else if (ctx->Polygon.BackMode == GL_LINE) {
-            line_aa = AA_SOMETIMES;
-
-            if ((ctx->Polygon.CullFlag &&
-                 ctx->Polygon.CullFaceMode == GL_FRONT))
-               line_aa = AA_ALWAYS;
-         }
-      }
-   }
-
-   key->line_aa = line_aa;
-
-   /* _NEW_HINT */
-   key->high_quality_derivatives =
-      ctx->Hint.FragmentShaderDerivative == GL_NICEST;
-
-   if (brw->gen < 6)
-      key->stats_wm = brw->stats_wm;
-
-   /* _NEW_LIGHT */
-   key->flat_shade = (ctx->Light.ShadeModel == GL_FLAT);
-
-   /* _NEW_FRAG_CLAMP | _NEW_BUFFERS */
-   key->clamp_fragment_color = ctx->Color._ClampFragmentColor;
-
-   /* _NEW_TEXTURE */
-   brw_populate_sampler_prog_key_data(ctx, prog, brw->wm.base.sampler_count,
-                                      &key->tex);
-
-   /* _NEW_BUFFERS */
-   /*
-    * Include the draw buffer origin and height so that we can calculate
-    * fragment position values relative to the bottom left of the drawable,
-    * from the incoming screen origin relative position we get as part of our
-    * payload.
-    *
-    * This is only needed for the WM_WPOSXY opcode when the fragment program
-    * uses the gl_FragCoord input.
-    *
-    * We could avoid recompiling by including this as a constant referenced by
-    * our program, but if we were to do that it would also be nice to handle
-    * getting that constant updated at batchbuffer submit time (when we
-    * hold the lock and know where the buffer really is) rather than at emit
-    * time when we don't hold the lock and are just guessing.  We could also
-    * just avoid using this as key data if the program doesn't use
-    * fragment.position.
-    *
-    * For DRI2 the origin_x/y will always be (0,0) but we still need the
-    * drawable height in order to invert the Y axis.
-    */
-   if (fp->program.Base.InputsRead & VARYING_BIT_POS) {
-      key->drawable_height = ctx->DrawBuffer->Height;
-   }
-
-   if ((fp->program.Base.InputsRead & VARYING_BIT_POS) || program_uses_dfdy) {
-      key->render_to_fbo = _mesa_is_user_fbo(ctx->DrawBuffer);
-   }
-
-   /* _NEW_BUFFERS */
-   key->nr_color_regions = ctx->DrawBuffer->_NumColorDrawBuffers;
-
-   /* _NEW_MULTISAMPLE, _NEW_COLOR, _NEW_BUFFERS */
-   key->replicate_alpha = ctx->DrawBuffer->_NumColorDrawBuffers > 1 &&
-      (ctx->Multisample.SampleAlphaToCoverage || ctx->Color.AlphaEnabled);
-
-   /* _NEW_BUFFERS _NEW_MULTISAMPLE */
-   /* Ignore sample qualifier while computing this flag. */
-   key->persample_shading =
-      _mesa_get_min_invocations_per_fragment(ctx, &fp->program, true) > 1;
-   if (key->persample_shading)
-      key->persample_2x = ctx->DrawBuffer->Visual.samples == 2;
-
-   key->compute_pos_offset =
-      _mesa_get_min_invocations_per_fragment(ctx, &fp->program, false) > 1 &&
-      fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_POS;
-
-   key->compute_sample_id =
-      multisample_fbo &&
-      ctx->Multisample.Enabled &&
-      (fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_ID);
-
-   /* BRW_NEW_VUE_MAP_GEOM_OUT */
-   if (brw->gen < 6 || _mesa_bitcount_64(fp->program.Base.InputsRead &
-                                         BRW_FS_VARYING_INPUT_MASK) > 16)
-      key->input_slots_valid = brw->vue_map_geom_out.slots_valid;
-
-
-   /* _NEW_COLOR | _NEW_BUFFERS */
-   /* Pre-gen6, the hardware alpha test always used each render
-    * target's alpha to do alpha test, as opposed to render target 0's alpha
-    * like GL requires.  Fix that by building the alpha test into the
-    * shader, and we'll skip enabling the fixed function alpha test.
-    */
-   if (brw->gen < 6 && ctx->DrawBuffer->_NumColorDrawBuffers > 1 && ctx->Color.AlphaEnabled) {
-      key->alpha_test_func = ctx->Color.AlphaFunc;
-      key->alpha_test_ref = ctx->Color.AlphaRef;
-   }
-
-   /* The unique fragment program ID */
-   key->program_string_id = fp->id;
-
-   ctx->DrawBuffer = NULL;
-}
-
-static uint8_t
-computed_depth_mode(struct gl_fragment_program *fp)
-{
-   if (fp->Base.OutputsWritten & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) {
-      switch (fp->FragDepthLayout) {
-      case FRAG_DEPTH_LAYOUT_NONE:
-      case FRAG_DEPTH_LAYOUT_ANY:
-         return BRW_PSCDEPTH_ON;
-      case FRAG_DEPTH_LAYOUT_GREATER:
-         return BRW_PSCDEPTH_ON_GE;
-      case FRAG_DEPTH_LAYOUT_LESS:
-         return BRW_PSCDEPTH_ON_LE;
-      case FRAG_DEPTH_LAYOUT_UNCHANGED:
-         return BRW_PSCDEPTH_OFF;
-      }
-   }
-   return BRW_PSCDEPTH_OFF;
-}
-
-static bool
-really_do_wm_prog(struct brw_context *brw,
-                  struct gl_shader_program *prog,
-                  struct brw_fragment_program *fp,
-                  struct brw_wm_prog_key *key, struct anv_pipeline *pipeline)
-{
-   struct gl_context *ctx = &brw->ctx;
-   void *mem_ctx = ralloc_context(NULL);
-   struct brw_wm_prog_data *prog_data = &pipeline->wm_prog_data;
-   struct gl_shader *fs = NULL;
-   unsigned int program_size;
-   const uint32_t *program;
-
-   if (prog)
-      fs = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
-
-   memset(prog_data, 0, sizeof(*prog_data));
-
-   /* key->alpha_test_func means simulating alpha testing via discards,
-    * so the shader definitely kills pixels.
-    */
-   prog_data->uses_kill = fp->program.UsesKill || key->alpha_test_func;
-
-   prog_data->computed_depth_mode = computed_depth_mode(&fp->program);
-
-   /* Allocate the references to the uniforms that will end up in the
-    * prog_data associated with the compiled program, and which will be freed
-    * by the state cache.
-    */
-   int param_count;
-   if (fs) {
-      param_count = fs->num_uniform_components;
-   } else {
-      param_count = fp->program.Base.Parameters->NumParameters * 4;
-   }
-   /* The backend also sometimes adds params for texture size. */
-   param_count += 2 * ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxTextureImageUnits;
-   prog_data->base.param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.pull_param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.nr_params = param_count;
-
-   prog_data->barycentric_interp_modes =
-      brw_compute_barycentric_interp_modes(brw, key->flat_shade,
-                                           key->persample_shading,
-                                           &fp->program);
-
-   set_binding_table_layout(&prog_data->base, pipeline,
-                            VK_SHADER_STAGE_FRAGMENT);
-   /* This needs to come after shader time and pull constant entries, but we
-    * don't have those set up now, so just put it after the layout entries.
-    */
-   prog_data->binding_table.render_target_start = 0;
-
-   program = brw_wm_fs_emit(brw, mem_ctx, key, prog_data,
-                            &fp->program, prog, &program_size);
-   if (program == NULL) {
-      ralloc_free(mem_ctx);
-      return false;
-   }
-
-   struct anv_state ps_state = anv_state_stream_alloc(&pipeline->program_stream,
-                                                      program_size, 64);
-   memcpy(ps_state.map, program, program_size);
-
-   if (prog_data->no_8)
-      pipeline->ps_simd8 = NO_KERNEL;
-   else
-      pipeline->ps_simd8 = ps_state.offset;
-
-   if (prog_data->no_8 || prog_data->prog_offset_16) {
-      pipeline->ps_simd16 = ps_state.offset + prog_data->prog_offset_16;
-   } else {
-      pipeline->ps_simd16 = NO_KERNEL;
-   }
-
-   ralloc_free(mem_ctx);
-
-   return true;
-}
-
-static void
-brw_gs_populate_key(struct brw_context *brw,
-                    struct anv_pipeline *pipeline,
-                    struct brw_geometry_program *gp,
-                    struct brw_gs_prog_key *key)
-{
-   struct gl_context *ctx = &brw->ctx;
-   struct brw_stage_state *stage_state = &brw->gs.base;
-   struct gl_program *prog = &gp->program.Base;
-
-   memset(key, 0, sizeof(*key));
-
-   key->base.program_string_id = gp->id;
-   brw_setup_vue_key_clip_info(brw, &key->base,
-                               gp->program.Base.UsesClipDistanceOut);
-
-   /* _NEW_TEXTURE */
-   brw_populate_sampler_prog_key_data(ctx, prog, stage_state->sampler_count,
-                                      &key->base.tex);
-
-   struct brw_vs_prog_data *prog_data = &pipeline->vs_prog_data;
-
-   /* BRW_NEW_VUE_MAP_VS */
-   key->input_varyings = prog_data->base.vue_map.slots_valid;
-}
-
-static bool
-really_do_gs_prog(struct brw_context *brw,
-                  struct gl_shader_program *prog,
-                  struct brw_geometry_program *gp,
-                  struct brw_gs_prog_key *key, struct anv_pipeline *pipeline)
-{
-   struct brw_gs_compile_output output;
-
-   /* FIXME: We pass the bind map to the compile in the output struct. Need
-    * something better. */
-   set_binding_table_layout(&output.prog_data.base.base,
-                            pipeline, VK_SHADER_STAGE_GEOMETRY);
-
-   brw_compile_gs_prog(brw, prog, gp, key, &output);
-
-   struct anv_state gs_state = anv_state_stream_alloc(&pipeline->program_stream,
-                                                      output.program_size, 64);
-   memcpy(gs_state.map, output.program, output.program_size);
-
-   pipeline->gs_vec4 = gs_state.offset;
-   pipeline->gs_vertex_count = gp->program.VerticesIn;
-
-   ralloc_free(output.mem_ctx);
-
-   return true;
-}
-
-static bool
-brw_codegen_cs_prog(struct brw_context *brw,
-                    struct gl_shader_program *prog,
-                    struct brw_compute_program *cp,
-                    struct brw_cs_prog_key *key, struct anv_pipeline *pipeline)
-{
-   struct gl_context *ctx = &brw->ctx;
-   const GLuint *program;
-   void *mem_ctx = ralloc_context(NULL);
-   GLuint program_size;
-   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
-
-   struct gl_shader *cs = prog->_LinkedShaders[MESA_SHADER_COMPUTE];
-   assert (cs);
-
-   memset(prog_data, 0, sizeof(*prog_data));
-
-   set_binding_table_layout(&prog_data->base, pipeline, VK_SHADER_STAGE_COMPUTE);
-
-   /* Allocate the references to the uniforms that will end up in the
-    * prog_data associated with the compiled program, and which will be freed
-    * by the state cache.
-    */
-   int param_count = cs->num_uniform_components;
-
-   /* The backend also sometimes adds params for texture size. */
-   param_count += 2 * ctx->Const.Program[MESA_SHADER_COMPUTE].MaxTextureImageUnits;
-   prog_data->base.param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.pull_param =
-      rzalloc_array(NULL, const gl_constant_value *, param_count);
-   prog_data->base.nr_params = param_count;
-
-   program = brw_cs_emit(brw, mem_ctx, key, prog_data,
-                         &cp->program, prog, &program_size);
-   if (program == NULL) {
-      ralloc_free(mem_ctx);
-      return false;
-   }
-
-   if (unlikely(INTEL_DEBUG & DEBUG_CS))
-      fprintf(stderr, "\n");
-
-   struct anv_state cs_state = anv_state_stream_alloc(&pipeline->program_stream,
-                                                      program_size, 64);
-   memcpy(cs_state.map, program, program_size);
-
-   pipeline->cs_simd = cs_state.offset;
-
-   ralloc_free(mem_ctx);
-
-   return true;
-}
-
-static void
-brw_cs_populate_key(struct brw_context *brw,
-                    struct brw_compute_program *bcp, struct brw_cs_prog_key *key)
-{
-   memset(key, 0, sizeof(*key));
-
-   /* The unique compute program ID */
-   key->program_string_id = bcp->id;
-}
-
-static void
-fail_on_compile_error(int status, const char *msg)
-{
-   int source, line, column;
-   char error[256];
-
-   if (status)
-      return;
-
-   if (sscanf(msg, "%d:%d(%d): error: %255[^\n]", &source, &line, &column, error) == 4)
-      fail_if(!status, "%d:%s\n", line, error);
-   else
-      fail_if(!status, "%s\n", msg);
-}
-
-struct anv_compiler {
-   struct anv_device *device;
-   struct intel_screen *screen;
-   struct brw_context *brw;
-   struct gl_pipeline_object pipeline;
-};
-
-extern "C" {
-
-struct anv_compiler *
-anv_compiler_create(struct anv_device *device)
-{
-   const struct brw_device_info *devinfo = &device->info;
-   struct anv_compiler *compiler;
-   struct gl_context *ctx;
-
-   compiler = rzalloc(NULL, struct anv_compiler);
-   if (compiler == NULL)
-      return NULL;
-
-   compiler->screen = rzalloc(compiler, struct intel_screen);
-   if (compiler->screen == NULL)
-      goto fail;
-
-   compiler->brw = rzalloc(compiler, struct brw_context);
-   if (compiler->brw == NULL)
-      goto fail;
-
-   compiler->device = device;
-
-   compiler->brw->optionCache.info = NULL;
-   compiler->brw->bufmgr = NULL;
-   compiler->brw->gen = devinfo->gen;
-   compiler->brw->is_g4x = devinfo->is_g4x;
-   compiler->brw->is_baytrail = devinfo->is_baytrail;
-   compiler->brw->is_haswell = devinfo->is_haswell;
-   compiler->brw->is_cherryview = devinfo->is_cherryview;
-
-   /* We need this at least for CS, which will check brw->max_cs_threads
-    * against the work group size. */
-   compiler->brw->max_vs_threads = devinfo->max_vs_threads;
-   compiler->brw->max_hs_threads = devinfo->max_hs_threads;
-   compiler->brw->max_ds_threads = devinfo->max_ds_threads;
-   compiler->brw->max_gs_threads = devinfo->max_gs_threads;
-   compiler->brw->max_wm_threads = devinfo->max_wm_threads;
-   compiler->brw->max_cs_threads = devinfo->max_cs_threads;
-   compiler->brw->urb.size = devinfo->urb.size;
-   compiler->brw->urb.min_vs_entries = devinfo->urb.min_vs_entries;
-   compiler->brw->urb.max_vs_entries = devinfo->urb.max_vs_entries;
-   compiler->brw->urb.max_hs_entries = devinfo->urb.max_hs_entries;
-   compiler->brw->urb.max_ds_entries = devinfo->urb.max_ds_entries;
-   compiler->brw->urb.max_gs_entries = devinfo->urb.max_gs_entries;
-
-   compiler->brw->intelScreen = compiler->screen;
-   compiler->screen->devinfo = &device->info;
-
-   brw_process_intel_debug_variable(compiler->screen);
-
-   compiler->screen->compiler = brw_compiler_create(compiler, &device->info);
-
-   ctx = &compiler->brw->ctx;
-   _mesa_init_shader_object_functions(&ctx->Driver);
-
-   _mesa_init_constants(&ctx->Const, API_OPENGL_CORE);
-
-   brw_initialize_context_constants(compiler->brw);
-
-   intelInitExtensions(ctx);
-
-   /* Set dd::NewShader */
-   brwInitFragProgFuncs(&ctx->Driver);
-
-   ctx->_Shader = &compiler->pipeline;
-
-   compiler->brw->precompile = false;
-
-   return compiler;
-
- fail:
-   ralloc_free(compiler);
-   return NULL;
-}
-
-void
-anv_compiler_destroy(struct anv_compiler *compiler)
-{
-   _mesa_free_errors_data(&compiler->brw->ctx);
-   ralloc_free(compiler);
-}
-
-/* From gen7_urb.c */
-
-/* FIXME: Add to struct intel_device_info */
-
-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->vs_simd8 != NO_KERNEL;
-   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->gs_vec4 != NO_KERNEL;
-   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 const struct {
-   uint32_t token;
-   gl_shader_stage stage;
-   const char *name;
-} stage_info[] = {
-   { GL_VERTEX_SHADER, MESA_SHADER_VERTEX, "vertex" },
-   { GL_TESS_CONTROL_SHADER, (gl_shader_stage)-1,"tess control" },
-   { GL_TESS_EVALUATION_SHADER, (gl_shader_stage)-1, "tess evaluation" },
-   { GL_GEOMETRY_SHADER, MESA_SHADER_GEOMETRY, "geometry" },
-   { GL_FRAGMENT_SHADER, MESA_SHADER_FRAGMENT, "fragment" },
-   { GL_COMPUTE_SHADER, MESA_SHADER_COMPUTE, "compute" },
-};
-
-struct spirv_header{
-   uint32_t magic;
-   uint32_t version;
-   uint32_t gen_magic;
-};
-
-static const char *
-src_as_glsl(const char *data)
-{
-   const struct spirv_header *as_spirv = (const struct spirv_header *)data;
-
-   /* Check alignment */
-   if ((intptr_t)data & 0x3) {
-      return data;
-   }
-
-   if (as_spirv->magic == SPIR_V_MAGIC_NUMBER) {
-      /* LunarG back-door */
-      if (as_spirv->version == 0)
-         return data + 12;
-      else
-         return NULL;
-   } else {
-      return data;
-   }
-}
-
-static void
-anv_compile_shader_glsl(struct anv_compiler *compiler,
-                   struct gl_shader_program *program,
-                   struct anv_pipeline *pipeline, uint32_t stage)
-{
-   struct brw_context *brw = compiler->brw;
-   struct gl_shader *shader;
-   int name = 0;
-
-   shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
-   fail_if(shader == NULL, "failed to create %s shader\n", stage_info[stage].name);
-
-   shader->Source = strdup(src_as_glsl(pipeline->shaders[stage]->module->data));
-   _mesa_glsl_compile_shader(&brw->ctx, shader, false, false);
-   fail_on_compile_error(shader->CompileStatus, shader->InfoLog);
-
-   program->Shaders[program->NumShaders] = shader;
-   program->NumShaders++;
-}
-
-static void
-setup_nir_io(struct gl_program *prog,
-             nir_shader *shader)
-{
-   foreach_list_typed(nir_variable, var, node, &shader->inputs) {
-      prog->InputsRead |= BITFIELD64_BIT(var->data.location);
-   }
-
-   foreach_list_typed(nir_variable, var, node, &shader->outputs) {
-      prog->OutputsWritten |= BITFIELD64_BIT(var->data.location);
-   }
-}
-
-static void
-anv_compile_shader_spirv(struct anv_compiler *compiler,
-                         struct gl_shader_program *program,
-                         struct anv_pipeline *pipeline, uint32_t stage)
-{
-   struct brw_context *brw = compiler->brw;
-   struct anv_shader *shader = pipeline->shaders[stage];
-   struct gl_shader *mesa_shader;
-   int name = 0;
-
-   mesa_shader = brw_new_shader(&brw->ctx, name, stage_info[stage].token);
-   fail_if(mesa_shader == NULL,
-           "failed to create %s shader\n", stage_info[stage].name);
-
-   switch (stage) {
-   case VK_SHADER_STAGE_VERTEX:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_vertex_program)->program.Base;
-      break;
-   case VK_SHADER_STAGE_GEOMETRY:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_geometry_program)->program.Base;
-      break;
-   case VK_SHADER_STAGE_FRAGMENT:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_fragment_program)->program.Base;
-      break;
-   case VK_SHADER_STAGE_COMPUTE:
-      mesa_shader->Program = &rzalloc(mesa_shader, struct brw_compute_program)->program.Base;
-      break;
-   }
-
-   mesa_shader->Program->Parameters =
-      rzalloc(mesa_shader, struct gl_program_parameter_list);
-
-   mesa_shader->Type = stage_info[stage].token;
-   mesa_shader->Stage = stage_info[stage].stage;
-
-   assert(shader->module->size % 4 == 0);
-
-   struct gl_shader_compiler_options *glsl_options =
-      &compiler->screen->compiler->glsl_compiler_options[stage_info[stage].stage];
-
-   mesa_shader->Program->nir =
-      spirv_to_nir((uint32_t *)shader->module->data, shader->module->size / 4,
-                   glsl_options->NirOptions);
-   nir_validate_shader(mesa_shader->Program->nir);
-
-   brw_process_nir(mesa_shader->Program->nir,
-                   compiler->screen->devinfo,
-                   NULL, mesa_shader->Stage);
-
-   setup_nir_io(mesa_shader->Program, mesa_shader->Program->nir);
-
-   fail_if(mesa_shader->Program->nir == NULL,
-           "failed to translate SPIR-V to NIR\n");
-
-   program->Shaders[program->NumShaders] = mesa_shader;
-   program->NumShaders++;
-}
-
-static void
-add_compiled_stage(struct anv_pipeline *pipeline, uint32_t 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];
-}
-
-int
-anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline)
-{
-   struct gl_shader_program *program;
-   int name = 0;
-   struct brw_context *brw = compiler->brw;
-
-   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));
-
-   brw->use_rep_send = pipeline->use_repclear;
-   brw->no_simd8 = pipeline->use_repclear;
-
-   program = brw->ctx.Driver.NewShaderProgram(name);
-   program->Shaders = (struct gl_shader **)
-      calloc(VK_SHADER_STAGE_NUM, sizeof(struct gl_shader *));
-   fail_if(program == NULL || program->Shaders == NULL,
-           "failed to create program\n");
-
-   bool all_spirv = true;
-   for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
-      if (pipeline->shaders[i] == NULL)
-         continue;
-
-      /* You need at least this much for "void main() { }" anyway */
-      assert(pipeline->shaders[i]->module->size >= 12);
-
-      if (src_as_glsl(pipeline->shaders[i]->module->data)) {
-         all_spirv = false;
-         break;
-      }
-
-      assert(pipeline->shaders[i]->module->size % 4 == 0);
-   }
-
-   if (all_spirv) {
-      for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
-         if (pipeline->shaders[i])
-            anv_compile_shader_spirv(compiler, program, pipeline, i);
-      }
-
-      for (unsigned i = 0; i < program->NumShaders; i++) {
-         struct gl_shader *shader = program->Shaders[i];
-         program->_LinkedShaders[shader->Stage] = shader;
-      }
-   } else {
-      for (unsigned i = 0; i < VK_SHADER_STAGE_NUM; i++) {
-         if (pipeline->shaders[i])
-            anv_compile_shader_glsl(compiler, program, pipeline, i);
-      }
-
-      _mesa_glsl_link_shader(&brw->ctx, program);
-      fail_on_compile_error(program->LinkStatus,
-                            program->InfoLog);
-   }
-
-   bool success;
-   pipeline->active_stages = 0;
-   pipeline->total_scratch = 0;
-
-   if (pipeline->shaders[VK_SHADER_STAGE_VERTEX]) {
-      struct brw_vs_prog_key vs_key;
-      struct gl_vertex_program *vp = (struct gl_vertex_program *)
-         program->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
-      struct brw_vertex_program *bvp = brw_vertex_program(vp);
-
-      brw_vs_populate_key(brw, bvp, &vs_key);
-
-      success = really_do_vs_prog(brw, program, bvp, &vs_key, pipeline);
-      fail_if(!success, "do_wm_prog failed\n");
-      add_compiled_stage(pipeline, VK_SHADER_STAGE_VERTEX,
-                         &pipeline->vs_prog_data.base.base);
-
-      if (vp->Base.OutputsWritten & VARYING_SLOT_PSIZ)
-         pipeline->writes_point_size = true;
-   } else {
-      memset(&pipeline->vs_prog_data, 0, sizeof(pipeline->vs_prog_data));
-      pipeline->vs_simd8 = NO_KERNEL;
-   }
-
-
-   if (pipeline->shaders[VK_SHADER_STAGE_GEOMETRY]) {
-      struct brw_gs_prog_key gs_key;
-      struct gl_geometry_program *gp = (struct gl_geometry_program *)
-         program->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program;
-      struct brw_geometry_program *bgp = brw_geometry_program(gp);
-
-      brw_gs_populate_key(brw, pipeline, bgp, &gs_key);
-
-      success = really_do_gs_prog(brw, program, bgp, &gs_key, pipeline);
-      fail_if(!success, "do_gs_prog failed\n");
-      add_compiled_stage(pipeline, VK_SHADER_STAGE_GEOMETRY,
-                         &pipeline->gs_prog_data.base.base);
-
-      if (gp->Base.OutputsWritten & VARYING_SLOT_PSIZ)
-         pipeline->writes_point_size = true;
-   } else {
-      pipeline->gs_vec4 = NO_KERNEL;
-   }
-
-   if (pipeline->shaders[VK_SHADER_STAGE_FRAGMENT]) {
-      struct brw_wm_prog_key wm_key;
-      struct gl_fragment_program *fp = (struct gl_fragment_program *)
-         program->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
-      struct brw_fragment_program *bfp = brw_fragment_program(fp);
-
-      brw_wm_populate_key(brw, bfp, &wm_key);
-
-      success = really_do_wm_prog(brw, program, bfp, &wm_key, pipeline);
-      fail_if(!success, "do_wm_prog failed\n");
-      add_compiled_stage(pipeline, VK_SHADER_STAGE_FRAGMENT,
-                         &pipeline->wm_prog_data.base);
-   }
-
-   if (pipeline->shaders[VK_SHADER_STAGE_COMPUTE]) {
-      struct brw_cs_prog_key cs_key;
-      struct gl_compute_program *cp = (struct gl_compute_program *)
-         program->_LinkedShaders[MESA_SHADER_COMPUTE]->Program;
-      struct brw_compute_program *bcp = brw_compute_program(cp);
-
-      brw_cs_populate_key(brw, bcp, &cs_key);
-
-      success = brw_codegen_cs_prog(brw, program, bcp, &cs_key, pipeline);
-      fail_if(!success, "brw_codegen_cs_prog failed\n");
-      add_compiled_stage(pipeline, VK_SHADER_STAGE_COMPUTE,
-                         &pipeline->cs_prog_data.base);
-   }
-
-   /* XXX: Deleting the shader is broken with our current SPIR-V hacks.  We
-    * need to fix this ASAP.
-    */
-   if (!all_spirv)
-      brw->ctx.Driver.DeleteShaderProgram(&brw->ctx, program);
-
-   struct anv_device *device = compiler->device;
-   while (device->scratch_block_pool.bo.size < pipeline->total_scratch)
-      anv_block_pool_alloc(&device->scratch_block_pool);
-
-   gen7_compute_urb_partition(pipeline);
-
-   return 0;
-}
-
-/* This badly named function frees the struct anv_pipeline data that the compiler
- * allocates.  Currently just the prog_data structs.
- */
-void
-anv_compiler_free(struct anv_pipeline *pipeline)
-{
-   for (uint32_t stage = 0; stage < VK_SHADER_STAGE_NUM; stage++) {
-      if (pipeline->prog_data[stage]) {
-         free(pipeline->prog_data[stage]->map_entries);
-         ralloc_free(pipeline->prog_data[stage]->param);
-         ralloc_free(pipeline->prog_data[stage]->pull_param);
-      }
-   }
-}
-
-}
diff --git a/src/vulkan/device.c b/src/vulkan/device.c
deleted file mode 100644 (file)
index 1073ab0..0000000
+++ /dev/null
@@ -1,2390 +0,0 @@
-/*
- * 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 "private.h"
-#include "mesa/main/git_sha1.h"
-
-static int
-anv_env_get_int(const char *name)
-{
-   const char *val = getenv(name);
-
-   if (!val)
-      return 0;
-
-   return strtol(val, NULL, 0);
-}
-
-static void
-anv_physical_device_finish(struct anv_physical_device *device)
-{
-   if (device->fd >= 0)
-      close(device->fd);
-}
-
-static VkResult
-anv_physical_device_init(struct anv_physical_device *device,
-                         struct anv_instance *instance,
-                         const char *path)
-{
-   device->fd = open(path, O_RDWR | O_CLOEXEC);
-   if (device->fd < 0)
-      return vk_error(VK_ERROR_UNAVAILABLE);
-
-   device->instance = instance;
-   device->path = path;
-   
-   device->chipset_id = anv_env_get_int("INTEL_DEVID_OVERRIDE");
-   device->no_hw = false;
-   if (device->chipset_id) {
-      /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */
-      device->no_hw = true;
-   } else {
-      device->chipset_id = anv_gem_get_param(device->fd, I915_PARAM_CHIPSET_ID);
-   }
-   if (!device->chipset_id)
-      goto fail;
-
-   device->name = brw_get_device_name(device->chipset_id);
-   device->info = brw_get_device_info(device->chipset_id, -1);
-   if (!device->info)
-      goto fail;
-   
-   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_WAIT_TIMEOUT))
-      goto fail;
-
-   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_EXECBUF2))
-      goto fail;
-
-   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_LLC))
-      goto fail;
-
-   if (!anv_gem_get_param(device->fd, I915_PARAM_HAS_EXEC_CONSTANTS))
-      goto fail;
-   
-   return VK_SUCCESS;
-   
-fail:
-   anv_physical_device_finish(device);
-   return vk_error(VK_ERROR_UNAVAILABLE);
-}
-
-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
-};
-
-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->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->pAllocUserData = alloc_callbacks->pUserData;
-   instance->pfnAlloc = alloc_callbacks->pfnAlloc;
-   instance->pfnFree = alloc_callbacks->pfnFree;
-   instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
-   instance->physicalDeviceCount = 0;
-
-   *pInstance = anv_instance_to_handle(instance);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyInstance(
-    VkInstance                                  _instance)
-{
-   ANV_FROM_HANDLE(anv_instance, instance, _instance);
-
-   if (instance->physicalDeviceCount > 0) {
-      anv_physical_device_finish(&instance->physicalDevice);
-   }
-
-   instance->pfnFree(instance->pAllocUserData, instance);
-
-   return VK_SUCCESS;
-}
-
-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_SUCCESS)
-         return result;
-
-      instance->physicalDeviceCount = 1;
-   }
-
-   /* 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,
-      .instancedDrawIndirect                    = true,
-      .depthClip                                = false,
-      .depthBiasClamp                           = false,
-      .fillModeNonSolid                         = true,
-      .depthBounds                              = false,
-      .wideLines                                = true,
-      .largePoints                              = true,
-      .textureCompressionETC2                   = true,
-      .textureCompressionASTC_LDR               = true,
-      .textureCompressionBC                     = true,
-      .pipelineStatisticsQuery                  = true,
-      .vertexSideEffects                        = false,
-      .tessellationSideEffects                  = false,
-      .geometrySideEffects                      = false,
-      .fragmentSideEffects                      = false,
-      .shaderTessellationPointSize              = false,
-      .shaderGeometryPointSize                  = true,
-      .shaderTextureGatherExtended              = true,
-      .shaderStorageImageExtendedFormats        = false,
-      .shaderStorageImageMultisample            = false,
-      .shaderStorageBufferArrayConstantIndexing = false,
-      .shaderStorageImageArrayConstantIndexing  = false,
-      .shaderUniformBufferArrayDynamicIndexing  = true,
-      .shaderSampledImageArrayDynamicIndexing   = false,
-      .shaderStorageBufferArrayDynamicIndexing  = false,
-      .shaderStorageImageArrayDynamicIndexing   = false,
-      .shaderClipDistance                       = false,
-      .shaderCullDistance                       = false,
-      .shaderFloat64                            = false,
-      .shaderInt64                              = false,
-      .shaderFloat16                            = false,
-      .shaderInt16                              = false,
-   };
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetPhysicalDeviceLimits(
-    VkPhysicalDevice                            physicalDevice,
-    VkPhysicalDeviceLimits*                     pLimits)
-{
-   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
-   const struct brw_device_info *devinfo = physical_device->info;
-
-   anv_finishme("Get correct values for PhysicalDeviceLimits");
-
-   *pLimits = (VkPhysicalDeviceLimits) {
-      .maxImageDimension1D                      = (1 << 14),
-      .maxImageDimension2D                      = (1 << 14),
-      .maxImageDimension3D                      = (1 << 10),
-      .maxImageDimensionCube                    = (1 << 14),
-      .maxImageArrayLayers                      = (1 << 10),
-      .maxTexelBufferSize                       = (1 << 14),
-      .maxUniformBufferSize                     = UINT32_MAX,
-      .maxStorageBufferSize                     = UINT32_MAX,
-      .maxPushConstantsSize                     = 128,
-      .maxMemoryAllocationCount                 = UINT32_MAX,
-      .bufferImageGranularity                   = 64, /* A cache line */
-      .maxBoundDescriptorSets                   = MAX_SETS,
-      .maxDescriptorSets                        = UINT32_MAX,
-      .maxPerStageDescriptorSamplers            = 64,
-      .maxPerStageDescriptorUniformBuffers      = 64,
-      .maxPerStageDescriptorStorageBuffers      = 64,
-      .maxPerStageDescriptorSampledImages       = 64,
-      .maxPerStageDescriptorStorageImages       = 64,
-      .maxDescriptorSetSamplers                 = 256,
-      .maxDescriptorSetUniformBuffers           = 256,
-      .maxDescriptorSetStorageBuffers           = 256,
-      .maxDescriptorSetSampledImages            = 256,
-      .maxDescriptorSetStorageImages            = 256,
-      .maxVertexInputAttributes                 = 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                             = 16,
-      .maxDynamicViewportStates                 = UINT32_MAX,
-      .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),
-   };
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetPhysicalDeviceProperties(
-    VkPhysicalDevice                            physicalDevice,
-    VkPhysicalDeviceProperties*                 pProperties)
-{
-   ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
-
-   *pProperties = (VkPhysicalDeviceProperties) {
-      .apiVersion = 1,
-      .driverVersion = 1,
-      .vendorId = 0x8086,
-      .deviceId = pdevice->chipset_id,
-      .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
-   };
-
-   strcpy(pProperties->deviceName, pdevice->name);
-   snprintf((char *)pProperties->pipelineCacheUUID, VK_UUID_LENGTH,
-            "anv-%s", MESA_GIT_SHA1 + 4);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetPhysicalDeviceQueueCount(
-    VkPhysicalDevice                            physicalDevice,
-    uint32_t*                                   pCount)
-{
-   *pCount = 1;
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetPhysicalDeviceQueueProperties(
-    VkPhysicalDevice                            physicalDevice,
-    uint32_t                                    count,
-    VkPhysicalDeviceQueueProperties*            pQueueProperties)
-{
-   assert(count == 1);
-
-   *pQueueProperties = (VkPhysicalDeviceQueueProperties) {
-      .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);
-
-   size_t aperture_size;
-   size_t heap_size;
-
-   if (anv_gem_get_aperture(physical_device, &aperture_size) == -1)
-      return vk_error(VK_ERROR_UNAVAILABLE);
-
-   /* Reserve some wiggle room for the driver by exposing only 75% of the
-    * aperture to the heap.
-    */
-   heap_size = 3 * 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,
-   };
-
-   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 void
-parse_debug_flags(struct anv_device *device)
-{
-   const char *debug, *p, *end;
-
-   debug = getenv("INTEL_DEBUG");
-   device->dump_aub = false;
-   if (debug) {
-      for (p = debug; *p; p = end + 1) {
-         end = strchrnul(p, ',');
-         if (end - p == 3 && memcmp(p, "aub", 3) == 0)
-            device->dump_aub = true;
-         if (end - p == 5 && memcmp(p, "no_hw", 5) == 0)
-            device->no_hw = true;
-         if (*end == '\0')
-            break;
-      }
-   }
-}
-
-static VkResult
-anv_queue_init(struct anv_device *device, struct anv_queue *queue)
-{
-   queue->device = device;
-   queue->pool = &device->surface_state_pool;
-
-   queue->completed_serial = anv_state_pool_alloc(queue->pool, 4, 4);
-   if (queue->completed_serial.map == NULL)
-      return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
-
-   *(uint32_t *)queue->completed_serial.map = 0;
-   queue->next_serial = 1;
-
-   return VK_SUCCESS;
-}
-
-static void
-anv_queue_finish(struct anv_queue *queue)
-{
-#ifdef HAVE_VALGRIND
-   /* This gets torn down with the device so we only need to do this if
-    * valgrind is present.
-    */
-   anv_state_pool_free(queue->pool, queue->completed_serial);
-#endif
-}
-
-static void
-anv_device_init_border_colors(struct anv_device *device)
-{
-   static const VkClearColorValue border_colors[] = {
-      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .f32 = { 0.0, 0.0, 0.0, 0.0 } },
-      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =       { .f32 = { 0.0, 0.0, 0.0, 1.0 } },
-      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =       { .f32 = { 1.0, 1.0, 1.0, 1.0 } },
-      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =    { .u32 = { 0, 0, 0, 0 } },
-      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =         { .u32 = { 0, 0, 0, 1 } },
-      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =         { .u32 = { 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));
-}
-
-static const uint32_t BATCH_SIZE = 8192;
-
-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);
-
-   device = instance->pfnAlloc(instance->pAllocUserData,
-                               sizeof(*device), 8,
-                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (!device)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   device->no_hw = physical_device->no_hw;
-   parse_debug_flags(device);
-
-   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;
-
-   anv_bo_pool_init(&device->batch_bo_pool, device, 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, 2048);
-   anv_block_pool_init(&device->surface_state_block_pool, device, 2048);
-
-   anv_state_pool_init(&device->surface_state_pool,
-                       &device->surface_state_block_pool);
-
-   anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
-
-   device->info = *physical_device->info;
-
-   device->compiler = anv_compiler_create(device);
-   device->aub_writer = NULL;
-
-   pthread_mutex_init(&device->mutex, NULL);
-
-   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_UNAVAILABLE);
-}
-
-VkResult anv_DestroyDevice(
-    VkDevice                                    _device)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-
-   anv_compiler_destroy(device->compiler);
-
-   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_bo_pool_finish(&device->batch_bo_pool);
-   anv_block_pool_finish(&device->dynamic_state_block_pool);
-   anv_block_pool_finish(&device->instruction_block_pool);
-   anv_block_pool_finish(&device->surface_state_block_pool);
-
-   close(device->fd);
-
-   if (device->aub_writer)
-      anv_aub_writer_destroy(device->aub_writer);
-
-   anv_device_free(device, device);
-
-   return VK_SUCCESS;
-}
-
-static const VkExtensionProperties global_extensions[] = {
-   {
-      .extName = "VK_WSI_LunarG",
-      .specVersion = 3
-   }
-};
-
-VkResult anv_GetGlobalExtensionProperties(
-    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_GetPhysicalDeviceExtensionProperties(
-    VkPhysicalDevice                            physicalDevice,
-    const char*                                 pLayerName,
-    uint32_t*                                   pCount,
-    VkExtensionProperties*                      pProperties)
-{
-   if (pProperties == NULL) {
-      *pCount = 0;
-      return VK_SUCCESS;
-   }
-
-   /* None supported at this time */
-   return vk_error(VK_ERROR_INVALID_EXTENSION);
-}
-
-VkResult anv_GetGlobalLayerProperties(
-    uint32_t*                                   pCount,
-    VkLayerProperties*                          pProperties)
-{
-   if (pProperties == NULL) {
-      *pCount = 0;
-      return VK_SUCCESS;
-   }
-
-   /* None supported at this time */
-   return vk_error(VK_ERROR_INVALID_LAYER);
-}
-
-VkResult anv_GetPhysicalDeviceLayerProperties(
-    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_INVALID_LAYER);
-}
-
-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]);
-
-      if (device->dump_aub)
-         anv_cmd_buffer_dump(cmd_buffer);
-
-      if (!device->no_hw) {
-         ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf);
-         if (ret != 0)
-            return vk_error(VK_ERROR_UNKNOWN);
-
-         if (fence) {
-            ret = anv_gem_execbuffer(device, &fence->execbuf);
-            if (ret != 0)
-               return vk_error(VK_ERROR_UNKNOWN);
-         }
-
-         for (uint32_t i = 0; i < cmd_buffer->exec2_bo_count; i++)
-            cmd_buffer->exec2_bos[i]->offset = cmd_buffer->exec2_objects[i].offset;
-      } else {
-         *(uint32_t *)queue->completed_serial.map = cmd_buffer->serial;
-      }
-   }
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_QueueWaitIdle(
-    VkQueue                                     _queue)
-{
-   ANV_FROM_HANDLE(anv_queue, queue, _queue);
-
-   return vkDeviceWaitIdle(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, GEN8_MI_BATCH_BUFFER_END);
-   anv_batch_emit(&batch, GEN8_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;
-
-   if (!device->no_hw) {
-      ret = anv_gem_execbuffer(device, &execbuf);
-      if (ret != 0) {
-         result = vk_error(VK_ERROR_UNKNOWN);
-         goto fail;
-      }
-
-      timeout = INT64_MAX;
-      ret = anv_gem_wait(device, bo->gem_handle, &timeout);
-      if (ret != 0) {
-         result = vk_error(VK_ERROR_UNKNOWN);
-         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 device->instance->pfnAlloc(device->instance->pAllocUserData,
-                                     size,
-                                     alignment,
-                                     allocType);
-}
-
-void
-anv_device_free(struct anv_device *             device,
-                void *                          mem)
-{
-   if (mem == NULL)
-      return;
-
-   return device->instance->pfnFree(device->instance->pAllocUserData,
-                                    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);
-
-   if (pAllocInfo->memoryTypeIndex != 0) {
-      /* We support exactly one memory heap. */
-      return vk_error(VK_ERROR_INVALID_VALUE);
-   }
-
-   /* 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;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-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;
-}
-
-VkResult anv_UnmapMemory(
-    VkDevice                                    _device,
-    VkDeviceMemory                              _mem)
-{
-   ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
-
-   anv_gem_munmap(mem->map, mem->map_size);
-
-   return VK_SUCCESS;
-}
-
-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, GEN8_MI_BATCH_BUFFER_END);
-   anv_batch_emit(&batch, GEN8_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;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-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);
-   int64_t t = timeout;
-   int ret;
-
-   /* FIXME: handle !waitAll */
-
-   for (uint32_t i = 0; i < fenceCount; i++) {
-      ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
-      ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
-      if (ret == -1 && errno == ETIME)
-         return VK_TIMEOUT;
-      else if (ret == -1)
-         return vk_error(VK_ERROR_UNKNOWN);
-   }
-
-   return VK_SUCCESS;
-}
-
-// Queue semaphore functions
-
-VkResult anv_CreateSemaphore(
-    VkDevice                                    device,
-    const VkSemaphoreCreateInfo*                pCreateInfo,
-    VkSemaphore*                                pSemaphore)
-{
-   stub_return(VK_UNSUPPORTED);
-}
-
-VkResult anv_DestroySemaphore(
-    VkDevice                                    device,
-    VkSemaphore                                 semaphore)
-{
-   stub_return(VK_UNSUPPORTED);
-}
-
-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);
-}
-
-VkResult anv_DestroyEvent(
-    VkDevice                                    device,
-    VkEvent                                     event)
-{
-   stub_return(VK_UNSUPPORTED);
-}
-
-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;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-// Buffer view functions
-
-void
-anv_fill_buffer_surface_state(void *state, VkFormat format,
-                              uint32_t offset, uint32_t range)
-{
-   const struct anv_format *info;
-
-   info = anv_format_for_vk_format(format);
-   /* This assumes RGBA float format. */
-   uint32_t stride = 4;
-   uint32_t num_elements = range / stride;
-
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = SURFTYPE_BUFFER,
-      .SurfaceArray = false,
-      .SurfaceFormat = info->surface_format,
-      .SurfaceVerticalAlignment = VALIGN4,
-      .SurfaceHorizontalAlignment = HALIGN4,
-      .TileMode = LINEAR,
-      .VerticalLineStride = 0,
-      .VerticalLineStrideOffset = 0,
-      .SamplerL2BypassModeDisable = true,
-      .RenderCacheReadWriteMode = WriteOnlyCache,
-      .MemoryObjectControlState = GEN8_MOCS,
-      .BaseMipLevel = 0.0,
-      .SurfaceQPitch = 0,
-      .Height = (num_elements >> 7) & 0x3fff,
-      .Width = num_elements & 0x7f,
-      .Depth = (num_elements >> 21) & 0x3f,
-      .SurfacePitch = stride - 1,
-      .MinimumArrayElement = 0,
-      .NumberofMultisamples = MULTISAMPLECOUNT_1,
-      .XOffset = 0,
-      .YOffset = 0,
-      .SurfaceMinLOD = 0,
-      .MIPCountLOD = 0,
-      .AuxiliarySurfaceMode = AUX_NONE,
-      .RedClearColor = 0,
-      .GreenClearColor = 0,
-      .BlueClearColor = 0,
-      .AlphaClearColor = 0,
-      .ShaderChannelSelectRed = SCS_RED,
-      .ShaderChannelSelectGreen = SCS_GREEN,
-      .ShaderChannelSelectBlue = SCS_BLUE,
-      .ShaderChannelSelectAlpha = SCS_ALPHA,
-      .ResourceMinLOD = 0.0,
-      /* FIXME: We assume that the image must be bound at this time. */
-      .SurfaceBaseAddress = { NULL, offset },
-   };
-
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
-}
-
-VkResult anv_CreateBufferView(
-    VkDevice                                    _device,
-    const VkBufferViewCreateInfo*               pCreateInfo,
-    VkBufferView*                               pView)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
-   struct anv_buffer_view *bview;
-   struct anv_surface_view *view;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
-
-   bview = anv_device_alloc(device, sizeof(*view), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (bview == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   view = &bview->view;
-   view->bo = buffer->bo;
-   view->offset = buffer->offset + pCreateInfo->offset;
-   view->surface_state =
-      anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-   view->format = pCreateInfo->format;
-   view->range = pCreateInfo->range;
-
-   anv_fill_buffer_surface_state(view->surface_state.map,
-                                 pCreateInfo->format,
-                                 view->offset, pCreateInfo->range);
-
-   *pView = anv_buffer_view_to_handle(bview);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyBufferView(
-    VkDevice                                    _device,
-    VkBufferView                                _bview)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_buffer_view, bview, _bview);
-
-   anv_surface_view_fini(device, &bview->view);
-   anv_device_free(device, bview);
-
-   return VK_SUCCESS;
-}
-
-// Sampler functions
-
-VkResult anv_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_WRAP]                     = TCM_WRAP,
-      [VK_TEX_ADDRESS_MIRROR]                   = TCM_MIRROR,
-      [VK_TEX_ADDRESS_CLAMP]                    = TCM_CLAMP,
-      [VK_TEX_ADDRESS_MIRROR_ONCE]              = TCM_MIRROR_ONCE,
-      [VK_TEX_ADDRESS_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 = 0,
-      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
-      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
-      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
-   };
-
-   GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
-
-   *pSampler = anv_sampler_to_handle(sampler);
-
-   return VK_SUCCESS;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-// 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;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
-
-   uint32_t sampler_count[VK_SHADER_STAGE_NUM] = { 0, };
-   uint32_t surface_count[VK_SHADER_STAGE_NUM] = { 0, };
-   uint32_t num_dynamic_buffers = 0;
-   uint32_t count = 0;
-   uint32_t stages = 0;
-   uint32_t s;
-
-   for (uint32_t i = 0; i < pCreateInfo->count; i++) {
-      switch (pCreateInfo->pBinding[i].descriptorType) {
-      case VK_DESCRIPTOR_TYPE_SAMPLER:
-      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
-         for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
-            sampler_count[s] += pCreateInfo->pBinding[i].arraySize;
-         break;
-      default:
-         break;
-      }
-
-      switch (pCreateInfo->pBinding[i].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[i].stageFlags)
-            surface_count[s] += pCreateInfo->pBinding[i].arraySize;
-         break;
-      default:
-         break;
-      }
-
-      switch (pCreateInfo->pBinding[i].descriptorType) {
-      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
-      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
-         num_dynamic_buffers += pCreateInfo->pBinding[i].arraySize;
-         break;
-      default:
-         break;
-      }
-
-      stages |= pCreateInfo->pBinding[i].stageFlags;
-      count += pCreateInfo->pBinding[i].arraySize;
-   }
-
-   uint32_t sampler_total = 0;
-   uint32_t surface_total = 0;
-   for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
-      sampler_total += sampler_count[s];
-      surface_total += surface_count[s];
-   }
-
-   size_t size = sizeof(*set_layout) +
-      (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
-   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);
-
-   set_layout->num_dynamic_buffers = num_dynamic_buffers;
-   set_layout->count = count;
-   set_layout->shader_stages = stages;
-
-   struct anv_descriptor_slot *p = set_layout->entries;
-   struct anv_descriptor_slot *sampler[VK_SHADER_STAGE_NUM];
-   struct anv_descriptor_slot *surface[VK_SHADER_STAGE_NUM];
-   for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
-      set_layout->stage[s].surface_count = surface_count[s];
-      set_layout->stage[s].surface_start = surface[s] = p;
-      p += surface_count[s];
-      set_layout->stage[s].sampler_count = sampler_count[s];
-      set_layout->stage[s].sampler_start = sampler[s] = p;
-      p += sampler_count[s];
-   }
-
-   uint32_t descriptor = 0;
-   int8_t dynamic_slot = 0;
-   bool is_dynamic;
-   for (uint32_t i = 0; i < pCreateInfo->count; i++) {
-      switch (pCreateInfo->pBinding[i].descriptorType) {
-      case VK_DESCRIPTOR_TYPE_SAMPLER:
-      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
-         for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
-            for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
-               sampler[s]->index = descriptor + j;
-               sampler[s]->dynamic_slot = -1;
-               sampler[s]++;
-            }
-         break;
-      default:
-         break;
-      }
-
-      switch (pCreateInfo->pBinding[i].descriptorType) {
-      case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
-      case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
-         is_dynamic = true;
-         break;
-      default:
-         is_dynamic = false;
-         break;
-      }
-
-      switch (pCreateInfo->pBinding[i].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[i].stageFlags)
-            for (uint32_t j = 0; j < pCreateInfo->pBinding[i].arraySize; j++) {
-               surface[s]->index = descriptor + j;
-               if (is_dynamic)
-                  surface[s]->dynamic_slot = dynamic_slot + j;
-               else
-                  surface[s]->dynamic_slot = -1;
-               surface[s]++;
-            }
-         break;
-      default:
-         break;
-      }
-
-      if (is_dynamic)
-         dynamic_slot += pCreateInfo->pBinding[i].arraySize;
-
-      descriptor += pCreateInfo->pBinding[i].arraySize;
-   }
-
-   *pSetLayout = anv_descriptor_set_layout_to_handle(set_layout);
-
-   return VK_SUCCESS;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_CreateDescriptorPool(
-    VkDevice                                    device,
-    VkDescriptorPoolUsage                       poolUsage,
-    uint32_t                                    maxSets,
-    const VkDescriptorPoolCreateInfo*           pCreateInfo,
-    VkDescriptorPool*                           pDescriptorPool)
-{
-   anv_finishme("VkDescriptorPool is a stub");
-   pDescriptorPool->handle = 1;
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyDescriptorPool(
-    VkDevice                                    _device,
-    VkDescriptorPool                            _pool)
-{
-   anv_finishme("VkDescriptorPool is a stub: free the pool's descriptor sets");
-   return VK_SUCCESS;
-}
-
-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->count * 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);
-
-   *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,
-    uint32_t*                                   pCount)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-
-   VkResult result;
-   struct anv_descriptor_set *set;
-
-   for (uint32_t 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) {
-         *pCount = i;
-         return result;
-      }
-
-      pDescriptorSets[i] = anv_descriptor_set_to_handle(set);
-   }
-
-   *pCount = count;
-
-   return VK_SUCCESS;
-}
-
-VkResult 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);
-
-      switch (write->descriptorType) {
-      case VK_DESCRIPTOR_TYPE_SAMPLER:
-      case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
-         for (uint32_t j = 0; j < write->count; j++) {
-            set->descriptors[write->destBinding + j].sampler =
-               anv_sampler_from_handle(write->pDescriptors[j].sampler);
-         }
-
-         if (write->descriptorType == VK_DESCRIPTOR_TYPE_SAMPLER)
-            break;
-
-         /* fallthrough */
-
-      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);
-            set->descriptors[write->destBinding + j].view = &iview->view;
-         }
-         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++) {
-            ANV_FROM_HANDLE(anv_buffer_view, bview,
-                            write->pDescriptors[j].bufferView);
-            set->descriptors[write->destBinding + j].view = &bview->view;
-         }
-
-      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];
-      }
-   }
-
-   return VK_SUCCESS;
-}
-
-// State object functions
-
-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;
-}
-
-VkResult anv_CreateDynamicViewportState(
-    VkDevice                                    _device,
-    const VkDynamicViewportStateCreateInfo*     pCreateInfo,
-    VkDynamicViewportState*                     pState)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_dynamic_vp_state *state;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO);
-
-   state = anv_device_alloc(device, sizeof(*state), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (state == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   unsigned count = pCreateInfo->viewportAndScissorCount;
-   state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
-                                            count * 64, 64);
-   state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
-                                       count * 8, 32);
-   state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
-                                         count * 32, 32);
-
-   for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
-      const VkViewport *vp = &pCreateInfo->pViewports[i];
-      const VkRect2D *s = &pCreateInfo->pScissors[i];
-
-      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 GEN8_CC_VIEWPORT cc_viewport = {
-         .MinimumDepth = vp->minDepth,
-         .MaximumDepth = vp->maxDepth
-      };
-
-      /* 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 GEN8_SCISSOR_RECT empty_scissor = {
-         .ScissorRectangleYMin = 1,
-         .ScissorRectangleXMin = 1,
-         .ScissorRectangleYMax = 0,
-         .ScissorRectangleXMax = 0
-      };
-
-      const int max = 0xffff;
-      struct GEN8_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)
-      };
-
-      GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
-      GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
-
-      if (s->extent.width <= 0 || s->extent.height <= 0) {
-         GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
-      } else {
-         GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
-      }
-   }
-
-   *pState = anv_dynamic_vp_state_to_handle(state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyDynamicViewportState(
-    VkDevice                                    _device,
-    VkDynamicViewportState                      _vp_state)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, _vp_state);
-
-   anv_state_pool_free(&device->dynamic_state_pool, vp_state->sf_clip_vp);
-   anv_state_pool_free(&device->dynamic_state_pool, vp_state->cc_vp);
-   anv_state_pool_free(&device->dynamic_state_pool, vp_state->scissor);
-
-   anv_device_free(device, vp_state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_CreateDynamicRasterState(
-    VkDevice                                    _device,
-    const VkDynamicRasterStateCreateInfo*       pCreateInfo,
-    VkDynamicRasterState*                       pState)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_dynamic_rs_state *state;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO);
-
-   state = anv_device_alloc(device, sizeof(*state), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (state == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   struct GEN8_3DSTATE_SF sf = {
-      GEN8_3DSTATE_SF_header,
-      .LineWidth = pCreateInfo->lineWidth,
-   };
-
-   GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
-
-   bool enable_bias = pCreateInfo->depthBias != 0.0f ||
-      pCreateInfo->slopeScaledDepthBias != 0.0f;
-   struct GEN8_3DSTATE_RASTER raster = {
-      .GlobalDepthOffsetEnableSolid = enable_bias,
-      .GlobalDepthOffsetEnableWireframe = enable_bias,
-      .GlobalDepthOffsetEnablePoint = enable_bias,
-      .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
-      .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
-      .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
-   };
-
-   GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
-
-   *pState = anv_dynamic_rs_state_to_handle(state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyDynamicRasterState(
-    VkDevice                                    _device,
-    VkDynamicRasterState                        _rs_state)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, _rs_state);
-
-   anv_device_free(device, rs_state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_CreateDynamicColorBlendState(
-    VkDevice                                    _device,
-    const VkDynamicColorBlendStateCreateInfo*   pCreateInfo,
-    VkDynamicColorBlendState*                   pState)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_dynamic_cb_state *state;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO);
-
-   state = anv_device_alloc(device, sizeof(*state), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (state == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   struct GEN8_COLOR_CALC_STATE color_calc_state = {
-      .BlendConstantColorRed = pCreateInfo->blendConst[0],
-      .BlendConstantColorGreen = pCreateInfo->blendConst[1],
-      .BlendConstantColorBlue = pCreateInfo->blendConst[2],
-      .BlendConstantColorAlpha = pCreateInfo->blendConst[3]
-   };
-
-   GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
-
-   *pState = anv_dynamic_cb_state_to_handle(state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyDynamicColorBlendState(
-    VkDevice                                    _device,
-    VkDynamicColorBlendState                    _cb_state)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, _cb_state);
-
-   anv_device_free(device, cb_state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_CreateDynamicDepthStencilState(
-    VkDevice                                    _device,
-    const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
-    VkDynamicDepthStencilState*                 pState)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_dynamic_ds_state *state;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO);
-
-   state = anv_device_alloc(device, sizeof(*state), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (state == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
-      GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
-
-      /* Is this what we need to do? */
-      .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
-
-      .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
-      .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
-
-      .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
-      .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
-   };
-
-   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
-                                      &wm_depth_stencil);
-
-   struct GEN8_COLOR_CALC_STATE color_calc_state = {
-      .StencilReferenceValue = pCreateInfo->stencilFrontRef,
-      .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
-   };
-
-   GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
-
-   *pState = anv_dynamic_ds_state_to_handle(state);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyDynamicDepthStencilState(
-    VkDevice                                    _device,
-    VkDynamicDepthStencilState                  _ds_state)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, _ds_state);
-
-   anv_device_free(device, ds_state);
-
-   return VK_SUCCESS;
-}
-
-// Command buffer functions
-
-VkResult anv_CreateCommandPool(
-    VkDevice                                    device,
-    const VkCmdPoolCreateInfo*                  pCreateInfo,
-    VkCmdPool*                                  pCmdPool)
-{
-   pCmdPool->handle = 7;
-
-   stub_return(VK_SUCCESS);
-}
-
-VkResult anv_DestroyCommandPool(
-    VkDevice                                    device,
-    VkCmdPool                                   cmdPool)
-{
-   stub_return(VK_SUCCESS);
-}
-
-VkResult anv_ResetCommandPool(
-    VkDevice                                    device,
-    VkCmdPool                                   cmdPool,
-    VkCmdPoolResetFlags                         flags)
-{
-   stub_return(VK_UNSUPPORTED);
-}
-
-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_attachment_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++) {
-      ANV_FROM_HANDLE(anv_attachment_view, view,
-                      pCreateInfo->pAttachments[i].view);
-
-      framebuffer->attachments[i] = view;
-   }
-
-   framebuffer->width = pCreateInfo->width;
-   framebuffer->height = pCreateInfo->height;
-   framebuffer->layers = pCreateInfo->layers;
-
-   anv_CreateDynamicViewportState(anv_device_to_handle(device),
-      &(VkDynamicViewportStateCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO,
-         .viewportAndScissorCount = 1,
-         .pViewports = (VkViewport[]) {
-            {
-               .originX = 0,
-               .originY = 0,
-               .width = pCreateInfo->width,
-               .height = pCreateInfo->height,
-               .minDepth = 0,
-               .maxDepth = 1
-            },
-         },
-         .pScissors = (VkRect2D[]) {
-            { {  0,  0 },
-              { pCreateInfo->width, pCreateInfo->height } },
-         }
-      },
-      &framebuffer->vp_state);
-
-   *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyFramebuffer(
-    VkDevice                                    _device,
-    VkFramebuffer                               _fb)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
-
-   anv_DestroyDynamicViewportState(anv_device_to_handle(device),
-                                   fb->vp_state);
-   anv_device_free(device, fb);
-
-   return VK_SUCCESS;
-}
-
-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;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
-
-   size = sizeof(*pass) +
-      pCreateInfo->subpassCount * sizeof(struct anv_subpass);
-   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;
-
-   size = pCreateInfo->attachmentCount * sizeof(*pass->attachments);
-   pass->attachments = anv_device_alloc(device, size, 8,
-                                        VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
-      pass->attachments[i].format = pCreateInfo->pAttachments[i].format;
-      pass->attachments[i].samples = pCreateInfo->pAttachments[i].samples;
-      pass->attachments[i].load_op = pCreateInfo->pAttachments[i].loadOp;
-      pass->attachments[i].stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp;
-      // pass->attachments[i].store_op = pCreateInfo->pAttachments[i].storeOp;
-      // pass->attachments[i].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->inputAttachments[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->colorAttachments[j].attachment;
-         }
-      }
-
-      if (desc->resolveAttachments) {
-         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->resolveAttachments[j].attachment;
-         }
-      }
-
-      subpass->depth_stencil_attachment = desc->depthStencilAttachment.attachment;
-   }
-
-   *pRenderPass = anv_render_pass_to_handle(pass);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_DestroyRenderPass(
-    VkDevice                                    _device,
-    VkRenderPass                                _pass)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
-
-   anv_device_free(device, pass->attachments);
-
-   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);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetRenderAreaGranularity(
-    VkDevice                                    device,
-    VkRenderPass                                renderPass,
-    VkExtent2D*                                 pGranularity)
-{
-   *pGranularity = (VkExtent2D) { 1, 1 };
-
-   return VK_SUCCESS;
-}
-
-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/formats.c b/src/vulkan/formats.c
deleted file mode 100644 (file)
index 9d9294b..0000000
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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 "private.h"
-
-#define UNSUPPORTED 0xffff
-
-#define fmt(__vk_fmt, ...) \
-   [__vk_fmt] = { .name = #__vk_fmt, __VA_ARGS__ }
-
-static const struct anv_format anv_formats[] = {
-   fmt(VK_FORMAT_UNDEFINED,               RAW,                    .cpp = 1,   .num_channels = 1),
-   fmt(VK_FORMAT_R4G4_UNORM,              UNSUPPORTED),
-   fmt(VK_FORMAT_R4G4_USCALED,            UNSUPPORTED),
-   fmt(VK_FORMAT_R4G4B4A4_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_R4G4B4A4_USCALED,        UNSUPPORTED),
-   fmt(VK_FORMAT_R5G6B5_UNORM,            UNSUPPORTED),
-   fmt(VK_FORMAT_R5G6B5_USCALED,          UNSUPPORTED),
-   fmt(VK_FORMAT_R5G5B5A1_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_R5G5B5A1_USCALED,        UNSUPPORTED),
-   fmt(VK_FORMAT_R8_UNORM,                R8_UNORM,               .cpp = 1,   .num_channels = 1),
-   fmt(VK_FORMAT_R8_SNORM,                R8_SNORM,               .cpp = 1,   .num_channels = 1,),
-   fmt(VK_FORMAT_R8_USCALED,              R8_USCALED,             .cpp = 1,   .num_channels = 1),
-   fmt(VK_FORMAT_R8_SSCALED,              R8_SSCALED,             .cpp = 1,   .num_channels = 1),
-   fmt(VK_FORMAT_R8_UINT,                 R8_UINT,                .cpp = 1,   .num_channels = 1),
-   fmt(VK_FORMAT_R8_SINT,                 R8_SINT,                .cpp = 1,   .num_channels = 1),
-   fmt(VK_FORMAT_R8_SRGB,                 UNSUPPORTED),
-   fmt(VK_FORMAT_R8G8_UNORM,              R8G8_UNORM,             .cpp = 2,   .num_channels = 2),
-   fmt(VK_FORMAT_R8G8_SNORM,              R8G8_SNORM,             .cpp = 2,   .num_channels = 2),
-   fmt(VK_FORMAT_R8G8_USCALED,            R8G8_USCALED,           .cpp = 2,   .num_channels = 2),
-   fmt(VK_FORMAT_R8G8_SSCALED,            R8G8_SSCALED,           .cpp = 2,   .num_channels = 2),
-   fmt(VK_FORMAT_R8G8_UINT,               R8G8_UINT,              .cpp = 2,   .num_channels = 2),
-   fmt(VK_FORMAT_R8G8_SINT,               R8G8_SINT,              .cpp = 2,   .num_channels = 2),
-   fmt(VK_FORMAT_R8G8_SRGB,               UNSUPPORTED), /* L8A8_UNORM_SRGB */
-   fmt(VK_FORMAT_R8G8B8_UNORM,            R8G8B8X8_UNORM,         .cpp = 3,   .num_channels = 3),
-   fmt(VK_FORMAT_R8G8B8_SNORM,            R8G8B8_SNORM,           .cpp = 3,   .num_channels = 3),
-   fmt(VK_FORMAT_R8G8B8_USCALED,          R8G8B8_USCALED,         .cpp = 3,   .num_channels = 3),
-   fmt(VK_FORMAT_R8G8B8_SSCALED,          R8G8B8_SSCALED,         .cpp = 3,   .num_channels = 3),
-   fmt(VK_FORMAT_R8G8B8_UINT,             R8G8B8_UINT,            .cpp = 3,   .num_channels = 3),
-   fmt(VK_FORMAT_R8G8B8_SINT,             R8G8B8_SINT,            .cpp = 3,   .num_channels = 3),
-   fmt(VK_FORMAT_R8G8B8_SRGB,             UNSUPPORTED), /* B8G8R8A8_UNORM_SRGB */
-   fmt(VK_FORMAT_R8G8B8A8_UNORM,          R8G8B8A8_UNORM,         .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R8G8B8A8_SNORM,          R8G8B8A8_SNORM,         .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R8G8B8A8_USCALED,        R8G8B8A8_USCALED,       .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R8G8B8A8_SSCALED,        R8G8B8A8_SSCALED,       .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R8G8B8A8_UINT,           R8G8B8A8_UINT,          .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R8G8B8A8_SINT,           R8G8B8A8_SINT,          .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R8G8B8A8_SRGB,           R8G8B8A8_UNORM_SRGB,    .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R10G10B10A2_UNORM,       R10G10B10A2_UNORM,      .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R10G10B10A2_SNORM,       R10G10B10A2_SNORM,      .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R10G10B10A2_USCALED,     R10G10B10A2_USCALED,    .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R10G10B10A2_SSCALED,     R10G10B10A2_SSCALED,    .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R10G10B10A2_UINT,        R10G10B10A2_UINT,       .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R10G10B10A2_SINT,        R10G10B10A2_SINT,       .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_R16_UNORM,               R16_UNORM,              .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16_SNORM,               R16_SNORM,              .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16_USCALED,             R16_USCALED,            .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16_SSCALED,             R16_SSCALED,            .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16_UINT,                R16_UINT,               .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16_SINT,                R16_SINT,               .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16_SFLOAT,              R16_FLOAT,              .cpp = 2,   .num_channels = 1),
-   fmt(VK_FORMAT_R16G16_UNORM,            R16G16_UNORM,           .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16_SNORM,            R16G16_SNORM,           .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16_USCALED,          R16G16_USCALED,         .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16_SSCALED,          R16G16_SSCALED,         .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16_UINT,             R16G16_UINT,            .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16_SINT,             R16G16_SINT,            .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16_SFLOAT,           R16G16_FLOAT,           .cpp = 4,   .num_channels = 2),
-   fmt(VK_FORMAT_R16G16B16_UNORM,         R16G16B16_UNORM,        .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16_SNORM,         R16G16B16_SNORM,        .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16_USCALED,       R16G16B16_USCALED,      .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16_SSCALED,       R16G16B16_SSCALED,      .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16_UINT,          R16G16B16_UINT,         .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16_SINT,          R16G16B16_SINT,         .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16_SFLOAT,        R16G16B16_FLOAT,        .cpp = 6,   .num_channels = 3),
-   fmt(VK_FORMAT_R16G16B16A16_UNORM,      R16G16B16A16_UNORM,     .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R16G16B16A16_SNORM,      R16G16B16A16_SNORM,     .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R16G16B16A16_USCALED,    R16G16B16A16_USCALED,   .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R16G16B16A16_SSCALED,    R16G16B16A16_SSCALED,   .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R16G16B16A16_UINT,       R16G16B16A16_UINT,      .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R16G16B16A16_SINT,       R16G16B16A16_SINT,      .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R16G16B16A16_SFLOAT,     R16G16B16A16_FLOAT,     .cpp = 8,   .num_channels = 4),
-   fmt(VK_FORMAT_R32_UINT,                R32_UINT,               .cpp = 4,   .num_channels = 1,),
-   fmt(VK_FORMAT_R32_SINT,                R32_SINT,               .cpp = 4,   .num_channels = 1,),
-   fmt(VK_FORMAT_R32_SFLOAT,              R32_FLOAT,              .cpp = 4,   .num_channels = 1,),
-   fmt(VK_FORMAT_R32G32_UINT,             R32G32_UINT,            .cpp = 8,   .num_channels = 2,),
-   fmt(VK_FORMAT_R32G32_SINT,             R32G32_SINT,            .cpp = 8,   .num_channels = 2,),
-   fmt(VK_FORMAT_R32G32_SFLOAT,           R32G32_FLOAT,           .cpp = 8,   .num_channels = 2,),
-   fmt(VK_FORMAT_R32G32B32_UINT,          R32G32B32_UINT,         .cpp = 12,  .num_channels = 3,),
-   fmt(VK_FORMAT_R32G32B32_SINT,          R32G32B32_SINT,         .cpp = 12,  .num_channels = 3,),
-   fmt(VK_FORMAT_R32G32B32_SFLOAT,        R32G32B32_FLOAT,        .cpp = 12,  .num_channels = 3,),
-   fmt(VK_FORMAT_R32G32B32A32_UINT,       R32G32B32A32_UINT,      .cpp = 16,  .num_channels = 4,),
-   fmt(VK_FORMAT_R32G32B32A32_SINT,       R32G32B32A32_SINT,      .cpp = 16,  .num_channels = 4,),
-   fmt(VK_FORMAT_R32G32B32A32_SFLOAT,     R32G32B32A32_FLOAT,     .cpp = 16,  .num_channels = 4,),
-   fmt(VK_FORMAT_R64_SFLOAT,              R64_FLOAT,              .cpp = 8,   .num_channels = 1),
-   fmt(VK_FORMAT_R64G64_SFLOAT,           R64G64_FLOAT,           .cpp = 16,  .num_channels = 2),
-   fmt(VK_FORMAT_R64G64B64_SFLOAT,        R64G64B64_FLOAT,        .cpp = 24,  .num_channels = 3),
-   fmt(VK_FORMAT_R64G64B64A64_SFLOAT,     R64G64B64A64_FLOAT,     .cpp = 32,  .num_channels = 4),
-   fmt(VK_FORMAT_R11G11B10_UFLOAT,        R11G11B10_FLOAT,        .cpp = 4,   .num_channels = 3),
-   fmt(VK_FORMAT_R9G9B9E5_UFLOAT,         R9G9B9E5_SHAREDEXP,     .cpp = 4,   .num_channels = 3),
-
-   fmt(VK_FORMAT_D16_UNORM,               R16_UNORM,              .cpp = 2,   .num_channels = 1, .depth_format = D16_UNORM),
-   fmt(VK_FORMAT_D24_UNORM,               R24_UNORM_X8_TYPELESS,  .cpp = 4,   .num_channels = 1, .depth_format = D24_UNORM_X8_UINT),
-   fmt(VK_FORMAT_D32_SFLOAT,              R32_FLOAT,              .cpp = 4,   .num_channels = 1, .depth_format = D32_FLOAT),
-   fmt(VK_FORMAT_S8_UINT,                 R8_UINT,                .cpp = 1,   .num_channels = 1,                                       .has_stencil = true),
-   fmt(VK_FORMAT_D16_UNORM_S8_UINT,       R16_UNORM,              .cpp = 2,   .num_channels = 2, .depth_format = D16_UNORM,            .has_stencil = true),
-   fmt(VK_FORMAT_D24_UNORM_S8_UINT,       R24_UNORM_X8_TYPELESS,  .cpp = 4,   .num_channels = 2, .depth_format = D24_UNORM_X8_UINT,    .has_stencil = true),
-   fmt(VK_FORMAT_D32_SFLOAT_S8_UINT,      R32_FLOAT,              .cpp = 4,   .num_channels = 2, .depth_format = D32_FLOAT,            .has_stencil = true),
-
-   fmt(VK_FORMAT_BC1_RGB_UNORM,           UNSUPPORTED),
-   fmt(VK_FORMAT_BC1_RGB_SRGB,            UNSUPPORTED),
-   fmt(VK_FORMAT_BC1_RGBA_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_BC1_RGBA_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_BC2_UNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC2_SRGB,                UNSUPPORTED),
-   fmt(VK_FORMAT_BC3_UNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC3_SRGB,                UNSUPPORTED),
-   fmt(VK_FORMAT_BC4_UNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC4_SNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC5_UNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC5_SNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC6H_UFLOAT,             UNSUPPORTED),
-   fmt(VK_FORMAT_BC6H_SFLOAT,             UNSUPPORTED),
-   fmt(VK_FORMAT_BC7_UNORM,               UNSUPPORTED),
-   fmt(VK_FORMAT_BC7_SRGB,                UNSUPPORTED),
-   fmt(VK_FORMAT_ETC2_R8G8B8_UNORM,       UNSUPPORTED),
-   fmt(VK_FORMAT_ETC2_R8G8B8_SRGB,        UNSUPPORTED),
-   fmt(VK_FORMAT_ETC2_R8G8B8A1_UNORM,     UNSUPPORTED),
-   fmt(VK_FORMAT_ETC2_R8G8B8A1_SRGB,      UNSUPPORTED),
-   fmt(VK_FORMAT_ETC2_R8G8B8A8_UNORM,     UNSUPPORTED),
-   fmt(VK_FORMAT_ETC2_R8G8B8A8_SRGB,      UNSUPPORTED),
-   fmt(VK_FORMAT_EAC_R11_UNORM,           UNSUPPORTED),
-   fmt(VK_FORMAT_EAC_R11_SNORM,           UNSUPPORTED),
-   fmt(VK_FORMAT_EAC_R11G11_UNORM,        UNSUPPORTED),
-   fmt(VK_FORMAT_EAC_R11G11_SNORM,        UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_4x4_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_4x4_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_5x4_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_5x4_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_5x5_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_5x5_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_6x5_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_6x5_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_6x6_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_6x6_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_8x5_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_8x5_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_8x6_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_8x6_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_8x8_UNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_8x8_SRGB,           UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x5_UNORM,         UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x5_SRGB,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x6_UNORM,         UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x6_SRGB,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x8_UNORM,         UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x8_SRGB,          UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x10_UNORM,        UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_10x10_SRGB,         UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_12x10_UNORM,        UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_12x10_SRGB,         UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_12x12_UNORM,        UNSUPPORTED),
-   fmt(VK_FORMAT_ASTC_12x12_SRGB,         UNSUPPORTED),
-   fmt(VK_FORMAT_B4G4R4A4_UNORM,          B4G4R4A4_UNORM,         .cpp = 2,   .num_channels = 4),
-   fmt(VK_FORMAT_B5G5R5A1_UNORM,          B5G5R5A1_UNORM,         .cpp = 2,   .num_channels = 4),
-   fmt(VK_FORMAT_B5G6R5_UNORM,            B5G6R5_UNORM,           .cpp = 2,   .num_channels = 3),
-   fmt(VK_FORMAT_B5G6R5_USCALED,          UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_UNORM,            UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_SNORM,            UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_USCALED,          UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_SSCALED,          UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_UINT,             UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_SINT,             UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8_SRGB,             UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8A8_UNORM,          B8G8R8A8_UNORM,         .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B8G8R8A8_SNORM,          UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8A8_USCALED,        UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8A8_SSCALED,        UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8A8_UINT,           UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8A8_SINT,           UNSUPPORTED),
-   fmt(VK_FORMAT_B8G8R8A8_SRGB,           B8G8R8A8_UNORM_SRGB,    .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B10G10R10A2_UNORM,       B10G10R10A2_UNORM,      .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B10G10R10A2_SNORM,       B10G10R10A2_SNORM,      .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B10G10R10A2_USCALED,     B10G10R10A2_USCALED,    .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B10G10R10A2_SSCALED,     B10G10R10A2_SSCALED,    .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B10G10R10A2_UINT,        B10G10R10A2_UINT,       .cpp = 4,   .num_channels = 4),
-   fmt(VK_FORMAT_B10G10R10A2_SINT,        B10G10R10A2_SINT,       .cpp = 4,   .num_channels = 4)
-};
-
-#undef fmt
-
-const struct anv_format *
-anv_format_for_vk_format(VkFormat format)
-{
-   return &anv_formats[format];
-}
-
-bool
-anv_is_vk_format_depth_or_stencil(VkFormat format)
-{
-   const struct anv_format *format_info =
-      anv_format_for_vk_format(format);
-
-   if (format_info->depth_format != UNSUPPORTED &&
-       format_info->depth_format != 0)
-      return true;
-
-   return format_info->has_stencil;
-}
-
-// Format capabilities
-
-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;
-};
-
-extern const struct surface_format_info surface_formats[];
-
-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);
-}
-
-VkResult anv_GetPhysicalDeviceFormatProperties(
-    VkPhysicalDevice                            physicalDevice,
-    VkFormat                                    _format,
-    VkFormatProperties*                         pFormatProperties)
-{
-   ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
-   const struct surface_format_info *info;
-   int gen;
-
-   const struct anv_format *format = anv_format_for_vk_format(_format);
-   if (format == NULL)
-      return vk_error(VK_ERROR_INVALID_VALUE);
-
-   gen = physical_device->info->gen * 10;
-   if (physical_device->info->is_haswell)
-      gen += 5;
-
-   if (format->surface_format == UNSUPPORTED)
-      goto unsupported;
-
-   info = &surface_formats[format->surface_format];
-   if (!info->exists)
-      goto unsupported;
-
-   uint32_t linear = 0, tiled = 0;
-   if (info->sampling <= gen) {
-      linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
-      tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
-   }
-   if (info->render_target <= gen) {
-      linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
-      tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
-   }
-   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;
-   }
-
-   pFormatProperties->linearTilingFeatures = linear;
-   pFormatProperties->optimalTilingFeatures = tiled;
-
-   return VK_SUCCESS;
-
- unsupported:
-   pFormatProperties->linearTilingFeatures = 0;
-   pFormatProperties->optimalTilingFeatures = 0;
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetPhysicalDeviceImageFormatProperties(
-    VkPhysicalDevice                            physicalDevice,
-    VkFormat                                    format,
-    VkImageType                                 type,
-    VkImageTiling                               tiling,
-    VkImageUsageFlags                           usage,
-    VkImageFormatProperties*                    pImageFormatProperties)
-{
-   /* TODO: We should do something here. Chad? */
-   stub_return(VK_UNSUPPORTED);
-}
-
-VkResult anv_GetPhysicalDeviceSparseImageFormatProperties(
-    VkPhysicalDevice                            physicalDevice,
-    VkFormat                                    format,
-    VkImageType                                 type,
-    uint32_t                                    samples,
-    VkImageUsageFlags                           usage,
-    VkImageTiling                               tiling,
-    uint32_t*                                   pNumProperties,
-    VkSparseImageFormatProperties*              pProperties)
-{
-   stub_return(VK_UNSUPPORTED);
-}
diff --git a/src/vulkan/gem.c b/src/vulkan/gem.c
deleted file mode 100644 (file)
index db0d29f..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * 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 "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(struct anv_physical_device *physical_dev, uint64_t *size)
-{
-   struct drm_i915_gem_get_aperture aperture;
-   int ret;
-
-   VG_CLEAR(aperture);
-   ret = anv_ioctl(physical_dev->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/image.c b/src/vulkan/image.c
deleted file mode 100644 (file)
index 4b37de5..0000000
+++ /dev/null
@@ -1,745 +0,0 @@
-/*
- * 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 "private.h"
-
-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* */
-};
-
-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
-};
-
-static const struct anv_surf_type_limits {
-   int32_t width;
-   int32_t height;
-   int32_t depth;
-} anv_surf_type_limits[] = {
-   [SURFTYPE_1D]     = {16384,       0,   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 {
-   uint32_t width;
-   uint32_t height;
-
-   /**
-    * 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[] = {
-   [LINEAR] = {   1,  1,   64 },
-   [XMAJOR] = { 512,  8, 4096 },
-   [YMAJOR] = { 128, 32, 4096 },
-   [WMAJOR] = { 128, 32, 4096 },
-};
-
-static uint32_t
-anv_image_choose_tile_mode(const struct anv_image_create_info *anv_info)
-{
-   if (anv_info->force_tile_mode)
-      return anv_info->tile_mode;
-
-   if (anv_info->vk_info->format == VK_FORMAT_S8_UINT)
-      return WMAJOR;
-
-   switch (anv_info->vk_info->tiling) {
-   case VK_IMAGE_TILING_LINEAR:
-      return LINEAR;
-   case VK_IMAGE_TILING_OPTIMAL:
-      return YMAJOR;
-   default:
-      assert(!"bad VKImageTiling");
-      return LINEAR;
-   }
-}
-
-static VkResult
-anv_image_make_surface(const struct anv_image_create_info *create_info,
-                       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 uint8_t tile_mode = anv_image_choose_tile_mode(create_info);
-
-   const struct anv_tile_info *tile_info =
-       &anv_tile_info_table[tile_mode];
-
-   const struct anv_format *format_info =
-      anv_format_for_vk_format(create_info->vk_info->format);
-
-   const uint32_t i = 4; /* FINISHME: Stop hardcoding subimage alignment */
-   const uint32_t j = 4; /* FINISHME: Stop hardcoding subimage alignment */
-   const uint32_t w0 = align_u32(extent->width, i);
-   const uint32_t h0 = align_u32(extent->height, j);
-
-   uint16_t qpitch;
-   uint32_t mt_width;
-   uint32_t mt_height;
-
-   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);
-
-      qpitch = h0 + h1 + 11 * j;
-      mt_width = MAX(w0, w1 + w2);
-      mt_height = array_size * qpitch;
-   }
-
-   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));
-
-   const uint32_t stride = align_u32(mt_width * format_info->cpp,
-                                     tile_info->width);
-   const uint32_t size = stride * align_u32(mt_height, tile_info->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,
-      .tile_mode = tile_mode,
-      .qpitch = qpitch,
-      .h_align = i,
-      .v_align = j,
-   };
-
-   return VK_SUCCESS;
-}
-
-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);
-
-   /* XXX: We don't handle any of these */
-   anv_assert(pCreateInfo->imageType == VK_IMAGE_TYPE_2D);
-   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];
-
-   if (extent->width > limits->width ||
-       extent->height > limits->height ||
-       extent->depth > limits->depth) {
-      /* TODO(chadv): What is the correct error? */
-      anv_loge("image extent is too large");
-      return vk_error(VK_ERROR_INVALID_MEMORY_SIZE);
-   }
-
-   const struct anv_format *format_info =
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   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 = pCreateInfo->format;
-   image->levels = pCreateInfo->mipLevels;
-   image->array_size = pCreateInfo->arraySize;
-   image->surf_type = surf_type;
-
-   if (likely(!format_info->has_stencil || format_info->depth_format)) {
-      /* The image's primary surface is a color or depth surface. */
-      r = anv_image_make_surface(create_info, &image->size, &image->alignment,
-                                 &image->primary_surface);
-      if (r != VK_SUCCESS)
-         goto fail;
-   }
-
-   if (format_info->has_stencil) {
-      /* From the GPU's perspective, the depth buffer and stencil buffer are
-       * separate buffers.  From Vulkan's perspective, though, depth and
-       * stencil reside in the same image.  To satisfy Vulkan and the GPU, we
-       * place the depth and stencil buffers in the same bo.
-       */
-      VkImageCreateInfo stencil_info = *pCreateInfo;
-      stencil_info.format = VK_FORMAT_S8_UINT;
-
-      r = anv_image_make_surface(
-            &(struct anv_image_create_info) {
-               .vk_info = &stencil_info,
-            },
-            &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);
-}
-
-VkResult
-anv_DestroyImage(VkDevice _device, VkImage _image)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-
-   anv_device_free(device, anv_image_from_handle(_image));
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetImageSubresourceLayout(
-    VkDevice                                    device,
-    VkImage                                     image,
-    const VkImageSubresource*                   pSubresource,
-    VkSubresourceLayout*                        pLayout)
-{
-   stub_return(VK_UNSUPPORTED);
-}
-
-void
-anv_surface_view_fini(struct anv_device *device,
-                      struct anv_surface_view *view)
-{
-   anv_state_pool_free(&device->surface_state_pool, view->surface_state);
-}
-
-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;
-   struct anv_surface_view *view = &iview->view;
-   struct anv_surface *surface;
-
-   const struct anv_format *format_info =
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   const struct anv_image_view_info *view_type_info
-      = &anv_image_view_info_table[pCreateInfo->viewType];
-
-   if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
-      anv_finishme("non-2D image views");
-
-   switch (pCreateInfo->subresourceRange.aspect) {
-   case VK_IMAGE_ASPECT_STENCIL:
-      anv_finishme("stencil image views");
-      abort();
-      break;
-   case VK_IMAGE_ASPECT_DEPTH:
-   case VK_IMAGE_ASPECT_COLOR:
-      view->offset = image->offset;
-      surface = &image->primary_surface;
-      break;
-   default:
-      unreachable("");
-      break;
-   }
-
-   view->bo = image->bo;
-   view->offset = image->offset + surface->offset;
-   view->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;
-   }
-
-   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
-   };
-
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = view_type_info->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 = surface->tile_mode,
-      .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,
-      .MinimumArrayElement = range->baseArraySlice,
-      .NumberofMultisamples = MULTISAMPLECOUNT_1,
-      .XOffset = 0,
-      .YOffset = 0,
-
-      /* For sampler surfaces, the hardware interprets field MIPCount/LOD as
-       * MIPCount.  The range of levels accessible by the sampler engine is
-       * [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
-       */
-      .MIPCountLOD = range->mipLevels - 1,
-      .SurfaceMinLOD = range->baseMipLevel,
-
-      .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, view->offset },
-   };
-
-   if (cmd_buffer) {
-      view->surface_state =
-         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
-   } else {
-      view->surface_state =
-         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-   }
-
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
-}
-
-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;
-   const struct anv_format *image_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);
-   image_format_info = anv_format_for_vk_format(image->format);
-   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->aspect >= VK_IMAGE_ASPECT_BEGIN_RANGE);
-   assert(subresource->aspect <= VK_IMAGE_ASPECT_END_RANGE);
-   assert(subresource->mipLevels > 0);
-   assert(subresource->arraySize > 0);
-   assert(subresource->baseMipLevel < image->levels);
-   assert(subresource->baseMipLevel + subresource->mipLevels <= image->levels);
-   assert(subresource->baseArraySlice < image->array_size);
-   assert(subresource->baseArraySlice + subresource->arraySize <= image->array_size);
-   assert(pView);
-
-   if (view_info->is_cube) {
-      assert(subresource->baseArraySlice % 6 == 0);
-      assert(subresource->arraySize % 6 == 0);
-   }
-
-   /* Validate format. */
-   switch (subresource->aspect) {
-   case VK_IMAGE_ASPECT_COLOR:
-      assert(!image_format_info->depth_format);
-      assert(!image_format_info->has_stencil);
-      assert(!view_format_info->depth_format);
-      assert(!view_format_info->has_stencil);
-      assert(view_format_info->cpp == image_format_info->cpp);
-      break;
-   case VK_IMAGE_ASPECT_DEPTH:
-      assert(image_format_info->depth_format);
-      assert(view_format_info->depth_format);
-      assert(view_format_info->cpp == image_format_info->cpp);
-      break;
-   case VK_IMAGE_ASPECT_STENCIL:
-      /* FINISHME: Is it legal to have an R8 view of S8? */
-      assert(image_format_info->has_stencil);
-      assert(view_format_info->has_stencil);
-      break;
-   default:
-      assert(!"bad VkImageAspect");
-      break;
-   }
-
-   return anv_CreateImageView(_device, pCreateInfo, pView);
-}
-
-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;
-}
-
-VkResult
-anv_DestroyImageView(VkDevice _device, VkImageView _iview)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_image_view, iview, _iview);
-
-   anv_surface_view_fini(device, &iview->view);
-   anv_device_free(device, iview);
-
-   return VK_SUCCESS;
-}
-
-void
-anv_color_attachment_view_init(struct anv_color_attachment_view *aview,
-                               struct anv_device *device,
-                               const VkAttachmentViewCreateInfo* pCreateInfo,
-                               struct anv_cmd_buffer *cmd_buffer)
-{
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-   struct anv_surface_view *view = &aview->view;
-   struct anv_surface *surface = &image->primary_surface;
-   const struct anv_format *format_info =
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   aview->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_COLOR;
-
-   anv_assert(pCreateInfo->arraySize > 0);
-   anv_assert(pCreateInfo->mipLevel < image->levels);
-   anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size);
-
-   view->bo = image->bo;
-   view->offset = image->offset + surface->offset;
-   view->format = pCreateInfo->format;
-
-   aview->base.extent = (VkExtent3D) {
-      .width = anv_minify(image->extent.width, pCreateInfo->mipLevel),
-      .height = anv_minify(image->extent.height, pCreateInfo->mipLevel),
-      .depth = anv_minify(image->extent.depth, pCreateInfo->mipLevel),
-   };
-
-   uint32_t depth = 1;
-   if (pCreateInfo->arraySize > 1) {
-      depth = pCreateInfo->arraySize;
-   } else if (image->extent.depth > 1) {
-      depth = image->extent.depth;
-   }
-
-   if (cmd_buffer) {
-      view->surface_state =
-         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
-   } else {
-      view->surface_state =
-         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-   }
-
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = SURFTYPE_2D,
-      .SurfaceArray = image->array_size > 1,
-      .SurfaceFormat = format_info->surface_format,
-      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
-      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
-      .TileMode = surface->tile_mode,
-      .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,
-      .MinimumArrayElement = pCreateInfo->baseArraySlice,
-      .NumberofMultisamples = MULTISAMPLECOUNT_1,
-      .XOffset = 0,
-      .YOffset = 0,
-
-      /* 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.
-       */
-      .SurfaceMinLOD = 0,
-      .MIPCountLOD = pCreateInfo->mipLevel,
-
-      .AuxiliarySurfaceMode = AUX_NONE,
-      .RedClearColor = 0,
-      .GreenClearColor = 0,
-      .BlueClearColor = 0,
-      .AlphaClearColor = 0,
-      .ShaderChannelSelectRed = SCS_RED,
-      .ShaderChannelSelectGreen = SCS_GREEN,
-      .ShaderChannelSelectBlue = SCS_BLUE,
-      .ShaderChannelSelectAlpha = SCS_ALPHA,
-      .ResourceMinLOD = 0.0,
-      .SurfaceBaseAddress = { NULL, view->offset },
-   };
-
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
-}
-
-static void
-anv_depth_stencil_view_init(struct anv_depth_stencil_view *view,
-                            const VkAttachmentViewCreateInfo *pCreateInfo)
-{
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-   struct anv_surface *depth_surface = &image->primary_surface;
-   struct anv_surface *stencil_surface = &image->stencil_surface;
-   const struct anv_format *format =
-      anv_format_for_vk_format(image->format);
-
-   view->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL;
-
-   /* XXX: We don't handle any of these */
-   anv_assert(pCreateInfo->mipLevel == 0);
-   anv_assert(pCreateInfo->baseArraySlice == 0);
-   anv_assert(pCreateInfo->arraySize == 1);
-
-   view->bo = image->bo;
-
-   view->depth_stride = depth_surface->stride;
-   view->depth_offset = image->offset + depth_surface->offset;
-   view->depth_format = format->depth_format;
-   view->depth_qpitch = 0; /* FINISHME: QPitch */
-
-   view->stencil_stride = stencil_surface->stride;
-   view->stencil_offset = image->offset + stencil_surface->offset;
-   view->stencil_qpitch = 0; /* FINISHME: QPitch */
-}
-
-VkResult
-anv_CreateAttachmentView(VkDevice _device,
-                         const VkAttachmentViewCreateInfo *pCreateInfo,
-                         VkAttachmentView *pView)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO);
-
-   if (anv_is_vk_format_depth_or_stencil(pCreateInfo->format)) {
-      struct anv_depth_stencil_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_depth_stencil_view_init(view, pCreateInfo);
-
-      *pView = anv_attachment_view_to_handle(&view->base);
-   } else {
-      struct anv_color_attachment_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_color_attachment_view_init(view, device, pCreateInfo, NULL);
-
-      *pView = anv_attachment_view_to_handle(&view->base);
-   }
-
-   return VK_SUCCESS;
-}
-
-VkResult
-anv_DestroyAttachmentView(VkDevice _device, VkAttachmentView _view)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_attachment_view, view, _view);
-
-   if (view->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_COLOR) {
-      struct anv_color_attachment_view *aview =
-         (struct anv_color_attachment_view *)view;
-
-      anv_surface_view_fini(device, &aview->view);
-   }
-
-   anv_device_free(device, view);
-
-   return VK_SUCCESS;
-}
diff --git a/src/vulkan/intel.c b/src/vulkan/intel.c
deleted file mode 100644 (file)
index e314ba6..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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 "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;
-
-   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;
-   }
-
-   *image = (struct anv_image) {
-      .bo = &mem->bo,
-      .offset = 0,
-      .type = VK_IMAGE_TYPE_2D,
-      .extent = pCreateInfo->extent,
-      .size = mem->bo.size,
-
-      .primary_surface = {
-         .offset = 0,
-         .stride = pCreateInfo->strideInBytes,
-         .tile_mode = XMAJOR,
-      },
-   };
-
-   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/meta.c b/src/vulkan/meta.c
deleted file mode 100644 (file)
index 3080958..0000000
+++ /dev/null
@@ -1,1449 +0,0 @@
-/*
- * 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 "private.h"
-#include "meta-spirv.h"
-
-static void
-anv_device_init_meta_clear_state(struct anv_device *device)
-{
-   /* We don't use a vertex shader for clearing, but instead build and pass
-    * the VUEs directly to the rasterization backend.
-    */
-   VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT,
-      out vec4 f_color;
-      flat in vec4 v_color;
-      void main()
-      {
-         f_color = v_color;
-      }
-   );
-
-   VkShader fs;
-   anv_CreateShader(anv_device_to_handle(device),
-      &(VkShaderCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
-         .module = fsm,
-         .pName = "main",
-      }, &fs);
-
-   /* We use instanced rendering to clear multiple render targets. We have two
-    * vertex buffers: the first vertex buffer holds per-vertex data and
-    * provides the vertices for the clear rectangle. The second one holds
-    * per-instance data, which consists of the VUE header (which selects the
-    * layer) and the color (Vulkan supports per-RT clear colors).
-    */
-   VkPipelineVertexInputStateCreateInfo vi_create_info = {
-      .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
-      .bindingCount = 2,
-      .pVertexBindingDescriptions = (VkVertexInputBindingDescription[]) {
-         {
-            .binding = 0,
-            .strideInBytes = 8,
-            .stepRate = VK_VERTEX_INPUT_STEP_RATE_VERTEX
-         },
-         {
-            .binding = 1,
-            .strideInBytes = 32,
-            .stepRate = VK_VERTEX_INPUT_STEP_RATE_INSTANCE
-         },
-      },
-      .attributeCount = 3,
-      .pVertexAttributeDescriptions = (VkVertexInputAttributeDescription[]) {
-         {
-            /* VUE Header */
-            .location = 0,
-            .binding = 1,
-            .format = VK_FORMAT_R32G32B32A32_UINT,
-            .offsetInBytes = 0
-         },
-         {
-            /* Position */
-            .location = 1,
-            .binding = 0,
-            .format = VK_FORMAT_R32G32_SFLOAT,
-            .offsetInBytes = 0
-         },
-         {
-            /* Color */
-            .location = 2,
-            .binding = 1,
-            .format = VK_FORMAT_R32G32B32A32_SFLOAT,
-            .offsetInBytes = 16
-         }
-      }
-   };
-
-   anv_pipeline_create(anv_device_to_handle(device),
-      &(VkGraphicsPipelineCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
-         .stageCount = 1,
-         .pStages = &(VkPipelineShaderStageCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
-            .stage = VK_SHADER_STAGE_FRAGMENT,
-            .shader = fs,
-            .pSpecializationInfo = NULL,
-         },
-         .pVertexInputState = &vi_create_info,
-         .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
-            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
-            .primitiveRestartEnable = false,
-         },
-         .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
-         },
-         .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 },
-            }
-         },
-         .flags = 0,
-      },
-      &(struct anv_pipeline_create_info) {
-         .use_repclear = true,
-         .disable_viewport = true,
-         .use_rectlist = true
-      },
-      &device->meta_state.clear.pipeline);
-
-   anv_DestroyShader(anv_device_to_handle(device), fs);
-}
-
-#define NUM_VB_USED 2
-struct anv_saved_state {
-   struct anv_vertex_binding old_vertex_bindings[NUM_VB_USED];
-   struct anv_descriptor_set *old_descriptor_set0;
-   struct anv_pipeline *old_pipeline;
-   VkDynamicColorBlendState cb_state;
-};
-
-static void
-anv_cmd_buffer_save(struct anv_cmd_buffer *cmd_buffer,
-                    struct anv_saved_state *state)
-{
-   state->old_pipeline = cmd_buffer->state.pipeline;
-   state->old_descriptor_set0 = cmd_buffer->state.descriptors[0].set;
-   memcpy(state->old_vertex_bindings, cmd_buffer->state.vertex_bindings,
-          sizeof(state->old_vertex_bindings));
-}
-
-static void
-anv_cmd_buffer_restore(struct anv_cmd_buffer *cmd_buffer,
-                       const struct anv_saved_state *state)
-{
-   cmd_buffer->state.pipeline = state->old_pipeline;
-   cmd_buffer->state.descriptors[0].set = 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 << NUM_VB_USED) - 1;
-   cmd_buffer->state.dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
-   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_VERTEX_BIT;
-}
-
-struct vue_header {
-   uint32_t Reserved;
-   uint32_t RTAIndex;
-   uint32_t ViewportIndex;
-   float PointWidth;
-};
-
-struct clear_instance_data {
-   struct vue_header vue_header;
-   VkClearColorValue color;
-};
-
-static void
-meta_emit_clear(struct anv_cmd_buffer *cmd_buffer,
-                int num_instances,
-                struct clear_instance_data *instance_data)
-{
-   struct anv_device *device = cmd_buffer->device;
-   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
-   struct anv_state state;
-   uint32_t size;
-
-   const float vertex_data[] = {
-      /* Rect-list coordinates */
-            0.0,        0.0,
-      fb->width,        0.0,
-      fb->width, fb->height,
-
-      /* Align to 16 bytes */
-            0.0,        0.0,
-   };
-
-   size = sizeof(vertex_data) + num_instances * sizeof(*instance_data);
-   state = anv_state_stream_alloc(&cmd_buffer->surface_state_stream, size, 16);
-
-   /* Copy in the vertex and instance data */
-   memcpy(state.map, vertex_data, sizeof(vertex_data));
-   memcpy(state.map + sizeof(vertex_data), instance_data,
-          num_instances * sizeof(*instance_data));
-
-   struct anv_buffer vertex_buffer = {
-      .device = cmd_buffer->device,
-      .size = size,
-      .bo = &device->surface_state_block_pool.bo,
-      .offset = 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(vertex_data)
-      });
-
-   if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.clear.pipeline))
-      anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
-                          VK_PIPELINE_BIND_POINT_GRAPHICS,
-                          device->meta_state.clear.pipeline);
-
-   /* We don't need anything here, only set if not already set. */
-   if (cmd_buffer->state.rs_state == NULL)
-      anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                    device->meta_state.shared.rs_state);
-
-   if (cmd_buffer->state.vp_state == NULL)
-      anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                      cmd_buffer->state.framebuffer->vp_state);
-
-   if (cmd_buffer->state.ds_state == NULL)
-      anv_CmdBindDynamicDepthStencilState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                          device->meta_state.shared.ds_state);
-
-   if (cmd_buffer->state.cb_state == NULL)
-      anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                        device->meta_state.shared.cb_state);
-
-   anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, num_instances);
-}
-
-void
-anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
-                                 struct anv_render_pass *pass,
-                                 const VkClearValue *clear_values)
-{
-   struct anv_saved_state saved_state;
-
-   int num_clear_layers = 0;
-   for (uint32_t i = 0; i < pass->attachment_count; i++) {
-      if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
-         if (anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) {
-            anv_finishme("Can't clear depth-stencil yet");
-            continue;
-         }
-         num_clear_layers++;
-      }
-   }
-
-   if (num_clear_layers == 0)
-      return;
-
-   struct clear_instance_data instance_data[num_clear_layers];
-   uint32_t color_attachments[num_clear_layers];
-
-   int layer = 0;
-   for (uint32_t i = 0; i < pass->attachment_count; i++) {
-      if (pass->attachments[i].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR &&
-          !anv_is_vk_format_depth_or_stencil(pass->attachments[i].format)) {
-         instance_data[layer] = (struct clear_instance_data) {
-            .vue_header = {
-               .RTAIndex = i,
-               .ViewportIndex = 0,
-               .PointWidth = 0.0
-            },
-            .color = clear_values[i].color,
-         };
-         color_attachments[layer] = i;
-         layer++;
-      }
-   }
-
-   anv_cmd_buffer_save(cmd_buffer, &saved_state);
-
-   struct anv_subpass subpass = {
-      .input_count = 0,
-      .color_count = num_clear_layers,
-      .color_attachments = color_attachments,
-      .depth_stencil_attachment = VK_ATTACHMENT_UNUSED,
-   };
-
-   anv_cmd_buffer_begin_subpass(cmd_buffer, &subpass);
-
-   meta_emit_clear(cmd_buffer, num_clear_layers, instance_data);
-
-   /* Restore API state */
-   anv_cmd_buffer_restore(cmd_buffer, &saved_state);
-}
-
-static void
-anv_device_init_meta_blit_state(struct anv_device *device)
-{
-   /* 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.
-    */
-   VkShaderModule vsm = GLSL_VK_SHADER_MODULE(device, VERTEX,
-      in vec2 a_pos;
-      in vec2 a_tex_coord;
-      out vec4 v_tex_coord;
-      void main()
-      {
-         v_tex_coord = vec4(a_tex_coord, 0, 1);
-         gl_Position = vec4(a_pos, 0, 1);
-      }
-   );
-
-   VkShaderModule fsm = GLSL_VK_SHADER_MODULE(device, FRAGMENT,
-      out vec4 f_color;
-      in vec4 v_tex_coord;
-      layout(set = 0, binding = 0) uniform sampler2D u_tex;
-      void main()
-      {
-         f_color = texture(u_tex, v_tex_coord.xy);
-      }
-   );
-
-   VkShader vs;
-   anv_CreateShader(anv_device_to_handle(device),
-      &(VkShaderCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
-         .module = vsm,
-         .pName = "main",
-      }, &vs);
-
-   VkShader fs;
-   anv_CreateShader(anv_device_to_handle(device),
-      &(VkShaderCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
-         .module = fsm,
-         .pName = "main",
-      }, &fs);
-
-   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 = 16,
-            .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_R32G32_SFLOAT,
-            .offsetInBytes = 8
-         }
-      }
-   };
-
-   VkDescriptorSetLayoutCreateInfo ds_layout_info = {
-      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-      .count = 1,
-      .pBinding = (VkDescriptorSetLayoutBinding[]) {
-         {
-            .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
-            .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);
-
-   anv_pipeline_create(anv_device_to_handle(device),
-      &(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,
-               .pSpecializationInfo = NULL
-            }, {
-               .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
-               .stage = VK_SHADER_STAGE_FRAGMENT,
-               .shader = fs,
-               .pSpecializationInfo = NULL
-            },
-         },
-         .pVertexInputState = &vi_create_info,
-         .pInputAssemblyState = &(VkPipelineInputAssemblyStateCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
-            .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
-            .primitiveRestartEnable = false,
-         },
-         .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
-         },
-         .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 },
-            }
-         },
-         .flags = 0,
-         .layout = device->meta_state.blit.pipeline_layout,
-      },
-      &(struct anv_pipeline_create_info) {
-         .use_repclear = false,
-         .disable_viewport = true,
-         .disable_scissor = true,
-         .disable_vs = true,
-         .use_rectlist = true
-      },
-      &device->meta_state.blit.pipeline);
-
-   anv_DestroyShader(anv_device_to_handle(device), vs);
-   anv_DestroyShader(anv_device_to_handle(device), fs);
-}
-
-static void
-meta_prepare_blit(struct anv_cmd_buffer *cmd_buffer,
-                  struct anv_saved_state *saved_state)
-{
-   struct anv_device *device = cmd_buffer->device;
-
-   anv_cmd_buffer_save(cmd_buffer, saved_state);
-
-   if (cmd_buffer->state.pipeline != anv_pipeline_from_handle(device->meta_state.blit.pipeline))
-      anv_CmdBindPipeline(anv_cmd_buffer_to_handle(cmd_buffer),
-                          VK_PIPELINE_BIND_POINT_GRAPHICS,
-                          device->meta_state.blit.pipeline);
-
-   /* We don't need anything here, only set if not already set. */
-   if (cmd_buffer->state.rs_state == NULL)
-      anv_CmdBindDynamicRasterState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                    device->meta_state.shared.rs_state);
-   if (cmd_buffer->state.ds_state == NULL)
-      anv_CmdBindDynamicDepthStencilState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                          device->meta_state.shared.ds_state);
-
-   saved_state->cb_state = anv_dynamic_cb_state_to_handle(cmd_buffer->state.cb_state);
-   anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                     device->meta_state.shared.cb_state);
-}
-
-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_view *src,
-               VkOffset3D src_offset,
-               VkExtent3D src_extent,
-               struct anv_color_attachment_view *dest,
-               VkOffset3D dest_offset,
-               VkExtent3D dest_extent)
-{
-   struct anv_device *device = cmd_buffer->device;
-   VkDescriptorPool dummy_desc_pool = { .handle = 1 };
-
-   struct blit_vb_data {
-      float pos[2];
-      float tex_coord[2];
-   } *vb_data;
-
-   unsigned vb_size = sizeof(struct vue_header) + 3 * sizeof(*vb_data);
-
-   struct anv_state vb_state =
-      anv_state_stream_alloc(&cmd_buffer->surface_state_stream, vb_size, 16);
-   memset(vb_state.map, 0, sizeof(struct vue_header));
-   vb_data = vb_state.map + sizeof(struct 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->extent.width,
-         (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
-      },
-   };
-
-   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->extent.width,
-         (float)(src_offset.y + src_extent.height) / (float)src->extent.height,
-      },
-   };
-
-   vb_data[2] = (struct blit_vb_data) {
-      .pos = {
-         dest_offset.x,
-         dest_offset.y,
-      },
-      .tex_coord = {
-         (float)src_offset.x / (float)src->extent.width,
-         (float)src_offset.y / (float)src->extent.height,
-      },
-   };
-
-   struct anv_buffer vertex_buffer = {
-      .device = device,
-      .size = vb_size,
-      .bo = &device->surface_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 vue_header),
-      });
-
-   uint32_t count;
-   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, &count);
-   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_SAMPLED_IMAGE,
-            .pDescriptors = (VkDescriptorInfo[]) {
-               {
-                  .imageView = anv_image_view_to_handle(src),
-                  .imageLayout = VK_IMAGE_LAYOUT_GENERAL
-               },
-            }
-         }
-      }, 0, NULL);
-
-   VkFramebuffer fb;
-   anv_CreateFramebuffer(anv_device_to_handle(device),
-      &(VkFramebufferCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
-         .attachmentCount = 1,
-         .pAttachments = (VkAttachmentBindInfo[]) {
-            {
-               .view = anv_attachment_view_to_handle(&dest->base),
-               .layout = VK_IMAGE_LAYOUT_GENERAL
-            }
-         },
-         .width = dest->base.extent.width,
-         .height = dest->base.extent.height,
-         .layers = 1
-      }, &fb);
-
-   VkRenderPass pass;
-   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 = dest->view.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,
-            .colorAttachments = &(VkAttachmentReference) {
-               .attachment = 0,
-               .layout = VK_IMAGE_LAYOUT_GENERAL,
-            },
-            .resolveAttachments = NULL,
-            .depthStencilAttachment = (VkAttachmentReference) {
-               .attachment = VK_ATTACHMENT_UNUSED,
-               .layout = VK_IMAGE_LAYOUT_GENERAL,
-            },
-            .preserveCount = 1,
-            .preserveAttachments = &(VkAttachmentReference) {
-               .attachment = 0,
-               .layout = VK_IMAGE_LAYOUT_GENERAL,
-            },
-         },
-         .dependencyCount = 0,
-      }, &pass);
-
-   anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
-      &(VkRenderPassBeginInfo) {
-         .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-         .renderPass = pass,
-         .framebuffer = fb,
-         .renderArea = {
-            .offset = { dest_offset.x, dest_offset.y },
-            .extent = { dest_extent.width, dest_extent.height },
-         },
-         .attachmentCount = 1,
-         .pAttachmentClearValues = NULL,
-      }, VK_RENDER_PASS_CONTENTS_INLINE);
-
-   anv_CmdBindDynamicViewportState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                   anv_framebuffer_from_handle(fb)->vp_state);
-
-   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_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, 1);
-
-   anv_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_DestroyFramebuffer(anv_device_to_handle(device), fb);
-   anv_DestroyRenderPass(anv_device_to_handle(device), pass);
-}
-
-static void
-meta_finish_blit(struct anv_cmd_buffer *cmd_buffer,
-                 const struct anv_saved_state *saved_state)
-{
-   anv_cmd_buffer_restore(cmd_buffer, saved_state);
-   anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
-                                     saved_state->cb_state);
-}
-
-static VkFormat
-vk_format_for_cpp(int cpp)
-{
-   switch (cpp) {
-   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 cpp");
-   }
-}
-
-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 = VK_IMAGE_USAGE_SAMPLED_BIT,
-      .flags = 0,
-   };
-
-   VkImage src_image, dest_image;
-   anv_CreateImage(vk_device, &image_info, &src_image);
-   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_view;
-   anv_image_view_init(&src_view, 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 = {
-            .aspect = VK_IMAGE_ASPECT_COLOR,
-            .baseMipLevel = 0,
-            .mipLevels = 1,
-            .baseArraySlice = 0,
-            .arraySize = 1
-         },
-      },
-      cmd_buffer);
-
-   struct anv_color_attachment_view dest_view;
-   anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
-      &(VkAttachmentViewCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
-         .image = dest_image,
-         .format = copy_format,
-         .mipLevel = 0,
-         .baseArraySlice = 0,
-         .arraySize = 1,
-      },
-      cmd_buffer);
-
-   meta_emit_blit(cmd_buffer,
-                  &src_view,
-                  (VkOffset3D) { 0, 0, 0 },
-                  (VkExtent3D) { width, height, 1 },
-                  &dest_view,
-                  (VkOffset3D) { 0, 0, 0 },
-                  (VkExtent3D) { width, height, 1 });
-
-   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_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 cpp = 16;
-
-      int fs = ffs(src_offset) - 1;
-      if (fs != -1)
-         cpp = MIN2(cpp, 1 << fs);
-      assert(src_offset % cpp == 0);
-
-      fs = ffs(dest_offset) - 1;
-      if (fs != -1)
-         cpp = MIN2(cpp, 1 << fs);
-      assert(dest_offset % cpp == 0);
-
-      fs = ffs(pRegions[r].copySize) - 1;
-      if (fs != -1)
-         cpp = MIN2(cpp, 1 << fs);
-      assert(pRegions[r].copySize % cpp == 0);
-
-      VkFormat copy_format = vk_format_for_cpp(cpp);
-
-      /* 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 * cpp;
-      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 * cpp);
-      assert(height < max_surface_dim);
-      if (height != 0) {
-         uint64_t rect_copy_size = height * max_surface_dim * cpp;
-         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 / cpp, 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);
-
-   struct anv_saved_state saved_state;
-
-   meta_prepare_blit(cmd_buffer, &saved_state);
-
-   for (unsigned r = 0; r < regionCount; r++) {
-      struct anv_image_view src_view;
-      anv_image_view_init(&src_view, cmd_buffer->device,
-         &(VkImageViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .image = srcImage,
-            .viewType = VK_IMAGE_VIEW_TYPE_2D,
-            .format = src_image->format,
-            .channels = {
-               VK_CHANNEL_SWIZZLE_R,
-               VK_CHANNEL_SWIZZLE_G,
-               VK_CHANNEL_SWIZZLE_B,
-               VK_CHANNEL_SWIZZLE_A
-            },
-            .subresourceRange = {
-               .aspect = pRegions[r].srcSubresource.aspect,
-               .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
-               .mipLevels = 1,
-               .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
-               .arraySize = 1
-            },
-         },
-         cmd_buffer);
-
-      struct anv_color_attachment_view dest_view;
-      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
-            .image = destImage,
-            .format = src_image->format,
-            .mipLevel = pRegions[r].destSubresource.mipLevel,
-            .baseArraySlice = pRegions[r].destSubresource.arraySlice,
-            .arraySize = 1,
-         },
-         cmd_buffer);
-
-      meta_emit_blit(cmd_buffer,
-                     &src_view,
-                     pRegions[r].srcOffset,
-                     pRegions[r].extent,
-                     &dest_view,
-                     pRegions[r].destOffset,
-                     pRegions[r].extent);
-   }
-
-   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);
-
-   struct anv_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_view;
-      anv_image_view_init(&src_view, cmd_buffer->device,
-         &(VkImageViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .image = srcImage,
-            .viewType = VK_IMAGE_VIEW_TYPE_2D,
-            .format = src_image->format,
-            .channels = {
-               VK_CHANNEL_SWIZZLE_R,
-               VK_CHANNEL_SWIZZLE_G,
-               VK_CHANNEL_SWIZZLE_B,
-               VK_CHANNEL_SWIZZLE_A
-            },
-            .subresourceRange = {
-               .aspect = pRegions[r].srcSubresource.aspect,
-               .baseMipLevel = pRegions[r].srcSubresource.mipLevel,
-               .mipLevels = 1,
-               .baseArraySlice = pRegions[r].srcSubresource.arraySlice,
-               .arraySize = 1
-            },
-         },
-         cmd_buffer);
-
-      struct anv_color_attachment_view dest_view;
-      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
-            .image = destImage,
-            .format = dest_image->format,
-            .mipLevel = pRegions[r].destSubresource.mipLevel,
-            .baseArraySlice = pRegions[r].destSubresource.arraySlice,
-            .arraySize = 1,
-         },
-         cmd_buffer);
-
-      meta_emit_blit(cmd_buffer,
-                     &src_view,
-                     pRegions[r].srcOffset,
-                     pRegions[r].srcExtent,
-                     &dest_view,
-                     pRegions[r].destOffset,
-                     pRegions[r].destExtent);
-   }
-
-   meta_finish_blit(cmd_buffer, &saved_state);
-}
-
-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_buffer, src_buffer, srcBuffer);
-   ANV_FROM_HANDLE(anv_image, dest_image, destImage);
-   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
-   struct anv_saved_state saved_state;
-
-   meta_prepare_blit(cmd_buffer, &saved_state);
-
-   for (unsigned r = 0; r < regionCount; r++) {
-      if (pRegions[r].bufferRowLength != 0)
-         anv_finishme("bufferRowLength not supported in CopyBufferToImage");
-      if (pRegions[r].bufferImageHeight != 0)
-         anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
-
-      VkImage srcImage;
-      anv_CreateImage(vk_device,
-         &(VkImageCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-            .imageType = VK_IMAGE_TYPE_2D,
-            .format = dest_image->format,
-            .extent = {
-               .width = pRegions[r].imageExtent.width,
-               .height = pRegions[r].imageExtent.height,
-               .depth = 1,
-            },
-            .mipLevels = 1,
-            .arraySize = 1,
-            .samples = 1,
-            .tiling = VK_IMAGE_TILING_LINEAR,
-            .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
-            .flags = 0,
-         }, &srcImage);
-
-      ANV_FROM_HANDLE(anv_image, src_image, srcImage);
-
-      /* 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.
-       */
-      src_image->bo = src_buffer->bo;
-      src_image->offset = src_buffer->offset + pRegions[r].bufferOffset;
-
-      struct anv_image_view src_view;
-      anv_image_view_init(&src_view, cmd_buffer->device,
-         &(VkImageViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .image = anv_image_to_handle(src_image),
-            .viewType = VK_IMAGE_VIEW_TYPE_2D,
-            .format = dest_image->format,
-            .channels = {
-               VK_CHANNEL_SWIZZLE_R,
-               VK_CHANNEL_SWIZZLE_G,
-               VK_CHANNEL_SWIZZLE_B,
-               VK_CHANNEL_SWIZZLE_A
-            },
-            .subresourceRange = {
-               .aspect = pRegions[r].imageSubresource.aspect,
-               .baseMipLevel = 0,
-               .mipLevels = 1,
-               .baseArraySlice = 0,
-               .arraySize = 1
-            },
-         },
-         cmd_buffer);
-
-      struct anv_color_attachment_view dest_view;
-      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
-            .image = anv_image_to_handle(dest_image),
-            .format = dest_image->format,
-            .mipLevel = pRegions[r].imageSubresource.mipLevel,
-            .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
-            .arraySize = 1,
-         },
-         cmd_buffer);
-
-      meta_emit_blit(cmd_buffer,
-                     &src_view,
-                     (VkOffset3D) { 0, 0, 0 },
-                     pRegions[r].imageExtent,
-                     &dest_view,
-                     pRegions[r].imageOffset,
-                     pRegions[r].imageExtent);
-
-      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);
-   ANV_FROM_HANDLE(anv_buffer, dest_buffer, destBuffer);
-   VkDevice vk_device = anv_device_to_handle(cmd_buffer->device);
-   struct anv_saved_state saved_state;
-
-   meta_prepare_blit(cmd_buffer, &saved_state);
-
-   for (unsigned r = 0; r < regionCount; r++) {
-      if (pRegions[r].bufferRowLength != 0)
-         anv_finishme("bufferRowLength not supported in CopyBufferToImage");
-      if (pRegions[r].bufferImageHeight != 0)
-         anv_finishme("bufferImageHeight not supported in CopyBufferToImage");
-
-      struct anv_image_view src_view;
-      anv_image_view_init(&src_view, cmd_buffer->device,
-         &(VkImageViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
-            .image = srcImage,
-            .viewType = VK_IMAGE_VIEW_TYPE_2D,
-            .format = src_image->format,
-            .channels = {
-               VK_CHANNEL_SWIZZLE_R,
-               VK_CHANNEL_SWIZZLE_G,
-               VK_CHANNEL_SWIZZLE_B,
-               VK_CHANNEL_SWIZZLE_A
-            },
-            .subresourceRange = {
-               .aspect = pRegions[r].imageSubresource.aspect,
-               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
-               .mipLevels = 1,
-               .baseArraySlice = pRegions[r].imageSubresource.arraySlice,
-               .arraySize = 1
-            },
-         },
-         cmd_buffer);
-
-      VkImage destImage;
-      anv_CreateImage(vk_device,
-         &(VkImageCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
-            .imageType = VK_IMAGE_TYPE_2D,
-            .format = src_image->format,
-            .extent = {
-               .width = pRegions[r].imageExtent.width,
-               .height = pRegions[r].imageExtent.height,
-               .depth = 1,
-            },
-            .mipLevels = 1,
-            .arraySize = 1,
-            .samples = 1,
-            .tiling = VK_IMAGE_TILING_LINEAR,
-            .usage = VK_IMAGE_USAGE_SAMPLED_BIT,
-            .flags = 0,
-         }, &destImage);
-
-      ANV_FROM_HANDLE(anv_image, dest_image, destImage);
-
-      /* 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.
-       */
-      dest_image->bo = dest_buffer->bo;
-      dest_image->offset = dest_buffer->offset + pRegions[r].bufferOffset;
-
-      struct anv_color_attachment_view dest_view;
-      anv_color_attachment_view_init(&dest_view, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
-            .image = destImage,
-            .format = src_image->format,
-            .mipLevel = 0,
-            .baseArraySlice = 0,
-            .arraySize = 1,
-         },
-         cmd_buffer);
-
-      meta_emit_blit(cmd_buffer,
-                     &src_view,
-                     pRegions[r].imageOffset,
-                     pRegions[r].imageExtent,
-                     &dest_view,
-                     (VkOffset3D) { 0, 0, 0 },
-                     pRegions[r].imageExtent);
-
-      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_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_saved_state saved_state;
-
-   anv_cmd_buffer_save(cmd_buffer, &saved_state);
-
-   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_color_attachment_view view;
-            anv_color_attachment_view_init(&view, cmd_buffer->device,
-               &(VkAttachmentViewCreateInfo) {
-                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
-                  .image = _image,
-                  .format = image->format,
-                  .mipLevel = pRanges[r].baseMipLevel + l,
-                  .baseArraySlice = pRanges[r].baseArraySlice + 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 = (VkAttachmentBindInfo[]) {
-                     {
-                        .view = anv_attachment_view_to_handle(&view.base),
-                        .layout = VK_IMAGE_LAYOUT_GENERAL
-                     }
-                  },
-                  .width = view.base.extent.width,
-                  .height = view.base.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 = view.view.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,
-                     .colorAttachments = &(VkAttachmentReference) {
-                        .attachment = 0,
-                        .layout = VK_IMAGE_LAYOUT_GENERAL,
-                     },
-                     .resolveAttachments = NULL,
-                     .depthStencilAttachment = (VkAttachmentReference) {
-                        .attachment = VK_ATTACHMENT_UNUSED,
-                        .layout = VK_IMAGE_LAYOUT_GENERAL,
-                     },
-                     .preserveCount = 1,
-                     .preserveAttachments = &(VkAttachmentReference) {
-                        .attachment = 0,
-                        .layout = VK_IMAGE_LAYOUT_GENERAL,
-                     },
-                  },
-                  .dependencyCount = 0,
-               }, &pass);
-
-            anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
-               &(VkRenderPassBeginInfo) {
-                  .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
-                  .renderArea = {
-                     .offset = { 0, 0, },
-                     .extent = {
-                        .width = view.base.extent.width,
-                        .height = view.base.extent.height,
-                     },
-                  },
-                  .renderPass = pass,
-                  .framebuffer = fb,
-                  .attachmentCount = 1,
-                  .pAttachmentClearValues = NULL,
-               }, VK_RENDER_PASS_CONTENTS_INLINE);
-
-            struct clear_instance_data instance_data = {
-               .vue_header = {
-                  .RTAIndex = 0,
-                  .ViewportIndex = 0,
-                  .PointWidth = 0.0
-               },
-               .color = *pColor,
-            };
-
-            meta_emit_clear(cmd_buffer, 1, &instance_data);
-
-            anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
-         }
-      }
-   }
-
-   /* Restore API state */
-   anv_cmd_buffer_restore(cmd_buffer, &saved_state);
-}
-
-void anv_CmdClearDepthStencilImage(
-    VkCmdBuffer                                 cmdBuffer,
-    VkImage                                     image,
-    VkImageLayout                               imageLayout,
-    float                                       depth,
-    uint32_t                                    stencil,
-    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                          imageAspectMask,
-    VkImageLayout                               imageLayout,
-    float                                       depth,
-    uint32_t                                    stencil,
-    uint32_t                                    rectCount,
-    const VkRect3D*                             pRects)
-{
-   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);
-
-   anv_CreateDynamicRasterState(anv_device_to_handle(device),
-      &(VkDynamicRasterStateCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO,
-      },
-      &device->meta_state.shared.rs_state);
-
-   anv_CreateDynamicColorBlendState(anv_device_to_handle(device),
-      &(VkDynamicColorBlendStateCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO
-      },
-      &device->meta_state.shared.cb_state);
-
-   anv_CreateDynamicDepthStencilState(anv_device_to_handle(device),
-      &(VkDynamicDepthStencilStateCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO
-      },
-      &device->meta_state.shared.ds_state);
-}
-
-void
-anv_device_finish_meta(struct anv_device *device)
-{
-   /* Clear */
-   anv_DestroyPipeline(anv_device_to_handle(device),
-                       device->meta_state.clear.pipeline);
-
-   /* Blit */
-   anv_DestroyPipeline(anv_device_to_handle(device),
-                       device->meta_state.blit.pipeline);
-   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);
-
-   /* Shared */
-   anv_DestroyDynamicRasterState(anv_device_to_handle(device),
-                                 device->meta_state.shared.rs_state);
-   anv_DestroyDynamicColorBlendState(anv_device_to_handle(device),
-                                     device->meta_state.shared.cb_state);
-   anv_DestroyDynamicDepthStencilState(anv_device_to_handle(device),
-                                       device->meta_state.shared.ds_state);
-}
diff --git a/src/vulkan/pipeline.c b/src/vulkan/pipeline.c
deleted file mode 100644 (file)
index fdb632c..0000000
+++ /dev/null
@@ -1,950 +0,0 @@
-/*
- * 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 "private.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->size = pCreateInfo->codeSize;
-   memcpy(module->data, pCreateInfo->pCode, module->size);
-
-   *pShaderModule = anv_shader_module_to_handle(module);
-
-   return VK_SUCCESS;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-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);
-
-   size_t name_len = strlen(pCreateInfo->pName);
-
-   if (strcmp(pCreateInfo->pName, "main") != 0) {
-      anv_finishme("Multiple shaders per module not really supported");
-   }
-
-   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, pCreateInfo->pName, name_len + 1);
-
-   *pShader = anv_shader_to_handle(shader);
-
-   return VK_SUCCESS;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-
-VkResult anv_CreatePipelineCache(
-    VkDevice                                    device,
-    const VkPipelineCacheCreateInfo*            pCreateInfo,
-    VkPipelineCache*                            pPipelineCache)
-{
-   pPipelineCache->handle = 1;
-
-   stub_return(VK_SUCCESS);
-}
-
-VkResult anv_DestroyPipelineCache(
-    VkDevice                                    _device,
-    VkPipelineCache                             _cache)
-{
-   /* VkPipelineCache is a dummy object. */
-   return VK_SUCCESS;
-}
-
-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);
-}
-
-// Pipeline functions
-
-static void
-emit_vertex_input(struct anv_pipeline *pipeline,
-                  const VkPipelineVertexInputStateCreateInfo *info)
-{
-   const uint32_t num_dwords = 1 + info->attributeCount * 2;
-   uint32_t *p;
-   bool instancing_enable[32];
-
-   pipeline->vb_used = 0;
-   for (uint32_t i = 0; i < info->bindingCount; i++) {
-      const VkVertexInputBindingDescription *desc =
-         &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:
-         instancing_enable[desc->binding] = false;
-         break;
-      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
-         instancing_enable[desc->binding] = true;
-         break;
-      }
-   }
-
-   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 = 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_pipeline_create_info *extra)
-{
-   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
-   };
-   uint32_t topology = vk_to_gen_primitive_type[info->topology];
-
-   if (extra && extra->use_rectlist)
-      topology = _3DPRIM_RECTLIST;
-
-   struct GEN8_3DSTATE_VF vf = {
-      GEN8_3DSTATE_VF_header,
-      .IndexedDrawCutIndexEnable = info->primitiveRestartEnable,
-   };
-   GEN8_3DSTATE_VF_pack(NULL, pipeline->state_vf, &vf);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_TOPOLOGY,
-                  .PrimitiveTopologyType = topology);
-}
-
-static void
-emit_rs_state(struct anv_pipeline *pipeline,
-              const VkPipelineRasterStateCreateInfo *info,
-              const struct anv_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->state_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->state_raster, &raster);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SBE,
-                  .ForceVertexURBEntryReadLength = false,
-                  .ForceVertexURBEntryReadOffset = false,
-                  .PointSpriteTextureCoordinateOrigin = UPPERLEFT,
-                  .NumberofSFOutputAttributes =
-                     pipeline->wm_prog_data.num_varying_inputs);
-
-}
-
-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 = 1 + info->attachmentCount * 2;
-   pipeline->blend_state =
-      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
-
-   struct GEN8_BLEND_STATE blend_state = {
-      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
-   };
-
-   uint32_t *state = pipeline->blend_state.map;
-   GEN8_BLEND_STATE_pack(NULL, state, &blend_state);
-
-   for (uint32_t i = 0; i < info->attachmentCount; i++) {
-      const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[i];
-
-      struct GEN8_BLEND_STATE_ENTRY 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_ENTRY_pack(NULL, state + i * 2 + 1, &entry);
-   }
-
-   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]                         = 0,
-   [VK_STENCIL_OP_ZERO]                         = 0,
-   [VK_STENCIL_OP_REPLACE]                      = 0,
-   [VK_STENCIL_OP_INC_CLAMP]                    = 0,
-   [VK_STENCIL_OP_DEC_CLAMP]                    = 0,
-   [VK_STENCIL_OP_INVERT]                       = 0,
-   [VK_STENCIL_OP_INC_WRAP]                     = 0,
-   [VK_STENCIL_OP_DEC_WRAP]                     = 0
-};
-
-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->state_wm_depth_stencil, 0,
-             sizeof(pipeline->state_wm_depth_stencil));
-      return;
-   }
-
-   /* VkBool32 depthBoundsEnable;          // 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->state_wm_depth_stencil, &wm_depth_stencil);
-}
-
-VkResult
-anv_pipeline_create(
-    VkDevice                                    _device,
-    const VkGraphicsPipelineCreateInfo*         pCreateInfo,
-    const struct anv_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);
-
-   pipeline->device = device;
-   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
-   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
-
-   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);
-
-   anv_state_stream_init(&pipeline->program_stream,
-                         &device->instruction_block_pool);
-
-   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
-      pipeline->shaders[pCreateInfo->pStages[i].stage] =
-         anv_shader_from_handle(pCreateInfo->pStages[i].shader);
-   }
-
-   if (pCreateInfo->pTessellationState)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
-   if (pCreateInfo->pViewportState)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
-   if (pCreateInfo->pMultisampleState)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
-
-   pipeline->use_repclear = extra && extra->use_repclear;
-
-   anv_compiler_run(device->compiler, pipeline);
-
-   /* 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_SBE_SWIZ);
-   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 = Vmask,
-                     .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,
-                     .ControlDataHeaderSize = gs_prog_data->control_data_header_size_hwords,
-                     //pipeline->gs_prog_data.dispatch_mode |
-                     .StatisticsEnable = true,
-                     .IncludePrimitiveID = gs_prog_data->include_primitive_id,
-                     .ReorderMode = TRAILING,
-                     .Enable = true,
-
-                     .ControlDataFormat = gs_prog_data->control_data_format,
-
-                     /* 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,
-                     .VertexURBEntryOutputReadOffset = 1,
-                     /* Even if VS is disabled, SBE still gets the amount of
-                      * vertex data to read from this field. We use attribute
-                      * count - 1, as we don't count the VUE header here. */
-                     .VertexURBEntryOutputLength =
-                        DIV_ROUND_UP(pCreateInfo->pVertexInputState->attributeCount - 1, 2));
-   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;
-   uint32_t ksp0, ksp2, grf_start0, grf_start2;
-
-   ksp2 = 0;
-   grf_start2 = 0;
-   if (pipeline->ps_simd8 != NO_KERNEL) {
-      ksp0 = pipeline->ps_simd8;
-      grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
-      if (pipeline->ps_simd16 != NO_KERNEL) {
-         ksp2 = pipeline->ps_simd16;
-         grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
-      }
-   } else if (pipeline->ps_simd16 != NO_KERNEL) {
-      ksp0 = pipeline->ps_simd16;
-      grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
-   } else {
-      unreachable("no ps shader");
-   }
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS,
-                  .KernelStartPointer0 = 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 = grf_start0,
-                  .DispatchGRFStartRegisterForConstantSetupData1 = 0,
-                  .DispatchGRFStartRegisterForConstantSetupData2 = grf_start2,
-
-                  .KernelStartPointer1 = 0,
-                  .KernelStartPointer2 = 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 anv_DestroyPipeline(
-    VkDevice                                    _device,
-    VkPipeline                                  _pipeline)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
-
-   anv_compiler_free(pipeline);
-   anv_reloc_list_finish(&pipeline->batch.relocs, pipeline->device);
-   anv_state_stream_finish(&pipeline->program_stream);
-   anv_state_pool_free(&device->dynamic_state_pool, pipeline->blend_state);
-   anv_device_free(pipeline->device, pipeline);
-
-   return VK_SUCCESS;
-}
-
-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_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);
-   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);
-
-   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);
-
-   anv_state_stream_init(&pipeline->program_stream,
-                         &device->instruction_block_pool);
-
-   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
-
-   pipeline->shaders[VK_SHADER_STAGE_COMPUTE] =
-      anv_shader_from_handle(pCreateInfo->cs.shader);
-
-   pipeline->use_repclear = false;
-
-   anv_compiler_run(device->compiler, pipeline);
-
-   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_FRAGMENT],
-                  .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;
-}
-
-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 *layout;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
-
-   layout = anv_device_alloc(device, sizeof(*layout), 8,
-                             VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (layout == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   layout->num_sets = pCreateInfo->descriptorSetCount;
-
-   uint32_t surface_start[VK_SHADER_STAGE_NUM] = { 0, };
-   uint32_t sampler_start[VK_SHADER_STAGE_NUM] = { 0, };
-
-   for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
-      layout->stage[s].surface_count = 0;
-      layout->stage[s].sampler_count = 0;
-   }
-
-   for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
-      ANV_FROM_HANDLE(anv_descriptor_set_layout, set_layout,
-                      pCreateInfo->pSetLayouts[i]);
-
-      layout->set[i].layout = set_layout;
-      for (uint32_t s = 0; s < VK_SHADER_STAGE_NUM; s++) {
-         layout->set[i].surface_start[s] = surface_start[s];
-         surface_start[s] += set_layout->stage[s].surface_count;
-         layout->set[i].sampler_start[s] = sampler_start[s];
-         sampler_start[s] += set_layout->stage[s].sampler_count;
-
-         layout->stage[s].surface_count += set_layout->stage[s].surface_count;
-         layout->stage[s].sampler_count += set_layout->stage[s].sampler_count;
-      }
-   }
-
-   *pPipelineLayout = anv_pipeline_layout_to_handle(layout);
-
-   return VK_SUCCESS;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
diff --git a/src/vulkan/private.h b/src/vulkan/private.h
deleted file mode 100644 (file)
index ac64f29..0000000
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * 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"
-
-#define VK_PROTOTYPES
-#include <vulkan/vulkan.h>
-#include <vulkan/vulkan_intel.h>
-#include <vulkan/vk_wsi_lunarg.h>
-
-#include "entrypoints.h"
-
-#include "brw_context.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#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 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.
- */
-
-static inline VkResult
-vk_error(VkResult error)
-{
-#ifdef DEBUG
-   fprintf(stderr, "vk_error: %x\n", error);
-#endif
-
-   return error;
-}
-
-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
-
-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_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;
-   uint32_t index;
-   uint64_t offset;
-   uint64_t size;
-
-   /* This field is here for the benefit of the aub dumper.  It can (and for
-    * userptr bos it must) be set to the cpu map of the buffer.  Destroying
-    * the bo won't clean up the mmap, it's still the responsibility of the bo
-    * user to do that. */
-   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 {
-      uint32_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_pool {
-   struct anv_device *device;
-
-   struct anv_bo bo;
-   void *map;
-   int fd;
-   uint32_t size;
-
-   /**
-    * 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;
-
-   uint32_t next_block;
-   union anv_free_list free_list;
-};
-
-struct anv_block_state {
-   union {
-      struct {
-         uint32_t next;
-         uint32_t end;
-      };
-      uint64_t u64;
-   };
-};
-
-struct anv_state {
-   uint32_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);
-uint32_t anv_block_pool_alloc(struct anv_block_pool *pool);
-void anv_block_pool_free(struct anv_block_pool *pool, uint32_t offset);
-void anv_state_pool_init(struct anv_state_pool *pool,
-                         struct anv_block_pool *block_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);
-
-struct anv_physical_device {
-    struct anv_instance *                       instance;
-    uint32_t                                    chipset_id;
-    bool                                        no_hw;
-    const char *                                path;
-    const char *                                name;
-    const struct brw_device_info *              info;
-    int                                         fd;
-};
-
-struct anv_instance {
-    void *                                      pAllocUserData;
-    PFN_vkAllocFunction                         pfnAlloc;
-    PFN_vkFreeFunction                          pfnFree;
-    uint32_t                                    apiVersion;
-    uint32_t                                    physicalDeviceCount;
-    struct anv_physical_device                  physicalDevice;
-};
-
-struct anv_meta_state {
-   struct {
-      VkPipeline                                pipeline;
-   } clear;
-
-   struct {
-      VkPipeline                                pipeline;
-      VkPipelineLayout                          pipeline_layout;
-      VkDescriptorSetLayout                     ds_layout;
-   } blit;
-
-   struct {
-      VkDynamicRasterState                      rs_state;
-      VkDynamicColorBlendState                  cb_state;
-      VkDynamicDepthStencilState                ds_state;
-   } shared;
-};
-
-struct anv_queue {
-    struct anv_device *                         device;
-
-    struct anv_state_pool *                     pool;
-
-    /**
-     * Serial number of the most recently completed batch executed on the
-     * engine.
-     */
-    struct anv_state                            completed_serial;
-
-    /**
-     * The next batch submitted to the engine will be assigned this serial
-     * number.
-     */
-    uint32_t                                    next_serial;
-
-    uint32_t                                    last_collected_serial;
-};
-
-struct anv_device {
-    struct anv_instance *                       instance;
-    uint32_t                                    chipset_id;
-    struct brw_device_info                      info;
-    int                                         context_id;
-    int                                         fd;
-    bool                                        no_hw;
-    bool                                        dump_aub;
-
-    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_meta_state                       meta_state;
-
-    struct anv_state                            border_colors;
-
-    struct anv_queue                            queue;
-
-    struct anv_block_pool                       scratch_block_pool;
-
-    struct anv_compiler *                       compiler;
-    struct anv_aub_writer *                     aub_writer;
-    pthread_mutex_t                             mutex;
-};
-
-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(struct anv_physical_device *physical_dev, 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 {
-   struct anv_bo                                bo;
-
-   /* Bytes actually consumed in this batch BO */
-   size_t                                       length;
-
-   /* These offsets reference the per-batch reloc list */
-   size_t                                       first_reloc;
-   size_t                                       num_relocs;
-
-   struct anv_batch_bo *                        prev_batch_bo;
-};
-
-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 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 {                            \
-      struct cmd __template = {                                         \
-         cmd ## _header,                                                \
-         __VA_ARGS__                                                    \
-      };                                                                \
-      void *__dst = anv_batch_emit_dwords(batch, cmd ## _length);       \
-      cmd ## _pack(batch, __dst, &__template);                          \
-   } while (0)
-
-#define anv_batch_emitn(batch, n, cmd, ...) ({          \
-      struct cmd __template = {                         \
-         cmd ## _header,                                \
-        .DwordLength = n - cmd ## _length_bias,         \
-         __VA_ARGS__                                    \
-      };                                                \
-      void *__dst = anv_batch_emit_dwords(batch, n);    \
-      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)
-
-#define GEN8_MOCS {                                     \
-      .MemoryTypeLLCeLLCCacheabilityControl = WB,       \
-      .TargetCache = L3DefertoPATforLLCeLLCselection,   \
-      .AgeforQUADLRU = 0                                \
-   }
-
-struct anv_device_memory {
-   struct anv_bo                                bo;
-   VkDeviceSize                                 map_size;
-   void *                                       map;
-};
-
-struct anv_dynamic_vp_state {
-   struct anv_state sf_clip_vp;
-   struct anv_state cc_vp;
-   struct anv_state scissor;
-};
-
-struct anv_dynamic_rs_state {
-   uint32_t state_sf[GEN8_3DSTATE_SF_length];
-   uint32_t state_raster[GEN8_3DSTATE_RASTER_length];
-};
-
-struct anv_dynamic_ds_state {
-   uint32_t state_wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
-   uint32_t state_color_calc[GEN8_COLOR_CALC_STATE_length];
-};
-
-struct anv_dynamic_cb_state {
-   uint32_t state_color_calc[GEN8_COLOR_CALC_STATE_length];
-
-};
-
-struct anv_descriptor_slot {
-   int8_t dynamic_slot;
-   uint8_t index;
-};
-
-struct anv_descriptor_set_layout {
-   struct {
-      uint32_t surface_count;
-      struct anv_descriptor_slot *surface_start;
-      uint32_t sampler_count;
-      struct anv_descriptor_slot *sampler_start;
-   } stage[VK_SHADER_STAGE_NUM];
-
-   uint32_t count;
-   uint32_t num_dynamic_buffers;
-   uint32_t shader_stages;
-   struct anv_descriptor_slot entries[0];
-};
-
-struct anv_descriptor {
-   struct anv_sampler *sampler;
-   struct anv_surface_view *view;
-};
-
-struct anv_descriptor_set {
-   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
-
-struct anv_pipeline_layout {
-   struct {
-      struct anv_descriptor_set_layout *layout;
-      uint32_t surface_start[VK_SHADER_STAGE_NUM];
-      uint32_t sampler_start[VK_SHADER_STAGE_NUM];
-   } set[MAX_SETS];
-
-   uint32_t num_sets;
-
-   struct {
-      uint32_t surface_count;
-      uint32_t sampler_count;
-   } stage[VK_SHADER_STAGE_NUM];
-};
-
-struct anv_buffer {
-   struct anv_device *                          device;
-   VkDeviceSize                                 size;
-
-   /* Set when bound */
-   struct anv_bo *                              bo;
-   VkDeviceSize                                 offset;   
-};
-
-#define ANV_CMD_BUFFER_PIPELINE_DIRTY           (1 << 0)
-#define ANV_CMD_BUFFER_RS_DIRTY                 (1 << 2)
-#define ANV_CMD_BUFFER_DS_DIRTY                 (1 << 3)
-#define ANV_CMD_BUFFER_CB_DIRTY                 (1 << 4)
-#define ANV_CMD_BUFFER_VP_DIRTY                 (1 << 5)
-#define ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY       (1 << 6)
-
-struct anv_vertex_binding {
-   struct anv_buffer *                          buffer;
-   VkDeviceSize                                 offset;
-};
-
-struct anv_descriptor_set_binding {
-   struct anv_descriptor_set *                  set;
-   uint32_t                                     dynamic_offsets[128];
-};
-
-/** State required while building cmd buffer */
-struct anv_cmd_state {
-   uint32_t                                     current_pipeline;
-   uint32_t                                     vb_dirty;
-   uint32_t                                     dirty;
-   uint32_t                                     compute_dirty;
-   uint32_t                                     descriptors_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;
-   struct anv_dynamic_rs_state *                rs_state;
-   struct anv_dynamic_ds_state *                ds_state;
-   struct anv_dynamic_vp_state *                vp_state;
-   struct anv_dynamic_cb_state *                cb_state;
-   uint32_t                                     state_vf[GEN8_3DSTATE_VF_length];
-   struct anv_vertex_binding                    vertex_bindings[MAX_VBS];
-   struct anv_descriptor_set_binding            descriptors[MAX_SETS];
-};
-
-VkResult anv_cmd_state_init(struct anv_cmd_state *state);
-void anv_cmd_state_fini(struct anv_cmd_state *state);
-
-struct anv_cmd_buffer {
-   struct anv_device *                          device;
-
-   struct drm_i915_gem_execbuffer2              execbuf;
-   struct drm_i915_gem_exec_object2 *           exec2_objects;
-   uint32_t                                     exec2_bo_count;
-   struct anv_bo **                             exec2_bos;
-   uint32_t                                     exec2_array_length;
-   bool                                         need_reloc;
-   uint32_t                                     serial;
-
-   struct anv_batch                             batch;
-   struct anv_batch_bo *                        last_batch_bo;
-   struct anv_batch_bo *                        surface_batch_bo;
-   uint32_t                                     surface_next;
-   struct anv_reloc_list                        surface_relocs;
-   struct anv_state_stream                      surface_state_stream;
-   struct anv_state_stream                      dynamic_state_stream;
-
-   struct anv_cmd_state                         state;
-};
-
-struct anv_state
-anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer,
-                                   uint32_t size, uint32_t alignment);
-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_surface_state_bo(struct anv_cmd_buffer *cmd_buffer);
-
-void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
-
-void anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
-                                  struct anv_subpass *subpass);
-
-void anv_cmd_buffer_clear_attachments(struct anv_cmd_buffer *cmd_buffer,
-                                      struct anv_render_pass *pass,
-                                      const VkClearValue *clear_values);
-
-void anv_cmd_buffer_dump(struct anv_cmd_buffer *cmd_buffer);
-void anv_aub_writer_destroy(struct anv_aub_writer *writer);
-
-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 anv_shader_module {
-   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[256];
-   struct anv_shader *                          shaders[VK_SHADER_STAGE_NUM];
-   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;
-
-   uint32_t                                     active_stages;
-   struct anv_state_stream                      program_stream;
-   struct anv_state                             blend_state;
-   uint32_t                                     vs_simd8;
-   uint32_t                                     ps_simd8;
-   uint32_t                                     ps_simd16;
-   uint32_t                                     gs_vec4;
-   uint32_t                                     gs_vertex_count;
-   uint32_t                                     cs_simd;
-
-   uint32_t                                     vb_used;
-   uint32_t                                     binding_stride[MAX_VBS];
-
-   uint32_t                                     state_sf[GEN8_3DSTATE_SF_length];
-   uint32_t                                     state_vf[GEN8_3DSTATE_VF_length];
-   uint32_t                                     state_raster[GEN8_3DSTATE_RASTER_length];
-   uint32_t                                     state_wm_depth_stencil[GEN8_3DSTATE_WM_DEPTH_STENCIL_length];
-
-   uint32_t                                     cs_thread_width_max;
-   uint32_t                                     cs_right_mask;
-};
-
-struct anv_pipeline_create_info {
-   bool                                         use_repclear;
-   bool                                         disable_viewport;
-   bool                                         disable_scissor;
-   bool                                         disable_vs;
-   bool                                         use_rectlist;
-};
-
-VkResult
-anv_pipeline_create(VkDevice device,
-                    const VkGraphicsPipelineCreateInfo *pCreateInfo,
-                    const struct anv_pipeline_create_info *extra,
-                    VkPipeline *pPipeline);
-
-struct anv_compiler *anv_compiler_create(struct anv_device *device);
-void anv_compiler_destroy(struct anv_compiler *compiler);
-int anv_compiler_run(struct anv_compiler *compiler, struct anv_pipeline *pipeline);
-void anv_compiler_free(struct anv_pipeline *pipeline);
-
-struct anv_format {
-   const char *name;
-   uint16_t surface_format; /**< RENDER_SURFACE_STATE.SurfaceFormat */
-   uint8_t cpp; /**< Bytes-per-pixel of anv_format::surface_format. */
-   uint8_t num_channels;
-   uint16_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
-   bool has_stencil;
-};
-
-const struct anv_format *
-anv_format_for_vk_format(VkFormat format);
-bool anv_is_vk_format_depth_or_stencil(VkFormat format);
-
-/**
- * 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 */
-   /** \} */
-
-   uint8_t tile_mode; /**< RENDER_SURFACE_STATE.TileMode */
-};
-
-struct anv_image {
-   VkImageType type;
-   VkExtent3D extent;
-   VkFormat format;
-   uint32_t levels;
-   uint32_t array_size;
-
-   VkDeviceSize size;
-   uint32_t alignment;
-
-   /* Set when bound */
-   struct anv_bo *bo;
-   VkDeviceSize offset;
-
-   struct anv_swap_chain *swap_chain;
-
-   /** RENDER_SURFACE_STATE.SurfaceType */
-   uint8_t surf_type;
-
-   /** Primary surface is either color or depth. */
-   struct anv_surface primary_surface;
-
-   /** Stencil surface is optional. */
-   struct anv_surface stencil_surface;
-};
-
-struct anv_surface_view {
-   struct anv_state surface_state; /**< RENDER_SURFACE_STATE */
-   struct anv_bo *bo;
-   uint32_t offset; /**< VkBufferCreateInfo::offset */
-   uint32_t range; /**< VkBufferCreateInfo::range */
-   VkFormat format; /**< VkBufferCreateInfo::format */
-};
-
-struct anv_buffer_view {
-   struct anv_surface_view view;
-};
-
-struct anv_image_view {
-   struct anv_surface_view view;
-   VkExtent3D extent;
-};
-
-enum anv_attachment_view_type {
-   ANV_ATTACHMENT_VIEW_TYPE_COLOR,
-   ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL,
-};
-
-struct anv_attachment_view {
-   enum anv_attachment_view_type attachment_type;
-   VkExtent3D extent;
-};
-
-struct anv_color_attachment_view {
-   struct anv_attachment_view base;
-   struct anv_surface_view view;
-};
-
-struct anv_depth_stencil_view {
-   struct anv_attachment_view base;
-
-   struct anv_bo *bo;
-
-   uint32_t depth_offset; /**< Offset into bo. */
-   uint32_t depth_stride; /**< 3DSTATE_DEPTH_BUFFER.SurfacePitch */
-   uint32_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
-   uint16_t depth_qpitch; /**< 3DSTATE_DEPTH_BUFFER.SurfaceQPitch */
-
-   uint32_t stencil_offset; /**< Offset into bo. */
-   uint32_t stencil_stride; /**< 3DSTATE_STENCIL_BUFFER.SurfacePitch */
-   uint16_t stencil_qpitch; /**< 3DSTATE_STENCIL_BUFFER.SurfaceQPitch */
-};
-
-struct anv_image_create_info {
-   const VkImageCreateInfo *vk_info;
-   bool force_tile_mode;
-   uint8_t tile_mode;
-};
-
-VkResult anv_image_create(VkDevice _device,
-                          const struct anv_image_create_info *info,
-                          VkImage *pImage);
-
-void anv_image_view_init(struct anv_image_view *view,
-                         struct anv_device *device,
-                         const VkImageViewCreateInfo* pCreateInfo,
-                         struct anv_cmd_buffer *cmd_buffer);
-
-void anv_color_attachment_view_init(struct anv_color_attachment_view *view,
-                                    struct anv_device *device,
-                                    const VkAttachmentViewCreateInfo* pCreateInfo,
-                                    struct anv_cmd_buffer *cmd_buffer);
-void anv_fill_buffer_surface_state(void *state, VkFormat format,
-                                   uint32_t offset, uint32_t range);
-
-void anv_surface_view_fini(struct anv_device *device,
-                           struct anv_surface_view *view);
-
-struct anv_sampler {
-   uint32_t state[4];
-};
-
-struct anv_framebuffer {
-   uint32_t                                     width;
-   uint32_t                                     height;
-   uint32_t                                     layers;
-
-   /* Viewport for clears */
-   VkDynamicViewportState                       vp_state;
-
-   uint32_t                                     attachment_count;
-   const struct anv_attachment_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 {
-   VkFormat                                     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];
-};
-
-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);
-
-#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_HANDLE_CASTS(anv_swap_chain, VkSwapChainWSI);
-
-ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_attachment_view, VkAttachmentView)
-ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer, VkBuffer)
-ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_buffer_view, VkBufferView);
-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_dynamic_cb_state, VkDynamicColorBlendState)
-ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_dynamic_ds_state, VkDynamicDepthStencilState)
-ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_dynamic_rs_state, VkDynamicRasterState)
-ANV_DEFINE_NONDISP_HANDLE_CASTS(anv_dynamic_vp_state, VkDynamicViewportState)
-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/query.c b/src/vulkan/query.c
deleted file mode 100644 (file)
index b3b8589..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * 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 "private.h"
-
-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;
-};
-
-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;
-}
-
-VkResult 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);
-
-   return VK_SUCCESS;
-}
-
-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)
-         return vk_error(VK_ERROR_UNKNOWN);
-   }
-
-   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;
-}
-
-static void
-anv_batch_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 anv_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:
-      anv_batch_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 anv_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:
-      anv_batch_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("");
-   }
-}
-
-void anv_CmdResetQueryPool(
-    VkCmdBuffer                                 cmdBuffer,
-    VkQueryPool                                 queryPool,
-    uint32_t                                    startQuery,
-    uint32_t                                    queryCount)
-{
-   stub();
-}
-
-#define TIMESTAMP 0x2358
-
-void anv_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 anv_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;
-   }
-}
diff --git a/src/vulkan/util.c b/src/vulkan/util.c
deleted file mode 100644 (file)
index 21cb648..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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 "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();
-}
-
-int
-anv_vector_init(struct anv_vector *vector, uint32_t element_size, uint32_t size)
-{
-   assert(is_power_of_two(size));
-   assert(element_size < size && 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/vk_gen.py b/src/vulkan/vk_gen.py
deleted file mode 100644 (file)
index d481af7..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-# 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:
-    for type, name, args, num, h in entrypoints:
-        print "%s anv_%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.
- */
-
-/* This file generated from vk_gen.py, don't edit directly. */
-
-#include "private.h"
-
-struct anv_entrypoint {
-   uint32_t name;
-   uint32_t hash;
-   void *function;
-   void *validate;
-};
-
-/* 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.
- */
-"""
-
-for type, name, args, num, h in entrypoints:
-    print "%s anv_validate_%s%s __attribute__ ((weak));" % (type, name, args)
-
-# 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, anv_%s, anv_validate_%s }," % (offsets[num], h, name, 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 void * __attribute__ ((noinline))
-resolve_entrypoint(uint32_t index)
-{
-   if (enable_validate && entrypoints[index].validate)
-      return entrypoints[index].validate;
-
-   return entrypoints[index].function;
-}
-"""
-
-# 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 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 resolve_entrypoint(i);
-}
-""" % (prime_factor, prime_step, hash_mask)
diff --git a/src/vulkan/x11.c b/src/vulkan/x11.c
deleted file mode 100644 (file)
index 1e0bdb1..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * 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 "private.h"
-
-#include <xcb/xcb.h>
-#include <xcb/dri3.h>
-#include <xcb/present.h>
-
-static const VkFormat formats[] = {
-   VK_FORMAT_B5G6R5_UNORM,
-   VK_FORMAT_B8G8R8A8_UNORM,
-   VK_FORMAT_B8G8R8A8_SRGB,
-};
-
-VkResult anv_GetDisplayInfoWSI(
-    VkDisplayWSI                            display,
-    VkDisplayInfoTypeWSI                    infoType,
-    size_t*                                 pDataSize,
-    void*                                   pData)
-{
-   VkDisplayFormatPropertiesWSI *properties = pData;
-   size_t size;
-
-   if (pDataSize == NULL)
-      return VK_ERROR_INVALID_POINTER;
-
-   switch (infoType) {
-   case VK_DISPLAY_INFO_TYPE_FORMAT_PROPERTIES_WSI:
-      size = sizeof(properties[0]) * ARRAY_SIZE(formats);
-
-      if (pData == NULL) {
-         *pDataSize = size;
-         return VK_SUCCESS;
-      }
-
-      if (*pDataSize < size)
-         return vk_error(VK_ERROR_INVALID_VALUE);
-
-      *pDataSize = size;
-
-      for (uint32_t i = 0; i < ARRAY_SIZE(formats); i++)
-         properties[i].swapChainFormat = formats[i];
-
-      return VK_SUCCESS;
-
-   default:
-      return VK_UNSUPPORTED;
-   }
-}
-
-struct anv_swap_chain {
-   struct anv_device *                          device;
-   xcb_connection_t *                           conn;
-   xcb_window_t                                 window;
-   xcb_gc_t                                     gc;
-   VkExtent2D                                   extent;
-   uint32_t                                     count;
-   struct {
-      struct anv_image *                        image;
-      struct anv_device_memory *                memory;
-      xcb_pixmap_t                              pixmap;
-   }                                            images[0];
-};
-
-VkResult anv_CreateSwapChainWSI(
-    VkDevice                                _device,
-    const VkSwapChainCreateInfoWSI*         pCreateInfo,
-    VkSwapChainWSI*                         pSwapChain)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-
-   struct anv_swap_chain *chain;
-   xcb_void_cookie_t cookie;
-   VkResult result;
-   size_t size;
-   int ret;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAP_CHAIN_CREATE_INFO_WSI);
-
-   size = sizeof(*chain) + pCreateInfo->imageCount * 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->device = device;
-   chain->conn = (xcb_connection_t *) pCreateInfo->pNativeWindowSystemHandle;
-   chain->window = (xcb_window_t) (uintptr_t) pCreateInfo->pNativeWindowHandle;
-   chain->count = pCreateInfo->imageCount;
-   chain->extent = pCreateInfo->imageExtent;
-
-   for (uint32_t i = 0; i < chain->count; i++) {
-      VkDeviceMemory memory_h;
-      VkImage image_h;
-      struct anv_image *image;
-      struct anv_surface *surface;
-      struct anv_device_memory *memory;
-
-      anv_image_create(_device,
-         &(struct anv_image_create_info) {
-            .force_tile_mode = true,
-            .tile_mode = XMAJOR,
-            .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);
-      surface = &image->primary_surface;
-
-      anv_AllocMemory(_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);
-
-      ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
-                               surface->stride, I915_TILING_X);
-      if (ret) {
-         result = vk_error(VK_ERROR_UNKNOWN);
-         goto fail;
-      }
-
-      int fd = anv_gem_handle_to_fd(device, memory->bo.gem_handle);
-      if (fd == -1) {
-         result = vk_error(VK_ERROR_UNKNOWN);
-         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;
-      image->swap_chain = chain;
-
-      xcb_discard_reply(chain->conn, cookie.sequence);
-   }
-
-   chain->gc = xcb_generate_id(chain->conn);
-   if (!chain->gc) {
-      result = vk_error(VK_ERROR_UNKNOWN);
-      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);
-
-   *pSwapChain = anv_swap_chain_to_handle(chain);
-
-   return VK_SUCCESS;
-
- fail:
-   return result;
-}
-
-VkResult anv_DestroySwapChainWSI(
-    VkSwapChainWSI                          _chain)
-{
-   ANV_FROM_HANDLE(anv_swap_chain, chain, _chain);
-
-   anv_device_free(chain->device, chain);
-
-   return VK_SUCCESS;
-}
-
-VkResult anv_GetSwapChainInfoWSI(
-    VkSwapChainWSI                          _chain,
-    VkSwapChainInfoTypeWSI                  infoType,
-    size_t*                                 pDataSize,
-    void*                                   pData)
-{
-   ANV_FROM_HANDLE(anv_swap_chain, chain, _chain);
-
-   VkSwapChainImageInfoWSI *images;
-   size_t size;
-
-   switch (infoType) {
-   case VK_SWAP_CHAIN_INFO_TYPE_PERSISTENT_IMAGES_WSI:
-      size = sizeof(*images) * chain->count;
-      if (pData && *pDataSize < size)
-         return VK_ERROR_INVALID_VALUE;
-
-      *pDataSize = size;
-      if (!pData)
-         return VK_SUCCESS;
-
-      images = pData;
-      for (uint32_t i = 0; i < chain->count; i++) {
-         images[i].image = anv_image_to_handle(chain->images[i].image);
-         images[i].memory = anv_device_memory_to_handle(chain->images[i].memory);
-      }
-
-      return VK_SUCCESS;
-
-   default:
-      return VK_UNSUPPORTED;
-   }
-}
-
-VkResult anv_QueuePresentWSI(
-    VkQueue                                 queue_,
-    const VkPresentInfoWSI*                 pPresentInfo)
-{
-   ANV_FROM_HANDLE(anv_image, image, pPresentInfo->image);
-
-   struct anv_swap_chain *chain = image->swap_chain;
-   xcb_void_cookie_t cookie;
-   xcb_pixmap_t pixmap;
-
-   assert(pPresentInfo->sType == VK_STRUCTURE_TYPE_PRESENT_INFO_WSI);
-
-   if (chain == NULL)
-      return vk_error(VK_ERROR_INVALID_VALUE);
-
-   pixmap = XCB_NONE;
-   for (uint32_t i = 0; i < chain->count; i++) {
-      if (image == chain->images[i].image) {
-         pixmap = chain->images[i].pixmap;
-         break;
-      }
-   }
-
-   if (pixmap == XCB_NONE)
-      return vk_error(VK_ERROR_INVALID_VALUE);
-
-   cookie = xcb_copy_area(chain->conn,
-                          pixmap,
-                          chain->window,
-                          chain->gc,
-                          0, 0,
-                          0, 0,
-                          chain->extent.width,
-                          chain->extent.height);
-   xcb_discard_reply(chain->conn, cookie.sequence);
-
-   xcb_flush(chain->conn);
-
-   return VK_SUCCESS;
-}