Add YCbCr sampler validation VUID-VkSamplerCreateInfo-addressModeU-01646 enforces constraints on address mode and anisotropy being disabled for YCbCr samplers. Enforce those constraints in dawn validation and when creating VkSampler. Bug: 513006636 Change-Id: I608a29e7e468bc06baae3fed45192bc5ad9144b0 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/309015 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Brandon Jones <bajones@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn/native/Sampler.cpp b/src/dawn/native/Sampler.cpp index e9509e4..706ef42 100644 --- a/src/dawn/native/Sampler.cpp +++ b/src/dawn/native/Sampler.cpp
@@ -77,6 +77,17 @@ DAWN_INVALID_IF(ycbcr->externalFormat == 0 && ycbcr->vkFormat == 0, "Both VkFormat and VkExternalFormatANDROID are undefined."); + + DAWN_INVALID_IF(descriptor->addressModeU != wgpu::AddressMode::ClampToEdge, + "addressModeU must be ClampToEdge for YCbCr samplers."); + DAWN_INVALID_IF(descriptor->addressModeV != wgpu::AddressMode::ClampToEdge, + "addressModeV must be ClampToEdge for YCbCr samplers."); + DAWN_INVALID_IF(descriptor->addressModeW != wgpu::AddressMode::ClampToEdge, + "addressModeW must be ClampToEdge for YCbCr samplers."); + + DAWN_INVALID_IF(descriptor->maxAnisotropy > 1, + "maxAnisotropy (%d) must be 1 for YCbCr samplers.", + descriptor->maxAnisotropy); } return {};
diff --git a/src/dawn/native/vulkan/SamplerVk.cpp b/src/dawn/native/vulkan/SamplerVk.cpp index 11a97d4..439a41f 100644 --- a/src/dawn/native/vulkan/SamplerVk.cpp +++ b/src/dawn/native/vulkan/SamplerVk.cpp
@@ -144,6 +144,13 @@ samplerYCbCrInfo.conversion = mSamplerYCbCrConversion; createInfo.pNext = &samplerYCbCrInfo; + + // VUID-VkSamplerCreateInfo-addressModeU-01646 requires CLAMP_TO_EDGE on every axis and + // anisotropy disabled when VkSamplerYcbcrConversionInfo is provided. + createInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + createInfo.anisotropyEnable = VK_FALSE; } DAWN_TRY(CheckVkSuccess(
diff --git a/src/dawn/tests/unittests/validation/YCbCrValidationTests.cpp b/src/dawn/tests/unittests/validation/YCbCrValidationTests.cpp index ab47124..58075fe 100644 --- a/src/dawn/tests/unittests/validation/YCbCrValidationTests.cpp +++ b/src/dawn/tests/unittests/validation/YCbCrValidationTests.cpp
@@ -127,6 +127,41 @@ device.CreateSampler(&samplerDesc); } +// Test that creating a YCbCr sampler with address mode or max anisotropy set to something invalid +// fails. +TEST_F(YCbCrVulkanSamplersTest, YCbCrSamplerRequiredParams) { + wgpu::SamplerDescriptor samplerDesc = {}; + wgpu::YCbCrVkDescriptor yCbCrDesc = {}; + yCbCrDesc.vkFormat = VK_FORMAT_R8G8B8A8_UNORM; + samplerDesc.nextInChain = &yCbCrDesc; + + // This should work. + device.CreateSampler(&samplerDesc); + + { + wgpu::SamplerDescriptor invalidSamplerDesc = samplerDesc; + invalidSamplerDesc.addressModeU = wgpu::AddressMode::Repeat; + ASSERT_DEVICE_ERROR(device.CreateSampler(&invalidSamplerDesc)); + } + + { + wgpu::SamplerDescriptor invalidSamplerDesc = samplerDesc; + invalidSamplerDesc.addressModeV = wgpu::AddressMode::Repeat; + ASSERT_DEVICE_ERROR(device.CreateSampler(&invalidSamplerDesc)); + } + + { + wgpu::SamplerDescriptor invalidSamplerDesc = samplerDesc; + invalidSamplerDesc.addressModeW = wgpu::AddressMode::Repeat; + ASSERT_DEVICE_ERROR(device.CreateSampler(&invalidSamplerDesc)); + } + { + wgpu::SamplerDescriptor invalidSamplerDesc = samplerDesc; + invalidSamplerDesc.maxAnisotropy = 2; + ASSERT_DEVICE_ERROR(device.CreateSampler(&invalidSamplerDesc)); + } +} + // Test that only OpaqueYCbCrAndroid textures can be used to create YCbCr views. TEST_F(YCbCrVulkanSamplersTest, YCbCrTextureViewRequiresOpaqueYCbCrAndroid) { wgpu::TextureViewDescriptor viewDesc{};