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