diff --git a/third_party/dawn/src/dawn/native/Sampler.cpp b/third_party/dawn/src/dawn/native/Sampler.cpp index e9509e47722..744a361fe61 100644 --- a/third_party/dawn/src/dawn/native/Sampler.cpp +++ b/third_party/dawn/src/dawn/native/Sampler.cpp @@ -77,6 +77,16 @@ MaybeError ValidateSamplerDescriptor(DeviceBase* device, const SamplerDescriptor DAWN_INVALID_IF(ycbcr->externalFormat == 0 && ycbcr->vkFormat == 0, "Both VkFormat and VkExternalFormatANDROID are undefined."); + + // VUID-VkSamplerCreateInfo-addressModeU-01646: when a YCbCr conversion + // is attached, addressModeU/V/W must be CLAMP_TO_EDGE. Reject anything + // else here so renderer-supplied tile modes cannot drive vkCreateSampler + // into spec-undefined behaviour in the GPU process. + DAWN_INVALID_IF(descriptor->addressModeU != wgpu::AddressMode::ClampToEdge || + descriptor->addressModeV != wgpu::AddressMode::ClampToEdge || + descriptor->addressModeW != wgpu::AddressMode::ClampToEdge, + "addressModeU/V/W must be ClampToEdge when a YCbCrVkDescriptor " + "is chained (VUID-VkSamplerCreateInfo-addressModeU-01646)."); } return {}; diff --git a/third_party/dawn/src/dawn/native/vulkan/SamplerVk.cpp b/third_party/dawn/src/dawn/native/vulkan/SamplerVk.cpp index 11a97d4e56c..eb1c29cc686 100644 --- a/third_party/dawn/src/dawn/native/vulkan/SamplerVk.cpp +++ b/third_party/dawn/src/dawn/native/vulkan/SamplerVk.cpp @@ -143,6 +143,16 @@ MaybeError Sampler::Initialize(const SamplerDescriptor* descriptor) { samplerYCbCrInfo.pNext = nullptr; samplerYCbCrInfo.conversion = mSamplerYCbCrConversion; + // VUID-VkSamplerCreateInfo-addressModeU-01646 requires CLAMP_TO_EDGE on + // every axis when a YCbCr conversion is enabled. This mirrors the + // safeguard Ganesh applies (skia/src/gpu/ganesh/vk/GrVkSampler.cpp) and + // is a backstop for callers that reach here with validation skipped + // (e.g. StaticSamplerSpecialization::Create above). + 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; + createInfo.unnormalizedCoordinates = VK_FALSE; createInfo.pNext = &samplerYCbCrInfo; } diff --git a/third_party/skia/src/gpu/graphite/dawn/DawnSampler.cpp b/third_party/skia/src/gpu/graphite/dawn/DawnSampler.cpp index 19b8f0a0ae6..1e954ee2695 100644 --- a/third_party/skia/src/gpu/graphite/dawn/DawnSampler.cpp +++ b/third_party/skia/src/gpu/graphite/dawn/DawnSampler.cpp @@ -93,6 +93,12 @@ sk_sp DawnSampler::Make(const DawnSharedContext* sharedContext, if (samplerDesc.isImmutable()) { ycbcrDescriptor = DawnDescriptorFromImmutableSamplerInfo(samplerDesc.immutableSamplerInfo()); + // Required values when using a YCbCr conversion + // (VUID-VkSamplerCreateInfo-addressModeU-01646). Matches the override + // applied by Ganesh's GrVkSampler::Create. + desc.addressModeU = wgpu::AddressMode::ClampToEdge; + desc.addressModeV = wgpu::AddressMode::ClampToEdge; + desc.addressModeW = wgpu::AddressMode::ClampToEdge; desc.nextInChain = &ycbcrDescriptor; } #endif