Re: [Mesa-dev] [PATCH 5/5] anv: setup appropriate border color structures on gen7/gen75

2016-10-17 Thread Kenneth Graunke
On Monday, October 17, 2016 11:09:32 AM PDT Jason Ekstrand wrote:
> On Mon, Oct 17, 2016 at 8:46 AM, Lionel Landwerlin 
> wrote:
> 
> > Up to this point we were using the gen8+ structures. Altough this commit
> > doesn't fixes the border color CTS tests, this is a step in the right
> > direction to fix the following tests :
> >
> 
> It's not entirely clear where you're headed but I'm afraid the approach may
> ultimately be doomed to failure.  The fundamental problem is that Vulkan
> allows complete mix-and-match of images and samplers in the shader.  We
> cannot know, until the shader *executes* which sampler will be associated
> with a particular texture.  This leaves us with two possible solutions:
> 
>  1) Emit a sampler for every possible sampler+image combination.
>  2) Piles of shader hacks.
> 
> Both approaches are highly annoying.  While the first option is probably
> the less annoying of the two, there is one format (R32_UINT maybe?  I don't
> remember for sure) for which integer border color just doesn't work at all
> on Haswell.

You're thinking of
https://bugs.freedesktop.org/show_bug.cgi?id=94196

In this case, Haswell behaves exactly as Ivybridge, despite appearing to
work in all other cases.  It's really sad.

> On Ivy Bridge, integer border color is so broken we probably
> shouldn't be using it at all.  This leaves us with shader hacks.  Ken wrote
> a bunch of code for this so that we could get the ES 3.1 CTS passing on
> Haswell and Ivy Bridge.  Maybe that could be ported?  Maybe we can find
> some magic Ivy Bridge "make border color work" bit?

CLAMP_TO_BORDER with integer formats is documented to not work at all.
It seems horribly buggy.  I've tried to figure out how to make it work,
and I couldn't.  Feel free to try, but I'm not sure it's possible.

It looks like the Windows driver emulates all integer texturing with
1,000 lines of jump tables and texelFetch/ld messages (at least on IVB).

My plan for IVB/BYT was to always use CLAMP_TO_EDGE and manually
bounds-check the texture coordinate in the shader, and supply the border
color via a uniform.  ivbborder of ~kwg/mesa has the last version I
worked on, but I believe Jordan took it over and has improved it a bunch
since then.  He might have an updated copy.

> > dEQP-VK.pipeline.sampler.view_type.2d.format.*.address_
> > modes.all_mode_clamp_to_border_*
> >
> > Signed-off-by: Lionel Landwerlin 
> > ---
> >  src/intel/vulkan/anv_cmd_buffer.c |  10 ++
> >  src/intel/vulkan/anv_device.c |  42 +---
> >  src/intel/vulkan/anv_genX.h   |   3 +-
> >  src/intel/vulkan/anv_private.h|   7 ++
> >  src/intel/vulkan/genX_state.c | 220 ++
> > ++--
> >  5 files changed, 208 insertions(+), 74 deletions(-)
> >
> > diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_
> > buffer.c
> > index b051489..a63f3d9 100644
> > --- a/src/intel/vulkan/anv_cmd_buffer.c
> > +++ b/src/intel/vulkan/anv_cmd_buffer.c
> > @@ -931,6 +931,16 @@ anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer
> > *cmd_buffer,
> >if (sampler == NULL)
> >   continue;
> >
> > +  /* On Haswell, although the border color structures are 20 dwords
> > long
> > +   * and must be aligned at 512 bytes, the position of the 8/16/32bits
> > +   * colors overlap, meaning we can't have a single color structure
> > +   * configured for all formats. We therefore need to reemit the
> > sampler
> > +   * structure for the used format. */
> > +  if (cmd_buffer->device->info.is_haswell) {
> > + gen75_pack_sampler_state(cmd_buffer->device, sampler,
> > +  desc->image_view->vk_format);
> > +  }
> > +
> >memcpy(state->map + (s * 16),
> >   sampler->state, sizeof(sampler->state));
> > }
> > diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> > index ce1b9c1..4e69307 100644
> > --- a/src/intel/vulkan/anv_device.c
> > +++ b/src/intel/vulkan/anv_device.c
> > @@ -724,46 +724,6 @@ anv_queue_finish(struct anv_queue *queue)
> >  {
> >  }
> >
> > -static struct anv_state
> > -anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size,
> > size_t align, const void *p)
> > -{
> > -   struct anv_state state;
> > -
> > -   state = anv_state_pool_alloc(pool, size, align);
> > -   memcpy(state.map, p, size);
> > -
> > -   if (!pool->block_pool->device->info.has_llc)
> > -  anv_state_clflush(state);
> > -
> > -   return state;
> > -}
> > -
> > -struct gen8_border_color {
> > -   union {
> > -  float float32[4];
> > -  uint32_t uint32[4];
> > -   };
> > -   /* Pad out to 64 bytes */
> > -   uint32_t _pad[12];
> > -};
> > -
> > -static void
> > -anv_device_init_border_colors(struct anv_device *device)
> > -{
> > -   static const struct gen8_border_color border_colors[] = {
> > -  [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .float32 = { 0.0,
> > 0.0, 0.0, 0.0 } },
> > -  [VK_BORDER_COLOR_FLOAT_OPAQUE_

Re: [Mesa-dev] [PATCH 5/5] anv: setup appropriate border color structures on gen7/gen75

2016-10-17 Thread Jason Ekstrand
On Mon, Oct 17, 2016 at 11:51 AM, Lionel Landwerlin 
wrote:

> On Mon, 2016-10-17 at 11:09 -0700, Jason Ekstrand wrote:
> > On Mon, Oct 17, 2016 at 8:46 AM, Lionel Landwerlin  > .com> wrote:
> > > Up to this point we were using the gen8+ structures. Altough this
> > > commit
> > > doesn't fixes the border color CTS tests, this is a step in the
> > > right
> > > direction to fix the following tests :
> >
> > It's not entirely clear where you're headed but I'm afraid the
> > approach may ultimately be doomed to failure.  The fundamental
> > problem is that Vulkan allows complete mix-and-match of images and
> > samplers in the shader.  We cannot know, until the shader *executes*
> > which sampler will be associated with a particular texture.
>
> Maybe I'm missing something, but essentially the approach here is to
> SAMPLER_STATE_pack() when we bind the descriptors set. That's when we
> know for sure what couples of (sampler, texture) are going to be used,
> at least that's my understanding.
>

That's where we know all possible (sampler, texture) tuples but we don't
know exactly which combinations will get used by the shader.  This is in
contrast to GL where sampler and texture are sort-of separate but by the
time you get into the shader, they're tied together.


> >   This leaves us with two possible solutions:
> >
> >  1) Emit a sampler for every possible sampler+image combination.
>
> Actually that may not be a bad idea.
>
> >  2) Piles of shader hacks.
> >
> > Both approaches are highly annoying.  While the first option is
> > probably the less annoying of the two, there is one format (R32_UINT
> > maybe?  I don't remember for sure) for which integer border color
> > just doesn't work at all on Haswell.  On Ivy Bridge, integer border
> > color is so broken we probably shouldn't be using it at all.  This
> > leaves us with shader hacks.  Ken wrote a bunch of code for this so
> > that we could get the ES 3.1 CTS passing on Haswell and Ivy Bridge.
> > Maybe that could be ported?  Maybe we can find some magic Ivy Bridge
> > "make border color work" bit?
> >
> > > dEQP-
> > > VK.pipeline.sampler.view_type.2d.format.*.address_modes.all_mode_cl
> > > amp_to_border_*
> > >
> > > Signed-off-by: Lionel Landwerlin 
> > > ---
> > >  src/intel/vulkan/anv_cmd_buffer.c |  10 ++
> > >  src/intel/vulkan/anv_device.c |  42 +---
> > >  src/intel/vulkan/anv_genX.h   |   3 +-
> > >  src/intel/vulkan/anv_private.h|   7 ++
> > >  src/intel/vulkan/genX_state.c | 220
> > > --
> > >  5 files changed, 208 insertions(+), 74 deletions(-)
> > >
> > > diff --git a/src/intel/vulkan/anv_cmd_buffer.c
> > > b/src/intel/vulkan/anv_cmd_buffer.c
> > > index b051489..a63f3d9 100644
> > > --- a/src/intel/vulkan/anv_cmd_buffer.c
> > > +++ b/src/intel/vulkan/anv_cmd_buffer.c
> > > @@ -931,6 +931,16 @@ anv_cmd_buffer_emit_samplers(struct
> > > anv_cmd_buffer *cmd_buffer,
> > >if (sampler == NULL)
> > >   continue;
> > >
> > > +  /* On Haswell, although the border color structures are 20
> > > dwords long
> > > +   * and must be aligned at 512 bytes, the position of the
> > > 8/16/32bits
> > > +   * colors overlap, meaning we can't have a single color
> > > structure
> > > +   * configured for all formats. We therefore need to reemit
> > > the sampler
> > > +   * structure for the used format. */
> > > +  if (cmd_buffer->device->info.is_haswell) {
> > > + gen75_pack_sampler_state(cmd_buffer->device, sampler,
> > > +  desc->image_view->vk_format);
> > > +  }
> > > +
> > >memcpy(state->map + (s * 16),
> > >   sampler->state, sizeof(sampler->state));
> > > }
> > > diff --git a/src/intel/vulkan/anv_device.c
> > > b/src/intel/vulkan/anv_device.c
> > > index ce1b9c1..4e69307 100644
> > > --- a/src/intel/vulkan/anv_device.c
> > > +++ b/src/intel/vulkan/anv_device.c
> > > @@ -724,46 +724,6 @@ anv_queue_finish(struct anv_queue *queue)
> > >  {
> > >  }
> > >
> > > -static struct anv_state
> > > -anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size,
> > > size_t align, const void *p)
> > > -{
> > > -   struct anv_state state;
> > > -
> > > -   state = anv_state_pool_alloc(pool, size, align);
> > > -   memcpy(state.map, p, size);
> > > -
> > > -   if (!pool->block_pool->device->info.has_llc)
> > > -  anv_state_clflush(state);
> > > -
> > > -   return state;
> > > -}
> > > -
> > > -struct gen8_border_color {
> > > -   union {
> > > -  float float32[4];
> > > -  uint32_t uint32[4];
> > > -   };
> > > -   /* Pad out to 64 bytes */
> > > -   uint32_t _pad[12];
> > > -};
> > > -
> > > -static void
> > > -anv_device_init_border_colors(struct anv_device *device)
> > > -{
> > > -   static const struct gen8_border_color border_colors[] = {
> > > -  [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .float32 = {
> > > 0.0, 0.0, 0.0, 0.0 } },
> > > -  [VK_BORDER_COLOR_FLOAT_OPAQUE_

Re: [Mesa-dev] [PATCH 5/5] anv: setup appropriate border color structures on gen7/gen75

2016-10-17 Thread Lionel Landwerlin
On Mon, 2016-10-17 at 11:09 -0700, Jason Ekstrand wrote:
> On Mon, Oct 17, 2016 at 8:46 AM, Lionel Landwerlin  .com> wrote:
> > Up to this point we were using the gen8+ structures. Altough this
> > commit
> > doesn't fixes the border color CTS tests, this is a step in the
> > right
> > direction to fix the following tests :
> 
> It's not entirely clear where you're headed but I'm afraid the
> approach may ultimately be doomed to failure.  The fundamental
> problem is that Vulkan allows complete mix-and-match of images and
> samplers in the shader.  We cannot know, until the shader *executes*
> which sampler will be associated with a particular texture.

Maybe I'm missing something, but essentially the approach here is to
SAMPLER_STATE_pack() when we bind the descriptors set. That's when we
know for sure what couples of (sampler, texture) are going to be used,
at least that's my understanding.

>   This leaves us with two possible solutions:
> 
>  1) Emit a sampler for every possible sampler+image combination.

Actually that may not be a bad idea.

>  2) Piles of shader hacks.
> 
> Both approaches are highly annoying.  While the first option is
> probably the less annoying of the two, there is one format (R32_UINT
> maybe?  I don't remember for sure) for which integer border color
> just doesn't work at all on Haswell.  On Ivy Bridge, integer border
> color is so broken we probably shouldn't be using it at all.  This
> leaves us with shader hacks.  Ken wrote a bunch of code for this so
> that we could get the ES 3.1 CTS passing on Haswell and Ivy Bridge. 
> Maybe that could be ported?  Maybe we can find some magic Ivy Bridge
> "make border color work" bit?
>  
> > dEQP-
> > VK.pipeline.sampler.view_type.2d.format.*.address_modes.all_mode_cl
> > amp_to_border_*
> > 
> > Signed-off-by: Lionel Landwerlin 
> > ---
> >  src/intel/vulkan/anv_cmd_buffer.c |  10 ++
> >  src/intel/vulkan/anv_device.c     |  42 +---
> >  src/intel/vulkan/anv_genX.h       |   3 +-
> >  src/intel/vulkan/anv_private.h    |   7 ++
> >  src/intel/vulkan/genX_state.c     | 220
> > --
> >  5 files changed, 208 insertions(+), 74 deletions(-)
> > 
> > diff --git a/src/intel/vulkan/anv_cmd_buffer.c
> > b/src/intel/vulkan/anv_cmd_buffer.c
> > index b051489..a63f3d9 100644
> > --- a/src/intel/vulkan/anv_cmd_buffer.c
> > +++ b/src/intel/vulkan/anv_cmd_buffer.c
> > @@ -931,6 +931,16 @@ anv_cmd_buffer_emit_samplers(struct
> > anv_cmd_buffer *cmd_buffer,
> >        if (sampler == NULL)
> >           continue;
> > 
> > +      /* On Haswell, although the border color structures are 20
> > dwords long
> > +       * and must be aligned at 512 bytes, the position of the
> > 8/16/32bits
> > +       * colors overlap, meaning we can't have a single color
> > structure
> > +       * configured for all formats. We therefore need to reemit
> > the sampler
> > +       * structure for the used format. */
> > +      if (cmd_buffer->device->info.is_haswell) {
> > +         gen75_pack_sampler_state(cmd_buffer->device, sampler,
> > +                                  desc->image_view->vk_format);
> > +      }
> > +
> >        memcpy(state->map + (s * 16),
> >               sampler->state, sizeof(sampler->state));
> >     }
> > diff --git a/src/intel/vulkan/anv_device.c
> > b/src/intel/vulkan/anv_device.c
> > index ce1b9c1..4e69307 100644
> > --- a/src/intel/vulkan/anv_device.c
> > +++ b/src/intel/vulkan/anv_device.c
> > @@ -724,46 +724,6 @@ anv_queue_finish(struct anv_queue *queue)
> >  {
> >  }
> > 
> > -static struct anv_state
> > -anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size,
> > size_t align, const void *p)
> > -{
> > -   struct anv_state state;
> > -
> > -   state = anv_state_pool_alloc(pool, size, align);
> > -   memcpy(state.map, p, size);
> > -
> > -   if (!pool->block_pool->device->info.has_llc)
> > -      anv_state_clflush(state);
> > -
> > -   return state;
> > -}
> > -
> > -struct gen8_border_color {
> > -   union {
> > -      float float32[4];
> > -      uint32_t uint32[4];
> > -   };
> > -   /* Pad out to 64 bytes */
> > -   uint32_t _pad[12];
> > -};
> > -
> > -static void
> > -anv_device_init_border_colors(struct anv_device *device)
> > -{
> > -   static const struct gen8_border_color border_colors[] = {
> > -      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .float32 = {
> > 0.0, 0.0, 0.0, 0.0 } },
> > -      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =       { .float32 = {
> > 0.0, 0.0, 0.0, 1.0 } },
> > -      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =       { .float32 = {
> > 1.0, 1.0, 1.0, 1.0 } },
> > -      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =    { .uint32 = {
> > 0, 0, 0, 0 } },
> > -      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =         { .uint32 = {
> > 0, 0, 0, 1 } },
> > -      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =         { .uint32 = {
> > 1, 1, 1, 1 } },
> > -   };
> > -
> > -   device->border_colors = anv_state_pool_emit_data(&device-
> > >dynamic_state_pool,
> > -                    

Re: [Mesa-dev] [PATCH 5/5] anv: setup appropriate border color structures on gen7/gen75

2016-10-17 Thread Jason Ekstrand
On Mon, Oct 17, 2016 at 8:46 AM, Lionel Landwerlin 
wrote:

> Up to this point we were using the gen8+ structures. Altough this commit
> doesn't fixes the border color CTS tests, this is a step in the right
> direction to fix the following tests :
>

It's not entirely clear where you're headed but I'm afraid the approach may
ultimately be doomed to failure.  The fundamental problem is that Vulkan
allows complete mix-and-match of images and samplers in the shader.  We
cannot know, until the shader *executes* which sampler will be associated
with a particular texture.  This leaves us with two possible solutions:

 1) Emit a sampler for every possible sampler+image combination.
 2) Piles of shader hacks.

Both approaches are highly annoying.  While the first option is probably
the less annoying of the two, there is one format (R32_UINT maybe?  I don't
remember for sure) for which integer border color just doesn't work at all
on Haswell.  On Ivy Bridge, integer border color is so broken we probably
shouldn't be using it at all.  This leaves us with shader hacks.  Ken wrote
a bunch of code for this so that we could get the ES 3.1 CTS passing on
Haswell and Ivy Bridge.  Maybe that could be ported?  Maybe we can find
some magic Ivy Bridge "make border color work" bit?


>
> dEQP-VK.pipeline.sampler.view_type.2d.format.*.address_
> modes.all_mode_clamp_to_border_*
>
> Signed-off-by: Lionel Landwerlin 
> ---
>  src/intel/vulkan/anv_cmd_buffer.c |  10 ++
>  src/intel/vulkan/anv_device.c |  42 +---
>  src/intel/vulkan/anv_genX.h   |   3 +-
>  src/intel/vulkan/anv_private.h|   7 ++
>  src/intel/vulkan/genX_state.c | 220 ++
> ++--
>  5 files changed, 208 insertions(+), 74 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_cmd_buffer.c b/src/intel/vulkan/anv_cmd_
> buffer.c
> index b051489..a63f3d9 100644
> --- a/src/intel/vulkan/anv_cmd_buffer.c
> +++ b/src/intel/vulkan/anv_cmd_buffer.c
> @@ -931,6 +931,16 @@ anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer
> *cmd_buffer,
>if (sampler == NULL)
>   continue;
>
> +  /* On Haswell, although the border color structures are 20 dwords
> long
> +   * and must be aligned at 512 bytes, the position of the 8/16/32bits
> +   * colors overlap, meaning we can't have a single color structure
> +   * configured for all formats. We therefore need to reemit the
> sampler
> +   * structure for the used format. */
> +  if (cmd_buffer->device->info.is_haswell) {
> + gen75_pack_sampler_state(cmd_buffer->device, sampler,
> +  desc->image_view->vk_format);
> +  }
> +
>memcpy(state->map + (s * 16),
>   sampler->state, sizeof(sampler->state));
> }
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index ce1b9c1..4e69307 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -724,46 +724,6 @@ anv_queue_finish(struct anv_queue *queue)
>  {
>  }
>
> -static struct anv_state
> -anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size,
> size_t align, const void *p)
> -{
> -   struct anv_state state;
> -
> -   state = anv_state_pool_alloc(pool, size, align);
> -   memcpy(state.map, p, size);
> -
> -   if (!pool->block_pool->device->info.has_llc)
> -  anv_state_clflush(state);
> -
> -   return state;
> -}
> -
> -struct gen8_border_color {
> -   union {
> -  float float32[4];
> -  uint32_t uint32[4];
> -   };
> -   /* Pad out to 64 bytes */
> -   uint32_t _pad[12];
> -};
> -
> -static void
> -anv_device_init_border_colors(struct anv_device *device)
> -{
> -   static const struct gen8_border_color border_colors[] = {
> -  [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .float32 = { 0.0,
> 0.0, 0.0, 0.0 } },
> -  [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =   { .float32 = { 0.0,
> 0.0, 0.0, 1.0 } },
> -  [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =   { .float32 = { 1.0,
> 1.0, 1.0, 1.0 } },
> -  [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] ={ .uint32 = { 0, 0,
> 0, 0 } },
> -  [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0,
> 0, 1 } },
> -  [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1,
> 1, 1 } },
> -   };
> -
> -   device->border_colors = anv_state_pool_emit_data(&
> device->dynamic_state_pool,
> -
> sizeof(border_colors), 64,
> -border_colors);
> -}
> -
>  VkResult
>  anv_device_submit_simple_batch(struct anv_device *device,
> struct anv_batch *batch)
> @@ -926,7 +886,7 @@ VkResult anv_CreateDevice(
>
> anv_device_init_blorp(device);
>
> -   anv_device_init_border_colors(device);
> +   ANV_GEN_DISPATCH(device, border_colors_setup, device);
>
> *pDevice = anv_device_to_handle(device);
>
> diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
> index 27c55b9..a4a39e1 100644
> --- a/src/intel/vulkan/anv_

[Mesa-dev] [PATCH 5/5] anv: setup appropriate border color structures on gen7/gen75

2016-10-17 Thread Lionel Landwerlin
Up to this point we were using the gen8+ structures. Altough this commit
doesn't fixes the border color CTS tests, this is a step in the right
direction to fix the following tests :

dEQP-VK.pipeline.sampler.view_type.2d.format.*.address_modes.all_mode_clamp_to_border_*

Signed-off-by: Lionel Landwerlin 
---
 src/intel/vulkan/anv_cmd_buffer.c |  10 ++
 src/intel/vulkan/anv_device.c |  42 +---
 src/intel/vulkan/anv_genX.h   |   3 +-
 src/intel/vulkan/anv_private.h|   7 ++
 src/intel/vulkan/genX_state.c | 220 --
 5 files changed, 208 insertions(+), 74 deletions(-)

diff --git a/src/intel/vulkan/anv_cmd_buffer.c 
b/src/intel/vulkan/anv_cmd_buffer.c
index b051489..a63f3d9 100644
--- a/src/intel/vulkan/anv_cmd_buffer.c
+++ b/src/intel/vulkan/anv_cmd_buffer.c
@@ -931,6 +931,16 @@ anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer 
*cmd_buffer,
   if (sampler == NULL)
  continue;
 
+  /* On Haswell, although the border color structures are 20 dwords long
+   * and must be aligned at 512 bytes, the position of the 8/16/32bits
+   * colors overlap, meaning we can't have a single color structure
+   * configured for all formats. We therefore need to reemit the sampler
+   * structure for the used format. */
+  if (cmd_buffer->device->info.is_haswell) {
+ gen75_pack_sampler_state(cmd_buffer->device, sampler,
+  desc->image_view->vk_format);
+  }
+
   memcpy(state->map + (s * 16),
  sampler->state, sizeof(sampler->state));
}
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index ce1b9c1..4e69307 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -724,46 +724,6 @@ anv_queue_finish(struct anv_queue *queue)
 {
 }
 
-static struct anv_state
-anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t 
align, const void *p)
-{
-   struct anv_state state;
-
-   state = anv_state_pool_alloc(pool, size, align);
-   memcpy(state.map, p, size);
-
-   if (!pool->block_pool->device->info.has_llc)
-  anv_state_clflush(state);
-
-   return state;
-}
-
-struct gen8_border_color {
-   union {
-  float float32[4];
-  uint32_t uint32[4];
-   };
-   /* Pad out to 64 bytes */
-   uint32_t _pad[12];
-};
-
-static void
-anv_device_init_border_colors(struct anv_device *device)
-{
-   static const struct gen8_border_color border_colors[] = {
-  [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =  { .float32 = { 0.0, 0.0, 
0.0, 0.0 } },
-  [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =   { .float32 = { 0.0, 0.0, 
0.0, 1.0 } },
-  [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =   { .float32 = { 1.0, 1.0, 
1.0, 1.0 } },
-  [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] ={ .uint32 = { 0, 0, 0, 0 } 
},
-  [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } 
},
-  [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } 
},
-   };
-
-   device->border_colors = 
anv_state_pool_emit_data(&device->dynamic_state_pool,
-sizeof(border_colors), 64,
-border_colors);
-}
-
 VkResult
 anv_device_submit_simple_batch(struct anv_device *device,
struct anv_batch *batch)
@@ -926,7 +886,7 @@ VkResult anv_CreateDevice(
 
anv_device_init_blorp(device);
 
-   anv_device_init_border_colors(device);
+   ANV_GEN_DISPATCH(device, border_colors_setup, device);
 
*pDevice = anv_device_to_handle(device);
 
diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
index 27c55b9..a4a39e1 100644
--- a/src/intel/vulkan/anv_genX.h
+++ b/src/intel/vulkan/anv_genX.h
@@ -28,7 +28,7 @@
 /*
  * Gen-specific function declarations.  This header must *not* be included
  * directly.  Instead, it is included multiple times by anv_private.h.
- * 
+ *
  * In this header file, the usual genx() macro is available.
  */
 
@@ -37,6 +37,7 @@
 #endif
 
 VkResult genX(init_device_state)(struct anv_device *device);
+void genX(border_colors_setup)(struct anv_device *device);
 
 void genX(cmd_buffer_emit_state_base_address)(struct anv_cmd_buffer 
*cmd_buffer);
 
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 69e6aac..faebbb2 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -643,6 +643,7 @@ struct anv_device {
 struct blorp_contextblorp;
 
 struct anv_stateborder_colors;
+uint32_tborder_color_align;
 
 struct anv_queuequeue;
 
@@ -1732,6 +1733,8 @@ void anv_buffer_view_fill_image_param(struct anv_device 
*device,
 
 struct anv_sampler {
uint32_t state[4];
+
+   VkSamplerCreateInfo info;
 };
 
 struct anv_framebuffer {
@@ -1783,6 +1786,10 @@ struct anv_query_pool {
str