• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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