Validate texture component type in BGL against its shader module declaration

We have already been validating the component type of a texture matches
the bind group layout. Here is another constraint introduced by
https://github.com/gpuweb/gpuweb/pull/384. For better code reuse,
conversion from wgpu::TextureComponentType to dawn_native::Format::Type
is factored out as a helper function.

Bug: dawn:202
Change-Id: I394497722b4043dc109eca60116224b7a617e02e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/12860
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Jiajie Hu 2019-10-31 09:51:11 +00:00 committed by Commit Bot service account
parent 64a3bb93dc
commit 9ec47a0bca
5 changed files with 66 additions and 11 deletions

View File

@ -22,6 +22,15 @@ namespace dawn_native {
// Format // Format
Format::Type Format::TextureComponentTypeToFormatType(
wgpu::TextureComponentType componentType) {
// Check that Type correctly mirrors TextureComponentType except for "Other".
static_assert(static_cast<Type>(wgpu::TextureComponentType::Float) == Type::Float, "");
static_assert(static_cast<Type>(wgpu::TextureComponentType::Sint) == Type::Sint, "");
static_assert(static_cast<Type>(wgpu::TextureComponentType::Uint) == Type::Uint, "");
return static_cast<Type>(componentType);
}
bool Format::IsColor() const { bool Format::IsColor() const {
return aspect == Aspect::Color; return aspect == Aspect::Color;
} }
@ -44,17 +53,7 @@ namespace dawn_native {
return false; return false;
} }
// Check that Type is correctly mirrors TextureComponentType except for "Other". return TextureComponentTypeToFormatType(componentType) == type;
static_assert(static_cast<wgpu::TextureComponentType>(Type::Float) ==
wgpu::TextureComponentType::Float,
"");
static_assert(
static_cast<wgpu::TextureComponentType>(Type::Sint) == wgpu::TextureComponentType::Sint,
"");
static_assert(
static_cast<wgpu::TextureComponentType>(Type::Uint) == wgpu::TextureComponentType::Uint,
"");
return static_cast<wgpu::TextureComponentType>(type) == componentType;
} }
size_t Format::GetIndex() const { size_t Format::GetIndex() const {

View File

@ -57,6 +57,8 @@ namespace dawn_native {
uint32_t blockWidth; uint32_t blockWidth;
uint32_t blockHeight; uint32_t blockHeight;
static Type TextureComponentTypeToFormatType(wgpu::TextureComponentType componentType);
bool IsColor() const; bool IsColor() const;
bool HasDepth() const; bool HasDepth() const;
bool HasStencil() const; bool HasStencil() const;

View File

@ -155,6 +155,12 @@ namespace dawn_native {
info.id = resource.id; info.id = resource.id;
info.base_type_id = resource.base_type_id; info.base_type_id = resource.base_type_id;
info.type = bindingType; info.type = bindingType;
if (info.type == wgpu::BindingType::SampledTexture) {
spirv_cross::SPIRType::BaseType textureComponentType =
compiler.get_type(compiler.get_type(info.base_type_id).image.type).basetype;
info.textureComponentType =
SpirvCrossBaseTypeToFormatType(textureComponentType);
}
} }
}; };
@ -285,6 +291,14 @@ namespace dawn_native {
if ((layoutInfo.visibilities[i] & StageBit(mExecutionModel)) == 0) { if ((layoutInfo.visibilities[i] & StageBit(mExecutionModel)) == 0) {
return false; return false;
} }
if (layoutBindingType == wgpu::BindingType::SampledTexture) {
Format::Type layoutTextureComponentType =
Format::TextureComponentTypeToFormatType(layoutInfo.textureComponentTypes[i]);
if (layoutTextureComponentType != moduleInfo.textureComponentType) {
return false;
}
}
} }
return true; return true;

View File

@ -51,6 +51,7 @@ namespace dawn_native {
uint32_t id; uint32_t id;
uint32_t base_type_id; uint32_t base_type_id;
wgpu::BindingType type; wgpu::BindingType type;
Format::Type textureComponentType;
bool used = false; bool used = false;
}; };
using ModuleBindingInfo = using ModuleBindingInfo =

View File

@ -321,3 +321,42 @@ TEST_F(RenderPipelineValidationTest, SampleCountCompatibilityWithRenderPass) {
} }
} }
} }
// Tests that the texture component type in shader must match the bind group layout.
TEST_F(RenderPipelineValidationTest, TextureComponentTypeCompatibility) {
constexpr uint32_t kNumTextureComponentType = 3u;
std::array<const char*, kNumTextureComponentType> kTexturePrefix = {{"", "i", "u"}};
std::array<wgpu::TextureComponentType, kNumTextureComponentType> kTextureComponentTypes = {{
wgpu::TextureComponentType::Float,
wgpu::TextureComponentType::Sint,
wgpu::TextureComponentType::Uint,
}};
for (size_t i = 0; i < kNumTextureComponentType; ++i) {
for (size_t j = 0; j < kNumTextureComponentType; ++j) {
utils::ComboRenderPipelineDescriptor descriptor(device);
descriptor.vertexStage.module = vsModule;
std::ostringstream stream;
stream << R"(
#version 450
layout(set = 0, binding = 0) uniform )"
<< kTexturePrefix[i] << R"(texture2D 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, wgpu::TextureViewDimension::e2D, kTextureComponentTypes[j]}});
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
if (i == j) {
device.CreateRenderPipeline(&descriptor);
} else {
ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
}
}
}
}