On Mon, 2016-10-17 at 11:09 -0700, Jason Ekstrand wrote:
> On Mon, Oct 17, 2016 at 8:46 AM, Lionel Landwerlin <llandwerlin@gmail
> .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 <lionel.g.landwer...@intel.com>
> > ---
> >  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_context                        blorp;
> > 
> >      struct anv_state                            border_colors;
> > +    uint32_t                                   
> > border_color_align;
> > 
> >      struct anv_queue                            queue;
> > 
> > @@ -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 {
> >     struct anv_bo                                bo;
> >  };
> > 
> > +void gen75_pack_sampler_state(struct anv_device *device,
> > +                              struct anv_sampler *sampler,
> > +                              VkFormat format);
> > +
> >  void *anv_lookup_entrypoint(const struct gen_device_info *devinfo,
> >                              const char *name);
> > 
> > diff --git a/src/intel/vulkan/genX_state.c
> > b/src/intel/vulkan/genX_state.c
> > index a6d405d..cbf7df2 100644
> > --- a/src/intel/vulkan/genX_state.c
> > +++ b/src/intel/vulkan/genX_state.c
> > @@ -28,11 +28,144 @@
> >  #include <fcntl.h>
> > 
> >  #include "anv_private.h"
> > +#include "vk_format_info.h"
> > 
> >  #include "common/gen_sample_positions.h"
> >  #include "genxml/gen_macros.h"
> >  #include "genxml/genX_pack.h"
> > 
> > +static uint32_t
> > +border_color_index(VkBorderColor border_color, VkFormat format)
> > +{
> > +#if GEN_IS_HASWELL
> > +   if (!vk_format_is_integer(format))
> > +      return border_color;
> > +
> > +   uint32_t max_bpc = vk_format_max_bpc(format);
> > +   uint32_t index = 0;
> > +
> > +   if (max_bpc <= 8)
> > +      return border_color;
> > +
> > +   if (max_bpc <= 16)
> > +      index = VK_BORDER_COLOR_END_RANGE + 1;
> > +   else
> > +      index = VK_BORDER_COLOR_END_RANGE + 4;
> > +
> > +   switch (border_color) {
> > +   case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
> > +   case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
> > +      index += 0;
> > +      break;
> > +
> > +   case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
> > +   case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
> > +      index += 1;
> > +      break;
> > +
> > +   case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
> > +   case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
> > +      index += 2;
> > +      break;
> > +
> > +   default:
> > +      unreachable("invalid border color");
> > +   }
> > +
> > +   return index;
> > +#else
> > +   return border_color;
> > +#endif
> > +}
> > +
> > +#define BORDER_COLOR(name, r, g, b, a) {           \
> > +      .BorderColor##name##Red   = r,               \
> > +      .BorderColor##name##Green = g,               \
> > +      .BorderColor##name##Blue  = b,               \
> > +      .BorderColor##name##Alpha = a,               \
> > +   }
> > +
> > +void
> > +genX(border_colors_setup)(struct anv_device *device)
> > +{
> > +#if GEN_IS_HASWELL
> > +   static const struct GENX(SAMPLER_BORDER_COLOR_STATE)
> > border_colors[] = {
> > +      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
> > +      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
> > +      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =
> > +         BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
> > +      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =
> > +         BORDER_COLOR(8bit, 0, 0, 0, 0),
> > +      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =
> > +         BORDER_COLOR(8bit, 0, 0, 0, 1),
> > +      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =
> > +         BORDER_COLOR(8bit, 1, 1, 1, 1),
> > +      [VK_BORDER_COLOR_END_RANGE + 1] =
> > +         BORDER_COLOR(16bit, 0, 0, 0, 0),
> > +      [VK_BORDER_COLOR_END_RANGE + 2] =
> > +         BORDER_COLOR(16bit, 0, 0, 0, 1),
> > +      [VK_BORDER_COLOR_END_RANGE + 3] =
> > +         BORDER_COLOR(16bit, 1, 1, 1, 1),
> > +      [VK_BORDER_COLOR_END_RANGE + 4] =
> > +         BORDER_COLOR(32bit, 0, 0, 0, 0),
> > +      [VK_BORDER_COLOR_END_RANGE + 5] =
> > +         BORDER_COLOR(32bit, 0, 0, 0, 1),
> > +      [VK_BORDER_COLOR_END_RANGE + 6] =
> > +         BORDER_COLOR(32bit, 1, 1, 1, 1)
> > +   };
> > +   device->border_color_align = 512;
> > +#elif GEN_GEN == 7
> > +   static const struct GENX(SAMPLER_BORDER_COLOR_STATE)
> > border_colors[] = {
> > +      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
> > +      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
> > +      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =
> > +         BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
> > +      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
> > +      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
> > +      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =
> > +         BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0)
> > +   };
> > +   device->border_color_align = 64;
> > +#else /* GEN_GEN >= 8 */
> > +   static const struct GENX(SAMPLER_BORDER_COLOR_STATE)
> > border_colors[] = {
> > +      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
> > +      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] =
> > +         BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
> > +      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] =
> > +         BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
> > +      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] =
> > +         BORDER_COLOR(32bit, 0, 0, 0, 0),
> > +      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] =
> > +         BORDER_COLOR(32bit, 0, 0, 0, 1),
> > +      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] =
> > +         BORDER_COLOR(32bit, 1, 1, 1, 1)
> > +   };
> > +   device->border_color_align = 64;
> > +#endif
> > +
> > +   device->border_colors =
> > +      anv_state_pool_alloc(&device->dynamic_state_pool,
> > +                           ARRAY_SIZE(border_colors) * device-
> > >border_color_align,
> > +                           device->border_color_align);
> > +
> > +   for (uint32_t i = 0; i < ARRAY_SIZE(border_colors); i++) {
> > +      GENX(SAMPLER_BORDER_COLOR_STATE_pack)(
> > +         NULL,
> > +         device->border_colors.map + i * device-
> > >border_color_align,
> > +         &border_colors[i]);
> > +   }
> > +
> > +   if (!device->info.has_llc)
> > +      anv_state_clflush(device->border_colors);
> > +}
> > +
> >  VkResult
> >  genX(init_device_state)(struct anv_device *device)
> >  {
> > @@ -148,24 +281,21 @@ static const uint32_t
> > vk_to_gen_shadow_compare_op[] = {
> >     [VK_COMPARE_OP_ALWAYS]                       =
> > PREFILTEROPNEVER,
> >  };
> > 
> > -VkResult genX(CreateSampler)(
> > -    VkDevice                                    _device,
> > -    const VkSamplerCreateInfo*                  pCreateInfo,
> > -    const VkAllocationCallbacks*                pAllocator,
> > -    VkSampler*                                  pSampler)
> > +#if GEN_IS_HASWELL
> > +void
> > +#else
> > +static void
> > +#endif
> > +genX(pack_sampler_state)(
> > +   struct anv_device *                          device,
> > +   struct anv_sampler *                         sampler,
> > +   VkFormat                                     format)
> >  {
> > -   ANV_FROM_HANDLE(anv_device, device, _device);
> > -   struct anv_sampler *sampler;
> > -
> > -   assert(pCreateInfo->sType ==
> > VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
> > -
> > -   sampler = anv_alloc2(&device->alloc, pAllocator,
> > sizeof(*sampler), 8,
> > -                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> > -   if (!sampler)
> > -      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> > -
> > -   uint32_t border_color_offset = device->border_colors.offset +
> > -                                  pCreateInfo->borderColor * 64;
> > +   uint32_t color_index =
> > +      border_color_index(sampler->info.borderColor, format);
> > +   uint32_t color_offset =
> > +      device->border_colors.offset +
> > +      color_index * device->border_color_align;
> > 
> >     struct GENX(SAMPLER_STATE) sampler_state = {
> >        .SamplerDisable = false,
> > @@ -180,28 +310,28 @@ VkResult genX(CreateSampler)(
> >  #if GEN_GEN == 8
> >        .BaseMipLevel = 0.0,
> >  #endif
> > -      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo-
> > >mipmapMode],
> > -      .MagModeFilter = vk_to_gen_tex_filter(pCreateInfo-
> > >magFilter,
> > -                                            pCreateInfo-
> > >anisotropyEnable),
> > -      .MinModeFilter = vk_to_gen_tex_filter(pCreateInfo-
> > >minFilter,
> > -                                            pCreateInfo-
> > >anisotropyEnable),
> > -      .TextureLODBias = anv_clamp_f(pCreateInfo->mipLodBias, -16,
> > 15.996),
> > +      .MipModeFilter = vk_to_gen_mipmap_mode[sampler-
> > >info.mipmapMode],
> > +      .MagModeFilter = vk_to_gen_tex_filter(sampler-
> > >info.magFilter,
> > +                                            sampler-
> > >info.anisotropyEnable),
> > +      .MinModeFilter = vk_to_gen_tex_filter(sampler-
> > >info.minFilter,
> > +                                            sampler-
> > >info.anisotropyEnable),
> > +      .TextureLODBias = anv_clamp_f(sampler->info.mipLodBias, -16,
> > 15.996),
> >        .AnisotropicAlgorithm = EWAApproximation,
> > -      .MinLOD = anv_clamp_f(pCreateInfo->minLod, 0, 14),
> > -      .MaxLOD = anv_clamp_f(pCreateInfo->maxLod, 0, 14),
> > +      .MinLOD = anv_clamp_f(sampler->info.minLod, 0, 14),
> > +      .MaxLOD = anv_clamp_f(sampler->info.maxLod, 0, 14),
> >        .ChromaKeyEnable = 0,
> >        .ChromaKeyIndex = 0,
> >        .ChromaKeyMode = 0,
> > -      .ShadowFunction = vk_to_gen_shadow_compare_op[pCreateInfo-
> > >compareOp],
> > +      .ShadowFunction = vk_to_gen_shadow_compare_op[sampler-
> > >info.compareOp],
> >        .CubeSurfaceControlMode = OVERRIDE,
> > 
> > -      .BorderColorPointer = border_color_offset,
> > +      .BorderColorPointer = color_offset,
> > 
> >  #if GEN_GEN >= 8
> >        .LODClampMagnificationMode = MIPNONE,
> >  #endif
> > 
> > -      .MaximumAnisotropy = vk_to_gen_max_anisotropy(pCreateInfo-
> > >maxAnisotropy),
> > +      .MaximumAnisotropy = vk_to_gen_max_anisotropy(sampler-
> > >info.maxAnisotropy),
> >        .RAddressMinFilterRoundingEnable = 0,
> >        .RAddressMagFilterRoundingEnable = 0,
> >        .VAddressMinFilterRoundingEnable = 0,
> > @@ -209,13 +339,39 @@ VkResult genX(CreateSampler)(
> >        .UAddressMinFilterRoundingEnable = 0,
> >        .UAddressMagFilterRoundingEnable = 0,
> >        .TrilinearFilterQuality = 0,
> > -      .NonnormalizedCoordinateEnable = pCreateInfo-
> > >unnormalizedCoordinates,
> > -      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo-
> > >addressModeU],
> > -      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo-
> > >addressModeV],
> > -      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo-
> > >addressModeW],
> > +      .NonnormalizedCoordinateEnable = sampler-
> > >info.unnormalizedCoordinates,
> > +      .TCXAddressControlMode = vk_to_gen_tex_address[sampler-
> > >info.addressModeU],
> > +      .TCYAddressControlMode = vk_to_gen_tex_address[sampler-
> > >info.addressModeV],
> > +      .TCZAddressControlMode = vk_to_gen_tex_address[sampler-
> > >info.addressModeW],
> >     };
> > 
> >     GENX(SAMPLER_STATE_pack)(NULL, sampler->state, &sampler_state);
> > +}
> > +
> > +
> > +VkResult genX(CreateSampler)(
> > +    VkDevice                                    _device,
> > +    const VkSamplerCreateInfo*                  pCreateInfo,
> > +    const VkAllocationCallbacks*                pAllocator,
> > +    VkSampler*                                  pSampler)
> > +{
> > +   ANV_FROM_HANDLE(anv_device, device, _device);
> > +   struct anv_sampler *sampler;
> > +
> > +   assert(pCreateInfo->sType ==
> > VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
> > +
> > +   sampler = anv_alloc2(&device->alloc, pAllocator,
> > sizeof(*sampler), 8,
> > +                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> > +   if (!sampler)
> > +      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> > +
> > +   sampler->info = *pCreateInfo;
> > +
> > +   /* No need to pack the sampler state on HSW, as the packing
> > will depend on
> > +    * the format of the associated texture. */
> > +#if ! GEN_IS_HASWELL
> > +   genX(pack_sampler_state)(device, sampler, VK_FORMAT_UNDEFINED);
> > +#endif
> > 
> >     *pSampler = anv_sampler_to_handle(sampler);
> > 
> > --
> > 2.9.3
> > 
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> > 
> 
> 
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to