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:
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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];
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user