Simplify the BindGroupLayout validation code.
It was using a lot of calls to helper functions full of switches that were hiding the logic that's relatively simple. Bug: dawn:527 Change-Id: Iaf2603efa255df5ba2f44989b5375d433f04d5df Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28561 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
aeda49ba50
commit
5b4e5fbe1f
|
@ -26,163 +26,38 @@
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
MaybeError ValidateBindingTypeWithShaderStageVisibility(
|
namespace {
|
||||||
wgpu::BindingType bindingType,
|
MaybeError ValidateStorageTextureFormat(DeviceBase* device,
|
||||||
wgpu::ShaderStage shaderStageVisibility) {
|
wgpu::TextureFormat storageTextureFormat) {
|
||||||
// TODO(jiawei.shao@intel.com): support read-write storage textures.
|
const Format* format = nullptr;
|
||||||
switch (bindingType) {
|
DAWN_TRY_ASSIGN(format, device->GetInternalFormat(storageTextureFormat));
|
||||||
case wgpu::BindingType::StorageBuffer: {
|
|
||||||
if ((shaderStageVisibility & wgpu::ShaderStage::Vertex) != 0) {
|
ASSERT(format != nullptr);
|
||||||
|
if (!format->supportsStorageUsage) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Texture format does not support storage textures");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
MaybeError ValidateStorageTextureViewDimension(wgpu::TextureViewDimension dimension) {
|
||||||
|
switch (dimension) {
|
||||||
|
case wgpu::TextureViewDimension::Cube:
|
||||||
|
case wgpu::TextureViewDimension::CubeArray:
|
||||||
return DAWN_VALIDATION_ERROR(
|
return DAWN_VALIDATION_ERROR(
|
||||||
"storage buffer binding is not supported in vertex shader");
|
"Cube map and cube map texture views cannot be used as storage textures");
|
||||||
}
|
|
||||||
break;
|
case wgpu::TextureViewDimension::e1D:
|
||||||
|
case wgpu::TextureViewDimension::e2D:
|
||||||
|
case wgpu::TextureViewDimension::e2DArray:
|
||||||
|
case wgpu::TextureViewDimension::e3D:
|
||||||
|
return {};
|
||||||
|
|
||||||
|
case wgpu::TextureViewDimension::Undefined:
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
|
||||||
if ((shaderStageVisibility & wgpu::ShaderStage::Vertex) != 0) {
|
|
||||||
return DAWN_VALIDATION_ERROR(
|
|
||||||
"write-only storage texture binding is not supported in vertex shader");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case wgpu::BindingType::UniformBuffer:
|
|
||||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
|
||||||
case wgpu::BindingType::Sampler:
|
|
||||||
case wgpu::BindingType::ComparisonSampler:
|
|
||||||
case wgpu::BindingType::SampledTexture:
|
|
||||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
} // anonymous namespace
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeError ValidateStorageTextureFormat(DeviceBase* device,
|
|
||||||
wgpu::BindingType bindingType,
|
|
||||||
wgpu::TextureFormat storageTextureFormat) {
|
|
||||||
switch (bindingType) {
|
|
||||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
||||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
|
||||||
if (storageTextureFormat == wgpu::TextureFormat::Undefined) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Storage texture format is missing");
|
|
||||||
}
|
|
||||||
DAWN_TRY(ValidateTextureFormat(storageTextureFormat));
|
|
||||||
|
|
||||||
const Format* format = nullptr;
|
|
||||||
DAWN_TRY_ASSIGN(format, device->GetInternalFormat(storageTextureFormat));
|
|
||||||
ASSERT(format != nullptr);
|
|
||||||
if (!format->supportsStorageUsage) {
|
|
||||||
return DAWN_VALIDATION_ERROR("The storage texture format is not supported");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case wgpu::BindingType::StorageBuffer:
|
|
||||||
case wgpu::BindingType::UniformBuffer:
|
|
||||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
|
||||||
case wgpu::BindingType::Sampler:
|
|
||||||
case wgpu::BindingType::ComparisonSampler:
|
|
||||||
case wgpu::BindingType::SampledTexture:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeError ValidateStorageTextureViewDimension(wgpu::BindingType bindingType,
|
|
||||||
wgpu::TextureViewDimension dimension) {
|
|
||||||
switch (bindingType) {
|
|
||||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
||||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case wgpu::BindingType::StorageBuffer:
|
|
||||||
case wgpu::BindingType::UniformBuffer:
|
|
||||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
|
||||||
case wgpu::BindingType::Sampler:
|
|
||||||
case wgpu::BindingType::ComparisonSampler:
|
|
||||||
case wgpu::BindingType::SampledTexture:
|
|
||||||
return {};
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (dimension) {
|
|
||||||
case wgpu::TextureViewDimension::Cube:
|
|
||||||
case wgpu::TextureViewDimension::CubeArray:
|
|
||||||
return DAWN_VALIDATION_ERROR(
|
|
||||||
"Cube map and cube map texture views cannot be used as storage textures");
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::e1D:
|
|
||||||
case wgpu::TextureViewDimension::e2D:
|
|
||||||
case wgpu::TextureViewDimension::e2DArray:
|
|
||||||
case wgpu::TextureViewDimension::e3D:
|
|
||||||
return {};
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::Undefined:
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeError ValidateBindingCanBeMultisampled(wgpu::BindingType bindingType,
|
|
||||||
wgpu::TextureViewDimension viewDimension) {
|
|
||||||
switch (bindingType) {
|
|
||||||
case wgpu::BindingType::SampledTexture:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
||||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
|
||||||
return DAWN_VALIDATION_ERROR("Storage texture bindings may not be multisampled");
|
|
||||||
|
|
||||||
case wgpu::BindingType::StorageBuffer:
|
|
||||||
case wgpu::BindingType::UniformBuffer:
|
|
||||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
|
||||||
return DAWN_VALIDATION_ERROR("Buffer bindings may not be multisampled");
|
|
||||||
|
|
||||||
case wgpu::BindingType::Sampler:
|
|
||||||
case wgpu::BindingType::ComparisonSampler:
|
|
||||||
return DAWN_VALIDATION_ERROR("Sampler bindings may not be multisampled");
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (viewDimension) {
|
|
||||||
case wgpu::TextureViewDimension::e2D:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::e2DArray:
|
|
||||||
return DAWN_VALIDATION_ERROR("2D array texture bindings may not be multisampled");
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::Cube:
|
|
||||||
case wgpu::TextureViewDimension::CubeArray:
|
|
||||||
return DAWN_VALIDATION_ERROR("Cube texture bindings may not be multisampled");
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::e3D:
|
|
||||||
return DAWN_VALIDATION_ERROR("3D texture bindings may not be multisampled");
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::e1D:
|
|
||||||
return DAWN_VALIDATION_ERROR("1D texture bindings may not be multisampled");
|
|
||||||
|
|
||||||
case wgpu::TextureViewDimension::Undefined:
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase* device,
|
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase* device,
|
||||||
const BindGroupLayoutDescriptor* descriptor) {
|
const BindGroupLayoutDescriptor* descriptor) {
|
||||||
|
@ -210,43 +85,53 @@ namespace dawn_native {
|
||||||
return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
|
return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_TRY(ValidateBindingTypeWithShaderStageVisibility(entry.type, entry.visibility));
|
bool canBeDynamic = false;
|
||||||
|
bool canBeMultisampled = false;
|
||||||
DAWN_TRY(ValidateStorageTextureFormat(device, entry.type, entry.storageTextureFormat));
|
wgpu::ShaderStage allowedStages = kAllStages;
|
||||||
|
|
||||||
DAWN_TRY(ValidateStorageTextureViewDimension(entry.type, viewDimension));
|
|
||||||
|
|
||||||
if (entry.multisampled) {
|
|
||||||
DAWN_TRY(ValidateBindingCanBeMultisampled(entry.type, viewDimension));
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (entry.type) {
|
switch (entry.type) {
|
||||||
case wgpu::BindingType::UniformBuffer:
|
|
||||||
case wgpu::BindingType::StorageBuffer:
|
case wgpu::BindingType::StorageBuffer:
|
||||||
|
allowedStages &= ~wgpu::ShaderStage::Vertex;
|
||||||
|
DAWN_FALLTHROUGH;
|
||||||
|
case wgpu::BindingType::UniformBuffer:
|
||||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||||
|
canBeDynamic = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case wgpu::BindingType::SampledTexture:
|
case wgpu::BindingType::SampledTexture:
|
||||||
if (entry.hasDynamicOffset) {
|
canBeMultisampled = true;
|
||||||
return DAWN_VALIDATION_ERROR("Sampled textures cannot be dynamic");
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||||
|
allowedStages &= ~wgpu::ShaderStage::Vertex;
|
||||||
|
DAWN_FALLTHROUGH;
|
||||||
|
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||||
|
DAWN_TRY(ValidateStorageTextureFormat(device, entry.storageTextureFormat));
|
||||||
|
DAWN_TRY(ValidateStorageTextureViewDimension(viewDimension));
|
||||||
|
break;
|
||||||
|
|
||||||
case wgpu::BindingType::Sampler:
|
case wgpu::BindingType::Sampler:
|
||||||
case wgpu::BindingType::ComparisonSampler:
|
case wgpu::BindingType::ComparisonSampler:
|
||||||
if (entry.hasDynamicOffset) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Samplers cannot be dynamic");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
|
||||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
|
||||||
if (entry.hasDynamicOffset) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Storage textures cannot be dynamic");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entry.multisampled) {
|
||||||
|
if (!canBeMultisampled) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Binding type cannot be multisampled.");
|
||||||
|
}
|
||||||
|
if (viewDimension != wgpu::TextureViewDimension::e2D) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Multisampled binding must be 2D.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.hasDynamicOffset && !canBeDynamic) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Binding type cannot be dynamic.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((entry.visibility & allowedStages) != entry.visibility) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Binding type cannot be used with this visibility.");
|
||||||
|
}
|
||||||
|
|
||||||
IncrementBindingCounts(&bindingCounts, entry);
|
IncrementBindingCounts(&bindingCounts, entry);
|
||||||
|
|
||||||
bindingsSet.insert(bindingNumber);
|
bindingsSet.insert(bindingNumber);
|
||||||
|
|
Loading…
Reference in New Issue