1 // Copyright 2019 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "tests/DawnTest.h"
16
17 #include <array>
18 #include <vector>
19
20 class NonzeroBufferCreationTests : public DawnTest {
21 public:
MapReadAsyncAndWait(wgpu::Buffer buffer,uint64_t offset,uint64_t size)22 void MapReadAsyncAndWait(wgpu::Buffer buffer, uint64_t offset, uint64_t size) {
23 bool done = false;
24 buffer.MapAsync(
25 wgpu::MapMode::Read, offset, size,
26 [](WGPUBufferMapAsyncStatus status, void* userdata) {
27 ASSERT_EQ(WGPUBufferMapAsyncStatus_Success, status);
28 *static_cast<bool*>(userdata) = true;
29 },
30 &done);
31
32 while (!done) {
33 WaitABit();
34 }
35 }
36 };
37
38 // Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when it
39 // is created with CopyDst usage.
TEST_P(NonzeroBufferCreationTests,BufferCreationWithCopyDstUsage)40 TEST_P(NonzeroBufferCreationTests, BufferCreationWithCopyDstUsage) {
41 constexpr uint32_t kSize = 32u;
42
43 wgpu::BufferDescriptor descriptor;
44 descriptor.size = kSize;
45 descriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
46
47 wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
48
49 std::vector<uint8_t> expectedData(kSize, uint8_t(1u));
50 EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(expectedData.data()), buffer, 0,
51 kSize / sizeof(uint32_t));
52 }
53
54 // Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when it
55 // is created with MapWrite without CopyDst usage.
TEST_P(NonzeroBufferCreationTests,BufferCreationWithMapWriteWithoutCopyDstUsage)56 TEST_P(NonzeroBufferCreationTests, BufferCreationWithMapWriteWithoutCopyDstUsage) {
57 constexpr uint32_t kSize = 32u;
58
59 wgpu::BufferDescriptor descriptor;
60 descriptor.size = kSize;
61 descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc;
62
63 wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
64
65 std::vector<uint8_t> expectedData(kSize, uint8_t(1u));
66 EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(expectedData.data()), buffer, 0,
67 kSize / sizeof(uint32_t));
68 }
69
70 // Verify that each byte of the buffer has all been initialized to 1 with the toggle enabled when
71 // it is created with mappedAtCreation == true.
TEST_P(NonzeroBufferCreationTests,BufferCreationWithMappedAtCreation)72 TEST_P(NonzeroBufferCreationTests, BufferCreationWithMappedAtCreation) {
73 // When we use Dawn wire, the lazy initialization of the buffers with mappedAtCreation == true
74 // are done in the Dawn wire and we don't plan to get it work with the toggle
75 // "nonzero_clear_resources_on_creation_for_testing" (we will have more tests on it in the
76 // BufferZeroInitTests.
77 DAWN_TEST_UNSUPPORTED_IF(UsesWire());
78
79 constexpr uint32_t kSize = 32u;
80
81 wgpu::BufferDescriptor defaultDescriptor;
82 defaultDescriptor.size = kSize;
83 defaultDescriptor.mappedAtCreation = true;
84
85 const std::vector<uint8_t> expectedData(kSize, uint8_t(1u));
86 const uint32_t* expectedDataPtr = reinterpret_cast<const uint32_t*>(expectedData.data());
87
88 // Buffer with MapRead usage
89 {
90 wgpu::BufferDescriptor descriptor = defaultDescriptor;
91 descriptor.usage = wgpu::BufferUsage::MapRead;
92 wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
93
94 const uint8_t* mappedData = static_cast<const uint8_t*>(buffer.GetConstMappedRange());
95 EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize));
96 buffer.Unmap();
97
98 MapReadAsyncAndWait(buffer, 0, kSize);
99 mappedData = static_cast<const uint8_t*>(buffer.GetConstMappedRange());
100 EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize));
101 buffer.Unmap();
102 }
103
104 // Buffer with MapWrite usage
105 {
106 wgpu::BufferDescriptor descriptor = defaultDescriptor;
107 descriptor.usage = wgpu::BufferUsage::MapWrite | wgpu::BufferUsage::CopySrc;
108 wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
109
110 const uint8_t* mappedData = static_cast<const uint8_t*>(buffer.GetConstMappedRange());
111 EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize));
112 buffer.Unmap();
113
114 EXPECT_BUFFER_U32_RANGE_EQ(expectedDataPtr, buffer, 0, kSize / sizeof(uint32_t));
115 }
116
117 // Buffer with neither MapRead nor MapWrite usage
118 {
119 wgpu::BufferDescriptor descriptor = defaultDescriptor;
120 descriptor.usage = wgpu::BufferUsage::CopySrc;
121 wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
122
123 const uint8_t* mappedData = static_cast<const uint8_t*>(buffer.GetConstMappedRange());
124 EXPECT_EQ(0, memcmp(mappedData, expectedData.data(), kSize));
125 buffer.Unmap();
126
127 EXPECT_BUFFER_U32_RANGE_EQ(expectedDataPtr, buffer, 0, kSize / sizeof(uint32_t));
128 }
129 }
130
131 DAWN_INSTANTIATE_TEST(NonzeroBufferCreationTests,
132 D3D12Backend({"nonzero_clear_resources_on_creation_for_testing"},
133 {"lazy_clear_resource_on_first_use"}),
134 MetalBackend({"nonzero_clear_resources_on_creation_for_testing"},
135 {"lazy_clear_resource_on_first_use"}),
136 OpenGLBackend({"nonzero_clear_resources_on_creation_for_testing"},
137 {"lazy_clear_resource_on_first_use"}),
138 OpenGLESBackend({"nonzero_clear_resources_on_creation_for_testing"},
139 {"lazy_clear_resource_on_first_use"}),
140 VulkanBackend({"nonzero_clear_resources_on_creation_for_testing"},
141 {"lazy_clear_resource_on_first_use"}));
142