Test TextureComponentType and TextureViewDimension compatibility

The TextureComponentType and TextureViewDimension of resources in
the shader must match those in the bind group layout.

This patch also extracts the texture view dimension from the SPIRV.

Bug: dawn:202
Change-Id: Ie155f17109f4f1b5d9b386d757062ae5ffe5da67
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/13861
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
Austin Eng 2019-11-22 16:40:22 +00:00 committed by Commit Bot service account
parent aca8c4a528
commit d0993ba83a
3 changed files with 90 additions and 3 deletions

View File

@ -41,6 +41,31 @@ namespace dawn_native {
return Format::Other;
}
}
wgpu::TextureViewDimension SpirvDimToTextureViewDimension(spv::Dim dim, bool arrayed) {
switch (dim) {
case spv::Dim::Dim1D:
return wgpu::TextureViewDimension::e1D;
case spv::Dim::Dim2D:
if (arrayed) {
return wgpu::TextureViewDimension::e2DArray;
} else {
return wgpu::TextureViewDimension::e2D;
}
case spv::Dim::Dim3D:
return wgpu::TextureViewDimension::e3D;
case spv::Dim::DimCube:
if (arrayed) {
return wgpu::TextureViewDimension::CubeArray;
} else {
return wgpu::TextureViewDimension::Cube;
}
default:
UNREACHABLE();
return wgpu::TextureViewDimension::Undefined;
}
}
} // anonymous namespace
MaybeError ValidateShaderModuleDescriptor(DeviceBase*,
@ -156,9 +181,14 @@ namespace dawn_native {
info.base_type_id = resource.base_type_id;
switch (bindingType) {
case wgpu::BindingType::SampledTexture: {
spirv_cross::SPIRType::ImageType imageType =
compiler.get_type(info.base_type_id).image;
spirv_cross::SPIRType::BaseType textureComponentType =
compiler.get_type(compiler.get_type(info.base_type_id).image.type)
.basetype;
compiler.get_type(imageType.type).basetype;
info.multisampled = imageType.ms;
info.textureDimension =
SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed);
info.textureComponentType =
SpirvCrossBaseTypeToFormatType(textureComponentType);
info.type = bindingType;
@ -322,6 +352,10 @@ namespace dawn_native {
if (layoutTextureComponentType != moduleInfo.textureComponentType) {
return false;
}
if (layoutInfo.textureDimensions[i] != moduleInfo.textureDimension) {
return false;
}
}
}

View File

@ -51,7 +51,10 @@ namespace dawn_native {
uint32_t id;
uint32_t base_type_id;
wgpu::BindingType type;
Format::Type textureComponentType;
// Match the defaults in BindGroupLayoutDescriptor
wgpu::TextureViewDimension textureDimension = wgpu::TextureViewDimension::Undefined;
Format::Type textureComponentType = Format::Type::Float;
bool multisampled = false;
bool used = false;
};
using ModuleBindingInfo =

View File

@ -360,3 +360,53 @@ TEST_F(RenderPipelineValidationTest, TextureComponentTypeCompatibility) {
}
}
}
// Tests that the texture view dimension in shader must match the bind group layout.
TEST_F(RenderPipelineValidationTest, TextureViewDimensionCompatibility) {
constexpr uint32_t kNumTextureViewDimensions = 6u;
std::array<const char*, kNumTextureViewDimensions> kTextureKeywords = {{
"texture1D",
"texture2D",
"texture2DArray",
"textureCube",
"textureCubeArray",
"texture3D",
}};
std::array<wgpu::TextureViewDimension, kNumTextureViewDimensions> kTextureViewDimensions = {{
wgpu::TextureViewDimension::e1D,
wgpu::TextureViewDimension::e2D,
wgpu::TextureViewDimension::e2DArray,
wgpu::TextureViewDimension::Cube,
wgpu::TextureViewDimension::CubeArray,
wgpu::TextureViewDimension::e3D,
}};
for (size_t i = 0; i < kNumTextureViewDimensions; ++i) {
for (size_t j = 0; j < kNumTextureViewDimensions; ++j) {
utils::ComboRenderPipelineDescriptor descriptor(device);
descriptor.vertexStage.module = vsModule;
std::ostringstream stream;
stream << R"(
#version 450
layout(set = 0, binding = 0) uniform )"
<< kTextureKeywords[i] << R"( tex;
void main() {
})";
descriptor.cFragmentStage.module = utils::CreateShaderModule(
device, utils::SingleShaderStage::Fragment, stream.str().c_str());
wgpu::BindGroupLayout bgl = utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false,
false, kTextureViewDimensions[j], wgpu::TextureComponentType::Float}});
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
if (i == j) {
device.CreateRenderPipeline(&descriptor);
} else {
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
}
}
}
}