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

Jason Ekstrand jason at jlekstrand.net
Wed Oct 19 21:49:56 UTC 2016


On Wed, Oct 19, 2016 at 8:50 AM, Lionel Landwerlin <llandwerlin at gmail.com>
wrote:

> Up to this point we were using the gen8+ structures to program border
> colors. This commit sets up the correct border colors for HSW & IVB.
>
> On HSW:
>    This fixes 140 failures of :
>      dEQP-VK.pipeline.sampler.view_type.*.format.*.address_modes.
> all_mode_clamp_to_border_*
>      (11 failures remain out of 840 tests)
>
>    Failures :
>      - dEQP-VK.pipeline.sampler.view_type.*.format.b4g4r4a4_unorm_
> pack16.address_modes.all_mode_clamp_to_border_*
>
>        There is no equivalent of b4g4r4a4_unorm on the GLES31 test suite
> and
>        the documentation doesn't seem to list this format in any of the
>        8/16/32bits supported ones.
>
>      - dEQP-VK.pipeline.sampler.view_type.2d.format.r32g32b32_uint.
> address_modes.all_mode_clamp_to_border_*
>
>        Some GLES31 equivalent tests are failing too :
>
>          dEQP-GLES31.functional.texture.border_clamp.formats.
> rgba32ui.nearest_size_pot
>          dEQP-GLES31.functional.texture.border_clamp.formats.
> rgba32ui.nearest_size_npot
>
>      - dEQP-VK.pipeline.sampler.view_type.2d.format.r32_uint.
> address_modes.all_mode_clamp_to_border_*
>
>        Seems to exhibit the same issue as r32g32b32_uint (some of the
>        corners of the sampled texture are missing).
>
> On IVB:
>    This fixes 73 failures of :
>      dEQP-VK.pipeline.sampler.view_type.*.format.*.address_modes.
> all_mode_clamp_to_border_*
>      (139 failures remain out of 795 tests)
>
>      All tests using *_sfloat, *_unorm, *_snorm formats are passing.
>
>    Failures :
>      - dEQP-VK.pipeline.sampler.view_type.*.format.r8g8b8_uint.
> address_modes.all_mode_clamp_to_border_*
>        dEQP-VK.pipeline.sampler.view_type.*.format.r16g16b16_sint.
> address_modes.all_mode_clamp_to_border_*
>        dEQP-VK.pipeline.sampler.view_type.*.format.r16g16b16_
> sfloat.address_modes.all_mode_clamp_to_border_*
>
>        These tests were triggering an assert before and remain broken. This
>        seems to be a hardware limitation we can't express through the
> Vulkan
>        API.
>
>      - Most of uint formats produce invalid results (some with invalid
>        border color, some with invalid texture data) with exception of :
>
>        dEQP-VK.pipeline.sampler.view_type.*.format.r32_sint.
> address_modes.all_mode_clamp_to_border_*
>
> v2: Implement Jason's suggestion to have all sampler configuration ready at
>     sampler cration
>     Also fix remaining issues with 1 & 2 components texture
>
> Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
> ---
>  src/intel/vulkan/anv_device.c      |  42 -------
>  src/intel/vulkan/anv_genX.h        |   3 +-
>  src/intel/vulkan/anv_private.h     |  11 +-
>  src/intel/vulkan/genX_cmd_buffer.c |   5 +-
>  src/intel/vulkan/genX_state.c      | 229 ++++++++++++++++++++++++++++++
> ++++---
>  5 files changed, 228 insertions(+), 62 deletions(-)
>
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index c995630..3ad01b9 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)
> @@ -943,8 +903,6 @@ VkResult anv_CreateDevice(
>
>     anv_device_init_blorp(device);
>
> -   anv_device_init_border_colors(device);
> -
>     *pDevice = anv_device_to_handle(device);
>
>     return VK_SUCCESS;
> diff --git a/src/intel/vulkan/anv_genX.h b/src/intel/vulkan/anv_genX.h
> index d4ed325..ebd0ee7 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);
> +uint32_t genX(sampler_index)(VkFormat format);
>
>  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 0e25827..2cca5c3 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -552,6 +552,7 @@ struct anv_device {
>      struct blorp_context                        blorp;
>
>      struct anv_state                            border_colors;
> +    uint32_t                                    border_color_align;
>
>      struct anv_queue                            queue;
>
> @@ -1642,7 +1643,15 @@ void anv_buffer_view_fill_image_param(struct
> anv_device *device,
>                                        struct brw_image_param *param);
>
>  struct anv_sampler {
> -   uint32_t state[4];
> +   /* On Haswell we need to have all samplers declined per number of
> component
> +    * for each possible integer format (8, 16 and 32 bits) and we also
> need
> +    * sampler configurations for normalized and floating point formats :
> +    *
> +    * 4 components * 3 integer formats + floats&normalized = 13
> configurations
> +    *
> +    * On all other platforms, only state[0] is used.
> +    */
> +   uint32_t state[13][4];
>  };
>
>  struct anv_framebuffer {
> diff --git a/src/intel/vulkan/genX_cmd_buffer.c
> b/src/intel/vulkan/genX_cmd_buffer.c
> index 5ea7c5f..88ed284 100644
> --- a/src/intel/vulkan/genX_cmd_buffer.c
> +++ b/src/intel/vulkan/genX_cmd_buffer.c
> @@ -905,8 +905,9 @@ emit_samplers(struct anv_cmd_buffer *cmd_buffer,
>        if (sampler == NULL)
>           continue;
>
> -      memcpy(state->map + (s * 16),
> -             sampler->state, sizeof(sampler->state));
> +      uint32_t sampler_index = genX(sampler_index)(desc->
> image_view->vk_format);
> +      memcpy(state->map + (s * 16), sampler->state[sampler_index],
> +             GENX(SAMPLER_STATE_length) * 4);
>

Unfortunately, this only works for the case where we have a combined image
and sampler.  desc->image_view could be null (just a plain sampler) or the
shader could end up combining this sampler with a different image (and
different format).  Sadly, I think this is probably yet another CTS
coverage hole.


>     }
>
>     if (!cmd_buffer->device->info.has_llc)
> diff --git a/src/intel/vulkan/genX_state.c b/src/intel/vulkan/genX_state.c
> index be1bd78..61aeef3 100644
> --- a/src/intel/vulkan/genX_state.c
> +++ b/src/intel/vulkan/genX_state.c
> @@ -28,11 +28,172 @@
>  #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"
>
> +uint32_t
> +genX(sampler_index)(VkFormat format)
> +{
> +#if ! GEN_IS_HASWELL
> +   return 0;
> +#else
> +   if (!vk_format_is_integer(format))
> +      return 0;
> +
> +   uint32_t index = 3 * (vk_format_n_channels(format) - 1);
> +
> +   switch(vk_format_max_bpc(format)) {
> +   case 8:
> +      index += 1;
> +      break;
> +
> +   case 10:
> +   case 16:
> +   case 24:
> +      index += 2;
> +      break;
> +
> +   case 32:
> +      index += 3;
> +      break;
> +   default:
> +      anv_finishme("unsupported sampling format with border color");
> +      return 0;
> +   }
> +
> +   return index;
> +#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,               \
> +   }
> +
> +static void
> +border_colors_setup(struct anv_device *device)
> +{
> +#if GEN_IS_HASWELL
> +   /* We order things differently for Haswell and only ever care about the
> +    * color, not whether the color integer or float (see
> genX(sampler_index)).
> +    * This consumes 13 * 3 * 512 ~= 20kb of memory. */
> +   static const struct GENX(SAMPLER_BORDER_COLOR_STATE) border_colors[]
> = {
> +      /* Transparent black: */
> +      BORDER_COLOR(Float, 0.0, 0.0, 0.0, 0.0),
> +      /*  - R textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +      /*  - RG textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +      /*  - RGB textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +      /*  - RBGA textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   0),
> +      BORDER_COLOR(16bit, 0,   0,   0,   0),
> +      BORDER_COLOR(32bit, 0,   0,   0,   0),
> +
> +      /* Opaque black: */
> +      BORDER_COLOR(Float, 0.0, 0.0, 0.0, 1.0),
> +      /*  - R textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +      /*  - RG textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +      /*  - RGB textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +      /*  - RGBA textures */
> +      BORDER_COLOR(8bit,  0,   0,   0,   1),
> +      BORDER_COLOR(16bit, 0,   0,   0,   1),
> +      BORDER_COLOR(32bit, 0,   0,   0,   1),
> +
> +      /* Opaque white: */
> +      BORDER_COLOR(Float, 1.0, 1.0, 1.0, 1.0),
> +      /*  - R textures */
> +      BORDER_COLOR(8bit,  1,   0,   0,   1),
> +      BORDER_COLOR(16bit, 1,   0,   0,   1),
> +      BORDER_COLOR(32bit, 1,   0,   0,   1),
> +      /*  - RG textures */
> +      BORDER_COLOR(8bit,  1,   1,   0,   1),
> +      BORDER_COLOR(16bit, 1,   1,   0,   1),
> +      BORDER_COLOR(32bit, 1,   1,   0,   1),
> +      /*  - RGB textures */
> +      BORDER_COLOR(8bit,  1,   1,   1,   1),
> +      BORDER_COLOR(16bit, 1,   1,   1,   1),
> +      BORDER_COLOR(32bit, 1,   1,   1,   1),
> +      /*  - RGBA textures */
> +      BORDER_COLOR(8bit,  1,   1,   1,   1),
> +      BORDER_COLOR(16bit, 1,   1,   1,   1),
> +      BORDER_COLOR(32bit, 1,   1,   1,   1),
> +   };
> +   static_assert(sizeof(struct anv_sampler) / (4 *
> GENX(SAMPLER_STATE_length)) ==
> +                 ARRAY_SIZE(border_colors) / 3,
> +                 "struct anv_sampler size doesn't match border_colors");
> +   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)
>  {
> @@ -91,6 +252,8 @@ genX(init_device_state)(struct anv_device *device)
>
>     assert(batch.next <= batch.end);
>
> +   border_colors_setup(device);
> +
>     return anv_device_submit_simple_batch(device, &batch);
>  }
>
> @@ -148,24 +311,34 @@ static const uint32_t vk_to_gen_shadow_compare_op[]
> = {
>     [VK_COMPARE_OP_ALWAYS]                       = PREFILTEROPNEVER,
>  };
>
> -VkResult genX(CreateSampler)(
> -    VkDevice                                    _device,
> +static void
> +pack_sampler_state(
> +   struct anv_device *                          device,
> +   struct anv_sampler *                         sampler,
>      const VkSamplerCreateInfo*                  pCreateInfo,
> -    const VkAllocationCallbacks*                pAllocator,
> -    VkSampler*                                  pSampler)
> +   uint32_t                                     offset,
> +   void *                                       dest)
>  {
> -   ANV_FROM_HANDLE(anv_device, device, _device);
> -   struct anv_sampler *sampler;
> -
> -   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
> +#if GEN_IS_HASWELL
> +   static const uint32_t haswell_border_color_offset[] = {
> +      [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = 0,
> +      [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = 0,
>
> -   sampler = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
> -                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> -   if (!sampler)
> -      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> +      [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = 1,
> +      [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = 1,
>
> -   uint32_t border_color_offset = device->border_colors.offset +
> -                                  pCreateInfo->borderColor * 64;
> +      [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = 2,
> +      [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = 2,
> +   };
> +   uint32_t color_index =
> +      ARRAY_SIZE(sampler->state) *
> +      haswell_border_color_offset[pCreateInfo->borderColor] + offset;
> +#else
> +   uint32_t color_index = pCreateInfo->borderColor;
> +#endif
> +   uint32_t color_offset =
> +      device->border_colors.offset +
> +      color_index * device->border_color_align;
>
>     struct GENX(SAMPLER_STATE) sampler_state = {
>        .SamplerDisable = false,
> @@ -195,7 +368,7 @@ VkResult genX(CreateSampler)(
>        .ShadowFunction = vk_to_gen_shadow_compare_op[
> pCreateInfo->compareOp],
>        .CubeSurfaceControlMode = OVERRIDE,
>
> -      .BorderColorPointer = border_color_offset,
> +      .BorderColorPointer = color_offset,
>
>  #if GEN_GEN >= 8
>        .LODClampMagnificationMode = MIPNONE,
> @@ -215,7 +388,31 @@ VkResult genX(CreateSampler)(
>        .TCZAddressControlMode = vk_to_gen_tex_address[
> pCreateInfo->addressModeW],
>     };
>
> -   GENX(SAMPLER_STATE_pack)(NULL, sampler->state, &sampler_state);
> +   GENX(SAMPLER_STATE_pack)(NULL, dest, &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 = vk_alloc2(&device->alloc, pAllocator, sizeof(*sampler), 8,
> +                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
> +   if (!sampler)
> +      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
> +
> +   pack_sampler_state(device, sampler, pCreateInfo, 0, sampler->state[0]);
> +#if GEN_IS_HASWELL
> +   for (uint32_t i = 1; i < ARRAY_SIZE(sampler->state); i++)
> +      pack_sampler_state(device, sampler, pCreateInfo, i,
> sampler->state[i]);
> +#endif
>
>     *pSampler = anv_sampler_to_handle(sampler);
>
> --
> 2.9.3
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161019/d6677f77/attachment-0001.html>


More information about the mesa-dev mailing list