Add Validation For External Texture Bind Group Layout Mismatch

Adds validation to ensure that external texture binding entries match
the bind group layout. This should fix an issue found by the fuzzer.

Bug: dawn:1082
Bug: chromium:1296935
Change-Id: I1cc542ed9105dbe29d775e01e52475a7d6c8d393
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/80460
Reviewed-by: Loko Kung <lokokung@google.com>
Auto-Submit: Brandon1 Jones <brandon1.jones@intel.com>
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Brandon Jones 2022-02-17 19:20:31 +00:00 committed by Dawn LUCI CQ
parent 0e5c0dc27a
commit df70004c52
2 changed files with 36 additions and 3 deletions

View File

@ -243,7 +243,8 @@ namespace dawn::native {
MaybeError ValidateExternalTextureBinding( MaybeError ValidateExternalTextureBinding(
const DeviceBase* device, const DeviceBase* device,
const BindGroupEntry& entry, const BindGroupEntry& entry,
const ExternalTextureBindingEntry* externalTextureBindingEntry) { const ExternalTextureBindingEntry* externalTextureBindingEntry,
const ExternalTextureBindingExpansionMap& expansions) {
DAWN_INVALID_IF(externalTextureBindingEntry == nullptr, DAWN_INVALID_IF(externalTextureBindingEntry == nullptr,
"Binding entry external texture not set."); "Binding entry external texture not set.");
@ -251,6 +252,11 @@ namespace dawn::native {
entry.sampler != nullptr || entry.textureView != nullptr || entry.buffer != nullptr, entry.sampler != nullptr || entry.textureView != nullptr || entry.buffer != nullptr,
"Expected only external texture to be set for binding entry."); "Expected only external texture to be set for binding entry.");
DAWN_INVALID_IF(
expansions.find(BindingNumber(entry.binding)) == expansions.end(),
"External texture binding entry %u is not present in the bind group layout.",
entry.binding);
DAWN_TRY(ValidateSingleSType(externalTextureBindingEntry->nextInChain, DAWN_TRY(ValidateSingleSType(externalTextureBindingEntry->nextInChain,
wgpu::SType::ExternalTextureBindingEntry)); wgpu::SType::ExternalTextureBindingEntry));
@ -306,8 +312,9 @@ namespace dawn::native {
const ExternalTextureBindingEntry* externalTextureBindingEntry = nullptr; const ExternalTextureBindingEntry* externalTextureBindingEntry = nullptr;
FindInChain(entry.nextInChain, &externalTextureBindingEntry); FindInChain(entry.nextInChain, &externalTextureBindingEntry);
if (externalTextureBindingEntry != nullptr) { if (externalTextureBindingEntry != nullptr) {
DAWN_TRY( DAWN_TRY(ValidateExternalTextureBinding(
ValidateExternalTextureBinding(device, entry, externalTextureBindingEntry)); device, entry, externalTextureBindingEntry,
descriptor->layout->GetExternalTextureBindingExpansionMap()));
continue; continue;
} }

View File

@ -456,4 +456,30 @@ namespace {
ASSERT_DEVICE_ERROR(queue.Submit(1, &commands)); ASSERT_DEVICE_ERROR(queue.Submit(1, &commands));
} }
} }
// Ensure that bind group validation catches external textures mimatched from the BGL.
TEST_F(ExternalTextureTest, BindGroupDoesNotMatchLayout) {
wgpu::TextureDescriptor textureDescriptor = CreateTextureDescriptor();
wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
wgpu::ExternalTextureDescriptor externalDesc;
externalDesc.plane0 = texture.CreateView();
wgpu::ExternalTexture externalTexture = device.CreateExternalTexture(&externalDesc);
// Control case should succeed.
{
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, &utils::kExternalTextureBindingLayout}});
utils::MakeBindGroup(device, bgl, {{0, externalTexture}});
}
// Bind group creation should fail when an external texture is not present in the
// corresponding slot of the bind group layout.
{
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BufferBindingType::Uniform}});
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl, {{0, externalTexture}}));
}
}
} // namespace } // namespace