Add validation rules for 3D texture view
3D texture view's baseArrayLayer must be 0, and its arrayLayerCount must be 1. In addition, 2D/2DArray/Cube/CubeArray (and 1D) views upon 3D textures are not allowed. Other behaviors for 3D texture views like default values are similar to 2D/2DArray views. This change also adds a test for aspect test against color format for completeness, in addition to the existing depth/stencil formats. Bug: dawn:558 Change-Id: I4f5d095b85c9b81e6f41497f1c8a54b569c210bb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/39600 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
parent
fbaa306056
commit
a32954a4d2
|
@ -63,6 +63,7 @@ namespace dawn_native {
|
|||
uint32_t textureViewArrayLayer) {
|
||||
switch (textureViewDimension) {
|
||||
case wgpu::TextureViewDimension::e2D:
|
||||
case wgpu::TextureViewDimension::e3D:
|
||||
return textureViewArrayLayer == 1u;
|
||||
case wgpu::TextureViewDimension::e2DArray:
|
||||
return true;
|
||||
|
@ -72,7 +73,6 @@ namespace dawn_native {
|
|||
return textureViewArrayLayer % 6 == 0;
|
||||
|
||||
case wgpu::TextureViewDimension::e1D:
|
||||
case wgpu::TextureViewDimension::e3D:
|
||||
case wgpu::TextureViewDimension::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -87,10 +87,10 @@ namespace dawn_native {
|
|||
return textureSize.width == textureSize.height;
|
||||
case wgpu::TextureViewDimension::e2D:
|
||||
case wgpu::TextureViewDimension::e2DArray:
|
||||
case wgpu::TextureViewDimension::e3D:
|
||||
return true;
|
||||
|
||||
case wgpu::TextureViewDimension::e1D:
|
||||
case wgpu::TextureViewDimension::e3D:
|
||||
case wgpu::TextureViewDimension::Undefined:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -287,9 +287,8 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
DAWN_TRY(ValidateTextureViewDimension(descriptor->dimension));
|
||||
if (descriptor->dimension == wgpu::TextureViewDimension::e1D ||
|
||||
descriptor->dimension == wgpu::TextureViewDimension::e3D) {
|
||||
return DAWN_VALIDATION_ERROR("Texture view dimension must be 2D compatible.");
|
||||
if (descriptor->dimension == wgpu::TextureViewDimension::e1D) {
|
||||
return DAWN_VALIDATION_ERROR("1D texture views aren't supported (yet).");
|
||||
}
|
||||
|
||||
DAWN_TRY(ValidateTextureFormat(descriptor->format));
|
||||
|
@ -440,8 +439,11 @@ namespace dawn_native {
|
|||
}
|
||||
uint32_t TextureBase::GetArrayLayers() const {
|
||||
ASSERT(!IsError());
|
||||
// TODO(cwallez@chromium.org): Update for 1D / 3D textures when they are supported.
|
||||
ASSERT(mDimension == wgpu::TextureDimension::e2D);
|
||||
// TODO(cwallez@chromium.org): Update for 1D textures when they are supported.
|
||||
ASSERT(mDimension != wgpu::TextureDimension::e1D);
|
||||
if (mDimension == wgpu::TextureDimension::e3D) {
|
||||
return 1;
|
||||
}
|
||||
return mSize.depth;
|
||||
}
|
||||
uint32_t TextureBase::GetNumMipLevels() const {
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace {
|
|||
|
||||
constexpr uint32_t kWidth = 32u;
|
||||
constexpr uint32_t kHeight = 32u;
|
||||
constexpr uint32_t kDepth = 6u;
|
||||
constexpr uint32_t kDefaultMipLevels = 6u;
|
||||
|
||||
constexpr wgpu::TextureFormat kDefaultTextureFormat = wgpu::TextureFormat::RGBA8Unorm;
|
||||
|
@ -42,6 +43,17 @@ namespace {
|
|||
return device.CreateTexture(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::Texture Create3DTexture(wgpu::Device& device) {
|
||||
wgpu::TextureDescriptor descriptor;
|
||||
descriptor.dimension = wgpu::TextureDimension::e3D;
|
||||
descriptor.size = {kWidth, kHeight, kDepth};
|
||||
descriptor.sampleCount = 1;
|
||||
descriptor.format = kDefaultTextureFormat;
|
||||
descriptor.mipLevelCount = kDefaultMipLevels;
|
||||
descriptor.usage = wgpu::TextureUsage::Sampled;
|
||||
return device.CreateTexture(&descriptor);
|
||||
}
|
||||
|
||||
wgpu::TextureViewDescriptor CreateDefaultViewDescriptor(wgpu::TextureViewDimension dimension) {
|
||||
wgpu::TextureViewDescriptor descriptor;
|
||||
descriptor.format = kDefaultTextureFormat;
|
||||
|
@ -82,6 +94,14 @@ namespace {
|
|||
texture.CreateView(&descriptor);
|
||||
}
|
||||
|
||||
// It is an error to create a 3D texture view on a 2D texture.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
|
||||
descriptor.dimension = wgpu::TextureViewDimension::e3D;
|
||||
descriptor.arrayLayerCount = 1;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
|
||||
// baseMipLevel == k && mipLevelCount == 0 means to use levels k..end.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base2DTextureViewDescriptor;
|
||||
|
@ -139,6 +159,14 @@ namespace {
|
|||
texture.CreateView(&descriptor);
|
||||
}
|
||||
|
||||
// It is an error to create a 3D texture view on a 2D array texture.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
|
||||
descriptor.dimension = wgpu::TextureViewDimension::e3D;
|
||||
descriptor.arrayLayerCount = 1;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
|
||||
// baseArrayLayer == k && arrayLayerCount == 0 means to use layers k..end.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base2DArrayTextureViewDescriptor;
|
||||
|
@ -172,10 +200,94 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// Test creating texture view on a 3D texture
|
||||
TEST_F(TextureViewValidationTest, CreateTextureViewOnTexture3D) {
|
||||
wgpu::Texture texture = Create3DTexture(device);
|
||||
|
||||
wgpu::TextureViewDescriptor base3DTextureViewDescriptor =
|
||||
CreateDefaultViewDescriptor(wgpu::TextureViewDimension::e3D);
|
||||
|
||||
// It is OK to create a 3D texture view on a 3D texture.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
|
||||
texture.CreateView(&descriptor);
|
||||
}
|
||||
|
||||
// It is an error to create a 2D/2DArray/Cube/CubeArray texture view on a 3D texture.
|
||||
{
|
||||
wgpu::TextureViewDimension invalidDimensions[] = {
|
||||
wgpu::TextureViewDimension::e2D,
|
||||
wgpu::TextureViewDimension::e2DArray,
|
||||
wgpu::TextureViewDimension::Cube,
|
||||
wgpu::TextureViewDimension::CubeArray,
|
||||
};
|
||||
for (wgpu::TextureViewDimension dimension : invalidDimensions) {
|
||||
wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
|
||||
descriptor.dimension = dimension;
|
||||
if (dimension == wgpu::TextureViewDimension::Cube ||
|
||||
dimension == wgpu::TextureViewDimension::CubeArray) {
|
||||
descriptor.arrayLayerCount = 6;
|
||||
}
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
// baseMipLevel == k && mipLevelCount == 0 means to use levels k..end.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
|
||||
descriptor.mipLevelCount = 0;
|
||||
|
||||
descriptor.baseMipLevel = 0;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.baseMipLevel = 1;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.baseMipLevel = kDefaultMipLevels - 1;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.baseMipLevel = kDefaultMipLevels;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
|
||||
// It is an error to make the mip level out of range.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
|
||||
descriptor.baseMipLevel = 0;
|
||||
descriptor.mipLevelCount = kDefaultMipLevels + 1;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
descriptor.baseMipLevel = 1;
|
||||
descriptor.mipLevelCount = kDefaultMipLevels;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
descriptor.baseMipLevel = kDefaultMipLevels - 1;
|
||||
descriptor.mipLevelCount = 2;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
descriptor.baseMipLevel = kDefaultMipLevels;
|
||||
descriptor.mipLevelCount = 1;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
|
||||
// baseArrayLayer == k && arrayLayerCount == 0 means to use layers k..end. But
|
||||
// baseArrayLayer must be 0, and arrayLayerCount must be 1 at most for 3D texture view.
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor = base3DTextureViewDescriptor;
|
||||
descriptor.arrayLayerCount = 0;
|
||||
descriptor.baseArrayLayer = 0;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.baseArrayLayer = 1;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
|
||||
descriptor.baseArrayLayer = 0;
|
||||
descriptor.arrayLayerCount = 1;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.arrayLayerCount = 2;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
descriptor.arrayLayerCount = kDepth;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
// Using the "none" ("default") values validates the same as explicitly
|
||||
// specifying the values they're supposed to default to.
|
||||
// Variant for a texture with more than 1 array layer.
|
||||
TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaultsArray) {
|
||||
// Variant for a 2D texture with more than 1 array layer.
|
||||
TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults2DArray) {
|
||||
constexpr uint32_t kDefaultArrayLayers = 6;
|
||||
wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
|
||||
|
||||
|
@ -215,8 +327,8 @@ namespace {
|
|||
|
||||
// Using the "none" ("default") values validates the same as explicitly
|
||||
// specifying the values they're supposed to default to.
|
||||
// Variant for a texture with only 1 array layer.
|
||||
TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaultsNonArray) {
|
||||
// Variant for a 2D texture with only 1 array layer.
|
||||
TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults2DNonArray) {
|
||||
constexpr uint32_t kDefaultArrayLayers = 1;
|
||||
wgpu::Texture texture = Create2DArrayTexture(device, kDefaultArrayLayers);
|
||||
|
||||
|
@ -257,6 +369,51 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
// Using the "none" ("default") values validates the same as explicitly
|
||||
// specifying the values they're supposed to default to.
|
||||
// Variant for a 3D texture.
|
||||
TEST_F(TextureViewValidationTest, TextureViewDescriptorDefaults3D) {
|
||||
wgpu::Texture texture = Create3DTexture(device);
|
||||
|
||||
{ texture.CreateView(); }
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor;
|
||||
descriptor.format = wgpu::TextureFormat::Undefined;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.format = wgpu::TextureFormat::R8Unorm;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor;
|
||||
descriptor.dimension = wgpu::TextureViewDimension::Undefined;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.dimension = wgpu::TextureViewDimension::e3D;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.dimension = wgpu::TextureViewDimension::e2DArray;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
descriptor.dimension = wgpu::TextureViewDimension::e2D;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor;
|
||||
descriptor.arrayLayerCount = 0;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.arrayLayerCount = 1;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.arrayLayerCount = 2;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
{
|
||||
wgpu::TextureViewDescriptor descriptor;
|
||||
descriptor.mipLevelCount = kDefaultMipLevels;
|
||||
texture.CreateView(&descriptor);
|
||||
descriptor.arrayLayerCount = kDepth;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&descriptor));
|
||||
}
|
||||
}
|
||||
|
||||
// Test creating cube map texture view
|
||||
TEST_F(TextureViewValidationTest, CreateCubeMapTextureView) {
|
||||
constexpr uint32_t kDefaultArrayLayers = 16;
|
||||
|
@ -381,6 +538,22 @@ namespace {
|
|||
viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
|
||||
texture.CreateView(&viewDescriptor);
|
||||
}
|
||||
|
||||
// Can select: All from RGBA8Unorm
|
||||
{
|
||||
descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
||||
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
||||
|
||||
wgpu::TextureViewDescriptor viewDescriptor = {};
|
||||
viewDescriptor.aspect = wgpu::TextureAspect::All;
|
||||
texture.CreateView(&viewDescriptor);
|
||||
|
||||
viewDescriptor.aspect = wgpu::TextureAspect::DepthOnly;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&viewDescriptor));
|
||||
|
||||
viewDescriptor.aspect = wgpu::TextureAspect::StencilOnly;
|
||||
ASSERT_DEVICE_ERROR(texture.CreateView(&viewDescriptor));
|
||||
}
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
|
Loading…
Reference in New Issue