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": 4, "name": "comparison sampler"},
{"value": 5, "name": "sampled texture"},
{"value": 6, "name": "readonly storage texture"},
{"value": 7, "name": "writeonly storage texture"}
{"value": 6, "name": "multisampled texture"},
{"value": 7, "name": "readonly storage texture"},
{"value": 8, "name": "writeonly storage texture"}
]
},
"blend descriptor": {

View File

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

View File

@ -81,15 +81,31 @@ namespace dawn_native {
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) {
return DAWN_VALIDATION_ERROR("some binding index was specified more than once");
}
bool canBeDynamic = false;
bool canBeMultisampled = false;
wgpu::ShaderStage allowedStages = kAllStages;
switch (entry.type) {
switch (type) {
case wgpu::BindingType::StorageBuffer:
allowedStages &= ~wgpu::ShaderStage::Vertex;
DAWN_FALLTHROUGH;
@ -99,7 +115,12 @@ namespace dawn_native {
break;
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;
case wgpu::BindingType::WriteonlyStorageTexture:
@ -115,15 +136,6 @@ namespace dawn_native {
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.");
}
@ -145,14 +157,13 @@ namespace dawn_native {
namespace {
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.minBufferBindingSize);
}
bool operator!=(const BindingInfo& a, const BindingInfo& b) {
return a.hasDynamicOffset != b.hasDynamicOffset || //
a.multisampled != b.multisampled || //
a.visibility != b.visibility || //
a.type != b.type || //
a.textureComponentType != b.textureComponentType || //
@ -168,14 +179,12 @@ namespace dawn_native {
case wgpu::BindingType::ReadonlyStorageBuffer:
return true;
case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::MultisampledTexture:
case wgpu::BindingType::Sampler:
case wgpu::BindingType::ComparisonSampler:
case wgpu::BindingType::ReadonlyStorageTexture:
case wgpu::BindingType::WriteonlyStorageTexture:
return false;
default:
UNREACHABLE();
return false;
}
}
@ -211,9 +220,6 @@ namespace dawn_native {
if (a.visibility != b.visibility) {
return a.visibility < b.visibility;
}
if (a.multisampled != b.multisampled) {
return a.multisampled < b.multisampled;
}
if (a.viewDimension != b.viewDimension) {
return a.viewDimension < b.viewDimension;
}
@ -256,6 +262,17 @@ namespace dawn_native {
: CachedObject(device), mBindingInfo(BindingIndex(descriptor->entryCount)) {
std::vector<BindGroupLayoutEntry> sortedBindings(
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);
for (BindingIndex i{0}; i < mBindingInfo.size(); ++i) {
@ -274,7 +291,6 @@ namespace dawn_native {
mBindingInfo[i].viewDimension = binding.viewDimension;
}
mBindingInfo[i].multisampled = binding.multisampled;
mBindingInfo[i].hasDynamicOffset = binding.hasDynamicOffset;
if (IsBufferBinding(binding.type)) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -113,9 +113,10 @@ namespace dawn_native { namespace d3d12 {
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
// sampled texture.
case wgpu::BindingType::SampledTexture:
case wgpu::BindingType::ReadonlyStorageTexture: {
auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
auto& srv = view->GetSRVDescriptor();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -58,6 +58,66 @@ class DeprecationTests : public DawnTest {
} \
} 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,
D3D12Backend(),
MetalBackend(),

View File

@ -381,6 +381,47 @@ TEST_F(BindGroupValidationTest, BufferOffsetAlignment) {
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
TEST_F(BindGroupValidationTest, BufferBindingOOB) {
wgpu::BindGroupLayout layout = utils::MakeBindGroupLayout(
@ -827,15 +868,15 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) {
// Multisampled 2D texture works.
utils::MakeBindGroupLayout(
device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
true, wgpu::TextureViewDimension::e2D},
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
0, false, wgpu::TextureViewDimension::e2D},
});
// Multisampled 2D (defaulted) texture works.
utils::MakeBindGroupLayout(
device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
true, wgpu::TextureViewDimension::Undefined},
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
0, false, wgpu::TextureViewDimension::Undefined},
});
// Multisampled 2D storage texture is invalid.
@ -855,29 +896,29 @@ TEST_F(BindGroupLayoutValidationTest, MultisampledTextures) {
// Multisampled cube texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
true, wgpu::TextureViewDimension::Cube},
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
0, false, wgpu::TextureViewDimension::Cube},
}));
// Multisampled cube array texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
true, wgpu::TextureViewDimension::CubeArray},
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
0, false, wgpu::TextureViewDimension::CubeArray},
}));
// Multisampled 3D texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
true, wgpu::TextureViewDimension::e3D},
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
0, false, wgpu::TextureViewDimension::e3D},
}));
// Multisampled 1D texture is invalid.
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
device, {
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
true, wgpu::TextureViewDimension::e1D},
{0, wgpu::ShaderStage::Compute, wgpu::BindingType::MultisampledTexture, false,
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());
}
{
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;
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(

View File

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