Mesa (main): v3dv: Implement VK_EXT_custom_border_color

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Aug 2 23:11:41 UTC 2021


Module: Mesa
Branch: main
Commit: 23a9339985d37db8c94fc71fe5ee6a11d368a1b9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=23a9339985d37db8c94fc71fe5ee6a11d368a1b9

Author: Ella-0 <estanforth at igalia.com>
Date:   Wed Jul 28 08:53:00 2021 +0000

v3dv: Implement VK_EXT_custom_border_color

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12076>

---

 docs/features.txt                   |   2 +-
 src/broadcom/vulkan/v3dv_device.c   |  22 ++++++-
 src/broadcom/vulkan/v3dvx_device.c  | 118 ++++++++++++++++++++++++++++++++++--
 src/broadcom/vulkan/v3dvx_private.h |   3 +-
 4 files changed, 136 insertions(+), 9 deletions(-)

diff --git a/docs/features.txt b/docs/features.txt
index 2df031b18a2..e8396d4cb9e 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -511,7 +511,7 @@ Khronos extensions that are not part of any Vulkan version:
   VK_EXT_color_write_enable                             DONE (anv, lvp)
   VK_EXT_conditional_rendering                          DONE (anv, lvp, radv, tu)
   VK_EXT_conservative_rasterization                     DONE (anv/gen9+, radv)
-  VK_EXT_custom_border_color                            DONE (anv, lvp, radv, tu)
+  VK_EXT_custom_border_color                            DONE (anv, lvp, radv, tu, v3dv)
   VK_EXT_debug_marker                                   DONE (radv)
   VK_EXT_depth_clip_enable                              DONE (anv, radv, tu)
   VK_EXT_depth_range_unrestricted                       DONE (radv)
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index 524d1ddbcc1..52f3e2612cc 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -139,6 +139,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
       .KHR_incremental_present             = true,
 #endif
       .KHR_variable_pointers               = true,
+      .EXT_custom_border_color             = true,
       .EXT_external_memory_dma_buf         = true,
       .EXT_index_type_uint8                = true,
       .EXT_physical_device_drm             = true,
@@ -1071,6 +1072,14 @@ v3dv_GetPhysicalDeviceFeatures2(VkPhysicalDevice physicalDevice,
 
    vk_foreach_struct(ext, pFeatures->pNext) {
       switch (ext->sType) {
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
+         VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =
+            (VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;
+         features->customBorderColors = true;
+         features->customBorderColorWithoutFormat = false;
+         break;
+      }
+
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
          VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
             (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
@@ -1386,6 +1395,12 @@ v3dv_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
 
    vk_foreach_struct(ext, pProperties->pNext) {
       switch (ext->sType) {
+      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
+         VkPhysicalDeviceCustomBorderColorPropertiesEXT *props =
+            (VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
+         props->maxCustomBorderColorSamplers = V3D_MAX_TEXTURE_SAMPLERS;
+         break;
+      }
       case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
          VkPhysicalDeviceIDProperties *id_props =
             (VkPhysicalDeviceIDProperties *)ext;
@@ -2528,7 +2543,12 @@ v3dv_CreateSampler(VkDevice _device,
 
    sampler->compare_enable = pCreateInfo->compareEnable;
    sampler->unnormalized_coordinates = pCreateInfo->unnormalizedCoordinates;
-   v3dv_X(device, pack_sampler_state)(sampler, pCreateInfo);
+
+   const VkSamplerCustomBorderColorCreateInfoEXT *bc_info =
+      vk_find_struct_const(pCreateInfo->pNext,
+                           SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
+
+   v3dv_X(device, pack_sampler_state)(sampler, pCreateInfo, bc_info);
 
    *pSampler = v3dv_sampler_to_handle(sampler);
 
diff --git a/src/broadcom/vulkan/v3dvx_device.c b/src/broadcom/vulkan/v3dvx_device.c
index d54c0a37d9f..f75b30e5477 100644
--- a/src/broadcom/vulkan/v3dvx_device.c
+++ b/src/broadcom/vulkan/v3dvx_device.c
@@ -28,6 +28,7 @@
 #include "broadcom/compiler/v3d_compiler.h"
 #include "vk_format_info.h"
 #include "util/u_pack_color.h"
+#include "util/half_float.h"
 
 static const enum V3DX(Wrap_Mode) vk_to_v3d_wrap_mode[] = {
    [VK_SAMPLER_ADDRESS_MODE_REPEAT]          = V3D_WRAP_MODE_REPEAT,
@@ -49,17 +50,109 @@ vk_to_v3d_compare_func[] = {
    [VK_COMPARE_OP_ALWAYS]                       = V3D_COMPARE_FUNC_ALWAYS,
 };
 
+
+static union pipe_color_union encode_border_color(
+   const VkSamplerCustomBorderColorCreateInfoEXT *bc_info)
+{
+   const struct util_format_description *desc =
+      vk_format_description(bc_info->format);
+
+   const struct v3dv_format *format = v3dX(get_format)(bc_info->format);
+
+   union pipe_color_union border;
+   for (int i = 0; i < 4; i++) {
+      if (format->swizzle[i] <= 3)
+         border.ui[i] = bc_info->customBorderColor.uint32[format->swizzle[i]];
+      else
+         border.ui[i] = 0;
+   }
+
+   /* handle clamping */
+   if (vk_format_has_depth(bc_info->format) &&
+       vk_format_has_stencil(bc_info->format)) {
+      border.f[0] = CLAMP(border.f[0], 0, 1);
+      border.ui[1] = CLAMP(border.ui[1], 0, 0xff);
+   } else if (vk_format_is_unorm(bc_info->format)) {
+      for (int i = 0; i < 4; i++)
+         border.f[i] = CLAMP(border.f[i], 0, 1);
+   } else if (vk_format_is_snorm(bc_info->format)) {
+      for (int i = 0; i < 4; i++)
+         border.f[i] = CLAMP(border.f[i], -1, 1);
+   } else if (vk_format_is_uint(bc_info->format) &&
+              desc->channel[0].size < 32) {
+      for (int i = 0; i < 4; i++)
+         border.ui[i] = CLAMP(border.ui[i], 0, (1 << desc->channel[i].size));
+   } else if (vk_format_is_sint(bc_info->format) &&
+              desc->channel[0].size < 32) {
+      for (int i = 0; i < 4; i++)
+         border.i[i] = CLAMP(border.i[i],
+                             -(1 << (desc->channel[i].size - 1)),
+                             (1 << (desc->channel[i].size - 1)) - 1);
+   }
+
+   /* convert from float to expected format */
+   if (vk_format_is_srgb(bc_info->format) ||
+       vk_format_is_compressed(bc_info->format)) {
+      for (int i = 0; i < 4; i++)
+         border.ui[i] = _mesa_float_to_half(border.f[i]);
+   } else if (vk_format_is_unorm(bc_info->format)) {
+      for (int i = 0; i < 4; i++) {
+         switch (desc->channel[i].size) {
+         case 8:
+         case 16:
+            /* expect u16 for non depth values */
+            if (!vk_format_has_depth(bc_info->format))
+               border.ui[i] = (uint32_t) (border.f[i] * (float) 0xffff);
+            break;
+         case 24:
+         case 32:
+            /* uses full f32; no conversion needed */
+            break;
+         default:
+            border.ui[i] = _mesa_float_to_half(border.f[i]);
+            break;
+         }
+      }
+   } else if (vk_format_is_snorm(bc_info->format)) {
+      for (int i = 0; i < 4; i++) {
+         switch (desc->channel[i].size) {
+         case 8:
+            border.ui[i] = (int32_t) (border.f[i] * (float) 0x3fff);
+            break;
+         case 16:
+            border.i[i] = (int32_t) (border.f[i] * (float) 0x7fff);
+            break;
+         case 24:
+         case 32:
+            /* uses full f32; no conversion needed */
+            break;
+         default:
+            border.ui[i] = _mesa_float_to_half(border.f[i]);
+            break;
+         }
+      }
+   } else if (vk_format_is_float(bc_info->format)) {
+      for (int i = 0; i < 4; i++) {
+         switch(desc->channel[i].size) {
+         case 16:
+            border.ui[i] = _mesa_float_to_half(border.f[i]);
+            break;
+         default:
+            break;
+         }
+      }
+   }
+
+   return border;
+}
+
 void
 v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,
-                         const VkSamplerCreateInfo *pCreateInfo)
+                         const VkSamplerCreateInfo *pCreateInfo,
+                         const VkSamplerCustomBorderColorCreateInfoEXT *bc_info)
 {
    enum V3DX(Border_Color_Mode) border_color_mode;
 
-   /* For now we only support the preset Vulkan border color modes. If we
-    * want to implement VK_EXT_custom_border_color in the future we would have
-    * to use V3D_BORDER_COLOR_FOLLOWS, and fill up border_color_word_[0/1/2/3]
-    * SAMPLER_STATE.
-    */
    switch (pCreateInfo->borderColor) {
    case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
    case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
@@ -73,6 +166,10 @@ v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,
    case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
       border_color_mode = V3D_BORDER_COLOR_1111;
       break;
+   case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
+   case VK_BORDER_COLOR_INT_CUSTOM_EXT:
+      border_color_mode = V3D_BORDER_COLOR_FOLLOWS;
+      break;
    default:
       unreachable("Unknown border color");
       break;
@@ -106,6 +203,15 @@ v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,
 
       s.border_color_mode = border_color_mode;
 
+      if (s.border_color_mode == V3D_BORDER_COLOR_FOLLOWS) {
+         union pipe_color_union border = encode_border_color(bc_info);
+
+         s.border_color_word_0 = border.ui[0];
+         s.border_color_word_1 = border.ui[1];
+         s.border_color_word_2 = border.ui[2];
+         s.border_color_word_3 = border.ui[3];
+      }
+
       s.wrap_i_border = false; /* Also hardcoded on v3d */
       s.wrap_s = vk_to_v3d_wrap_mode[pCreateInfo->addressModeU];
       s.wrap_t = vk_to_v3d_wrap_mode[pCreateInfo->addressModeV];
diff --git a/src/broadcom/vulkan/v3dvx_private.h b/src/broadcom/vulkan/v3dvx_private.h
index edebf251833..b74824a58d8 100644
--- a/src/broadcom/vulkan/v3dvx_private.h
+++ b/src/broadcom/vulkan/v3dvx_private.h
@@ -130,7 +130,8 @@ v3dX(cmd_buffer_render_pass_setup_render_target)(struct v3dv_cmd_buffer *cmd_buf
 
 void
 v3dX(pack_sampler_state)(struct v3dv_sampler *sampler,
-                         const VkSamplerCreateInfo *pCreateInfo);
+                         const VkSamplerCreateInfo *pCreateInfo,
+                         const VkSamplerCustomBorderColorCreateInfoEXT *bc_info);
 
 void
 v3dX(framebuffer_compute_internal_bpp_msaa)(const struct v3dv_framebuffer *framebuffer,



More information about the mesa-commit mailing list