1 // Copyright 2021 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/unittests/validation/ValidationTest.h"
16
17 #include "utils/WGPUHelpers.h"
18
19 class QueueWriteBufferValidationTest : public ValidationTest {
20 private:
SetUp()21 void SetUp() override {
22 ValidationTest::SetUp();
23 queue = device.GetQueue();
24 }
25
26 protected:
CreateBuffer(uint64_t size)27 wgpu::Buffer CreateBuffer(uint64_t size) {
28 wgpu::BufferDescriptor descriptor;
29 descriptor.size = size;
30 descriptor.usage = wgpu::BufferUsage::CopyDst;
31 return device.CreateBuffer(&descriptor);
32 }
33
34 wgpu::Queue queue;
35 };
36
37 // Test the success case for WriteBuffer
TEST_F(QueueWriteBufferValidationTest,Success)38 TEST_F(QueueWriteBufferValidationTest, Success) {
39 wgpu::Buffer buf = CreateBuffer(4);
40
41 uint32_t foo = 0x01020304;
42 queue.WriteBuffer(buf, 0, &foo, sizeof(foo));
43 }
44
45 // Test error case for WriteBuffer out of bounds
TEST_F(QueueWriteBufferValidationTest,OutOfBounds)46 TEST_F(QueueWriteBufferValidationTest, OutOfBounds) {
47 wgpu::Buffer buf = CreateBuffer(4);
48
49 uint32_t foo[2] = {0, 0};
50 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, foo, 8));
51 }
52
53 // Test error case for WriteBuffer out of bounds with an overflow
TEST_F(QueueWriteBufferValidationTest,OutOfBoundsOverflow)54 TEST_F(QueueWriteBufferValidationTest, OutOfBoundsOverflow) {
55 wgpu::Buffer buf = CreateBuffer(1024);
56
57 uint32_t foo[2] = {0, 0};
58
59 // An offset that when added to "4" would overflow to be zero and pass validation without
60 // overflow checks.
61 uint64_t offset = uint64_t(int64_t(0) - int64_t(4));
62
63 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, offset, foo, 4));
64 }
65
66 // Test error case for WriteBuffer with the wrong usage
TEST_F(QueueWriteBufferValidationTest,WrongUsage)67 TEST_F(QueueWriteBufferValidationTest, WrongUsage) {
68 wgpu::BufferDescriptor descriptor;
69 descriptor.size = 4;
70 descriptor.usage = wgpu::BufferUsage::Vertex;
71 wgpu::Buffer buf = device.CreateBuffer(&descriptor);
72
73 uint32_t foo = 0;
74 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &foo, sizeof(foo)));
75 }
76
77 // Test WriteBuffer with unaligned size
TEST_F(QueueWriteBufferValidationTest,UnalignedSize)78 TEST_F(QueueWriteBufferValidationTest, UnalignedSize) {
79 wgpu::Buffer buf = CreateBuffer(4);
80
81 uint16_t value = 123;
82 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &value, sizeof(value)));
83 }
84
85 // Test WriteBuffer with unaligned offset
TEST_F(QueueWriteBufferValidationTest,UnalignedOffset)86 TEST_F(QueueWriteBufferValidationTest, UnalignedOffset) {
87 wgpu::Buffer buf = CreateBuffer(8);
88
89 uint32_t value = 0x01020304;
90 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 2, &value, sizeof(value)));
91 }
92
93 // Test WriteBuffer with destroyed buffer
TEST_F(QueueWriteBufferValidationTest,DestroyedBuffer)94 TEST_F(QueueWriteBufferValidationTest, DestroyedBuffer) {
95 wgpu::Buffer buf = CreateBuffer(4);
96 buf.Destroy();
97
98 uint32_t value = 0;
99 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &value, sizeof(value)));
100 }
101
102 // Test WriteBuffer with mapped buffer
TEST_F(QueueWriteBufferValidationTest,MappedBuffer)103 TEST_F(QueueWriteBufferValidationTest, MappedBuffer) {
104 // mappedAtCreation
105 {
106 wgpu::BufferDescriptor descriptor;
107 descriptor.size = 4;
108 descriptor.usage = wgpu::BufferUsage::CopyDst;
109 descriptor.mappedAtCreation = true;
110 wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
111
112 uint32_t value = 0;
113 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buffer, 0, &value, sizeof(value)));
114 }
115
116 // MapAsync
117 {
118 wgpu::BufferDescriptor descriptor;
119 descriptor.size = 4;
120 descriptor.usage = wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::MapRead;
121 wgpu::Buffer buf = device.CreateBuffer(&descriptor);
122
123 buf.MapAsync(wgpu::MapMode::Read, 0, 4, nullptr, nullptr);
124 uint32_t value = 0;
125 ASSERT_DEVICE_ERROR(queue.WriteBuffer(buf, 0, &value, sizeof(value)));
126 }
127 }
128