Fix rectangular mipmap textures used as color attachments.
ValidateOrSetAttachmentSize() was asserting that textureSize.width >> attachment->GetBaseMipLevel() is nonzero. This is not true for rectangular textures, where the smaller dimension may hit the lower bound and must be be clamped at 1. Fixed by calling GetMipLevelVirtualSize() which performs the clamp. Added a test which exercises rectangular mipmapped textures as color attachments. This required a few fixes to the test harness, which had the same bug as that fixed in the code (assumes (width >> size) > 0). Bug: dawn:535 Change-Id: Idde3b68feb14d8a241803d09a094b059d9935d91 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/29261 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
16ebcf601d
commit
ed3a93f690
|
@ -186,16 +186,15 @@ namespace dawn_native {
|
|||
MaybeError ValidateOrSetAttachmentSize(const TextureViewBase* attachment,
|
||||
uint32_t* width,
|
||||
uint32_t* height) {
|
||||
const Extent3D& textureSize = attachment->GetTexture()->GetSize();
|
||||
const uint32_t attachmentWidth = textureSize.width >> attachment->GetBaseMipLevel();
|
||||
const uint32_t attachmentHeight = textureSize.height >> attachment->GetBaseMipLevel();
|
||||
const Extent3D& attachmentSize =
|
||||
attachment->GetTexture()->GetMipLevelVirtualSize(attachment->GetBaseMipLevel());
|
||||
|
||||
if (*width == 0) {
|
||||
DAWN_ASSERT(*height == 0);
|
||||
*width = attachmentWidth;
|
||||
*height = attachmentHeight;
|
||||
*width = attachmentSize.width;
|
||||
*height = attachmentSize.height;
|
||||
DAWN_ASSERT(*width != 0 && *height != 0);
|
||||
} else if (*width != attachmentWidth || *height != attachmentHeight) {
|
||||
} else if (*width != attachmentSize.width || *height != attachmentSize.height) {
|
||||
return DAWN_VALIDATION_ERROR("Attachment size mismatch");
|
||||
}
|
||||
|
||||
|
|
|
@ -453,14 +453,14 @@ class TextureViewRenderingTest : public DawnTest {
|
|||
uint32_t layerCount,
|
||||
uint32_t levelCount,
|
||||
uint32_t textureViewBaseLayer,
|
||||
uint32_t textureViewBaseLevel) {
|
||||
uint32_t textureViewBaseLevel,
|
||||
uint32_t textureWidthLevel0,
|
||||
uint32_t textureHeightLevel0) {
|
||||
ASSERT(dimension == wgpu::TextureViewDimension::e2D ||
|
||||
dimension == wgpu::TextureViewDimension::e2DArray);
|
||||
ASSERT_LT(textureViewBaseLayer, layerCount);
|
||||
ASSERT_LT(textureViewBaseLevel, levelCount);
|
||||
|
||||
const uint32_t textureWidthLevel0 = 1 << levelCount;
|
||||
const uint32_t textureHeightLevel0 = 1 << levelCount;
|
||||
constexpr wgpu::TextureUsage kUsage =
|
||||
wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
||||
wgpu::Texture texture = Create2DTexture(device, textureWidthLevel0, textureHeightLevel0,
|
||||
|
@ -511,8 +511,8 @@ class TextureViewRenderingTest : public DawnTest {
|
|||
queue.Submit(1, &commands);
|
||||
|
||||
// Check if the right pixels (Green) have been written into the right part of the texture.
|
||||
uint32_t textureViewWidth = textureWidthLevel0 >> textureViewBaseLevel;
|
||||
uint32_t textureViewHeight = textureHeightLevel0 >> textureViewBaseLevel;
|
||||
uint32_t textureViewWidth = std::max(1u, textureWidthLevel0 >> textureViewBaseLevel);
|
||||
uint32_t textureViewHeight = std::max(1u, textureHeightLevel0 >> textureViewBaseLevel);
|
||||
uint32_t bytesPerRow =
|
||||
Align(kBytesPerTexel * textureWidthLevel0, kTextureBytesPerRowAlignment);
|
||||
uint32_t expectedDataSize =
|
||||
|
@ -534,14 +534,43 @@ TEST_P(TextureViewRenderingTest, Texture2DViewOnALevelOf2DTextureAsColorAttachme
|
|||
{
|
||||
constexpr uint32_t kBaseLevel = 0;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
|
||||
// Rendering into the last level
|
||||
{
|
||||
constexpr uint32_t kBaseLevel = kMipLevels - 1;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
}
|
||||
|
||||
// Test rendering into a 2D texture view created on a mipmap level of a rectangular 2D texture.
|
||||
TEST_P(TextureViewRenderingTest, Texture2DViewOnALevelOfRectangular2DTextureAsColorAttachment) {
|
||||
constexpr uint32_t kLayers = 1;
|
||||
constexpr uint32_t kMipLevels = 4;
|
||||
constexpr uint32_t kBaseLayer = 0;
|
||||
|
||||
// Rendering into the first level
|
||||
{
|
||||
constexpr uint32_t kBaseLevel = 0;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels,
|
||||
1 << (kMipLevels - 2));
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel, 1 << (kMipLevels - 2),
|
||||
1 << kMipLevels);
|
||||
}
|
||||
|
||||
// Rendering into the last level
|
||||
{
|
||||
constexpr uint32_t kBaseLevel = kMipLevels - 1;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels,
|
||||
1 << (kMipLevels - 2));
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel, 1 << (kMipLevels - 2),
|
||||
1 << kMipLevels);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,14 +584,14 @@ TEST_P(TextureViewRenderingTest, Texture2DViewOnALayerOf2DArrayTextureAsColorAtt
|
|||
{
|
||||
constexpr uint32_t kBaseLayer = 0;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
|
||||
// Rendering into the last layer
|
||||
{
|
||||
constexpr uint32_t kBaseLayer = kLayers - 1;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2D, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -576,14 +605,14 @@ TEST_P(TextureViewRenderingTest, Texture2DArrayViewOnALevelOf2DTextureAsColorAtt
|
|||
{
|
||||
constexpr uint32_t kBaseLevel = 0;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2DArray, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
|
||||
// Rendering into the last level
|
||||
{
|
||||
constexpr uint32_t kBaseLevel = kMipLevels - 1;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2DArray, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -597,14 +626,14 @@ TEST_P(TextureViewRenderingTest, Texture2DArrayViewOnALayerOf2DArrayTextureAsCol
|
|||
{
|
||||
constexpr uint32_t kBaseLayer = 0;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2DArray, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
|
||||
// Rendering into the last layer
|
||||
{
|
||||
constexpr uint32_t kBaseLayer = kLayers - 1;
|
||||
TextureLayerAsColorAttachmentTest(wgpu::TextureViewDimension::e2DArray, kLayers, kMipLevels,
|
||||
kBaseLayer, kBaseLevel);
|
||||
kBaseLayer, kBaseLevel, 1 << kMipLevels, 1 << kMipLevels);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue