Add wgpu::BindingType::MultisampledTexture

And deprecate wgpu::BindGroupLayoutEntry.multisampled.

Bug: dawn:527

Change-Id: I00f38eb6b1f82f9d9aedda5da23b1350263a3044
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28562
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
Corentin Wallez 2020-09-24 11:41:07 +00:00 committed by Commit Bot service account
parent ed0b3cf153
commit a46737c0aa
25 changed files with 210 additions and 81 deletions

View File

@ -117,8 +117,9 @@
{"value": 3, "name": "sampler"}, {"value": 3, "name": "sampler"},
{"value": 4, "name": "comparison sampler"}, {"value": 4, "name": "comparison sampler"},
{"value": 5, "name": "sampled texture"}, {"value": 5, "name": "sampled texture"},
{"value": 6, "name": "readonly storage texture"}, {"value": 6, "name": "multisampled texture"},
{"value": 7, "name": "writeonly storage texture"} {"value": 7, "name": "readonly storage texture"},
{"value": 8, "name": "writeonly storage texture"}
] ]
}, },
"blend descriptor": { "blend descriptor": {

View File

@ -94,6 +94,7 @@ namespace dawn_native {
MaybeError ValidateTextureBinding(const DeviceBase* device, MaybeError ValidateTextureBinding(const DeviceBase* device,
const BindGroupEntry& entry, const BindGroupEntry& entry,
wgpu::TextureUsage requiredUsage, wgpu::TextureUsage requiredUsage,
bool multisampled,
const BindingInfo& bindingInfo) { const BindingInfo& bindingInfo) {
if (entry.textureView == nullptr || entry.sampler != nullptr || if (entry.textureView == nullptr || entry.sampler != nullptr ||
entry.buffer != nullptr) { entry.buffer != nullptr) {
@ -107,7 +108,7 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR("texture binding usage mismatch"); return DAWN_VALIDATION_ERROR("texture binding usage mismatch");
} }
if (texture->IsMultisampledTexture() != bindingInfo.multisampled) { if (texture->IsMultisampledTexture() != multisampled) {
return DAWN_VALIDATION_ERROR("texture multisampling mismatch"); return DAWN_VALIDATION_ERROR("texture multisampling mismatch");
} }
@ -212,7 +213,11 @@ namespace dawn_native {
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Sampled, DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Sampled,
bindingInfo)); false, bindingInfo));
break;
case wgpu::BindingType::MultisampledTexture:
DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Sampled,
true, bindingInfo));
break; break;
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
@ -221,7 +226,7 @@ namespace dawn_native {
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Storage, DAWN_TRY(ValidateTextureBinding(device, entry, wgpu::TextureUsage::Storage,
bindingInfo)); false, bindingInfo));
break; break;
} }
} }
@ -360,6 +365,8 @@ namespace dawn_native {
ASSERT(!IsError()); ASSERT(!IsError());
ASSERT(bindingIndex < mLayout->GetBindingCount()); ASSERT(bindingIndex < mLayout->GetBindingCount());
ASSERT(mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::SampledTexture || ASSERT(mLayout->GetBindingInfo(bindingIndex).type == wgpu::BindingType::SampledTexture ||
mLayout->GetBindingInfo(bindingIndex).type ==
wgpu::BindingType::MultisampledTexture ||
mLayout->GetBindingInfo(bindingIndex).type == mLayout->GetBindingInfo(bindingIndex).type ==
wgpu::BindingType::ReadonlyStorageTexture || wgpu::BindingType::ReadonlyStorageTexture ||
mLayout->GetBindingInfo(bindingIndex).type == mLayout->GetBindingInfo(bindingIndex).type ==

View File

@ -81,15 +81,31 @@ namespace dawn_native {
viewDimension = entry.viewDimension; viewDimension = entry.viewDimension;
} }
// Fixup multisampled=true to use MultisampledTexture instead.
// TODO(dawn:527): Remove once the deprecation of multisampled is done.
wgpu::BindingType type = entry.type;
if (entry.multisampled) {
if (type == wgpu::BindingType::MultisampledTexture) {
return DAWN_VALIDATION_ERROR(
"Cannot use multisampled = true and MultisampledTexture at the same time.");
} else if (type == wgpu::BindingType::SampledTexture) {
device->EmitDeprecationWarning(
"BGLEntry::multisampled is deprecated, use "
"wgpu::BindingType::MultisampledTexture instead.");
type = wgpu::BindingType::MultisampledTexture;
} else {
return DAWN_VALIDATION_ERROR("Binding type cannot be multisampled");
}
}
if (bindingsSet.count(bindingNumber) != 0) { if (bindingsSet.count(bindingNumber) != 0) {
return DAWN_VALIDATION_ERROR("some binding index was specified more than once"); return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
} }
bool canBeDynamic = false; bool canBeDynamic = false;
bool canBeMultisampled = false;
wgpu::ShaderStage allowedStages = kAllStages; wgpu::ShaderStage allowedStages = kAllStages;
switch (entry.type) { switch (type) {
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
allowedStages &= ~wgpu::ShaderStage::Vertex; allowedStages &= ~wgpu::ShaderStage::Vertex;
DAWN_FALLTHROUGH; DAWN_FALLTHROUGH;
@ -99,7 +115,12 @@ namespace dawn_native {
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
canBeMultisampled = true; break;
case wgpu::BindingType::MultisampledTexture:
if (viewDimension != wgpu::TextureViewDimension::e2D) {
return DAWN_VALIDATION_ERROR("Multisampled binding must be 2D.");
}
break; break;
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
@ -115,15 +136,6 @@ namespace dawn_native {
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) { if (entry.hasDynamicOffset && !canBeDynamic) {
return DAWN_VALIDATION_ERROR("Binding type cannot be dynamic."); return DAWN_VALIDATION_ERROR("Binding type cannot be dynamic.");
} }
@ -145,14 +157,13 @@ namespace dawn_native {
namespace { namespace {
void HashCombineBindingInfo(size_t* hash, const BindingInfo& info) { void HashCombineBindingInfo(size_t* hash, const BindingInfo& info) {
HashCombine(hash, info.hasDynamicOffset, info.multisampled, info.visibility, info.type, HashCombine(hash, info.hasDynamicOffset, info.visibility, info.type,
info.textureComponentType, info.viewDimension, info.storageTextureFormat, info.textureComponentType, info.viewDimension, info.storageTextureFormat,
info.minBufferBindingSize); info.minBufferBindingSize);
} }
bool operator!=(const BindingInfo& a, const BindingInfo& b) { bool operator!=(const BindingInfo& a, const BindingInfo& b) {
return a.hasDynamicOffset != b.hasDynamicOffset || // return a.hasDynamicOffset != b.hasDynamicOffset || //
a.multisampled != b.multisampled || //
a.visibility != b.visibility || // a.visibility != b.visibility || //
a.type != b.type || // a.type != b.type || //
a.textureComponentType != b.textureComponentType || // a.textureComponentType != b.textureComponentType || //
@ -168,14 +179,12 @@ namespace dawn_native {
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
return true; return true;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
return false; return false;
default:
UNREACHABLE();
return false;
} }
} }
@ -211,9 +220,6 @@ namespace dawn_native {
if (a.visibility != b.visibility) { if (a.visibility != b.visibility) {
return a.visibility < b.visibility; return a.visibility < b.visibility;
} }
if (a.multisampled != b.multisampled) {
return a.multisampled < b.multisampled;
}
if (a.viewDimension != b.viewDimension) { if (a.viewDimension != b.viewDimension) {
return a.viewDimension < b.viewDimension; return a.viewDimension < b.viewDimension;
} }
@ -256,6 +262,17 @@ namespace dawn_native {
: CachedObject(device), mBindingInfo(BindingIndex(descriptor->entryCount)) { : CachedObject(device), mBindingInfo(BindingIndex(descriptor->entryCount)) {
std::vector<BindGroupLayoutEntry> sortedBindings( std::vector<BindGroupLayoutEntry> sortedBindings(
descriptor->entries, descriptor->entries + descriptor->entryCount); descriptor->entries, descriptor->entries + descriptor->entryCount);
// Fixup multisampled=true to use MultisampledTexture instead.
// TODO(dawn:527): Remove once multisampled=true deprecation is finished.
for (BindGroupLayoutEntry& entry : sortedBindings) {
if (entry.multisampled) {
ASSERT(entry.type == wgpu::BindingType::SampledTexture);
entry.multisampled = false;
entry.type = wgpu::BindingType::MultisampledTexture;
}
}
std::sort(sortedBindings.begin(), sortedBindings.end(), SortBindingsCompare); std::sort(sortedBindings.begin(), sortedBindings.end(), SortBindingsCompare);
for (BindingIndex i{0}; i < mBindingInfo.size(); ++i) { for (BindingIndex i{0}; i < mBindingInfo.size(); ++i) {
@ -274,7 +291,6 @@ namespace dawn_native {
mBindingInfo[i].viewDimension = binding.viewDimension; mBindingInfo[i].viewDimension = binding.viewDimension;
} }
mBindingInfo[i].multisampled = binding.multisampled;
mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset; mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset;
if (IsBufferBinding(binding.type)) { if (IsBufferBinding(binding.type)) {

View File

@ -45,6 +45,7 @@ namespace dawn_native {
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount; perStageBindingCountMember = &PerStageBindingCounts::sampledTextureCount;
break; break;

View File

@ -56,7 +56,6 @@ namespace dawn_native {
wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::Undefined; wgpu::TextureViewDimension viewDimension = wgpu::TextureViewDimension::Undefined;
wgpu::TextureFormat storageTextureFormat = wgpu::TextureFormat::Undefined; wgpu::TextureFormat storageTextureFormat = wgpu::TextureFormat::Undefined;
bool hasDynamicOffset = false; bool hasDynamicOffset = false;
bool multisampled = false;
uint64_t minBufferBindingSize = 0; uint64_t minBufferBindingSize = 0;
}; };

View File

@ -89,7 +89,6 @@ namespace dawn_native {
modifiedEntry->binding == mergedEntry.binding && // modifiedEntry->binding == mergedEntry.binding && //
modifiedEntry->type == mergedEntry.type && // modifiedEntry->type == mergedEntry.type && //
modifiedEntry->hasDynamicOffset == mergedEntry.hasDynamicOffset && // modifiedEntry->hasDynamicOffset == mergedEntry.hasDynamicOffset && //
modifiedEntry->multisampled == mergedEntry.multisampled && //
modifiedEntry->viewDimension == mergedEntry.viewDimension && // modifiedEntry->viewDimension == mergedEntry.viewDimension && //
modifiedEntry->textureComponentType == mergedEntry.textureComponentType; modifiedEntry->textureComponentType == mergedEntry.textureComponentType;
@ -117,7 +116,6 @@ namespace dawn_native {
BindGroupLayoutEntry entry = {}; BindGroupLayoutEntry entry = {};
entry.type = shaderBinding.type; entry.type = shaderBinding.type;
entry.hasDynamicOffset = false; entry.hasDynamicOffset = false;
entry.multisampled = shaderBinding.multisampled;
entry.viewDimension = shaderBinding.viewDimension; entry.viewDimension = shaderBinding.viewDimension;
entry.textureComponentType = entry.textureComponentType =
Format::FormatTypeToTextureComponentType(shaderBinding.textureComponentType); Format::FormatTypeToTextureComponentType(shaderBinding.textureComponentType);

View File

@ -47,7 +47,8 @@ namespace dawn_native {
break; break;
} }
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture: {
TextureViewBase* view = group->GetBindingAsTextureView(bindingIndex); TextureViewBase* view = group->GetBindingAsTextureView(bindingIndex);
usageTracker->TextureViewUsedAs(view, wgpu::TextureUsage::Sampled); usageTracker->TextureViewUsedAs(view, wgpu::TextureUsage::Sampled);
break; break;

View File

@ -418,7 +418,8 @@ namespace dawn_native {
} }
switch (layoutInfo.type) { switch (layoutInfo.type) {
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture: {
if (layoutInfo.textureComponentType != shaderInfo.textureComponentType) { if (layoutInfo.textureComponentType != shaderInfo.textureComponentType) {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"The textureComponentType of the bind group layout entry is " "The textureComponentType of the bind group layout entry is "
@ -469,10 +470,6 @@ namespace dawn_native {
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
break; break;
default:
UNREACHABLE();
return DAWN_VALIDATION_ERROR("Unsupported binding type");
} }
} }
@ -550,12 +547,15 @@ namespace dawn_native {
spirv_cross::SPIRType::BaseType textureComponentType = spirv_cross::SPIRType::BaseType textureComponentType =
compiler.get_type(imageType.type).basetype; compiler.get_type(imageType.type).basetype;
info->multisampled = imageType.ms;
info->viewDimension = info->viewDimension =
SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed); SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed);
info->textureComponentType = info->textureComponentType =
SpirvBaseTypeToFormatType(textureComponentType); SpirvBaseTypeToFormatType(textureComponentType);
info->type = bindingType; if (imageType.ms) {
info->type = wgpu::BindingType::MultisampledTexture;
} else {
info->type = wgpu::BindingType::SampledTexture;
}
break; break;
} }
case wgpu::BindingType::StorageBuffer: { case wgpu::BindingType::StorageBuffer: {
@ -595,7 +595,10 @@ namespace dawn_native {
return DAWN_VALIDATION_ERROR( return DAWN_VALIDATION_ERROR(
"The storage texture format is not supported"); "The storage texture format is not supported");
} }
info->multisampled = imageType.ms; if (imageType.ms) {
return DAWN_VALIDATION_ERROR(
"Multisampled storage texture aren't supported");
}
info->storageTextureFormat = storageTextureFormat; info->storageTextureFormat = storageTextureFormat;
info->viewDimension = info->viewDimension =
SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed); SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed);

View File

@ -113,9 +113,10 @@ namespace dawn_native { namespace d3d12 {
break; break;
} }
case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
// Readonly storage is implemented as SRV so it can be used at the same time as a // Readonly storage is implemented as SRV so it can be used at the same time as a
// sampled texture. // sampled texture.
case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::ReadonlyStorageTexture: { case wgpu::BindingType::ReadonlyStorageTexture: {
auto* view = ToBackend(GetBindingAsTextureView(bindingIndex)); auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
auto& srv = view->GetSRVDescriptor(); auto& srv = view->GetSRVDescriptor();

View File

@ -31,6 +31,7 @@ namespace dawn_native { namespace d3d12 {
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
return BindGroupLayout::DescriptorType::UAV; return BindGroupLayout::DescriptorType::UAV;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
return BindGroupLayout::DescriptorType::SRV; return BindGroupLayout::DescriptorType::SRV;
@ -115,6 +116,7 @@ namespace dawn_native { namespace d3d12 {
mBindingOffsets[bindingIndex] = baseRegister++; mBindingOffsets[bindingIndex] = baseRegister++;
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:

View File

@ -269,8 +269,9 @@ namespace dawn_native { namespace d3d12 {
} }
break; break;
} }
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture:
TextureViewBase* view = case wgpu::BindingType::MultisampledTexture: {
TextureViewBase* view =
mBindGroups[index]->GetBindingAsTextureView(binding); mBindGroups[index]->GetBindingAsTextureView(binding);
ToBackend(view->GetTexture()) ToBackend(view->GetTexture())
->TransitionUsageAndGetResourceBarrier( ->TransitionUsageAndGetResourceBarrier(
@ -294,10 +295,6 @@ namespace dawn_native { namespace d3d12 {
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
// Don't require barriers. // Don't require barriers.
break; break;
default:
UNREACHABLE();
break;
} }
} }
} }
@ -386,6 +383,7 @@ namespace dawn_native { namespace d3d12 {
} }
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:

View File

@ -49,6 +49,7 @@ namespace dawn_native { namespace d3d12 {
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
return D3D12_ROOT_PARAMETER_TYPE_SRV; return D3D12_ROOT_PARAMETER_TYPE_SRV;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:

View File

@ -461,6 +461,7 @@ namespace dawn_native { namespace metal {
} }
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: { case wgpu::BindingType::WriteonlyStorageTexture: {
auto textureView = auto textureView =

View File

@ -52,6 +52,7 @@ namespace dawn_native { namespace metal {
samplerIndex++; samplerIndex++;
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
mIndexInfo[stage][group][bindingIndex] = textureIndex; mIndexInfo[stage][group][bindingIndex] = textureIndex;

View File

@ -48,13 +48,10 @@ namespace dawn_native { namespace opengl {
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
break; break;
default:
UNREACHABLE();
break;
} }
} }

View File

@ -297,7 +297,8 @@ namespace dawn_native { namespace opengl {
break; break;
} }
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture: {
TextureView* view = TextureView* view =
ToBackend(group->GetBindingAsTextureView(bindingIndex)); ToBackend(group->GetBindingAsTextureView(bindingIndex));
GLuint handle = view->GetHandle(); GLuint handle = view->GetHandle();

View File

@ -145,6 +145,7 @@ namespace dawn_native { namespace opengl {
case wgpu::BindingType::Sampler: case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
// These binding types are handled in the separate sampler and texture // These binding types are handled in the separate sampler and texture
// emulation // emulation
break; break;

View File

@ -45,6 +45,7 @@ namespace dawn_native { namespace opengl {
samplerIndex++; samplerIndex++;
break; break;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
mIndexInfo[group][bindingIndex] = sampledTextureIndex; mIndexInfo[group][bindingIndex] = sampledTextureIndex;
sampledTextureIndex++; sampledTextureIndex++;
break; break;

View File

@ -57,6 +57,7 @@ namespace dawn_native { namespace vulkan {
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
return VK_DESCRIPTOR_TYPE_SAMPLER; return VK_DESCRIPTOR_TYPE_SAMPLER;
case wgpu::BindingType::SampledTexture: case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE; return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
case wgpu::BindingType::ReadonlyStorageBuffer: case wgpu::BindingType::ReadonlyStorageBuffer:
@ -67,8 +68,6 @@ namespace dawn_native { namespace vulkan {
case wgpu::BindingType::ReadonlyStorageTexture: case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture: case wgpu::BindingType::WriteonlyStorageTexture:
return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; return VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
default:
UNREACHABLE();
} }
} }

View File

@ -84,7 +84,8 @@ namespace dawn_native { namespace vulkan {
break; break;
} }
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture: {
TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex)); TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
writeImageInfo[numWrites].imageView = view->GetHandle(); writeImageInfo[numWrites].imageView = view->GetHandle();
@ -107,8 +108,6 @@ namespace dawn_native { namespace vulkan {
write.pImageInfo = &writeImageInfo[numWrites]; write.pImageInfo = &writeImageInfo[numWrites];
break; break;
} }
default:
UNREACHABLE();
} }
numWrites++; numWrites++;

View File

@ -193,7 +193,8 @@ namespace dawn_native { namespace vulkan {
break; break;
} }
case wgpu::BindingType::SampledTexture: { case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture: {
TextureViewBase* view = TextureViewBase* view =
mBindGroups[index]->GetBindingAsTextureView(binding); mBindGroups[index]->GetBindingAsTextureView(binding);
ToBackend(view->GetTexture()) ToBackend(view->GetTexture())
@ -207,10 +208,6 @@ namespace dawn_native { namespace vulkan {
case wgpu::BindingType::ComparisonSampler: case wgpu::BindingType::ComparisonSampler:
// Don't require barriers. // Don't require barriers.
break; break;
default:
UNREACHABLE();
break;
} }
} }
} }

View File

@ -58,6 +58,66 @@ class DeprecationTests : public DawnTest {
} \ } \
} while (0) } while (0)
// Test that using BGLEntry.multisampled = true emits a deprecation warning.
TEST_P(DeprecationTests, BGLEntryMultisampledDeprecated) {
wgpu::BindGroupLayoutEntry entry{};
entry.visibility = wgpu::ShaderStage::Fragment;
entry.type = wgpu::BindingType::SampledTexture;
entry.multisampled = true;
entry.binding = 0;
wgpu::BindGroupLayoutDescriptor desc;
desc.entryCount = 1;
desc.entries = &entry;
EXPECT_DEPRECATION_WARNING(device.CreateBindGroupLayout(&desc));
}
// Test that using BGLEntry.multisampled = true with MultisampledTexture is an error.
TEST_P(DeprecationTests, BGLEntryMultisampledBooleanAndTypeIsAnError) {
wgpu::BindGroupLayoutEntry entry{};
entry.visibility = wgpu::ShaderStage::Fragment;
entry.type = wgpu::BindingType::MultisampledTexture;
entry.multisampled = true;
entry.binding = 0;
wgpu::BindGroupLayoutDescriptor desc;
desc.entryCount = 1;
desc.entries = &entry;
ASSERT_DEVICE_ERROR(device.CreateBindGroupLayout(&desc));
}
// Test that a using BGLEntry.multisampled produces the correct state tracking.
TEST_P(DeprecationTests, BGLEntryMultisampledBooleanTracking) {
// Create a BGL with the deprecated multisampled boolean
wgpu::BindGroupLayoutEntry entry{};
entry.visibility = wgpu::ShaderStage::Fragment;
entry.type = wgpu::BindingType::SampledTexture;
entry.multisampled = true;
entry.binding = 0;
wgpu::BindGroupLayoutDescriptor desc;
desc.entryCount = 1;
desc.entries = &entry;
wgpu::BindGroupLayout bgl;
EXPECT_DEPRECATION_WARNING(bgl = device.CreateBindGroupLayout(&desc));
// Create both a multisampled and non-multisampled texture.
wgpu::TextureDescriptor textureDesc;
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
textureDesc.usage = wgpu::TextureUsage::Sampled;
textureDesc.size = {1, 1, 1};
textureDesc.dimension = wgpu::TextureDimension::e2D;
textureDesc.sampleCount = 1;
wgpu::Texture texture1Sample = device.CreateTexture(&textureDesc);
textureDesc.sampleCount = 4;
wgpu::Texture texture4Sample = device.CreateTexture(&textureDesc);
// Creating a bindgroup with that layout is only valid with multisampled = true
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, bgl, {{0, texture1Sample.CreateView()}}));
utils::MakeBindGroup(device, bgl, {{0, texture4Sample.CreateView()}});
}
DAWN_INSTANTIATE_TEST(DeprecationTests, DAWN_INSTANTIATE_TEST(DeprecationTests,
D3D12Backend(), D3D12Backend(),
MetalBackend(), MetalBackend(),

View File

@ -381,6 +381,47 @@ TEST_F(BindGroupValidationTest, BufferOffsetAlignment) {
ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 255, 256}})); ASSERT_DEVICE_ERROR(utils::MakeBindGroup(device, layout, {{0, mUBO, 255, 256}}));
} }
// Tests constraints on the texture for MultisampledTexture bindings
TEST_F(BindGroupValidationTest, MultisampledTexture) {
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::MultisampledTexture, false, 0,
false, wgpu::TextureViewDimension::e2D, wgpu::TextureComponentType::Float}});
wgpu::BindGroupEntry binding;
binding.binding = 0;
binding.sampler = nullptr;
binding.textureView = nullptr;
binding.buffer = nullptr;
binding.offset = 0;
binding.size = 0;
wgpu::BindGroupDescriptor descriptor;
descriptor.layout = layout;
descriptor.entryCount = 1;
descriptor.entries = &binding;
// Not setting anything fails
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
// Control case: setting a multisampled 2D texture works
wgpu::TextureDescriptor textureDesc;
textureDesc.sampleCount = 4;
textureDesc.usage = wgpu::TextureUsage::Sampled;
textureDesc.dimension = wgpu::TextureDimension::e2D;
textureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
textureDesc.size = {1, 1, 1};
wgpu::Texture msTexture = device.CreateTexture(&textureDesc);
binding.textureView = msTexture.CreateView();
device.CreateBindGroup(&descriptor);
binding.textureView = nullptr;
// Error case: setting a single sampled 2D texture is an error.
binding.textureView = mSampledTextureView;
ASSERT_DEVICE_ERROR(device.CreateBindGroup(&descriptor));
binding.textureView = nullptr;
}
// Tests constraints to be sure the buffer binding fits in the buffer // Tests constraints to be sure the buffer binding fits in the buffer
TEST_F(BindGroupValidationTest, BufferBindingOOB) { TEST_F(BindGroupValidationTest, BufferBindingOOB) {
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout( wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
@ -827,15 +868,15 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) {
// Multisampled 2D texture works. // Multisampled 2D texture works.
utils::MakeBindGroupLayout( utils::MakeBindGroupLayout(
device, { device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, {0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
true, wgpu::TextureViewDimension::e2D}, 0, false, wgpu::TextureViewDimension::e2D},
}); });
// Multisampled 2D (defaulted) texture works. // Multisampled 2D (defaulted) texture works.
utils::MakeBindGroupLayout( utils::MakeBindGroupLayout(
device, { device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, {0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
true, wgpu::TextureViewDimension::Undefined}, 0, false, wgpu::TextureViewDimension::Undefined},
}); });
// Multisampled 2D storage texture is invalid. // Multisampled 2D storage texture is invalid.
@ -855,29 +896,29 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) {
// Multisampled cube texture is invalid. // Multisampled cube texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, { device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, {0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
true, wgpu::TextureViewDimension::Cube}, 0, false, wgpu::TextureViewDimension::Cube},
})); }));
// Multisampled cube array texture is invalid. // Multisampled cube array texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, { device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, {0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
true, wgpu::TextureViewDimension::CubeArray}, 0, false, wgpu::TextureViewDimension::CubeArray},
})); }));
// Multisampled 3D texture is invalid. // Multisampled 3D texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, { device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, {0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
true, wgpu::TextureViewDimension::e3D}, 0, false, wgpu::TextureViewDimension::e3D},
})); }));
// Multisampled 1D texture is invalid. // Multisampled 1D texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout( ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, { device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, {0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
true, wgpu::TextureViewDimension::e1D}, 0, false, wgpu::TextureViewDimension::e1D},
})); }));
} }

View File

@ -222,6 +222,16 @@ TEST_F(GetBindGroupLayoutTests, BindingType) {
EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get()); EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
} }
{
binding.type = wgpu::BindingType::MultisampledTexture;
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
#version 450
layout(set = 0, binding = 0) uniform texture2DMS tex;
void main() {})");
EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
}
{ {
binding.type = wgpu::BindingType::Sampler; binding.type = wgpu::BindingType::Sampler;
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"( wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(

View File

@ -789,15 +789,8 @@ TEST_F(StorageTextureValidationTests, MultisampledStorageTexture) {
for (wgpu::BindingType bindingType : kSupportedStorageTextureBindingTypes) { for (wgpu::BindingType bindingType : kSupportedStorageTextureBindingTypes) {
std::string computeShader = std::string computeShader =
CreateComputeShaderWithStorageTexture(bindingType, "rgba8", "", "image2DMS"); CreateComputeShaderWithStorageTexture(bindingType, "rgba8", "", "image2DMS");
wgpu::ShaderModule csModule = utils::CreateShaderModule( ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, utils::SingleShaderStage::Compute,
device, utils::SingleShaderStage::Compute, computeShader.c_str()); computeShader.c_str()));
wgpu::ComputePipelineDescriptor descriptor;
descriptor.layout = nullptr;
descriptor.computeStage.module = csModule;
descriptor.computeStage.entryPoint = "main";
ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&descriptor));
} }
} }