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