Skip to content

Commit 53011b2

Browse files
committed
layers: Add YCbCr2Plane VUs
1 parent 6001784 commit 53011b2

File tree

12 files changed

+196
-25
lines changed

12 files changed

+196
-25
lines changed

layers/stateless/sl_buffer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include "stateless/stateless_validation.h"
20+
#include "containers/container_utils.h"
2021
#include "generated/enum_flag_bits.h"
2122
#include "utils/image_utils.h"
2223
#include "utils/math_utils.h"
@@ -148,6 +149,16 @@ bool Device::manual_PreCallValidateCreateBufferView(VkDevice device, const VkBuf
148149
}
149150
}
150151

152+
if (api_version < VK_API_VERSION_1_3 && !enabled_features.ycbcr2plane444Formats) {
153+
if (IsValueIn(pCreateInfo->format,
154+
{VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
155+
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM})) {
156+
skip |= LogError("VUID-VkBufferViewCreateInfo-None-12278", device,
157+
context.error_obj.location.dot(Field::pCreateInfo).dot(Field::format), "is %s.",
158+
string_VkFormat(pCreateInfo->format));
159+
}
160+
}
161+
151162
return skip;
152163
}
153164

layers/stateless/sl_descriptor.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,15 @@ bool Device::manual_PreCallValidateGetDescriptorEXT(VkDevice device, const VkDes
12201220
"is VK_FORMAT_UNDEFINED.");
12211221
}
12221222
}
1223+
1224+
if (api_version < VK_API_VERSION_1_3 && !enabled_features.ycbcr2plane444Formats) {
1225+
if (IsValueIn(address_info->format,
1226+
{VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
1227+
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM})) {
1228+
skip |= LogError("VUID-VkDescriptorAddressInfoEXT-None-12271", device, address_loc.dot(Field::format), "is %s.",
1229+
string_VkFormat(address_info->format));
1230+
}
1231+
}
12231232
}
12241233

12251234
const auto *tensor_struct = vku::FindStructInPNextChain<VkDescriptorGetTensorInfoARM>(pDescriptorInfo->pNext);

layers/stateless/sl_image.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
/* Copyright (c) 2015-2025 The Khronos Group Inc.
2-
* Copyright (c) 2015-2025 Valve Corporation
3-
* Copyright (c) 2015-2025 LunarG, Inc.
4-
* Copyright (C) 2015-2024 Google Inc.
1+
/* Copyright (c) 2015-2026 The Khronos Group Inc.
2+
* Copyright (c) 2015-2026 Valve Corporation
3+
* Copyright (c) 2015-2026 LunarG, Inc.
4+
* Copyright (C) 2015-2026 Google Inc.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -360,6 +360,13 @@ bool Device::manual_PreCallValidateCreateImage(VkDevice device, const VkImageCre
360360
"(%s) is Y Chroma Subsampled (has _420 suffix) so the height (%" PRIu32 ") must be a multiple of 2.",
361361
string_VkFormat(image_format), pCreateInfo->extent.height);
362362
}
363+
if (api_version < VK_API_VERSION_1_3 && !enabled_features.ycbcr2plane444Formats) {
364+
if (IsValueIn(image_format, {VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
365+
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM})) {
366+
skip |= LogError("VUID-VkImageCreateInfo-None-12279", device, create_info_loc.dot(Field::format), "is %s.",
367+
string_VkFormat(image_format));
368+
}
369+
}
363370

364371
return skip;
365372
}
@@ -944,6 +951,15 @@ bool Device::ValidateImageViewCreateInfo(const VkImageViewCreateInfo &create_inf
944951
create_info_loc, "VK_EXPORT_METAL_OBJECT_TYPE_METAL_TEXTURE_BIT_EXT", create_info.pNext);
945952
#endif // VK_USE_PLATFORM_METAL_EXT
946953

954+
if (api_version < VK_API_VERSION_1_3 && !enabled_features.ycbcr2plane444Formats) {
955+
if (IsValueIn(create_info.format,
956+
{VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
957+
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM})) {
958+
skip |= LogError("VUID-VkImageViewCreateInfo-None-12280", device, create_info_loc.dot(Field::format), "is %s.",
959+
string_VkFormat(create_info.format));
960+
}
961+
}
962+
947963
return skip;
948964
}
949965

layers/stateless/sl_instance_device.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
/* Copyright (c) 2015-2025 The Khronos Group Inc.
2-
* Copyright (c) 2015-2025 Valve Corporation
3-
* Copyright (c) 2015-2025 LunarG, Inc.
4-
* Copyright (C) 2015-2025 Google Inc.
1+
/* Copyright (c) 2015-2026 The Khronos Group Inc.
2+
* Copyright (c) 2015-2026 Valve Corporation
3+
* Copyright (c) 2015-2026 LunarG, Inc.
4+
* Copyright (C) 2015-2026 Google Inc.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -295,7 +295,7 @@ void Instance::CommonPostCallRecordEnumeratePhysicalDevice(const VkPhysicalDevic
295295
ext_props.resize(ext_count);
296296
DispatchEnumerateDeviceExtensionProperties(phys_device, nullptr, &ext_count, ext_props.data());
297297

298-
DeviceExtensions phys_dev_exts(extensions, phys_dev_props->apiVersion, ext_props);
298+
DeviceExtensions phys_dev_exts(extensions, api_version, ext_props);
299299
physical_device_extensions[phys_device] = std::move(phys_dev_exts);
300300
}
301301
}
@@ -1047,4 +1047,43 @@ bool Instance::manual_PreCallValidateGetPhysicalDeviceProperties2(VkPhysicalDevi
10471047
}
10481048
return skip;
10491049
}
1050+
1051+
bool Instance::ValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
1052+
VkFormatProperties2 *pFormatProperties, const Context &context) const {
1053+
bool skip = false;
1054+
1055+
if (IsValueIn(format, {VK_FORMAT_G8_B8R8_2PLANE_444_UNORM, VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
1056+
VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16, VK_FORMAT_G16_B16R16_2PLANE_444_UNORM})) {
1057+
const auto &exposed_extensions = physical_device_extensions.at(physicalDevice);
1058+
1059+
if (api_version < VK_API_VERSION_1_3 && !exposed_extensions.vk_khr_maintenance5 &&
1060+
!exposed_extensions.vk_ext_ycbcr_2plane_444_formats) {
1061+
const char *vuid = context.error_obj.location.function == Func::vkGetPhysicalDeviceFormatProperties
1062+
? "VUID-vkGetPhysicalDeviceFormatProperties-None-12272"
1063+
: "VUID-vkGetPhysicalDeviceFormatProperties2-None-12273";
1064+
skip |=
1065+
LogError(vuid, physicalDevice, context.error_obj.location.dot(Field::format), "is %s.", string_VkFormat(format));
1066+
}
1067+
}
1068+
1069+
return skip;
1070+
}
1071+
1072+
bool Instance::manual_PreCallValidateGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
1073+
VkFormatProperties *pFormatProperties,
1074+
const Context &context) const {
1075+
if (!pFormatProperties) {
1076+
return false;
1077+
}
1078+
VkFormatProperties2 format_props_2 = vku::InitStructHelper();
1079+
format_props_2.formatProperties = *pFormatProperties;
1080+
return ValidateGetPhysicalDeviceFormatProperties2(physicalDevice, format, &format_props_2, context);
1081+
}
1082+
1083+
bool Instance::manual_PreCallValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
1084+
VkFormatProperties2 *pFormatProperties,
1085+
const Context &context) const {
1086+
return ValidateGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties, context);
1087+
}
1088+
10501089
} // namespace stateless

layers/stateless/stateless_validation.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,15 @@ class Instance : public vvl::base::Instance {
427427
VkSurfaceFormat2KHR *pSurfaceFormats,
428428
const Context &context) const;
429429

430+
bool ValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
431+
VkFormatProperties2 *pFormatProperties, const Context &context) const;
432+
bool manual_PreCallValidateGetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format,
433+
VkFormatProperties *pFormatProperties,
434+
const Context &context) const;
435+
bool manual_PreCallValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
436+
VkFormatProperties2 *pFormatProperties,
437+
const Context &context) const;
438+
430439
#include "generated/stateless_instance_methods.h"
431440
};
432441

layers/vulkan/generated/stateless_validation_helper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7901,6 +7901,7 @@ bool Instance::PreCallValidateGetPhysicalDeviceFormatProperties(VkPhysicalDevice
79017901
"VUID-vkGetPhysicalDeviceFormatProperties-format-parameter");
79027902
skip |= context.ValidateRequiredPointer(loc.dot(Field::pFormatProperties), pFormatProperties,
79037903
"VUID-vkGetPhysicalDeviceFormatProperties-pFormatProperties-parameter");
7904+
if (!skip) skip |= manual_PreCallValidateGetPhysicalDeviceFormatProperties(physicalDevice, format, pFormatProperties, context);
79047905
return skip;
79057906
}
79067907

@@ -11564,6 +11565,7 @@ bool Instance::PreCallValidateGetPhysicalDeviceFormatProperties2(VkPhysicalDevic
1156411565
allowed_structs_VkFormatProperties2.data(), GeneratedVulkanHeaderVersion,
1156511566
"VUID-VkFormatProperties2-pNext-pNext", "VUID-VkFormatProperties2-sType-unique", false);
1156611567
}
11568+
if (!skip) skip |= manual_PreCallValidateGetPhysicalDeviceFormatProperties2(physicalDevice, format, pFormatProperties, context);
1156711569
return skip;
1156811570
}
1156911571

scripts/generators/stateless_validation_helper_generator.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ def __init__(self,
231231
'vkGetCalibratedTimestampsKHR',
232232
'vkGetDynamicRenderingTilePropertiesQCOM',
233233
'vkGetSwapchainTimeDomainPropertiesEXT',
234+
'vkGetPhysicalDeviceFormatProperties',
235+
'vkGetPhysicalDeviceFormatProperties2',
234236
]
235237

236238
# Commands to ignore

tests/framework/video_objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3150,6 +3150,7 @@ class VkVideoLayerTest : public VkLayerTest {
31503150
// NOTE: this appears to be required for the format that is chosen in
31513151
// VkVideoLayerTest.BeginCodingIncompatRefPicProfile
31523152
AddOptionalExtensions(VK_EXT_YCBCR_2PLANE_444_FORMATS_EXTENSION_NAME);
3153+
AddOptionalFeature(vkt::Feature::ycbcr2plane444Formats);
31533154

31543155
AddOptionalExtensions(VK_KHR_VIDEO_DECODE_H264_EXTENSION_NAME);
31553156
AddOptionalExtensions(VK_KHR_VIDEO_DECODE_H265_EXTENSION_NAME);

tests/unit/buffer.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
2-
* Copyright (c) 2015-2025 The Khronos Group Inc.
3-
* Copyright (c) 2015-2025 Valve Corporation
4-
* Copyright (c) 2015-2025 LunarG, Inc.
5-
* Copyright (c) 2015-2025 Google, Inc.
2+
* Copyright (c) 2015-2026 The Khronos Group Inc.
3+
* Copyright (c) 2015-2026 Valve Corporation
4+
* Copyright (c) 2015-2026 LunarG, Inc.
5+
* Copyright (c) 2015-2026 Google, Inc.
66
* Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
77
*
88
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -200,6 +200,22 @@ TEST_F(NegativeBuffer, BufferViewCreateInfoEntries) {
200200
CreateBufferViewTest(buff_view_ci, "VUID-VkBufferViewCreateInfo-offset-00931");
201201
}
202202

203+
TEST_F(NegativeBuffer, BufferViewYcbCr2Plane) {
204+
TEST_DESCRIPTION("Attempt to create a buffer view with invalid create info.");
205+
RETURN_IF_SKIP(Init());
206+
207+
vkt::Buffer buffer(*m_device, 4096, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT);
208+
VkBufferViewCreateInfo buff_view_ci = vku::InitStructHelper();
209+
buff_view_ci.buffer = buffer;
210+
buff_view_ci.offset = 0;
211+
buff_view_ci.format = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM;
212+
buff_view_ci.range = VK_WHOLE_SIZE;
213+
m_errorMonitor->SetAllowedFailureMsg("VUID-VkBufferViewCreateInfo-format-parameter");
214+
m_errorMonitor->SetDesiredError("VUID-VkBufferViewCreateInfo-None-12278");
215+
vkt::BufferView view(*m_device, buff_view_ci);
216+
m_errorMonitor->VerifyFound();
217+
}
218+
203219
TEST_F(NegativeBuffer, BufferViewCreateInfoFeatures) {
204220
TEST_DESCRIPTION("Attempt to create a buffer view with invalid create info.");
205221
RETURN_IF_SKIP(Init());

tests/unit/descriptor_buffer.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/*
2-
* Copyright (c) 2015-2025 The Khronos Group Inc.
3-
* Copyright (c) 2015-2025 Valve Corporation
4-
* Copyright (c) 2015-2025 LunarG, Inc.
5-
* Copyright (c) 2015-2025 Google, Inc.
2+
* Copyright (c) 2015-2026 The Khronos Group Inc.
3+
* Copyright (c) 2015-2026 Valve Corporation
4+
* Copyright (c) 2015-2026 LunarG, Inc.
5+
* Copyright (c) 2015-2026 Google, Inc.
66
* Modifications Copyright (C) 2020-2022 Advanced Micro Devices, Inc. All rights reserved.
77
* Modifications Copyright (C) 2021 ARM, Inc. All rights reserved.
88
*
@@ -1912,6 +1912,29 @@ TEST_F(NegativeDescriptorBuffer, TexelBufferFormat) {
19121912
m_errorMonitor->VerifyFound();
19131913
}
19141914

1915+
TEST_F(NegativeDescriptorBuffer, TexelBufferFormat2) {
1916+
RETURN_IF_SKIP(InitBasicDescriptorBuffer());
1917+
1918+
vkt::Buffer buffer(*m_device, 4096,
1919+
VK_BUFFER_USAGE_RESOURCE_DESCRIPTOR_BUFFER_BIT_EXT | VK_BUFFER_USAGE_SAMPLER_DESCRIPTOR_BUFFER_BIT_EXT,
1920+
vkt::device_address);
1921+
1922+
VkDescriptorAddressInfoEXT dai = vku::InitStructHelper();
1923+
dai.address = buffer.Address();
1924+
dai.range = 4;
1925+
dai.format = VK_FORMAT_G16_B16R16_2PLANE_444_UNORM;
1926+
1927+
VkDescriptorGetInfoEXT dgi = vku::InitStructHelper();
1928+
dgi.type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
1929+
dgi.data.pUniformTexelBuffer = &dai;
1930+
1931+
uint8_t out;
1932+
m_errorMonitor->SetDesiredError("VUID-VkDescriptorAddressInfoEXT-format-parameter");
1933+
m_errorMonitor->SetDesiredError("VUID-VkDescriptorAddressInfoEXT-None-12271");
1934+
vk::GetDescriptorEXT(device(), &dgi, descriptor_buffer_properties.uniformTexelBufferDescriptorSize, &out);
1935+
m_errorMonitor->VerifyFound();
1936+
}
1937+
19151938
TEST_F(NegativeDescriptorBuffer, MaxResourceDescriptorBufferBindings) {
19161939
RETURN_IF_SKIP(InitBasicDescriptorBuffer());
19171940

0 commit comments

Comments
 (0)