Merge branch '259-fix-arm-gcc-issue' into 'vulkan-cts-1.0'
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiBufferTests.cpp
1 /*------------------------------------------------------------------------
2  *  Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
26  *
27  *//*!
28  * \file
29  * \brief Vulkan Buffers Tests
30  *//*--------------------------------------------------------------------*/
31
32 #include "vktApiBufferTests.hpp"
33
34 #include "deStringUtil.hpp"
35 #include "gluVarType.hpp"
36 #include "tcuTestLog.hpp"
37 #include "vkPrograms.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkRefUtil.hpp"
40 #include "vktTestCase.hpp"
41
42 namespace vkt
43 {
44
45 using namespace vk;
46
47 namespace api
48 {
49
50 namespace
51 {
52
53 struct BufferCaseParameters
54 {
55         VkBufferUsageFlags      usage;
56         VkBufferCreateFlags     flags;
57         VkSharingMode           sharingMode;
58 };
59
60 class BufferTestInstance : public TestInstance
61 {
62 public:
63                                                                 BufferTestInstance                      (Context&                               ctx,
64                                                                                                                          BufferCaseParameters   testCase)
65                                                                         : TestInstance  (ctx)
66                                                                         , m_testCase    (testCase)
67                                                                 {}
68         virtual tcu::TestStatus         iterate                                         (void);
69         tcu::TestStatus                         bufferCreateAndAllocTest        (VkDeviceSize           size);
70
71 private:
72         BufferCaseParameters            m_testCase;
73 };
74
75 class BuffersTestCase : public TestCase
76 {
77 public:
78                                                         BuffersTestCase         (tcu::TestContext&              testCtx,
79                                                                                                  const std::string&             name,
80                                                                                                  const std::string&             description,
81                                                                                                  BufferCaseParameters   testCase)
82                                                                 : TestCase(testCtx, name, description)
83                                                                 , m_testCase(testCase)
84                                                         {}
85
86         virtual                                 ~BuffersTestCase        (void) {}
87         virtual TestInstance*   createInstance          (Context&                               ctx) const
88                                                         {
89                                                                 tcu::TestLog& log       = m_testCtx.getLog();
90                                                                 log << tcu::TestLog::Message << getBufferUsageFlagsStr(m_testCase.usage) << tcu::TestLog::EndMessage;
91                                                                 return new BufferTestInstance(ctx, m_testCase);
92                                                         }
93
94 private:
95         BufferCaseParameters            m_testCase;
96 };
97
98  tcu::TestStatus BufferTestInstance::bufferCreateAndAllocTest (VkDeviceSize size)
99 {
100         const VkDevice                  vkDevice                        = m_context.getDevice();
101         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
102         Move<VkBuffer>                  testBuffer;
103         VkMemoryRequirements    memReqs;
104         Move<VkDeviceMemory>    memory;
105         const deUint32                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
106
107         // Create buffer
108         {
109                 const VkBufferCreateInfo                bufferParams            =
110                 {
111                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
112                         DE_NULL,
113                         m_testCase.flags,
114                         size,
115                         m_testCase.usage,
116                         m_testCase.sharingMode,
117                         1u,                                                                             //      deUint32                        queueFamilyCount;
118                         &queueFamilyIndex,
119                 };
120
121                 try
122                 {
123                         testBuffer = createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
124                 }
125                 catch (const vk::Error& error)
126                 {
127                         return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
128                 }
129
130                 vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
131
132                 if (size > memReqs.size)
133                 {
134                         std::ostringstream errorMsg;
135                         errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
136                         return tcu::TestStatus::fail(errorMsg.str());
137                 }
138         }
139
140         // Allocate and bind memory
141         {
142                 const VkMemoryAllocateInfo memAlloc =
143                 {
144                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
145                         NULL,
146                         memReqs.size,
147                         deCtz32(memReqs.memoryTypeBits)                         //      deUint32                memoryTypeIndex
148                 };
149
150                 try
151                 {
152                         memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
153                 }
154                 catch (const vk::Error& error)
155                 {
156                         return tcu::TestStatus::fail("Alloc memory failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
157                 }
158
159                 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) ||
160                         (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) ||
161                         (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT))
162                 {
163                         VkQueue queue                                                                                           = 0;
164
165                         vk.getDeviceQueue(vkDevice, queueFamilyIndex, 0, &queue);
166
167                         const VkSparseMemoryBind                        sparseMemoryBind                =
168                         {
169                                 0,                                                                              // VkDeviceSize                                                         resourceOffset;
170                                 memReqs.size,                                                   // VkDeviceSize                                                         size;
171                                 *memory,                                                                // VkDeviceMemory                                                       memory;
172                                 0,                                                                              // VkDeviceSize                                                         memoryOffset;
173                                 0                                                                               // VkSparseMemoryBindFlags                                      flags;
174                         };
175
176                         const VkSparseBufferMemoryBindInfo      sparseBufferMemoryBindInfo      =
177                         {
178                                 *testBuffer,                                                    // VkBuffer                                                                     buffer;
179                                 1u,                                                                             // deUint32                                                                     bindCount;
180                                 &sparseMemoryBind                                               // const VkSparseMemoryBind*                            pBinds;
181                         };
182
183                         const VkBindSparseInfo                          bindSparseInfo                  =
184                         {
185                                 VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,             // VkStructureType                                                      sType;
186                                 DE_NULL,                                                                // const void*                                                          pNext;
187                                 0,                                                                              // deUint32                                                                     waitSemaphoreCount;
188                                 DE_NULL,                                                                // const VkSemaphore*                                           pWaitSemaphores;
189                                 1u,                                                                             // deUint32                                                                     bufferBindCount;
190                                 &sparseBufferMemoryBindInfo,                    // const VkSparseBufferMemoryBindInfo*          pBufferBinds;
191                                 0,                                                                              // deUint32                                                                     imageOpaqueBindCount;
192                                 DE_NULL,                                                                // const VkSparseImageOpaqueMemoryBindInfo*     pImageOpaqueBinds;
193                                 0,                                                                              // deUint32                                                                     imageBindCount;
194                                 DE_NULL,                                                                // const VkSparseImageMemoryBindInfo*           pImageBinds;
195                                 0,                                                                              // deUint32                                                                     signalSemaphoreCount;
196                                 DE_NULL,                                                                // const VkSemaphore*                                           pSignalSemaphores;
197                         };
198
199                         const VkFenceCreateInfo fenceParams =
200                         {
201                                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
202                                 DE_NULL,                                                                // const void*                  pNext;
203                                 0u                                                                              // VkFenceCreateFlags   flags;
204                         };
205
206                         const vk::Unique<vk::VkFence> fence(vk::createFence(vk, vkDevice, &fenceParams));
207
208                         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
209                         if (vk.queueBindSparse(queue, 1, &bindSparseInfo, *fence) != VK_SUCCESS)
210                                 return tcu::TestStatus::fail("Bind sparse buffer memory failed! (requested memory size: " + de::toString(size) + ")");
211
212                         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~(0ull) /* infinity */));
213                 } else
214                         if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
215                                 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
216         }
217
218         return tcu::TestStatus::pass("Buffer test");
219 }
220
221 tcu::TestStatus BufferTestInstance::iterate (void)
222 {
223         const VkPhysicalDeviceFeatures& physicalDeviceFeatures  = m_context.getDeviceFeatures();
224
225         if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT ) && !physicalDeviceFeatures.sparseBinding)
226                 TCU_THROW(NotSupportedError, "Sparse bindings feature is not supported");
227
228         if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT ) && !physicalDeviceFeatures.sparseResidencyBuffer)
229                 TCU_THROW(NotSupportedError, "Sparse buffer residency feature is not supported");
230
231         if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT ) && !physicalDeviceFeatures.sparseResidencyAliased)
232                 TCU_THROW(NotSupportedError, "Sparse aliased residency feature is not supported");
233
234         const VkDeviceSize testSizes[] =
235         {
236                 1,
237                 1181,
238                 15991,
239                 16384
240         };
241         tcu::TestStatus                                 testStatus                      = tcu::TestStatus::pass("Buffer test");
242
243         for (int i = 0; i < DE_LENGTH_OF_ARRAY(testSizes); i++)
244         {
245                 if ((testStatus = bufferCreateAndAllocTest(testSizes[i])).getCode() != QP_TEST_RESULT_PASS)
246                         return testStatus;
247         }
248
249         if (m_testCase.usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT))
250         {
251                 const VkPhysicalDevice                                  vkPhysicalDevice        = m_context.getPhysicalDevice();
252                 const InstanceInterface&                                vkInstance                      = m_context.getInstanceInterface();
253                 const VkPhysicalDeviceMemoryProperties  memoryProperties        = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
254                 VkPhysicalDeviceProperties      props;
255
256                 vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &props);
257
258                 const VkDeviceSize maxTestBufferSize = de::min((VkDeviceSize) props.limits.maxTexelBufferElements, memoryProperties.memoryHeaps[memoryProperties.memoryTypes[0].heapIndex].size / 16);
259
260                 testStatus = bufferCreateAndAllocTest(maxTestBufferSize);
261         }
262
263         return testStatus;
264 }
265
266 } // anonymous
267
268  tcu::TestCaseGroup* createBufferTests (tcu::TestContext& testCtx)
269 {
270         const VkBufferUsageFlags bufferUsageModes[] =
271         {
272                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
273                 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
274                 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
275                 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
276                 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
277                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
278                 VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
279                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
280                 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
281         };
282
283         const VkBufferCreateFlags bufferCreateFlags[] =
284         {
285                 VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
286                 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
287                 VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
288         };
289
290         de::MovePtr<tcu::TestCaseGroup> buffersTests    (new tcu::TestCaseGroup(testCtx, "buffer", "Buffer Tests"));
291
292         deUint32        numberOfBufferUsageFlags                        = DE_LENGTH_OF_ARRAY(bufferUsageModes);
293         deUint32        numberOfBufferCreateFlags                       = DE_LENGTH_OF_ARRAY(bufferCreateFlags);
294         deUint32        maximumValueOfBufferUsageFlags          = (1 << (numberOfBufferUsageFlags - 1)) - 1;
295         deUint32        maximumValueOfBufferCreateFlags         = (1 << (numberOfBufferCreateFlags)) - 1;
296
297         for (deUint32 combinedBufferCreateFlags = 0; combinedBufferCreateFlags <= maximumValueOfBufferCreateFlags; combinedBufferCreateFlags++)
298         {
299                 for (deUint32 combinedBufferUsageFlags = 1; combinedBufferUsageFlags <= maximumValueOfBufferUsageFlags; combinedBufferUsageFlags++)
300                 {
301                         if (combinedBufferCreateFlags == VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
302                         {
303                                 // spec says: If flags contains VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain at least one of
304                                 // VK_BUFFER_CREATE_SPARSE_BINDING_BIT or VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
305                                 continue;
306                         }
307                         BufferCaseParameters    testParams =
308                         {
309                                 combinedBufferUsageFlags,
310                                 combinedBufferCreateFlags,
311                                 VK_SHARING_MODE_EXCLUSIVE
312                         };
313                         std::ostringstream      testName;
314                         std::ostringstream      testDescription;
315                         testName << "createBuffer_" << combinedBufferUsageFlags << "_" << combinedBufferCreateFlags;
316                         testDescription << "vkCreateBuffer test " << combinedBufferUsageFlags << " " << combinedBufferCreateFlags;
317                         buffersTests->addChild(new BuffersTestCase(testCtx, testName.str(), testDescription.str(), testParams));
318                 }
319         }
320
321         return buffersTests.release();
322 }
323
324 } // api
325 } // vk