diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 6274f849c6..def417ab64 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp @@ -1072,7 +1072,7 @@ namespace dawn_native { namespace vulkan { device->fn.CmdCopyBufferToImage( recordingContext->commandBuffer, ToBackend(uploadHandle.stagingBuffer)->GetBufferHandle(), GetHandle(), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, regions.data()); + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, regions.size(), regions.data()); } else { for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount; ++level) { diff --git a/src/tests/DawnTest.h b/src/tests/DawnTest.h index 8bf1629d1f..b016a33480 100644 --- a/src/tests/DawnTest.h +++ b/src/tests/DawnTest.h @@ -39,6 +39,13 @@ #define EXPECT_BUFFER(buffer, offset, size, expectation) \ AddBufferExpectation(__FILE__, __LINE__, buffer, offset, size, expectation) +#define EXPECT_BUFFER_U8_EQ(expected, buffer, offset) \ + EXPECT_BUFFER(buffer, offset, sizeof(uint8_t), new ::detail::ExpectEq(expected)) + +#define EXPECT_BUFFER_U8_RANGE_EQ(expected, buffer, offset, count) \ + EXPECT_BUFFER(buffer, offset, sizeof(uint8_t) * (count), \ + new ::detail::ExpectEq(expected, count)) + #define EXPECT_BUFFER_U16_EQ(expected, buffer, offset) \ EXPECT_BUFFER(buffer, offset, sizeof(uint16_t), new ::detail::ExpectEq(expected)) @@ -174,6 +181,7 @@ namespace utils { namespace detail { class Expectation; + class CustomTextureExpectation; template class ExpectEq; @@ -361,6 +369,22 @@ class DawnTestBase { origin, {1, 1}, level, aspect, sizeof(T), bytesPerRow); } + template ::value>::type> + std::ostringstream& AddTextureExpectation(const char* file, + int line, + E* expectation, + const wgpu::Texture& texture, + wgpu::Origin3D origin, + wgpu::Extent3D extent, + uint32_t level = 0, + wgpu::TextureAspect aspect = wgpu::TextureAspect::All, + uint32_t bytesPerRow = 0) { + return AddTextureExpectationImpl(file, line, expectation, texture, origin, extent, level, + aspect, expectation->DataSize(), bytesPerRow); + } + template std::ostringstream& AddTextureBetweenColorsExpectation( const char* file, @@ -634,6 +658,13 @@ namespace detail { // each counterparts. It doesn't matter which value is higher or lower. Essentially color = // lerp(color0, color1, t) where t is [0,1]. But I don't want to be too strict here. extern template class ExpectBetweenColors; + + class CustomTextureExpectation : public Expectation { + public: + virtual ~CustomTextureExpectation() = default; + virtual uint32_t DataSize() = 0; + }; + } // namespace detail #endif // TESTS_DAWNTEST_H_ diff --git a/src/tests/end2end/NonzeroTextureCreationTests.cpp b/src/tests/end2end/NonzeroTextureCreationTests.cpp index 9cd3a9518c..b20d2ec39c 100644 --- a/src/tests/end2end/NonzeroTextureCreationTests.cpp +++ b/src/tests/end2end/NonzeroTextureCreationTests.cpp @@ -15,257 +15,276 @@ #include "tests/DawnTest.h" #include "common/Constants.h" +#include "common/Math.h" #include "utils/ComboRenderPipelineDescriptor.h" +#include "utils/TestUtils.h" #include "utils/WGPUHelpers.h" -class NonzeroTextureCreationTests : public DawnTest { - protected: - constexpr static uint32_t kSize = 128; - constexpr static uint32_t kDepthOrArrayLayers = 7; -}; +namespace { -// Test that texture clears 0xFF because toggle is enabled. + using Format = wgpu::TextureFormat; + using Usage = wgpu::TextureUsage; + using Dimension = wgpu::TextureDimension; + using DepthOrArrayLayers = uint32_t; + using Mip = uint32_t; + + DAWN_TEST_PARAM_STRUCT(Params, Format, Usage, Dimension, DepthOrArrayLayers, Mip) + + template + class ExpectNonZero : public detail::CustomTextureExpectation { + public: + uint32_t DataSize() override { + return sizeof(T); + } + + testing::AssertionResult Check(const void* data, size_t size) override { + ASSERT(size % DataSize() == 0 && size > 0); + const T* actual = static_cast(data); + T value = *actual; + if (value == T(0)) { + return testing::AssertionFailure() + << "Expected data to be non-zero, was " << value << std::endl; + } + for (size_t i = 0; i < size / DataSize(); ++i) { + if (actual[i] != value) { + return testing::AssertionFailure() + << "Expected data[" << i << "] to be " << value << ", actual " + << actual[i] << std::endl; + } + } + + return testing::AssertionSuccess(); + } + }; + +#define EXPECT_TEXTURE_NONZERO(T, ...) \ + AddTextureExpectation(__FILE__, __LINE__, new ExpectNonZero(), __VA_ARGS__) + + class NonzeroTextureCreationTests : public DawnTestWithParams { + protected: + constexpr static uint32_t kSize = 128; + constexpr static uint32_t kMipLevelCount = 4; + + std::vector GetRequiredExtensions() override { + if (GetParam().mFormat == wgpu::TextureFormat::BC1RGBAUnorm && + SupportsExtensions({"texture_compression_bc"})) { + return {"texture_compression_bc"}; + } + return {}; + } + + void Run() { + DAWN_TEST_UNSUPPORTED_IF(GetParam().mFormat == wgpu::TextureFormat::BC1RGBAUnorm && + !SupportsExtensions({"texture_compression_bc"})); + + // TODO(crbug.com/dawn/667): Work around the fact that some platforms do not support + // reading from Snorm textures. + DAWN_TEST_UNSUPPORTED_IF(GetParam().mFormat == wgpu::TextureFormat::RGBA8Snorm && + HasToggleEnabled("disable_snorm_read")); + + // TODO(crbug.com/dawn/547): 3D texture copies not fully implemented on D3D12. + // TODO(crbug.com/angleproject/5967): This texture readback hits an assert in ANGLE. + DAWN_SUPPRESS_TEST_IF(GetParam().mDimension == wgpu::TextureDimension::e3D && + (IsANGLE() || IsD3D12())); + + // TODO(crbug.com/dawn/791): Determine Intel specific platforms this occurs on, and + // implement a workaround on all backends (happens on Windows too, but not on our test + // machines). + DAWN_SUPPRESS_TEST_IF(GetParam().mFormat == wgpu::TextureFormat::Depth32Float && + IsMetal() && IsIntel() && GetParam().mMip != 0); + + // Copies from depth textures not fully supported on the OpenGL backend right now. + DAWN_SUPPRESS_TEST_IF(GetParam().mFormat == wgpu::TextureFormat::Depth32Float && + (IsOpenGL() || IsOpenGLES())); + + // GL may support the extension, but reading data back is not implemented. + DAWN_TEST_UNSUPPORTED_IF(GetParam().mFormat == wgpu::TextureFormat::BC1RGBAUnorm && + (IsOpenGL() || IsOpenGLES())); + + wgpu::TextureDescriptor descriptor; + descriptor.dimension = GetParam().mDimension; + descriptor.size.width = kSize; + descriptor.size.height = kSize; + descriptor.size.depthOrArrayLayers = GetParam().mDepthOrArrayLayers; + descriptor.sampleCount = 1; + descriptor.format = GetParam().mFormat; + descriptor.usage = GetParam().mUsage; + descriptor.mipLevelCount = kMipLevelCount; + + wgpu::Texture texture = device.CreateTexture(&descriptor); + + uint32_t mip = GetParam().mMip; + uint32_t mipSize = std::max(kSize >> mip, 1u); + uint32_t depthOrArrayLayers = GetParam().mDimension == wgpu::TextureDimension::e3D + ? std::max(GetParam().mDepthOrArrayLayers >> mip, 1u) + : GetParam().mDepthOrArrayLayers; + + switch (GetParam().mFormat) { + case wgpu::TextureFormat::R8Unorm: { + EXPECT_TEXTURE_EQ(new ExpectNonZero(), texture, {0, 0, 0}, + {mipSize, mipSize, depthOrArrayLayers}, mip); + break; + } + case wgpu::TextureFormat::RG8Unorm: { + EXPECT_TEXTURE_EQ(new ExpectNonZero(), texture, {0, 0, 0}, + {mipSize, mipSize, depthOrArrayLayers}, mip); + break; + } + case wgpu::TextureFormat::RGBA8Unorm: + case wgpu::TextureFormat::RGBA8Snorm: { + EXPECT_TEXTURE_EQ(new ExpectNonZero(), texture, {0, 0, 0}, + {mipSize, mipSize, depthOrArrayLayers}, mip); + break; + } + case wgpu::TextureFormat::Depth32Float: { + EXPECT_TEXTURE_EQ(new ExpectNonZero(), texture, {0, 0, 0}, + {mipSize, mipSize, depthOrArrayLayers}, mip); + break; + } + case wgpu::TextureFormat::BC1RGBAUnorm: { + // Set buffer with dirty data so we know it is cleared by the lazy cleared + // texture copy + uint32_t blockWidth = utils::GetTextureFormatBlockWidth(GetParam().mFormat); + uint32_t blockHeight = utils::GetTextureFormatBlockHeight(GetParam().mFormat); + wgpu::Extent3D copySize = {Align(mipSize, blockWidth), + Align(mipSize, blockHeight), depthOrArrayLayers}; + + uint32_t bytesPerRow = + utils::GetMinimumBytesPerRow(GetParam().mFormat, copySize.width); + uint32_t rowsPerImage = copySize.height / blockHeight; + + uint64_t bufferSize = utils::RequiredBytesInCopy(bytesPerRow, rowsPerImage, + copySize, GetParam().mFormat); + + std::vector data(bufferSize, 100); + wgpu::Buffer bufferDst = utils::CreateBufferFromData( + device, data.data(), bufferSize, wgpu::BufferUsage::CopySrc); + + wgpu::ImageCopyBuffer imageCopyBuffer = + utils::CreateImageCopyBuffer(bufferDst, 0, bytesPerRow, rowsPerImage); + wgpu::ImageCopyTexture imageCopyTexture = + utils::CreateImageCopyTexture(texture, mip, {0, 0, 0}); + + wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); + encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, ©Size); + wgpu::CommandBuffer commands = encoder.Finish(); + queue.Submit(1, &commands); + + uint32_t copiedWidthInBytes = + utils::GetTexelBlockSizeInBytes(GetParam().mFormat) * copySize.width / + blockWidth; + uint8_t* d = data.data(); + for (uint32_t z = 0; z < depthOrArrayLayers; ++z) { + for (uint32_t row = 0; row < copySize.height / blockHeight; ++row) { + std::fill_n(d, copiedWidthInBytes, 1); + d += bytesPerRow; + } + } + EXPECT_BUFFER_U8_RANGE_EQ(data.data(), bufferDst, 0, bufferSize); + break; + } + default: + UNREACHABLE(); + } + } + }; + + class NonzeroNonrenderableTextureCreationTests : public NonzeroTextureCreationTests {}; + class NonzeroCompressedTextureCreationTests : public NonzeroTextureCreationTests {}; + class NonzeroDepthTextureCreationTests : public NonzeroTextureCreationTests {}; + +} // anonymous namespace + +// Test that texture clears to a non-zero value because toggle is enabled. TEST_P(NonzeroTextureCreationTests, TextureCreationClears) { - wgpu::TextureDescriptor descriptor; - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.width = kSize; - descriptor.size.height = kSize; - descriptor.size.depthOrArrayLayers = 1; - descriptor.sampleCount = 1; - descriptor.format = wgpu::TextureFormat::RGBA8Unorm; - descriptor.mipLevelCount = 1; - descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; - - // 2D - { - wgpu::Texture texture = device.CreateTexture(&descriptor); - - std::vector expected(kSize * kSize, RGBA8(255, 255, 255, 255)); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0}, {kSize, kSize}); - } - - // 2D Array - { - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - wgpu::Texture texture = device.CreateTexture(&descriptor); - - std::vector expected(kSize * kSize * kDepthOrArrayLayers, RGBA8(255, 255, 255, 255)); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0, 0}, {kSize, kSize, kDepthOrArrayLayers}); - } + Run(); } -// Test that 3D texture clears to nonzero because toggle is enabled. -TEST_P(NonzeroTextureCreationTests, Texture3DCreationClears) { - // TODO(crbug.com/dawn/547): 3D texture copies not fully implemented on D3D12. - // TODO(crbug.com/angleproject/5967): This texture readback hits an assert in ANGLE. - DAWN_TEST_UNSUPPORTED_IF(IsD3D12()); - DAWN_SUPPRESS_TEST_IF(IsANGLE()); - - wgpu::TextureDescriptor descriptor; - descriptor.dimension = wgpu::TextureDimension::e3D; - descriptor.size.width = kSize; - descriptor.size.height = kSize; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - descriptor.sampleCount = 1; - descriptor.format = wgpu::TextureFormat::RGBA8Unorm; - descriptor.mipLevelCount = 1; - descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; - wgpu::Texture texture = device.CreateTexture(&descriptor); - - std::vector expected(kSize * kSize * kDepthOrArrayLayers, RGBA8(255, 255, 255, 255)); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0, 0}, {kSize, kSize, kDepthOrArrayLayers}); +// Test that texture clears to a non-zero value because toggle is enabled. +TEST_P(NonzeroNonrenderableTextureCreationTests, TextureCreationClears) { + Run(); } -// Test that a depth texture clears 0xFF because toggle is enabled. -TEST_P(NonzeroTextureCreationTests, Depth32TextureCreationDepthClears) { - // Copies from depth textures not fully supported on the OpenGL backend right now. - DAWN_TEST_UNSUPPORTED_IF(IsOpenGL() || IsOpenGLES()); - - wgpu::TextureDescriptor descriptor; - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.width = kSize; - descriptor.size.height = kSize; - descriptor.size.depthOrArrayLayers = 1; - descriptor.sampleCount = 1; - descriptor.mipLevelCount = 1; - descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; - descriptor.format = wgpu::TextureFormat::Depth32Float; - - // We can only really test Depth32Float here because Depth24Plus(Stencil8)? may be in an unknown - // format. - // TODO(crbug.com/dawn/145): Test other formats via sampling. - - // 2D - { - wgpu::Texture texture = device.CreateTexture(&descriptor); - std::vector expected(kSize * kSize, 1.f); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0}, {kSize, kSize}); - } - - // 2D Array - { - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - wgpu::Texture texture = device.CreateTexture(&descriptor); - std::vector expected(kSize * kSize * kDepthOrArrayLayers, 1.f); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0, 0}, {kSize, kSize, kDepthOrArrayLayers}); - } +// Test that texture clears to a non-zero value because toggle is enabled. +TEST_P(NonzeroCompressedTextureCreationTests, TextureCreationClears) { + Run(); } -// Test that non-zero mip level clears 0xFF because toggle is enabled. -TEST_P(NonzeroTextureCreationTests, MipMapClears) { - constexpr uint32_t mipLevels = 4; - - wgpu::TextureDescriptor descriptor; - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.width = kSize; - descriptor.size.height = kSize; - descriptor.size.depthOrArrayLayers = 1; - descriptor.sampleCount = 1; - descriptor.format = wgpu::TextureFormat::RGBA8Unorm; - descriptor.mipLevelCount = mipLevels; - descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc; - - // 2D - { - wgpu::Texture texture = device.CreateTexture(&descriptor); - uint32_t mipSize = kSize >> 2; - std::vector expected(mipSize * mipSize, RGBA8(255, 255, 255, 255)); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0}, {mipSize, mipSize}, 2); - } - - // 2D Array - { - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - wgpu::Texture texture = device.CreateTexture(&descriptor); - uint32_t mipSize = kSize >> 2; - std::vector expected(mipSize * mipSize * kDepthOrArrayLayers, - RGBA8(255, 255, 255, 255)); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0, 0}, - {mipSize, mipSize, kDepthOrArrayLayers}, 2); - } - - // 3D - { - descriptor.dimension = wgpu::TextureDimension::e3D; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - wgpu::Texture texture = device.CreateTexture(&descriptor); - uint32_t mipSize = kSize >> 2; - uint32_t mipDepth = kDepthOrArrayLayers >> 2; - std::vector expected(mipSize * mipSize * mipDepth, RGBA8(255, 255, 255, 255)); - EXPECT_TEXTURE_EQ(expected.data(), texture, {0, 0, 0}, {mipSize, mipSize, mipDepth}, 2); - } +// Test that texture clears to a non-zero value because toggle is enabled. +TEST_P(NonzeroDepthTextureCreationTests, TextureCreationClears) { + Run(); } -// Test that nonrenderable texture formats clear 0x01 because toggle is enabled -TEST_P(NonzeroTextureCreationTests, NonrenderableTextureFormat) { - // TODO(crbug.com/dawn/667): Work around the fact that some platforms do not support reading - // from Snorm textures. - DAWN_TEST_UNSUPPORTED_IF(HasToggleEnabled("disable_snorm_read")); +// TODO(crbug.com/794): Test/implement texture initialization for multisampled textures. - wgpu::TextureDescriptor descriptor; - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.width = kSize; - descriptor.size.height = kSize; - descriptor.size.depthOrArrayLayers = 1; - descriptor.sampleCount = 1; - descriptor.format = wgpu::TextureFormat::RGBA8Snorm; - descriptor.mipLevelCount = 1; - descriptor.usage = wgpu::TextureUsage::CopySrc; +DAWN_INSTANTIATE_TEST_P( + NonzeroTextureCreationTests, + {D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLESBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"})}, + {wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm, wgpu::TextureFormat::RGBA8Unorm}, + {wgpu::TextureUsage(wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc), + wgpu::TextureUsage::CopySrc}, + {wgpu::TextureDimension::e2D, wgpu::TextureDimension::e3D}, + {1u, 7u}, + {0u, 1u, 2u, 3u}); - // 2D - { - wgpu::Texture texture = device.CreateTexture(&descriptor); - - // Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy - uint32_t bufferSize = kSize * kSize; - std::vector data(sizeof(uint32_t) * bufferSize, 100); - wgpu::Buffer bufferDst = utils::CreateBufferFromData( - device, data.data(), static_cast(data.size()), wgpu::BufferUsage::CopySrc); - - wgpu::ImageCopyBuffer imageCopyBuffer = - utils::CreateImageCopyBuffer(bufferDst, 0, kSize * 4); - wgpu::ImageCopyTexture imageCopyTexture = - utils::CreateImageCopyTexture(texture, 0, {0, 0, 0}); - wgpu::Extent3D copySize = {kSize, kSize, 1}; - - wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); - encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, ©Size); - wgpu::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); - - uint32_t expectedBytes = IsVulkan() ? 0x7F7F7F7F : 0x01010101; - std::vector expected(bufferSize, expectedBytes); - EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), bufferDst, 0, expected.size()); - } - - // 2D Array - { - descriptor.dimension = wgpu::TextureDimension::e2D; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - wgpu::Texture texture = device.CreateTexture(&descriptor); - - // Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy - uint32_t bufferSize = kSize * kSize * kDepthOrArrayLayers; - std::vector data(sizeof(uint32_t) * bufferSize, 100); - wgpu::Buffer bufferDst = utils::CreateBufferFromData( - device, data.data(), static_cast(data.size()), wgpu::BufferUsage::CopySrc); - - wgpu::ImageCopyBuffer imageCopyBuffer = - utils::CreateImageCopyBuffer(bufferDst, 0, kSize * 4, kSize); - wgpu::ImageCopyTexture imageCopyTexture = - utils::CreateImageCopyTexture(texture, 0, {0, 0, 0}); - wgpu::Extent3D copySize = {kSize, kSize, kDepthOrArrayLayers}; - - wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); - encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, ©Size); - wgpu::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); - - uint32_t expectedBytes = IsVulkan() ? 0x7F7F7F7F : 0x01010101; - std::vector expected(bufferSize, expectedBytes); - EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), bufferDst, 0, expected.size()); - } - - // 3D - { - descriptor.dimension = wgpu::TextureDimension::e3D; - descriptor.size.depthOrArrayLayers = kDepthOrArrayLayers; - wgpu::Texture texture = device.CreateTexture(&descriptor); - - // Set buffer with dirty data so we know it is cleared by the lazy cleared texture copy - uint32_t bufferSize = kSize * kSize * kDepthOrArrayLayers; - std::vector data(sizeof(uint32_t) * bufferSize, 100); - wgpu::Buffer bufferDst = utils::CreateBufferFromData( - device, data.data(), static_cast(data.size()), wgpu::BufferUsage::CopySrc); - - wgpu::ImageCopyBuffer imageCopyBuffer = - utils::CreateImageCopyBuffer(bufferDst, 0, kSize * 4, kSize); - wgpu::ImageCopyTexture imageCopyTexture = - utils::CreateImageCopyTexture(texture, 0, {0, 0, 0}); - wgpu::Extent3D copySize = {kSize, kSize, kDepthOrArrayLayers}; - - wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); - encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, ©Size); - wgpu::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); - - uint32_t expectedBytes = IsVulkan() ? 0x7F7F7F7F : 0x01010101; - std::vector expected(bufferSize, expectedBytes); - EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), bufferDst, 0, expected.size()); - } -} - -DAWN_INSTANTIATE_TEST(NonzeroTextureCreationTests, - D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}, - {"lazy_clear_resource_on_first_use"}), - MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}, - {"lazy_clear_resource_on_first_use"}), - OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}, - {"lazy_clear_resource_on_first_use"}), - OpenGLESBackend({"nonzero_clear_resources_on_creation_for_testing"}, +DAWN_INSTANTIATE_TEST_P(NonzeroNonrenderableTextureCreationTests, + {D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}, {"lazy_clear_resource_on_first_use"}), - VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}, - {"lazy_clear_resource_on_first_use"})); + MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLESBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"})}, + {wgpu::TextureFormat::RGBA8Snorm}, + {wgpu::TextureUsage::CopySrc}, + {wgpu::TextureDimension::e2D, wgpu::TextureDimension::e3D}, + {1u, 7u}, + {0u, 1u, 2u, 3u}); + +DAWN_INSTANTIATE_TEST_P(NonzeroCompressedTextureCreationTests, + {D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLESBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"})}, + {wgpu::TextureFormat::BC1RGBAUnorm}, + {wgpu::TextureUsage::CopySrc}, + {wgpu::TextureDimension::e2D}, + {1u, 7u}, + {0u, 1u, 2u, 3u}); + +DAWN_INSTANTIATE_TEST_P(NonzeroDepthTextureCreationTests, + {D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + MetalBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + OpenGLESBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"}), + VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"}, + {"lazy_clear_resource_on_first_use"})}, + {wgpu::TextureFormat::Depth32Float}, + {wgpu::TextureUsage(wgpu::TextureUsage::RenderAttachment | + wgpu::TextureUsage::CopySrc), + wgpu::TextureUsage::CopySrc}, + {wgpu::TextureDimension::e2D}, + {1u, 7u}, + {0u, 1u, 2u, 3u}); diff --git a/src/utils/TestUtils.cpp b/src/utils/TestUtils.cpp index acae87e3d6..cf700af36f 100644 --- a/src/utils/TestUtils.cpp +++ b/src/utils/TestUtils.cpp @@ -26,7 +26,9 @@ namespace utils { uint32_t GetMinimumBytesPerRow(wgpu::TextureFormat format, uint32_t width) { const uint32_t bytesPerBlock = utils::GetTexelBlockSizeInBytes(format); - return Align(bytesPerBlock * width, kTextureBytesPerRowAlignment); + const uint32_t blockWidth = utils::GetTextureFormatBlockWidth(format); + ASSERT(width % blockWidth == 0); + return Align(bytesPerBlock * (width / blockWidth), kTextureBytesPerRowAlignment); } TextureDataCopyLayout GetTextureDataCopyLayoutForTexture2DAtLevel(