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