[YCbCr Samplers] Add some more validations for ExternalFormat

Address some validation follow-ups from adding TextureFormat::External
[1]. This makes it a warning log for externalFormat and checks that
texture with ExternalFormat is initialized.

[1] https://dawn-review.googlesource.com/c/dawn/+/187361

Bug: dawn:2476
Change-Id: I3315a4d7a87d2dc37d364d74085a18a424c0f709
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/191240
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Saifuddin Hitawala <hitawala@chromium.org>
diff --git a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
index 732806a..144dca3 100644
--- a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
+++ b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
@@ -543,7 +543,9 @@
         // TODO(crbug.com/dawn/2476): Validate more as per
         // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkImageCreateInfo.html
         if (useExternalFormat) {
-            DAWN_ASSERT(bufferFormatProperties.externalFormat != 0);
+            DAWN_INVALID_IF(
+                bufferFormatProperties.externalFormat == 0,
+                "AHardwareBuffer with external sampler must have non-zero external format.");
             vkFormat = VK_FORMAT_UNDEFINED;
             externalFormatAndroid.externalFormat = bufferFormatProperties.externalFormat;
             properties.format = wgpu::TextureFormat::External;
@@ -999,8 +1001,10 @@
     TextureBase* texture,
     const UnpackedPtr<BeginAccessDescriptor>& descriptor) {
     // TODO(dawn/2276): support concurrent read access.
-    // TODO(dawn/2476): Validate texture with TextureFormat::External is initialized.
     DAWN_INVALID_IF(descriptor->concurrentRead, "Vulkan backend doesn't support concurrent read.");
+    DAWN_INVALID_IF(
+        texture->GetFormat().format == wgpu::TextureFormat::External && !descriptor->initialized,
+        "BeginAccess with Texture format (%s) must be initialized", texture->GetFormat().format);
 
     wgpu::SType type;
     DAWN_TRY_ASSIGN(
diff --git a/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp b/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
index d24cc0a..93e146f 100644
--- a/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
+++ b/src/dawn/tests/white_box/SharedTextureMemoryTests_android.cpp
@@ -560,6 +560,47 @@
     EXPECT_EQ(bufferFormatProperties.externalFormat, yCbCrInfo.externalFormat);
 }
 
+// Test BeginAccess on an uninitialized texture with external format fails.
+TEST_P(SharedTextureMemoryTests, GPUReadForUninitializedTextureWithExternalFormatFails) {
+    const AHardwareBuffer_Desc aHardwareBufferDesc = {
+        .width = 4,
+        .height = 4,
+        .layers = 1,
+        .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+        .usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
+    };
+    AHardwareBuffer* aHardwareBuffer;
+    EXPECT_EQ(AHardwareBuffer_allocate(&aHardwareBufferDesc, &aHardwareBuffer), 0);
+
+    wgpu::SharedTextureMemoryAHardwareBufferDescriptor stmAHardwareBufferDesc;
+    stmAHardwareBufferDesc.handle = aHardwareBuffer;
+    stmAHardwareBufferDesc.useExternalFormat = true;
+
+    wgpu::SharedTextureMemoryDescriptor desc;
+    desc.nextInChain = &stmAHardwareBufferDesc;
+
+    const wgpu::SharedTextureMemory memory = device.ImportSharedTextureMemory(&desc);
+
+    wgpu::TextureDescriptor descriptor;
+    descriptor.dimension = wgpu::TextureDimension::e2D;
+    descriptor.size.width = 4;
+    descriptor.size.height = 4;
+    descriptor.size.depthOrArrayLayers = 1u;
+    descriptor.sampleCount = 1u;
+    descriptor.format = wgpu::TextureFormat::External;
+    descriptor.mipLevelCount = 1u;
+    descriptor.usage = wgpu::TextureUsage::TextureBinding;
+    auto texture = memory.CreateTexture(&descriptor);
+    AHardwareBuffer_release(aHardwareBuffer);
+
+    wgpu::SharedTextureMemoryBeginAccessDescriptor beginDesc = {};
+    beginDesc.initialized = false;
+    wgpu::SharedTextureMemoryVkImageLayoutBeginState beginLayout{};
+    beginDesc.nextInChain = &beginLayout;
+
+    ASSERT_DEVICE_ERROR(memory.BeginAccess(texture, &beginDesc));
+}
+
 DAWN_INSTANTIATE_PREFIXED_TEST_P(Vulkan,
                                  SharedTextureMemoryNoFeatureTests,
                                  {VulkanBackend()},