mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-10-09 11:29:02 +00:00
Previously, this code path was gated on whether or not the texture format is renderable. This should not be the case as this Vulkan command only requires the texture to have TRANSFER_DST. Bug: dawn:145 Change-Id: Ifd8f75a70477a8d159c04d1180247cd076c767bc Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/27941 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Stephen White <senorblanco@chromium.org>
298 lines
12 KiB
C++
298 lines
12 KiB
C++
// Copyright 2019 The Dawn Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "tests/DawnTest.h"
|
|
|
|
#include "common/Constants.h"
|
|
#include "utils/ComboRenderPipelineDescriptor.h"
|
|
#include "utils/WGPUHelpers.h"
|
|
|
|
class NonzeroTextureCreationTests : public DawnTest {
|
|
protected:
|
|
void SetUp() override {
|
|
DawnTest::SetUp();
|
|
}
|
|
|
|
constexpr static uint32_t kSize = 128;
|
|
};
|
|
|
|
// Test that texture clears 0xFF 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.depth = 1;
|
|
descriptor.sampleCount = 1;
|
|
descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
|
descriptor.mipLevelCount = 1;
|
|
descriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
RGBA8 filled(255, 255, 255, 255);
|
|
EXPECT_PIXEL_RGBA8_EQ(filled, texture, 0, 0);
|
|
}
|
|
|
|
// Test that a depth texture clears 0xFF because toggle is enabled.
|
|
TEST_P(NonzeroTextureCreationTests, Depth32TextureCreationDepthClears) {
|
|
// Copies from depth textures not supported on the OpenGL backend right now.
|
|
DAWN_SKIP_TEST_IF(IsOpenGL());
|
|
|
|
wgpu::TextureDescriptor descriptor;
|
|
descriptor.dimension = wgpu::TextureDimension::e2D;
|
|
descriptor.size.width = kSize;
|
|
descriptor.size.height = kSize;
|
|
descriptor.size.depth = 1;
|
|
descriptor.sampleCount = 1;
|
|
descriptor.mipLevelCount = 1;
|
|
descriptor.usage = wgpu::TextureUsage::OutputAttachment | 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.
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
std::vector<float> expected(kSize * kSize, 1.f);
|
|
EXPECT_TEXTURE_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 0);
|
|
}
|
|
|
|
// 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.depth = 1;
|
|
descriptor.sampleCount = 1;
|
|
descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
|
descriptor.mipLevelCount = mipLevels;
|
|
descriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
std::vector<RGBA8> expected;
|
|
RGBA8 filled(255, 255, 255, 255);
|
|
for (uint32_t i = 0; i < kSize * kSize; ++i) {
|
|
expected.push_back(filled);
|
|
}
|
|
uint32_t mipSize = kSize >> 2;
|
|
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, mipSize, mipSize, 2, 0);
|
|
}
|
|
|
|
// Test that non-zero array layers clears 0xFF because toggle is enabled.
|
|
TEST_P(NonzeroTextureCreationTests, ArrayLayerClears) {
|
|
constexpr uint32_t arrayLayers = 4;
|
|
|
|
wgpu::TextureDescriptor descriptor;
|
|
descriptor.dimension = wgpu::TextureDimension::e2D;
|
|
descriptor.size.width = kSize;
|
|
descriptor.size.height = kSize;
|
|
descriptor.size.depth = arrayLayers;
|
|
descriptor.sampleCount = 1;
|
|
descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
|
descriptor.mipLevelCount = 1;
|
|
descriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
std::vector<RGBA8> expected;
|
|
RGBA8 filled(255, 255, 255, 255);
|
|
for (uint32_t i = 0; i < kSize * kSize; ++i) {
|
|
expected.push_back(filled);
|
|
}
|
|
|
|
EXPECT_TEXTURE_RGBA8_EQ(expected.data(), texture, 0, 0, kSize, kSize, 0, 2);
|
|
}
|
|
|
|
// Test that nonrenderable texture formats clear 0x01 because toggle is enabled
|
|
TEST_P(NonzeroTextureCreationTests, NonrenderableTextureFormat) {
|
|
wgpu::TextureDescriptor descriptor;
|
|
descriptor.dimension = wgpu::TextureDimension::e2D;
|
|
descriptor.size.width = kSize;
|
|
descriptor.size.height = kSize;
|
|
descriptor.size.depth = 1;
|
|
descriptor.sampleCount = 1;
|
|
descriptor.format = wgpu::TextureFormat::RGBA8Snorm;
|
|
descriptor.mipLevelCount = 1;
|
|
descriptor.usage = wgpu::TextureUsage::CopySrc;
|
|
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 = 4 * kSize * kSize;
|
|
std::vector<uint8_t> data(bufferSize, 100);
|
|
wgpu::Buffer bufferDst = utils::CreateBufferFromData(
|
|
device, data.data(), static_cast<uint32_t>(data.size()), wgpu::BufferUsage::CopySrc);
|
|
|
|
wgpu::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(bufferDst, 0, kSize * 4, 0);
|
|
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, {0, 0, 0});
|
|
wgpu::Extent3D copySize = {kSize, kSize, 1};
|
|
|
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
encoder.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, ©Size);
|
|
wgpu::CommandBuffer commands = encoder.Finish();
|
|
queue.Submit(1, &commands);
|
|
|
|
uint32_t expectedBytes = IsVulkan() ? 0x7F7F7F7F : 0x01010101;
|
|
std::vector<uint32_t> expected(bufferSize, expectedBytes);
|
|
EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), bufferDst, 0, 8);
|
|
}
|
|
|
|
// Test that textures with more than 1 array layers and nonrenderable texture formats clear to 0x01
|
|
// because toggle is enabled
|
|
TEST_P(NonzeroTextureCreationTests, NonRenderableTextureClearWithMultiArrayLayers) {
|
|
wgpu::TextureDescriptor descriptor;
|
|
descriptor.dimension = wgpu::TextureDimension::e2D;
|
|
descriptor.size.width = kSize;
|
|
descriptor.size.height = kSize;
|
|
descriptor.size.depth = 2;
|
|
descriptor.sampleCount = 1;
|
|
descriptor.format = wgpu::TextureFormat::RGBA8Snorm;
|
|
descriptor.mipLevelCount = 1;
|
|
descriptor.usage = wgpu::TextureUsage::CopySrc;
|
|
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 = 4 * kSize * kSize;
|
|
std::vector<uint8_t> data(bufferSize, 100);
|
|
wgpu::Buffer bufferDst = utils::CreateBufferFromData(
|
|
device, data.data(), static_cast<uint32_t>(data.size()), wgpu::BufferUsage::CopySrc);
|
|
|
|
wgpu::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(bufferDst, 0, kSize * 4, 0);
|
|
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(texture, 0, {0, 0, 1});
|
|
wgpu::Extent3D copySize = {kSize, kSize, 1};
|
|
|
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
|
encoder.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, ©Size);
|
|
wgpu::CommandBuffer commands = encoder.Finish();
|
|
queue.Submit(1, &commands);
|
|
|
|
uint32_t expectedBytes = IsVulkan() ? 0x7F7F7F7F : 0x01010101;
|
|
std::vector<uint32_t> expected(bufferSize, expectedBytes);
|
|
EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), bufferDst, 0, 8);
|
|
}
|
|
|
|
// Test that all subresources of a renderable texture are filled because the toggle is enabled.
|
|
TEST_P(NonzeroTextureCreationTests, AllSubresourcesFilled) {
|
|
wgpu::TextureDescriptor baseDescriptor;
|
|
baseDescriptor.dimension = wgpu::TextureDimension::e2D;
|
|
baseDescriptor.size.width = kSize;
|
|
baseDescriptor.size.height = kSize;
|
|
baseDescriptor.size.depth = 1;
|
|
baseDescriptor.sampleCount = 1;
|
|
baseDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
|
|
baseDescriptor.mipLevelCount = 1;
|
|
baseDescriptor.usage = wgpu::TextureUsage::OutputAttachment | wgpu::TextureUsage::CopySrc;
|
|
|
|
RGBA8 filled(255, 255, 255, 255);
|
|
|
|
{
|
|
wgpu::TextureDescriptor descriptor = baseDescriptor;
|
|
// Some textures may be cleared with render pass load/store ops.
|
|
// Test above the max attachment count.
|
|
descriptor.size.depth = kMaxColorAttachments + 1;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
for (uint32_t i = 0; i < descriptor.size.depth; ++i) {
|
|
EXPECT_TEXTURE_RGBA8_EQ(&filled, texture, 0, 0, 1, 1, 0, i);
|
|
}
|
|
}
|
|
|
|
{
|
|
wgpu::TextureDescriptor descriptor = baseDescriptor;
|
|
descriptor.mipLevelCount = 3;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
for (uint32_t i = 0; i < descriptor.mipLevelCount; ++i) {
|
|
EXPECT_TEXTURE_RGBA8_EQ(&filled, texture, 0, 0, 1, 1, i, 0);
|
|
}
|
|
}
|
|
|
|
{
|
|
wgpu::TextureDescriptor descriptor = baseDescriptor;
|
|
// Some textures may be cleared with render pass load/store ops.
|
|
// Test above the max attachment count.
|
|
descriptor.size.depth = kMaxColorAttachments + 1;
|
|
descriptor.mipLevelCount = 3;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
for (uint32_t i = 0; i < descriptor.size.depth; ++i) {
|
|
for (uint32_t j = 0; j < descriptor.mipLevelCount; ++j) {
|
|
EXPECT_TEXTURE_RGBA8_EQ(&filled, texture, 0, 0, 1, 1, j, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Test that all subresources of a nonrenderable texture are filled because the toggle is enabled.
|
|
TEST_P(NonzeroTextureCreationTests, NonRenderableAllSubresourcesFilled) {
|
|
wgpu::TextureDescriptor baseDescriptor;
|
|
baseDescriptor.dimension = wgpu::TextureDimension::e2D;
|
|
baseDescriptor.size.width = kSize;
|
|
baseDescriptor.size.height = kSize;
|
|
baseDescriptor.size.depth = 1;
|
|
baseDescriptor.sampleCount = 1;
|
|
baseDescriptor.format = wgpu::TextureFormat::RGBA8Snorm;
|
|
baseDescriptor.mipLevelCount = 1;
|
|
baseDescriptor.usage = wgpu::TextureUsage::CopySrc;
|
|
|
|
RGBA8 filled = IsVulkan() ? RGBA8(127, 127, 127, 127) : RGBA8(1, 1, 1, 1);
|
|
|
|
{
|
|
wgpu::TextureDescriptor descriptor = baseDescriptor;
|
|
// Some textures may be cleared with render pass load/store ops.
|
|
// Test above the max attachment count.
|
|
descriptor.size.depth = kMaxColorAttachments + 1;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
for (uint32_t i = 0; i < descriptor.size.depth; ++i) {
|
|
EXPECT_TEXTURE_RGBA8_EQ(&filled, texture, 0, 0, 1, 1, 0, i);
|
|
}
|
|
}
|
|
|
|
{
|
|
wgpu::TextureDescriptor descriptor = baseDescriptor;
|
|
descriptor.mipLevelCount = 3;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
for (uint32_t i = 0; i < descriptor.mipLevelCount; ++i) {
|
|
EXPECT_TEXTURE_RGBA8_EQ(&filled, texture, 0, 0, 1, 1, i, 0);
|
|
}
|
|
}
|
|
|
|
{
|
|
wgpu::TextureDescriptor descriptor = baseDescriptor;
|
|
// Some textures may be cleared with render pass load/store ops.
|
|
// Test above the max attachment count.
|
|
descriptor.size.depth = kMaxColorAttachments + 1;
|
|
descriptor.mipLevelCount = 3;
|
|
wgpu::Texture texture = device.CreateTexture(&descriptor);
|
|
|
|
for (uint32_t i = 0; i < descriptor.size.depth; ++i) {
|
|
for (uint32_t j = 0; j < descriptor.mipLevelCount; ++j) {
|
|
EXPECT_TEXTURE_RGBA8_EQ(&filled, texture, 0, 0, 1, 1, j, i);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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"}),
|
|
VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"},
|
|
{"lazy_clear_resource_on_first_use"}));
|