v3dv: Implement VK_EXT_custom_border_color

Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12076>
This commit is contained in:
Ella-0
2021-07-28 08:53:00 +00:00
committed by Marge Bot
parent 0a464f2e07
commit 23a9339985
4 changed files with 136 additions and 9 deletions

View File

@@ -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)

View File

@@ -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);

View File

@@ -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];

View File

@@ -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,