// 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 #include class NonzeroBufferCreationTests : public DawnTest { public: void MapReadAsyncAndWait(wgpu::Buffer buffer, uint64_t offset, uint64_t size) { bool done = false; buffer.MapAsync( wgpu::MapMode::Read, offset, size, [](WGPUBufferMapAsyncStatus status, void* userdata) { ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status); *static_cast(userdata) = true; }, &done); while (!done) { WaitABit(); } } }; // Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when it // is created with CopyDst usage. TEST_P(NonzeroBufferCreationTests, BufferCreationWithCopyDstUsage) { constexpr uint32_t kSize = 32u; wgpu::BufferDescriptor descriptor; descriptor.size = kSize; descriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst; wgpu::Buffer buffer = device.CreateBuffer(&descriptor); std::vector expectedData(kSize, uint8_t(1u)); EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast(expectedData.data()), buffer, 0, kSize / sizeof(uint32_t)); } // Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when it // is created with MapWrite without CopyDst usage. TEST_P(NonzeroBufferCreationTests, BufferCreationWithMapWriteWithoutCopyDstUsage) { constexpr uint32_t kSize = 32u; wgpu::BufferDescriptor descriptor; descriptor.size = kSize; descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc; wgpu::Buffer buffer = device.CreateBuffer(&descriptor); std::vector expectedData(kSize, uint8_t(1u)); EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast(expectedData.data()), buffer, 0, kSize / sizeof(uint32_t)); } // Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when // it is created with mappedAtCreation == true. TEST_P(NonzeroBufferCreationTests, BufferCreationWithMappedAtCreation) { // When we use Dawn wire, the lazy initialization of the buffers with mappedAtCreation == true // are done in the Dawn wire and we don't plan to get it work with the toggle // "nonzero_clear_resources_on_creation_for_testing" (we will have more tests on it in the // BufferZeroInitTests. DAWN_TEST_UNSUPPORTED_IF(UsesWire()); constexpr uint32_t kSize = 32u; wgpu::BufferDescriptor defaultDescriptor; defaultDescriptor.size = kSize; defaultDescriptor.mappedAtCreation = true; const std::vector expectedData(kSize, uint8_t(1u)); const uint32_t* expectedDataPtr = reinterpret_cast(expectedData.data()); // Buffer with MapRead usage { wgpu::BufferDescriptor descriptor = defaultDescriptor; descriptor.usage = wgpu::BufferUsage::MapRead; wgpu::Buffer buffer = device.CreateBuffer(&descriptor); const uint8_t* mappedData = static_cast(buffer.GetConstMappedRange()); EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize)); buffer.Unmap(); MapReadAsyncAndWait(buffer, 0, kSize); mappedData = static_cast(buffer.GetConstMappedRange()); EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize)); buffer.Unmap(); } // Buffer with MapWrite usage { wgpu::BufferDescriptor descriptor = defaultDescriptor; descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc; wgpu::Buffer buffer = device.CreateBuffer(&descriptor); const uint8_t* mappedData = static_cast(buffer.GetConstMappedRange()); EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize)); buffer.Unmap(); EXPECT_BUFFER_U32_RANGE_EQ(expectedDataPtr, buffer, 0, kSize / sizeof(uint32_t)); } // Buffer with neither MapRead nor MapWrite usage { wgpu::BufferDescriptor descriptor = defaultDescriptor; descriptor.usage = wgpu::BufferUsage::CopySrc; wgpu::Buffer buffer = device.CreateBuffer(&descriptor); const uint8_t* mappedData = static_cast(buffer.GetConstMappedRange()); EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize)); buffer.Unmap(); EXPECT_BUFFER_U32_RANGE_EQ(expectedDataPtr, buffer, 0, kSize / sizeof(uint32_t)); } } DAWN_INSTANTIATE_TEST(NonzeroBufferCreationTests, 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"}));