Disallow using cube or cube array texture views as storage textures
This patch adds validations to forbid using cube or cube array texture views as storage textures in Dawn as they are not supported on D3D12. BUG=dawn:267 TEST=dawn_unittests Change-Id: Iafb705a4bedae25ee54cfa45f710b2f3b7aab912 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/22166 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
55c85f66d2
commit
f62ab75a5c
|
@ -94,6 +94,47 @@ namespace dawn_native {
|
|||
return {};
|
||||
}
|
||||
|
||||
MaybeError ValidateStorageTextureViewDimension(wgpu::BindingType bindingType,
|
||||
wgpu::TextureViewDimension dimension) {
|
||||
switch (bindingType) {
|
||||
case wgpu::BindingType::ReadonlyStorageTexture:
|
||||
case wgpu::BindingType::WriteonlyStorageTexture: {
|
||||
break;
|
||||
}
|
||||
|
||||
case wgpu::BindingType::StorageBuffer:
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||
case wgpu::BindingType::Sampler:
|
||||
case wgpu::BindingType::ComparisonSampler:
|
||||
case wgpu::BindingType::SampledTexture:
|
||||
return {};
|
||||
|
||||
case wgpu::BindingType::StorageTexture:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
switch (dimension) {
|
||||
case wgpu::TextureViewDimension::Cube:
|
||||
case wgpu::TextureViewDimension::CubeArray:
|
||||
return DAWN_VALIDATION_ERROR(
|
||||
"Cube map and cube map texture views cannot be used as storage textures");
|
||||
|
||||
case wgpu::TextureViewDimension::e1D:
|
||||
case wgpu::TextureViewDimension::e2D:
|
||||
case wgpu::TextureViewDimension::e2DArray:
|
||||
case wgpu::TextureViewDimension::e3D:
|
||||
case wgpu::TextureViewDimension::Undefined:
|
||||
return {};
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
MaybeError ValidateBindGroupLayoutDescriptor(DeviceBase* device,
|
||||
const BindGroupLayoutDescriptor* descriptor) {
|
||||
if (descriptor->nextInChain != nullptr) {
|
||||
|
@ -123,6 +164,8 @@ namespace dawn_native {
|
|||
|
||||
DAWN_TRY(ValidateStorageTextureFormat(device, entry.type, entry.storageTextureFormat));
|
||||
|
||||
DAWN_TRY(ValidateStorageTextureViewDimension(entry.type, entry.viewDimension));
|
||||
|
||||
switch (entry.type) {
|
||||
case wgpu::BindingType::UniformBuffer:
|
||||
if (entry.hasDynamicOffset) {
|
||||
|
|
|
@ -42,6 +42,9 @@ namespace dawn_native {
|
|||
wgpu::BindingType bindingType,
|
||||
wgpu::TextureFormat storageTextureFormat);
|
||||
|
||||
MaybeError ValidateStorageTextureViewDimension(wgpu::BindingType bindingType,
|
||||
wgpu::TextureViewDimension dimension);
|
||||
|
||||
// Bindings are specified as a |BindingNumber| in the BindGroupLayoutDescriptor.
|
||||
// These numbers may be arbitrary and sparse. Internally, Dawn packs these numbers
|
||||
// into a packed range of |BindingIndex| integers.
|
||||
|
|
|
@ -155,6 +155,8 @@ namespace dawn_native {
|
|||
bindingInfo.type, StageBit(module->GetExecutionModel())));
|
||||
DAWN_TRY(ValidateStorageTextureFormat(device, bindingInfo.type,
|
||||
bindingInfo.storageTextureFormat));
|
||||
DAWN_TRY(ValidateStorageTextureViewDimension(bindingInfo.type,
|
||||
bindingInfo.viewDimension));
|
||||
|
||||
bindingSlot.visibility =
|
||||
GetShaderStageVisibilityWithBindingType(bindingInfo.type);
|
||||
|
|
|
@ -460,6 +460,47 @@ TEST_F(StorageTextureValidationTests, UnsupportedSPIRVStorageTextureFormat) {
|
|||
}
|
||||
}
|
||||
|
||||
// Verify that declaring a storage texture dimension that is not supported in WebGPU in shader
|
||||
// causes validation error at the creation of PSO. WebGPU doesn't support using cube map texture
|
||||
// views and cube map array texture views as storage textures.
|
||||
TEST_F(StorageTextureValidationTests, UnsupportedTextureViewDimensionInShader) {
|
||||
constexpr std::array<wgpu::TextureViewDimension, 2> kUnsupportedTextureViewDimensions = {
|
||||
wgpu::TextureViewDimension::Cube, wgpu::TextureViewDimension::CubeArray};
|
||||
constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::R32Float;
|
||||
|
||||
for (wgpu::BindingType bindingType : kSupportedStorageTextureBindingTypes) {
|
||||
for (wgpu::TextureViewDimension dimension : kUnsupportedTextureViewDimensions) {
|
||||
std::string computeShader =
|
||||
CreateComputeShaderWithStorageTexture(bindingType, kFormat, dimension);
|
||||
wgpu::ShaderModule csModule = utils::CreateShaderModule(
|
||||
device, utils::SingleShaderStage::Compute, computeShader.c_str());
|
||||
|
||||
wgpu::ComputePipelineDescriptor computePipelineDescriptor;
|
||||
computePipelineDescriptor.computeStage.module = csModule;
|
||||
computePipelineDescriptor.computeStage.entryPoint = "main";
|
||||
computePipelineDescriptor.layout = nullptr;
|
||||
ASSERT_DEVICE_ERROR(device.CreateComputePipeline(&computePipelineDescriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that declaring a texture view dimension that is not supported to be used as storage
|
||||
// textures in WebGPU in bind group layout causes validation error. WebGPU doesn't support using
|
||||
// cube map texture views and cube map array texture views as storage textures.
|
||||
TEST_F(StorageTextureValidationTests, UnsupportedTextureViewDimensionInBindGroupLayout) {
|
||||
constexpr std::array<wgpu::TextureViewDimension, 2> kUnsupportedTextureViewDimensions = {
|
||||
wgpu::TextureViewDimension::Cube, wgpu::TextureViewDimension::CubeArray};
|
||||
constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::R32Float;
|
||||
|
||||
for (wgpu::BindingType bindingType : kSupportedStorageTextureBindingTypes) {
|
||||
for (wgpu::TextureViewDimension dimension : kUnsupportedTextureViewDimensions) {
|
||||
ASSERT_DEVICE_ERROR(utils::MakeBindGroupLayout(
|
||||
device, {{0, wgpu::ShaderStage::Compute, bindingType, false, false, dimension,
|
||||
wgpu::TextureComponentType::Float, kFormat}}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify when we create and use a bind group layout with storage textures in the creation of
|
||||
// render and compute pipeline, the binding type in the bind group layout must match the
|
||||
// declaration in the shader.
|
||||
|
@ -605,14 +646,13 @@ TEST_F(StorageTextureValidationTests, BindGroupLayoutStorageTextureFormatMatches
|
|||
// Verify the dimension of the bind group layout with storage textures must match the one declared
|
||||
// in shader.
|
||||
TEST_F(StorageTextureValidationTests, BindGroupLayoutViewDimensionMatchesShaderDeclaration) {
|
||||
constexpr std::array<wgpu::TextureViewDimension, 6> kAllDimensions = {
|
||||
wgpu::TextureViewDimension::e1D, wgpu::TextureViewDimension::e2D,
|
||||
wgpu::TextureViewDimension::e2DArray, wgpu::TextureViewDimension::Cube,
|
||||
wgpu::TextureViewDimension::CubeArray, wgpu::TextureViewDimension::e3D};
|
||||
constexpr std::array<wgpu::TextureViewDimension, 4> kSupportedDimensions = {
|
||||
wgpu::TextureViewDimension::e1D, wgpu::TextureViewDimension::e2D,
|
||||
wgpu::TextureViewDimension::e2DArray, wgpu::TextureViewDimension::e3D};
|
||||
constexpr wgpu::TextureFormat kStorageTextureFormat = wgpu::TextureFormat::R32Float;
|
||||
|
||||
for (wgpu::BindingType bindingType : kSupportedStorageTextureBindingTypes) {
|
||||
for (wgpu::TextureViewDimension dimensionInShader : kAllDimensions) {
|
||||
for (wgpu::TextureViewDimension dimensionInShader : kSupportedDimensions) {
|
||||
// Create the compute shader with the given texture view dimension.
|
||||
std::string computeShader = CreateComputeShaderWithStorageTexture(
|
||||
bindingType, kStorageTextureFormat, dimensionInShader);
|
||||
|
@ -629,7 +669,7 @@ TEST_F(StorageTextureValidationTests, BindGroupLayoutViewDimensionMatchesShaderD
|
|||
bindingType};
|
||||
defaultBindGroupLayoutEntry.storageTextureFormat = kStorageTextureFormat;
|
||||
|
||||
for (wgpu::TextureViewDimension dimensionInBindGroupLayout : kAllDimensions) {
|
||||
for (wgpu::TextureViewDimension dimensionInBindGroupLayout : kSupportedDimensions) {
|
||||
// Create the bind group layout with the given texture view dimension.
|
||||
wgpu::BindGroupLayoutEntry bindGroupLayoutBinding = defaultBindGroupLayoutEntry;
|
||||
bindGroupLayoutBinding.viewDimension = dimensionInBindGroupLayout;
|
||||
|
@ -795,9 +835,8 @@ TEST_F(StorageTextureValidationTests, StorageTextureViewDimensionInBindGroup) {
|
|||
// Currently we only support creating 2D-compatible texture view dimensions.
|
||||
// TODO(jiawei.shao@intel.com): test the use of 1D and 3D texture view dimensions when they are
|
||||
// supported in Dawn.
|
||||
constexpr std::array<wgpu::TextureViewDimension, 4> kSupportedDimensions = {
|
||||
wgpu::TextureViewDimension::e2D, wgpu::TextureViewDimension::e2DArray,
|
||||
wgpu::TextureViewDimension::Cube, wgpu::TextureViewDimension::CubeArray};
|
||||
constexpr std::array<wgpu::TextureViewDimension, 2> kSupportedDimensions = {
|
||||
wgpu::TextureViewDimension::e2D, wgpu::TextureViewDimension::e2DArray};
|
||||
|
||||
wgpu::Texture texture =
|
||||
CreateTexture(wgpu::TextureUsage::Storage, kStorageTextureFormat, 1, kArrayLayerCount);
|
||||
|
@ -807,6 +846,7 @@ TEST_F(StorageTextureValidationTests, StorageTextureViewDimensionInBindGroup) {
|
|||
kDefaultTextureViewDescriptor.baseMipLevel = 0;
|
||||
kDefaultTextureViewDescriptor.mipLevelCount = 1;
|
||||
kDefaultTextureViewDescriptor.baseArrayLayer = 0;
|
||||
kDefaultTextureViewDescriptor.arrayLayerCount = 1u;
|
||||
|
||||
for (wgpu::BindingType storageBindingType : kSupportedStorageTextureBindingTypes) {
|
||||
wgpu::BindGroupLayoutEntry defaultBindGroupLayoutEntry;
|
||||
|
@ -826,13 +866,6 @@ TEST_F(StorageTextureValidationTests, StorageTextureViewDimensionInBindGroup) {
|
|||
// Create a texture view with given texture view dimension.
|
||||
wgpu::TextureViewDescriptor textureViewDescriptor = kDefaultTextureViewDescriptor;
|
||||
textureViewDescriptor.dimension = dimensionOfTextureView;
|
||||
|
||||
if (dimensionOfTextureView == wgpu::TextureViewDimension::Cube ||
|
||||
dimensionOfTextureView == wgpu::TextureViewDimension::CubeArray) {
|
||||
textureViewDescriptor.arrayLayerCount = 6u;
|
||||
} else {
|
||||
textureViewDescriptor.arrayLayerCount = 1u;
|
||||
}
|
||||
wgpu::TextureView storageTextureView = texture.CreateView(&textureViewDescriptor);
|
||||
|
||||
// Verify that the dimension of the texture view used as storage texture in a bind
|
||||
|
|
|
@ -51,7 +51,7 @@ wgpu::Device ValidationTest::CreateDeviceFromAdapter(
|
|||
const std::vector<const char*>& requiredExtensions) {
|
||||
wgpu::Device deviceToTest;
|
||||
|
||||
// Always keep the code path to test creating a device without a device descriptor.
|
||||
// Always keep this code path to test creating a device without a device descriptor.
|
||||
if (requiredExtensions.empty()) {
|
||||
deviceToTest = wgpu::Device::Acquire(adapterToTest.CreateDevice());
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue