Add validation on the creation of 4x Multisampled textures

This patch adds validations on the creation of the multisampled textures
with sampleCount == 4. The validations include:
1. Only accept 1 or 4 as valid value of sampleCount.
2. According to Vulkan SPEC, when sampleCount > 1:
- The value of mipLevelCount can only be 1
- We cannot create cube map or cube map array texture views on this
  texture.

BUG=dawn:56
TEST=dawn_unittests

Change-Id: Iac7cbe7cd7af16216b9185afd37a80eef0712f6b
Reviewed-on: https://dawn-review.googlesource.com/c/5160
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
Jiawei Shao 2019-03-04 01:31:38 +00:00 committed by Commit Bot service account
parent 1c92c159ad
commit a8ce0a434e
4 changed files with 98 additions and 8 deletions

View File

@ -47,6 +47,22 @@ namespace dawn_native {
}
}
bool IsTextureViewDimensionCompatibleWithTextureSampleCount(
dawn::TextureViewDimension textureViewDimension,
const uint32_t sampleCount) {
switch (textureViewDimension) {
case dawn::TextureViewDimension::Cube:
case dawn::TextureViewDimension::CubeArray:
return sampleCount == 1;
case dawn::TextureViewDimension::e2D:
case dawn::TextureViewDimension::e2DArray:
return true;
default:
UNREACHABLE();
return false;
}
}
// TODO(jiawei.shao@intel.com): support validation on all texture view dimensions
bool IsArrayLayerValidForTextureViewDimension(
dawn::TextureViewDimension textureViewDimension,
@ -82,10 +98,20 @@ namespace dawn_native {
}
}
// TODO(jiawei.shao@intel.com): support multisampled textures
MaybeError ValidateSampleCount(uint32_t sampleCount) {
if (sampleCount != 1) {
return DAWN_VALIDATION_ERROR("The sample count of the texture is not supported.");
// TODO(jiawei.shao@intel.com): support more sample count.
MaybeError ValidateSampleCount(const TextureDescriptor* descriptor) {
switch (descriptor->sampleCount) {
case 1:
break;
case 4:
if (descriptor->mipLevelCount > 1) {
return DAWN_VALIDATION_ERROR(
"The mipmap level count of a multisampled texture must be 1.");
}
break;
default:
return DAWN_VALIDATION_ERROR(
"The sample count of the texture is not supported.");
}
return {};
@ -107,6 +133,13 @@ namespace dawn_native {
"original texture");
}
if (!IsTextureViewDimensionCompatibleWithTextureSampleCount(
descriptor->dimension, texture->GetSampleCount())) {
return DAWN_VALIDATION_ERROR(
"The dimension of the texture view is not compatible with the sample count of "
"the original texture");
}
if (!IsTextureSizeValidForTextureViewDimension(descriptor->dimension,
texture->GetSize())) {
return DAWN_VALIDATION_ERROR(
@ -151,7 +184,7 @@ namespace dawn_native {
DAWN_TRY(ValidateTextureUsageBit(descriptor->usage));
DAWN_TRY(ValidateTextureDimension(descriptor->dimension));
DAWN_TRY(ValidateTextureFormat(descriptor->format));
DAWN_TRY(ValidateSampleCount(descriptor->sampleCount));
DAWN_TRY(ValidateSampleCount(descriptor));
// TODO(jiawei.shao@intel.com): check stuff based on the dimension
if (descriptor->size.width == 0 || descriptor->size.height == 0 ||
@ -290,6 +323,7 @@ namespace dawn_native {
mSize(descriptor->size),
mArrayLayerCount(descriptor->arrayLayerCount),
mMipLevelCount(descriptor->mipLevelCount),
mSampleCount(descriptor->sampleCount),
mUsage(descriptor->usage) {
}
@ -322,6 +356,10 @@ namespace dawn_native {
ASSERT(!IsError());
return mMipLevelCount;
}
uint32_t TextureBase::GetSampleCount() const {
ASSERT(!IsError());
return mSampleCount;
}
dawn::TextureUsageBit TextureBase::GetUsage() const {
ASSERT(!IsError());
return mUsage;
@ -332,6 +370,11 @@ namespace dawn_native {
return {};
}
bool TextureBase::IsMultisampledTexture() const {
ASSERT(!IsError());
return mSampleCount > 1;
}
TextureViewBase* TextureBase::CreateDefaultTextureView() {
TextureViewDescriptor descriptor = {};

View File

@ -54,10 +54,13 @@ namespace dawn_native {
const Extent3D& GetSize() const;
uint32_t GetArrayLayers() const;
uint32_t GetNumMipLevels() const;
uint32_t GetSampleCount() const;
dawn::TextureUsageBit GetUsage() const;
MaybeError ValidateCanUseInSubmitNow() const;
bool IsMultisampledTexture() const;
// Dawn API
TextureViewBase* CreateDefaultTextureView();
TextureViewBase* CreateTextureView(const TextureViewDescriptor* descriptor);
@ -70,6 +73,7 @@ namespace dawn_native {
Extent3D mSize;
uint32_t mArrayLayerCount;
uint32_t mMipLevelCount;
uint32_t mSampleCount;
dawn::TextureUsageBit mUsage = dawn::TextureUsageBit::None;
};

View File

@ -56,6 +56,14 @@ TEST_F(TextureValidationTest, SampleCount) {
device.CreateTexture(&descriptor);
}
// sampleCount == 4 is allowed.
{
dawn::TextureDescriptor descriptor = defaultDescriptor;
descriptor.sampleCount = 4;
device.CreateTexture(&descriptor);
}
// It is an error to create a texture with an invalid sampleCount.
{
dawn::TextureDescriptor descriptor = defaultDescriptor;
@ -63,5 +71,14 @@ TEST_F(TextureValidationTest, SampleCount) {
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
}
// It is an error to create a multisampled texture with mipLevelCount > 1.
{
dawn::TextureDescriptor descriptor = defaultDescriptor;
descriptor.sampleCount = 4;
descriptor.mipLevelCount = 2;
ASSERT_DEVICE_ERROR(device.CreateTexture(&descriptor));
}
}
} // namespace

View File

@ -28,16 +28,18 @@ constexpr dawn::TextureFormat kDefaultTextureFormat = dawn::TextureFormat::R8G8B
dawn::Texture Create2DArrayTexture(dawn::Device& device,
uint32_t arrayLayerCount,
uint32_t width = kWidth,
uint32_t height = kHeight) {
uint32_t height = kHeight,
uint32_t mipLevelCount = kDefaultMipLevels,
uint32_t sampleCount = 1) {
dawn::TextureDescriptor descriptor;
descriptor.dimension = dawn::TextureDimension::e2D;
descriptor.size.width = width;
descriptor.size.height = height;
descriptor.size.depth = 1;
descriptor.arrayLayerCount = arrayLayerCount;
descriptor.sampleCount = 1;
descriptor.sampleCount = sampleCount;
descriptor.format = kDefaultTextureFormat;
descriptor.mipLevelCount = kDefaultMipLevels;
descriptor.mipLevelCount = mipLevelCount;
descriptor.usage = dawn::TextureUsageBit::Sampled;
return device.CreateTexture(&descriptor);
}
@ -198,6 +200,30 @@ TEST_F(TextureViewValidationTest, CreateCubeMapTextureView) {
descriptor.arrayLayerCount = 12;
ASSERT_DEVICE_ERROR(nonSquareTexture.CreateTextureView(&descriptor));
}
// It is an error to create a cube map texture view on a multisampled texture.
{
constexpr uint32_t kSampleCount = 4;
dawn::Texture multisampledTexture = Create2DArrayTexture(device, kDefaultArrayLayers,
kWidth, kHeight, 1, kSampleCount);
dawn::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
descriptor.dimension = dawn::TextureViewDimension::Cube;
descriptor.arrayLayerCount = 6;
descriptor.mipLevelCount = 1;
ASSERT_DEVICE_ERROR(multisampledTexture.CreateTextureView(&descriptor));
}
// It is an error to create a cube map array texture view on a multisampled texture.
{
constexpr uint32_t kSampleCount = 4;
dawn::Texture multisampledTexture = Create2DArrayTexture(device, kDefaultArrayLayers,
kWidth, kHeight, 1, kSampleCount);
dawn::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
descriptor.dimension = dawn::TextureViewDimension::CubeArray;
descriptor.arrayLayerCount = 12;
descriptor.mipLevelCount = 1;
ASSERT_DEVICE_ERROR(multisampledTexture.CreateTextureView(&descriptor));
}
}
// Test the format compatibility rules when creating a texture view.