mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 02:39:11 +00:00
Updating BindGroupLayoutEntry interface to match latest spec
Updates BindGroupLayoutEntry to allow for the newly split-up descriptors that define each binding type in it's own member (buffer, texture, etc.) The previous style of descriptor is still supported but is deprecated. For the sake of keeping the scope reasonable, this change does not alter the BindingInfo structure that's used internally by the various backends. That will come as a followup. Bug: dawn:527 Change-Id: I2f301f5f36fa2ce7ff15126ac90dc4c19d5e32ca Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/34921 Commit-Queue: Brandon Jones <bajones@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
ed883bc1d9
commit
9c52c2997c
@@ -240,6 +240,9 @@ namespace dawn_native {
|
||||
DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Storage,
|
||||
false, bindingInfo));
|
||||
break;
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -71,75 +71,169 @@ namespace dawn_native {
|
||||
const BindGroupLayoutEntry& entry = descriptor->entries[i];
|
||||
BindingNumber bindingNumber = BindingNumber(entry.binding);
|
||||
|
||||
DAWN_TRY(ValidateShaderStage(entry.visibility));
|
||||
DAWN_TRY(ValidateBindingType(entry.type));
|
||||
DAWN_TRY(ValidateTextureComponentType(entry.textureComponentType));
|
||||
|
||||
wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
if (entry.viewDimension != wgpu::TextureViewDimension::Undefined) {
|
||||
DAWN_TRY(ValidateTextureViewDimension(entry.viewDimension));
|
||||
viewDimension = entry.viewDimension;
|
||||
}
|
||||
|
||||
if (bindingsSet.count(bindingNumber) != 0) {
|
||||
return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
|
||||
}
|
||||
|
||||
bool canBeDynamic = false;
|
||||
DAWN_TRY(ValidateShaderStage(entry.visibility));
|
||||
|
||||
int bindingMemberCount = 0;
|
||||
wgpu::ShaderStage allowedStages = kAllStages;
|
||||
|
||||
switch (entry.type) {
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
if (entry.buffer.type != wgpu::BufferBindingType::Undefined) {
|
||||
bindingMemberCount++;
|
||||
const BufferBindingLayout& buffer = entry.buffer;
|
||||
DAWN_TRY(ValidateBufferBindingType(buffer.type));
|
||||
|
||||
// TODO(dawn:527): ReadOnlyStorage should have the same limits as Storage
|
||||
// regarding use with Vertex shaders.
|
||||
if (buffer.type == wgpu::BufferBindingType::Storage) {
|
||||
allowedStages &= ~wgpu::ShaderStage::Vertex;
|
||||
DAWN_FALLTHROUGH;
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
canBeDynamic = true;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::MultisampledTexture:
|
||||
if (viewDimension != wgpu::TextureViewDimension::e2D) {
|
||||
return DAWN_VALIDATION_ERROR("Multisampled binding must be 2D.");
|
||||
}
|
||||
if (entry.textureComponentType == wgpu::TextureComponentType::DepthComparison) {
|
||||
// Dynamic storage buffers aren't bounds checked properly in D3D12. Disallow
|
||||
// them as unsafe until the bounds checks are implemented.
|
||||
if (device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs) &&
|
||||
buffer.hasDynamicOffset) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Multisampled binding must not be DepthComparison.");
|
||||
"Dynamic storage buffers are disallowed because they aren't secure "
|
||||
"yet. See https://crbug.com/dawn/429");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry.sampler.type != wgpu::SamplerBindingType::Undefined) {
|
||||
bindingMemberCount++;
|
||||
DAWN_TRY(ValidateSamplerBindingType(entry.sampler.type));
|
||||
}
|
||||
if (entry.texture.sampleType != wgpu::TextureSampleType::Undefined) {
|
||||
bindingMemberCount++;
|
||||
const TextureBindingLayout& texture = entry.texture;
|
||||
DAWN_TRY(ValidateTextureSampleType(texture.sampleType));
|
||||
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
// viewDimension defaults to 2D if left undefined, needs validation otherwise.
|
||||
wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
if (texture.viewDimension != wgpu::TextureViewDimension::Undefined) {
|
||||
DAWN_TRY(ValidateTextureViewDimension(texture.viewDimension));
|
||||
viewDimension = texture.viewDimension;
|
||||
}
|
||||
|
||||
if (texture.multisampled) {
|
||||
if (viewDimension != wgpu::TextureViewDimension::e2D) {
|
||||
return DAWN_VALIDATION_ERROR("Multisampled texture bindings must be 2D.");
|
||||
}
|
||||
// TODO: This check should eventually become obsolete. According to the spec,
|
||||
// depth can be used with both regular and comparison sampling. As such, during
|
||||
// pipeline creation we have to check that if a comparison sampler is used
|
||||
// with a texture, that texture must be both depth and not multisampled.
|
||||
if (texture.sampleType == wgpu::TextureSampleType::Depth) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Multisampled texture bindings must not be Depth.");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (entry.storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
|
||||
bindingMemberCount++;
|
||||
const StorageTextureBindingLayout& storageTexture = entry.storageTexture;
|
||||
DAWN_TRY(ValidateStorageTextureAccess(storageTexture.access));
|
||||
DAWN_TRY(ValidateStorageTextureFormat(device, storageTexture.format));
|
||||
|
||||
// viewDimension defaults to 2D if left undefined, needs validation otherwise.
|
||||
if (storageTexture.viewDimension != wgpu::TextureViewDimension::Undefined) {
|
||||
DAWN_TRY(ValidateTextureViewDimension(storageTexture.viewDimension));
|
||||
DAWN_TRY(ValidateStorageTextureViewDimension(storageTexture.viewDimension));
|
||||
}
|
||||
|
||||
if (storageTexture.access == wgpu::StorageTextureAccess::WriteOnly) {
|
||||
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::ComparisonSampler:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.hasDynamicOffset && !canBeDynamic) {
|
||||
return DAWN_VALIDATION_ERROR("Binding type cannot be dynamic.");
|
||||
if (bindingMemberCount > 1) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Only one of buffer, sampler, texture, or storageTexture may be set for each "
|
||||
"BindGroupLayoutEntry");
|
||||
} else if (bindingMemberCount > 1) {
|
||||
if (entry.type != wgpu::BindingType::Undefined) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"BindGroupLayoutEntry type must be undefined if any of buffer, sampler, "
|
||||
"texture, or storageTexture are set");
|
||||
}
|
||||
} else if (bindingMemberCount == 0) {
|
||||
// TODO(dawn:527): Raising this warning breaks a ton of validation tests.
|
||||
// Deprecated validation path
|
||||
/*device->EmitDeprecationWarning(
|
||||
"The format of BindGroupLayoutEntry has changed, and will soon require the "
|
||||
"buffer, sampler, texture, or storageTexture members be set rather than "
|
||||
"setting type, etc. on the entry directly.");*/
|
||||
|
||||
DAWN_TRY(ValidateBindingType(entry.type));
|
||||
DAWN_TRY(ValidateTextureComponentType(entry.textureComponentType));
|
||||
|
||||
wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
if (entry.viewDimension != wgpu::TextureViewDimension::Undefined) {
|
||||
DAWN_TRY(ValidateTextureViewDimension(entry.viewDimension));
|
||||
viewDimension = entry.viewDimension;
|
||||
}
|
||||
|
||||
bool canBeDynamic = false;
|
||||
|
||||
switch (entry.type) {
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
allowedStages &= ~wgpu::ShaderStage::Vertex;
|
||||
DAWN_FALLTHROUGH;
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
canBeDynamic = true;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::MultisampledTexture:
|
||||
if (viewDimension != wgpu::TextureViewDimension::e2D) {
|
||||
return DAWN_VALIDATION_ERROR("Multisampled binding must be 2D.");
|
||||
}
|
||||
if (entry.textureComponentType ==
|
||||
wgpu::TextureComponentType::DepthComparison) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Multisampled binding must not be DepthComparison.");
|
||||
}
|
||||
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::ComparisonSampler:
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
if (entry.hasDynamicOffset && !canBeDynamic) {
|
||||
return DAWN_VALIDATION_ERROR("Binding type cannot be dynamic.");
|
||||
}
|
||||
|
||||
// Dynamic storage buffers aren't bounds checked properly in D3D12. Disallow them as
|
||||
// unsafe until the bounds checks are implemented.
|
||||
if (device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs) && entry.hasDynamicOffset &&
|
||||
(entry.type == wgpu::BindingType::StorageBuffer ||
|
||||
entry.type == wgpu::BindingType::ReadonlyStorageBuffer)) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Dynamic storage buffers are disallowed because they aren't secure yet. "
|
||||
"See https://crbug.com/dawn/429");
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsSubset(entry.visibility, allowedStages)) {
|
||||
return DAWN_VALIDATION_ERROR("Binding type cannot be used with this visibility.");
|
||||
}
|
||||
|
||||
// Dynamic storage buffers aren't bounds checked properly in D3D12. Disallow them as
|
||||
// unsafe until the bounds checks are implemented.
|
||||
if (device->IsToggleEnabled(Toggle::DisallowUnsafeAPIs) &&
|
||||
entry.type == wgpu::BindingType::StorageBuffer && entry.hasDynamicOffset) {
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Dynamic storage buffers are disallowed because they aren't secure yet. See "
|
||||
"https://crbug.com/dawn/429");
|
||||
}
|
||||
|
||||
IncrementBindingCounts(&bindingCounts, entry);
|
||||
|
||||
bindingsSet.insert(bindingNumber);
|
||||
@@ -163,8 +257,8 @@ namespace dawn_native {
|
||||
a.minBufferBindingSize != b.minBufferBindingSize;
|
||||
}
|
||||
|
||||
bool IsBufferBinding(wgpu::BindingType bindingType) {
|
||||
switch (bindingType) {
|
||||
bool IsBufferBindingType(wgpu::BindingType type) {
|
||||
switch (type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
@@ -175,27 +269,58 @@ namespace dawn_native {
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
case wgpu::BindingType::Undefined:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBufferBinding(const BindGroupLayoutEntry& binding) {
|
||||
if (binding.buffer.type != wgpu::BufferBindingType::Undefined) {
|
||||
return true;
|
||||
} else if (binding.sampler.type != wgpu::SamplerBindingType::Undefined) {
|
||||
return false;
|
||||
} else if (binding.texture.sampleType != wgpu::TextureSampleType::Undefined) {
|
||||
return false;
|
||||
} else if (binding.storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsBufferBindingType(binding.type);
|
||||
}
|
||||
|
||||
bool BindingHasDynamicOffset(const BindGroupLayoutEntry& binding) {
|
||||
if (binding.buffer.type != wgpu::BufferBindingType::Undefined) {
|
||||
return binding.buffer.hasDynamicOffset;
|
||||
} else if (binding.sampler.type != wgpu::SamplerBindingType::Undefined) {
|
||||
return false;
|
||||
} else if (binding.texture.sampleType != wgpu::TextureSampleType::Undefined) {
|
||||
return false;
|
||||
} else if (binding.storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return binding.hasDynamicOffset;
|
||||
}
|
||||
|
||||
bool SortBindingsCompare(const BindGroupLayoutEntry& a, const BindGroupLayoutEntry& b) {
|
||||
const bool aIsBuffer = IsBufferBinding(a.type);
|
||||
const bool bIsBuffer = IsBufferBinding(b.type);
|
||||
const bool aIsBuffer = IsBufferBinding(a);
|
||||
const bool bIsBuffer = IsBufferBinding(b);
|
||||
if (aIsBuffer != bIsBuffer) {
|
||||
// Always place buffers first.
|
||||
return aIsBuffer;
|
||||
} else {
|
||||
if (aIsBuffer) {
|
||||
bool aHasDynamicOffset = BindingHasDynamicOffset(a);
|
||||
bool bHasDynamicOffset = BindingHasDynamicOffset(b);
|
||||
ASSERT(bIsBuffer);
|
||||
if (a.hasDynamicOffset != b.hasDynamicOffset) {
|
||||
if (aHasDynamicOffset != bHasDynamicOffset) {
|
||||
// Buffers with dynamic offsets should come before those without.
|
||||
// This makes it easy to iterate over the dynamic buffer bindings
|
||||
// [0, dynamicBufferCount) during validation.
|
||||
return a.hasDynamicOffset;
|
||||
return aHasDynamicOffset;
|
||||
}
|
||||
if (a.hasDynamicOffset) {
|
||||
ASSERT(b.hasDynamicOffset);
|
||||
if (aHasDynamicOffset) {
|
||||
ASSERT(bHasDynamicOffset);
|
||||
ASSERT(a.binding != b.binding);
|
||||
// Above, we ensured that dynamic buffers are first. Now, ensure that
|
||||
// dynamic buffer bindings are in increasing order. This is because dynamic
|
||||
@@ -232,7 +357,7 @@ namespace dawn_native {
|
||||
BindingIndex lastBufferIndex{0};
|
||||
BindingIndex firstNonBufferIndex = std::numeric_limits<BindingIndex>::max();
|
||||
for (BindingIndex i{0}; i < bindings.size(); ++i) {
|
||||
if (IsBufferBinding(bindings[i].type)) {
|
||||
if (IsBufferBindingType(bindings[i].type)) {
|
||||
lastBufferIndex = std::max(i, lastBufferIndex);
|
||||
} else {
|
||||
firstNonBufferIndex = std::min(i, firstNonBufferIndex);
|
||||
@@ -258,22 +383,109 @@ namespace dawn_native {
|
||||
|
||||
for (BindingIndex i{0}; i < mBindingInfo.size(); ++i) {
|
||||
const BindGroupLayoutEntry& binding = sortedBindings[static_cast<uint32_t>(i)];
|
||||
mBindingInfo[i].binding = BindingNumber(binding.binding);
|
||||
mBindingInfo[i].type = binding.type;
|
||||
mBindingInfo[i].visibility = binding.visibility;
|
||||
mBindingInfo[i].textureComponentType = binding.textureComponentType;
|
||||
mBindingInfo[i].storageTextureFormat = binding.storageTextureFormat;
|
||||
mBindingInfo[i].minBufferBindingSize = binding.minBufferBindingSize;
|
||||
|
||||
if (binding.viewDimension == wgpu::TextureViewDimension::Undefined) {
|
||||
mBindingInfo[i].viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
// TODO(dawn:527): This code currently converts the new-style BindGroupLayoutEntry
|
||||
// definitions into the older-style BindingInfo. This is to allow for a staggered
|
||||
// conversion, but it means that there's some combinations that the more expressive new
|
||||
// style can handle that will be lost in the translation. The solution is to update
|
||||
// BindingInfo to only reflect the new-style entry layout and convert the old-style
|
||||
// entry layout into it instead.
|
||||
mBindingInfo[i].binding = BindingNumber(binding.binding);
|
||||
mBindingInfo[i].visibility = binding.visibility;
|
||||
|
||||
if (binding.buffer.type != wgpu::BufferBindingType::Undefined) {
|
||||
switch (binding.buffer.type) {
|
||||
case wgpu::BufferBindingType::Uniform:
|
||||
mBindingInfo[i].type = wgpu::BindingType::UniformBuffer;
|
||||
break;
|
||||
case wgpu::BufferBindingType::Storage:
|
||||
mBindingInfo[i].type = wgpu::BindingType::StorageBuffer;
|
||||
break;
|
||||
case wgpu::BufferBindingType::ReadOnlyStorage:
|
||||
mBindingInfo[i].type = wgpu::BindingType::ReadonlyStorageBuffer;
|
||||
break;
|
||||
case wgpu::BufferBindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
mBindingInfo[i].minBufferBindingSize = binding.buffer.minBindingSize;
|
||||
mBindingInfo[i].hasDynamicOffset = binding.buffer.hasDynamicOffset;
|
||||
} else if (binding.sampler.type != wgpu::SamplerBindingType::Undefined) {
|
||||
switch (binding.sampler.type) {
|
||||
case wgpu::SamplerBindingType::Filtering:
|
||||
case wgpu::SamplerBindingType::NonFiltering:
|
||||
mBindingInfo[i].type = wgpu::BindingType::Sampler;
|
||||
break;
|
||||
case wgpu::SamplerBindingType::Comparison:
|
||||
mBindingInfo[i].type = wgpu::BindingType::ComparisonSampler;
|
||||
break;
|
||||
case wgpu::SamplerBindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else if (binding.texture.sampleType != wgpu::TextureSampleType::Undefined) {
|
||||
mBindingInfo[i].type = binding.texture.multisampled
|
||||
? wgpu::BindingType::MultisampledTexture
|
||||
: wgpu::BindingType::SampledTexture;
|
||||
switch (binding.texture.sampleType) {
|
||||
case wgpu::TextureSampleType::Float:
|
||||
case wgpu::TextureSampleType::UnfilterableFloat:
|
||||
mBindingInfo[i].textureComponentType = wgpu::TextureComponentType::Float;
|
||||
break;
|
||||
case wgpu::TextureSampleType::Sint:
|
||||
mBindingInfo[i].textureComponentType = wgpu::TextureComponentType::Sint;
|
||||
break;
|
||||
case wgpu::TextureSampleType::Uint:
|
||||
mBindingInfo[i].textureComponentType = wgpu::TextureComponentType::Uint;
|
||||
break;
|
||||
case wgpu::TextureSampleType::Depth:
|
||||
mBindingInfo[i].textureComponentType =
|
||||
wgpu::TextureComponentType::DepthComparison;
|
||||
break;
|
||||
case wgpu::TextureSampleType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
if (binding.texture.viewDimension == wgpu::TextureViewDimension::Undefined) {
|
||||
mBindingInfo[i].viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
} else {
|
||||
mBindingInfo[i].viewDimension = binding.texture.viewDimension;
|
||||
}
|
||||
} else if (binding.storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
|
||||
switch (binding.storageTexture.access) {
|
||||
case wgpu::StorageTextureAccess::ReadOnly:
|
||||
mBindingInfo[i].type = wgpu::BindingType::ReadonlyStorageTexture;
|
||||
break;
|
||||
case wgpu::StorageTextureAccess::WriteOnly:
|
||||
mBindingInfo[i].type = wgpu::BindingType::WriteonlyStorageTexture;
|
||||
break;
|
||||
case wgpu::StorageTextureAccess::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
mBindingInfo[i].storageTextureFormat = binding.storageTexture.format;
|
||||
|
||||
if (binding.storageTexture.viewDimension == wgpu::TextureViewDimension::Undefined) {
|
||||
mBindingInfo[i].viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
} else {
|
||||
mBindingInfo[i].viewDimension = binding.storageTexture.viewDimension;
|
||||
}
|
||||
} else {
|
||||
mBindingInfo[i].viewDimension = binding.viewDimension;
|
||||
// Deprecated entry layout. As noted above, though, this is currently the only
|
||||
// lossless path.
|
||||
mBindingInfo[i].type = binding.type;
|
||||
mBindingInfo[i].textureComponentType = binding.textureComponentType;
|
||||
mBindingInfo[i].storageTextureFormat = binding.storageTextureFormat;
|
||||
mBindingInfo[i].minBufferBindingSize = binding.minBufferBindingSize;
|
||||
|
||||
if (binding.viewDimension == wgpu::TextureViewDimension::Undefined) {
|
||||
mBindingInfo[i].viewDimension = wgpu::TextureViewDimension::e2D;
|
||||
} else {
|
||||
mBindingInfo[i].viewDimension = binding.viewDimension;
|
||||
}
|
||||
|
||||
mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset;
|
||||
}
|
||||
|
||||
mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset;
|
||||
|
||||
if (IsBufferBinding(binding.type)) {
|
||||
if (IsBufferBinding(binding)) {
|
||||
// Buffers must be contiguously packed at the start of the binding info.
|
||||
ASSERT(GetBufferCount() == i);
|
||||
}
|
||||
|
||||
@@ -20,44 +20,86 @@ namespace dawn_native {
|
||||
bindingCounts->totalCount += 1;
|
||||
|
||||
uint32_t PerStageBindingCounts::*perStageBindingCountMember = nullptr;
|
||||
switch (entry.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
++bindingCounts->bufferCount;
|
||||
if (entry.hasDynamicOffset) {
|
||||
++bindingCounts->dynamicUniformBufferCount;
|
||||
}
|
||||
if (entry.minBufferBindingSize == 0) {
|
||||
++bindingCounts->unverifiedBufferCount;
|
||||
}
|
||||
perStageBindingCountMember = &PerStageBindingCounts::uniformBufferCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
++bindingCounts->bufferCount;
|
||||
if (entry.hasDynamicOffset) {
|
||||
++bindingCounts->dynamicStorageBufferCount;
|
||||
}
|
||||
if (entry.minBufferBindingSize == 0) {
|
||||
++bindingCounts->unverifiedBufferCount;
|
||||
}
|
||||
perStageBindingCountMember = &PerStageBindingCounts::storageBufferCount;
|
||||
break;
|
||||
if (entry.buffer.type != wgpu::BufferBindingType::Undefined) {
|
||||
++bindingCounts->bufferCount;
|
||||
const BufferBindingLayout& buffer = entry.buffer;
|
||||
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
case wgpu::BindingType::MultisampledTexture:
|
||||
perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount;
|
||||
break;
|
||||
if (buffer.minBindingSize == 0) {
|
||||
++bindingCounts->unverifiedBufferCount;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
perStageBindingCountMember = &PerStageBindingCounts::samplerCount;
|
||||
break;
|
||||
switch (buffer.type) {
|
||||
case wgpu::BufferBindingType::Uniform:
|
||||
if (buffer.hasDynamicOffset) {
|
||||
++bindingCounts->dynamicUniformBufferCount;
|
||||
}
|
||||
perStageBindingCountMember = &PerStageBindingCounts::uniformBufferCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
perStageBindingCountMember = &PerStageBindingCounts::storageTextureCount;
|
||||
break;
|
||||
case wgpu::BufferBindingType::Storage:
|
||||
case wgpu::BufferBindingType::ReadOnlyStorage:
|
||||
if (buffer.hasDynamicOffset) {
|
||||
++bindingCounts->dynamicStorageBufferCount;
|
||||
}
|
||||
perStageBindingCountMember = &PerStageBindingCounts::storageBufferCount;
|
||||
break;
|
||||
|
||||
case wgpu::BufferBindingType::Undefined:
|
||||
// Can't get here due to the enclosing if statement.
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
} else if (entry.sampler.type != wgpu::SamplerBindingType::Undefined) {
|
||||
perStageBindingCountMember = &PerStageBindingCounts::samplerCount;
|
||||
} else if (entry.texture.sampleType != wgpu::TextureSampleType::Undefined) {
|
||||
perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount;
|
||||
} else if (entry.storageTexture.access != wgpu::StorageTextureAccess::Undefined) {
|
||||
perStageBindingCountMember = &PerStageBindingCounts::storageTextureCount;
|
||||
} else {
|
||||
// Deprecated path.
|
||||
switch (entry.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
++bindingCounts->bufferCount;
|
||||
if (entry.hasDynamicOffset) {
|
||||
++bindingCounts->dynamicUniformBufferCount;
|
||||
}
|
||||
if (entry.minBufferBindingSize == 0) {
|
||||
++bindingCounts->unverifiedBufferCount;
|
||||
}
|
||||
perStageBindingCountMember = &PerStageBindingCounts::uniformBufferCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
++bindingCounts->bufferCount;
|
||||
if (entry.hasDynamicOffset) {
|
||||
++bindingCounts->dynamicStorageBufferCount;
|
||||
}
|
||||
if (entry.minBufferBindingSize == 0) {
|
||||
++bindingCounts->unverifiedBufferCount;
|
||||
}
|
||||
perStageBindingCountMember = &PerStageBindingCounts::storageBufferCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
case wgpu::BindingType::MultisampledTexture:
|
||||
perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
perStageBindingCountMember = &PerStageBindingCounts::samplerCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
perStageBindingCountMember = &PerStageBindingCounts::storageTextureCount;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(perStageBindingCountMember != nullptr);
|
||||
|
||||
@@ -75,6 +75,9 @@ namespace dawn_native {
|
||||
usageTracker->TextureViewUsedAs(view, wgpu::TextureUsage::Storage);
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,6 +425,9 @@ namespace dawn_native {
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,9 @@ namespace dawn_native { namespace d3d12 {
|
||||
viewAllocation.OffsetFrom(viewSizeIncrement, bindingOffsets[bindingIndex]));
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace dawn_native { namespace d3d12 {
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
return BindGroupLayout::DescriptorType::Sampler;
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
} // anonymous namespace
|
||||
@@ -121,6 +123,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -291,6 +291,9 @@ namespace dawn_native { namespace d3d12 {
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
// Don't require barriers.
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,6 +387,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace dawn_native { namespace d3d12 {
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,6 +461,9 @@ namespace dawn_native { namespace metal {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,8 @@ namespace dawn_native { namespace metal {
|
||||
mIndexInfo[stage][group][bindingIndex] = textureIndex;
|
||||
textureIndex++;
|
||||
break;
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,9 @@ namespace dawn_native { namespace opengl {
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -365,6 +365,9 @@ namespace dawn_native { namespace opengl {
|
||||
texture->GetGLFormat().internalFormat);
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,6 +176,9 @@ namespace dawn_native { namespace opengl {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@ namespace dawn_native { namespace opengl {
|
||||
mIndexInfo[group][bindingIndex] = storageTextureIndex;
|
||||
storageTextureIndex++;
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,8 @@ namespace dawn_native { namespace vulkan {
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture:
|
||||
return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ namespace dawn_native { namespace vulkan {
|
||||
write.pImageInfo = &writeImageInfo[numWrites];
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
numWrites++;
|
||||
|
||||
@@ -208,6 +208,9 @@ namespace dawn_native { namespace vulkan {
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
// Don't require barriers.
|
||||
break;
|
||||
|
||||
case wgpu::BindingType::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user