1 // Copyright 2019 The Amber 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 "src/vulkan/vertex_buffer.h"
16
17 #include <utility>
18
19 #include "amber/value.h"
20 #include "gtest/gtest.h"
21 #include "src/format.h"
22 #include "src/make_unique.h"
23 #include "src/type_parser.h"
24 #include "src/vulkan/command_buffer.h"
25 #include "src/vulkan/command_pool.h"
26 #include "src/vulkan/device.h"
27
28 namespace amber {
29 namespace vulkan {
30 namespace {
31
32 class DummyDevice : public Device {
33 public:
DummyDevice()34 DummyDevice()
35 : Device(VkInstance(),
36 VkPhysicalDevice(),
37 0u,
38 VkDevice(this),
39 VkQueue()) {
40 memory_.resize(64);
41 dummyPtrs_.vkCreateBuffer = vkCreateBuffer;
42 dummyPtrs_.vkGetBufferMemoryRequirements = vkGetBufferMemoryRequirements;
43 dummyPtrs_.vkAllocateMemory = vkAllocateMemory;
44 dummyPtrs_.vkBindBufferMemory = vkBindBufferMemory;
45 dummyPtrs_.vkMapMemory = vkMapMemory;
46 dummyPtrs_.vkCmdPipelineBarrier = vkCmdPipelineBarrier;
47 dummyPtrs_.vkAllocateCommandBuffers = vkAllocateCommandBuffers;
48 dummyPtrs_.vkCreateFence = vkCreateFence;
49 dummyPtrs_.vkDestroyBufferView = vkDestroyBufferView;
50 dummyPtrs_.vkFreeMemory = vkFreeMemory;
51 dummyPtrs_.vkDestroyBuffer = vkDestroyBuffer;
52 }
~DummyDevice()53 ~DummyDevice() override {}
54
GetPtrs() const55 const VulkanPtrs* GetPtrs() const override { return &dummyPtrs_; }
56
HasMemoryFlags(uint32_t,const VkMemoryPropertyFlags) const57 bool HasMemoryFlags(uint32_t, const VkMemoryPropertyFlags) const override {
58 return true;
59 }
60
GetMemoryPtr()61 void* GetMemoryPtr() { return memory_.data(); }
62
63 private:
64 VulkanPtrs dummyPtrs_;
65 std::vector<uint8_t> memory_;
66
vkCreateBuffer(VkDevice,const VkBufferCreateInfo *,const VkAllocationCallbacks *,VkBuffer * pBuffer)67 static VkResult vkCreateBuffer(VkDevice,
68 const VkBufferCreateInfo*,
69 const VkAllocationCallbacks*,
70 VkBuffer* pBuffer) {
71 *pBuffer = VkBuffer(1);
72 return VK_SUCCESS;
73 }
vkGetBufferMemoryRequirements(VkDevice,VkBuffer,VkMemoryRequirements * pMemoryRequirements)74 static void vkGetBufferMemoryRequirements(
75 VkDevice,
76 VkBuffer,
77 VkMemoryRequirements* pMemoryRequirements) {
78 pMemoryRequirements->alignment = 0;
79 pMemoryRequirements->size = 0;
80 pMemoryRequirements->memoryTypeBits = 0xffffffff;
81 }
vkAllocateMemory(VkDevice,const VkMemoryAllocateInfo *,const VkAllocationCallbacks *,VkDeviceMemory *)82 static VkResult vkAllocateMemory(VkDevice,
83 const VkMemoryAllocateInfo*,
84 const VkAllocationCallbacks*,
85 VkDeviceMemory*) {
86 return VK_SUCCESS;
87 }
vkBindBufferMemory(VkDevice,VkBuffer,VkDeviceMemory,VkDeviceSize)88 static VkResult vkBindBufferMemory(VkDevice,
89 VkBuffer,
90 VkDeviceMemory,
91 VkDeviceSize) {
92 return VK_SUCCESS;
93 }
vkMapMemory(VkDevice device,VkDeviceMemory,VkDeviceSize,VkDeviceSize,VkMemoryMapFlags,void ** ppData)94 static VkResult vkMapMemory(VkDevice device,
95 VkDeviceMemory,
96 VkDeviceSize,
97 VkDeviceSize,
98 VkMemoryMapFlags,
99 void** ppData) {
100 DummyDevice* devicePtr = reinterpret_cast<DummyDevice*>(device);
101 *ppData = devicePtr->GetMemoryPtr();
102 return VK_SUCCESS;
103 }
vkCmdPipelineBarrier(VkCommandBuffer,VkPipelineStageFlags,VkPipelineStageFlags,VkDependencyFlags,uint32_t,const VkMemoryBarrier *,uint32_t,const VkBufferMemoryBarrier *,uint32_t,const VkImageMemoryBarrier *)104 static void vkCmdPipelineBarrier(VkCommandBuffer,
105 VkPipelineStageFlags,
106 VkPipelineStageFlags,
107 VkDependencyFlags,
108 uint32_t,
109 const VkMemoryBarrier*,
110 uint32_t,
111 const VkBufferMemoryBarrier*,
112 uint32_t,
113 const VkImageMemoryBarrier*) {}
vkAllocateCommandBuffers(VkDevice,const VkCommandBufferAllocateInfo *,VkCommandBuffer *)114 static VkResult vkAllocateCommandBuffers(VkDevice,
115 const VkCommandBufferAllocateInfo*,
116 VkCommandBuffer*) {
117 return VK_SUCCESS;
118 }
vkCreateFence(VkDevice,const VkFenceCreateInfo *,const VkAllocationCallbacks *,VkFence *)119 static VkResult vkCreateFence(VkDevice,
120 const VkFenceCreateInfo*,
121 const VkAllocationCallbacks*,
122 VkFence*) {
123 return VK_SUCCESS;
124 }
vkDestroyBufferView(VkDevice,VkBufferView,const VkAllocationCallbacks *)125 static void vkDestroyBufferView(VkDevice,
126 VkBufferView,
127 const VkAllocationCallbacks*) {}
vkFreeMemory(VkDevice,VkDeviceMemory,const VkAllocationCallbacks *)128 static void vkFreeMemory(VkDevice,
129 VkDeviceMemory,
130 const VkAllocationCallbacks*) {}
vkDestroyBuffer(VkDevice,VkBuffer,const VkAllocationCallbacks *)131 static void vkDestroyBuffer(VkDevice,
132 VkBuffer,
133 const VkAllocationCallbacks*) {}
134 };
135
136 class VertexBufferTest : public testing::Test {
137 public:
VertexBufferTest()138 VertexBufferTest()
139 : device_(MakeUnique<DummyDevice>()),
140 commandPool_(MakeUnique<CommandPool>(device_.get())),
141 commandBuffer_(
142 MakeUnique<CommandBuffer>(device_.get(), commandPool_.get())),
143 vertex_buffer_(MakeUnique<VertexBuffer>(device_.get())) {
144 commandBuffer_->Initialize();
145 }
146
~VertexBufferTest()147 ~VertexBufferTest() override { vertex_buffer_.reset(); }
148
SetData(uint8_t location,Format * format,std::vector<Value> values)149 Result SetData(uint8_t location, Format* format, std::vector<Value> values) {
150 auto buffer = MakeUnique<Buffer>();
151 buffer->SetFormat(format);
152 buffer->SetData(std::move(values));
153
154 vertex_buffer_->SetData(location, buffer.get(), InputRate::kVertex, format,
155 0, format->SizeInBytes());
156 return vertex_buffer_->SendVertexData(commandBuffer_.get());
157 }
158
GetVkBufferPtr()159 const void* GetVkBufferPtr() { return device_->GetMemoryPtr(); }
160
161 private:
162 std::unique_ptr<DummyDevice> device_;
163 std::unique_ptr<CommandPool> commandPool_;
164 std::unique_ptr<CommandBuffer> commandBuffer_;
165 std::unique_ptr<VertexBuffer> vertex_buffer_;
166 };
167
168 } // namespace
169
TEST_F(VertexBufferTest,R8G8B8A8_UINT)170 TEST_F(VertexBufferTest, R8G8B8A8_UINT) {
171 std::vector<Value> values(4);
172 values[0].SetIntValue(55);
173 values[1].SetIntValue(3);
174 values[2].SetIntValue(27);
175 values[3].SetIntValue(255);
176
177 TypeParser parser;
178 auto type = parser.Parse("R8G8B8A8_UINT");
179 Format fmt(type.get());
180 Result r = SetData(0, &fmt, values);
181
182 const uint8_t* ptr = static_cast<const uint8_t*>(GetVkBufferPtr());
183 EXPECT_EQ(55, ptr[0]);
184 EXPECT_EQ(3, ptr[1]);
185 EXPECT_EQ(27, ptr[2]);
186 EXPECT_EQ(255, ptr[3]);
187 }
188
TEST_F(VertexBufferTest,R16G16B16A16_UINT)189 TEST_F(VertexBufferTest, R16G16B16A16_UINT) {
190 std::vector<Value> values(4);
191 values[0].SetIntValue(55);
192 values[1].SetIntValue(3);
193 values[2].SetIntValue(27);
194 values[3].SetIntValue(255);
195
196 TypeParser parser;
197 auto type = parser.Parse("R16G16B16A16_UINT");
198 Format fmt(type.get());
199 Result r = SetData(0, &fmt, values);
200
201 const uint16_t* ptr = static_cast<const uint16_t*>(GetVkBufferPtr());
202 EXPECT_EQ(55, ptr[0]);
203 EXPECT_EQ(3, ptr[1]);
204 EXPECT_EQ(27, ptr[2]);
205 EXPECT_EQ(255, ptr[3]);
206 }
207
TEST_F(VertexBufferTest,R32G32B32A32_UINT)208 TEST_F(VertexBufferTest, R32G32B32A32_UINT) {
209 std::vector<Value> values(4);
210 values[0].SetIntValue(55);
211 values[1].SetIntValue(3);
212 values[2].SetIntValue(27);
213 values[3].SetIntValue(255);
214
215 TypeParser parser;
216 auto type = parser.Parse("R32G32B32A32_UINT");
217 Format fmt(type.get());
218 Result r = SetData(0, &fmt, values);
219
220 const uint32_t* ptr = static_cast<const uint32_t*>(GetVkBufferPtr());
221 EXPECT_EQ(55, ptr[0]);
222 EXPECT_EQ(3, ptr[1]);
223 EXPECT_EQ(27, ptr[2]);
224 EXPECT_EQ(255, ptr[3]);
225 }
226
TEST_F(VertexBufferTest,R64G64B64A64_UINT)227 TEST_F(VertexBufferTest, R64G64B64A64_UINT) {
228 std::vector<Value> values(4);
229 values[0].SetIntValue(55);
230 values[1].SetIntValue(3);
231 values[2].SetIntValue(27);
232 values[3].SetIntValue(255);
233
234 TypeParser parser;
235 auto type = parser.Parse("R64G64B64A64_UINT");
236 Format fmt(type.get());
237 Result r = SetData(0, &fmt, values);
238
239 const uint64_t* ptr = static_cast<const uint64_t*>(GetVkBufferPtr());
240 EXPECT_EQ(55, ptr[0]);
241 EXPECT_EQ(3, ptr[1]);
242 EXPECT_EQ(27, ptr[2]);
243 EXPECT_EQ(255, ptr[3]);
244 }
245
TEST_F(VertexBufferTest,R8G8B8A8_SNORM)246 TEST_F(VertexBufferTest, R8G8B8A8_SNORM) {
247 std::vector<Value> values(4);
248 values[0].SetIntValue(static_cast<uint64_t>(-55));
249 values[1].SetIntValue(3);
250 values[2].SetIntValue(static_cast<uint64_t>(-128));
251 values[3].SetIntValue(127);
252
253 TypeParser parser;
254 auto type = parser.Parse("R8G8B8A8_SNORM");
255 Format fmt(type.get());
256 Result r = SetData(0, &fmt, values);
257 const int8_t* ptr = static_cast<const int8_t*>(GetVkBufferPtr());
258
259 EXPECT_EQ(-55, ptr[0]);
260 EXPECT_EQ(3, ptr[1]);
261 EXPECT_EQ(-128, ptr[2]);
262 EXPECT_EQ(127, ptr[3]);
263 }
264
TEST_F(VertexBufferTest,R16G16B16A16_SNORM)265 TEST_F(VertexBufferTest, R16G16B16A16_SNORM) {
266 std::vector<Value> values(4);
267 values[0].SetIntValue(static_cast<uint64_t>(-55));
268 values[1].SetIntValue(3);
269 values[2].SetIntValue(static_cast<uint64_t>(-27));
270 values[3].SetIntValue(255);
271
272 TypeParser parser;
273 auto type = parser.Parse("R16G16B16A16_SNORM");
274 Format fmt(type.get());
275 Result r = SetData(0, &fmt, values);
276
277 const int16_t* ptr = static_cast<const int16_t*>(GetVkBufferPtr());
278 EXPECT_EQ(-55, ptr[0]);
279 EXPECT_EQ(3, ptr[1]);
280 EXPECT_EQ(-27, ptr[2]);
281 EXPECT_EQ(255, ptr[3]);
282 }
283
TEST_F(VertexBufferTest,R32G32B32A32_SINT)284 TEST_F(VertexBufferTest, R32G32B32A32_SINT) {
285 std::vector<Value> values(4);
286 values[0].SetIntValue(static_cast<uint64_t>(-55));
287 values[1].SetIntValue(3);
288 values[2].SetIntValue(static_cast<uint64_t>(-27));
289 values[3].SetIntValue(255);
290
291 TypeParser parser;
292 auto type = parser.Parse("R32G32B32A32_SINT");
293 Format fmt(type.get());
294 Result r = SetData(0, &fmt, values);
295
296 const int32_t* ptr = static_cast<const int32_t*>(GetVkBufferPtr());
297 EXPECT_EQ(-55, ptr[0]);
298 EXPECT_EQ(3, ptr[1]);
299 EXPECT_EQ(-27, ptr[2]);
300 EXPECT_EQ(255, ptr[3]);
301 }
302
TEST_F(VertexBufferTest,R64G64B64A64_SINT)303 TEST_F(VertexBufferTest, R64G64B64A64_SINT) {
304 std::vector<Value> values(4);
305 values[0].SetIntValue(static_cast<uint64_t>(-55));
306 values[1].SetIntValue(3);
307 values[2].SetIntValue(static_cast<uint64_t>(-27));
308 values[3].SetIntValue(255);
309
310 TypeParser parser;
311 auto type = parser.Parse("R64G64B64A64_SINT");
312 Format fmt(type.get());
313 Result r = SetData(0, &fmt, values);
314
315 const int64_t* ptr = static_cast<const int64_t*>(GetVkBufferPtr());
316 EXPECT_EQ(-55, ptr[0]);
317 EXPECT_EQ(3, ptr[1]);
318 EXPECT_EQ(-27, ptr[2]);
319 EXPECT_EQ(255, ptr[3]);
320 }
321
TEST_F(VertexBufferTest,R32G32B32_SFLOAT)322 TEST_F(VertexBufferTest, R32G32B32_SFLOAT) {
323 std::vector<Value> values(3);
324 values[0].SetDoubleValue(-6.0);
325 values[1].SetDoubleValue(14.0);
326 values[2].SetDoubleValue(0.1171875);
327
328 TypeParser parser;
329 auto type = parser.Parse("R32G32B32_SFLOAT");
330 Format fmt(type.get());
331 Result r = SetData(0, &fmt, values);
332
333 const float* ptr = static_cast<const float*>(GetVkBufferPtr());
334 EXPECT_FLOAT_EQ(-6.0f, ptr[0]);
335 EXPECT_FLOAT_EQ(14.0f, ptr[1]);
336 EXPECT_FLOAT_EQ(0.1171875f, ptr[2]);
337 }
338
TEST_F(VertexBufferTest,R64G64B64_SFLOAT)339 TEST_F(VertexBufferTest, R64G64B64_SFLOAT) {
340 std::vector<Value> values(3);
341 values[0].SetDoubleValue(-6.0);
342 values[1].SetDoubleValue(14.0);
343 values[2].SetDoubleValue(0.1171875);
344
345 TypeParser parser;
346 auto type = parser.Parse("R64G64B64_SFLOAT");
347 Format fmt(type.get());
348 Result r = SetData(0, &fmt, values);
349
350 const double* ptr = static_cast<const double*>(GetVkBufferPtr());
351 EXPECT_DOUBLE_EQ(-6.0, ptr[0]);
352 EXPECT_DOUBLE_EQ(14.0, ptr[1]);
353 EXPECT_DOUBLE_EQ(0.1171875, ptr[2]);
354 }
355
356 } // namespace vulkan
357 } // namespace amber
358