Merge "Allow alternative form for refract()." into nyc-dev
[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  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Vulkan Buffers Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktApiBufferTests.hpp"
26
27 #include "deStringUtil.hpp"
28 #include "gluVarType.hpp"
29 #include "tcuTestLog.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vktTestCase.hpp"
34
35 namespace vkt
36 {
37
38 using namespace vk;
39
40 namespace api
41 {
42
43 namespace
44 {
45
46 static const deUint32   MAX_BUFFER_SIZE_DIVISOR = 16;
47
48 struct BufferCaseParameters
49 {
50         VkBufferUsageFlags      usage;
51         VkBufferCreateFlags     flags;
52         VkSharingMode           sharingMode;
53 };
54
55 class BufferTestInstance : public TestInstance
56 {
57 public:
58                                                                 BufferTestInstance                      (Context&                               ctx,
59                                                                                                                          BufferCaseParameters   testCase)
60                                                                         : TestInstance  (ctx)
61                                                                         , m_testCase    (testCase)
62                                                                 {}
63         virtual tcu::TestStatus         iterate                                         (void);
64         tcu::TestStatus                         bufferCreateAndAllocTest        (VkDeviceSize           size);
65
66 private:
67         BufferCaseParameters            m_testCase;
68 };
69
70 class BuffersTestCase : public TestCase
71 {
72 public:
73                                                         BuffersTestCase         (tcu::TestContext&              testCtx,
74                                                                                                  const std::string&             name,
75                                                                                                  const std::string&             description,
76                                                                                                  BufferCaseParameters   testCase)
77                                                                 : TestCase(testCtx, name, description)
78                                                                 , m_testCase(testCase)
79                                                         {}
80
81         virtual                                 ~BuffersTestCase        (void) {}
82         virtual TestInstance*   createInstance          (Context&                               ctx) const
83                                                         {
84                                                                 tcu::TestLog& log       = m_testCtx.getLog();
85                                                                 log << tcu::TestLog::Message << getBufferUsageFlagsStr(m_testCase.usage) << tcu::TestLog::EndMessage;
86                                                                 return new BufferTestInstance(ctx, m_testCase);
87                                                         }
88
89 private:
90         BufferCaseParameters            m_testCase;
91 };
92
93  tcu::TestStatus BufferTestInstance::bufferCreateAndAllocTest (VkDeviceSize size)
94 {
95         const VkPhysicalDevice          vkPhysicalDevice        = m_context.getPhysicalDevice();
96         const InstanceInterface&        vkInstance                      = m_context.getInstanceInterface();
97         const VkDevice                          vkDevice                        = m_context.getDevice();
98         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
99         Move<VkBuffer>                          testBuffer;
100         VkMemoryRequirements            memReqs;
101         Move<VkDeviceMemory>            memory;
102         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
103         const VkPhysicalDeviceMemoryProperties  memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
104
105         // Create buffer
106         {
107                 VkBufferCreateInfo              bufferParams            =
108                 {
109                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
110                         DE_NULL,
111                         m_testCase.flags,
112                         size,
113                         m_testCase.usage,
114                         m_testCase.sharingMode,
115                         1u,                                                                             //      deUint32                        queueFamilyCount;
116                         &queueFamilyIndex,
117                 };
118
119                 try
120                 {
121                         testBuffer = createBuffer(vk, vkDevice, &bufferParams);
122                 }
123                 catch (const vk::Error& error)
124                 {
125                         return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
126                 }
127
128                 vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
129
130                 const deUint32          heapTypeIndex   = (deUint32)deCtz32(memReqs.memoryTypeBits);
131                 const VkMemoryType      memoryType              = memoryProperties.memoryTypes[heapTypeIndex];
132                 const VkMemoryHeap      memoryHeap              = memoryProperties.memoryHeaps[memoryType.heapIndex];
133                 const VkDeviceSize      maxBufferSize   = memoryHeap.size / MAX_BUFFER_SIZE_DIVISOR;
134                 // If the requested size is too large, clamp it based on the selected heap size
135                 if (size > maxBufferSize)
136                 {
137                         size = maxBufferSize;
138                         bufferParams.size = size;
139                         try
140                         {
141                                 // allocate a new buffer with the adjusted size, the old one will be destroyed by the smart pointer
142                                 testBuffer = createBuffer(vk, vkDevice, &bufferParams);
143                         }
144                         catch (const vk::Error& error)
145                         {
146                                 return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
147                         }
148                         vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
149                 }
150
151                 if (size > memReqs.size)
152                 {
153                         std::ostringstream errorMsg;
154                         errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
155                         return tcu::TestStatus::fail(errorMsg.str());
156                 }
157         }
158
159         // Allocate and bind memory
160         {
161                 const VkMemoryAllocateInfo memAlloc =
162                 {
163                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
164                         NULL,
165                         memReqs.size,
166                         (deUint32)deCtz32(memReqs.memoryTypeBits)       //      deUint32                memoryTypeIndex
167                 };
168
169                 try
170                 {
171                         memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
172                 }
173                 catch (const vk::Error& error)
174                 {
175                         return tcu::TestStatus::fail("Alloc memory failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
176                 }
177
178                 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) ||
179                         (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) ||
180                         (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT))
181                 {
182                         VkQueue queue                                                                                           = 0;
183
184                         vk.getDeviceQueue(vkDevice, queueFamilyIndex, 0, &queue);
185
186                         const VkSparseMemoryBind                        sparseMemoryBind                =
187                         {
188                                 0,                                                                              // VkDeviceSize                                                         resourceOffset;
189                                 memReqs.size,                                                   // VkDeviceSize                                                         size;
190                                 *memory,                                                                // VkDeviceMemory                                                       memory;
191                                 0,                                                                              // VkDeviceSize                                                         memoryOffset;
192                                 0                                                                               // VkSparseMemoryBindFlags                                      flags;
193                         };
194
195                         const VkSparseBufferMemoryBindInfo      sparseBufferMemoryBindInfo      =
196                         {
197                                 *testBuffer,                                                    // VkBuffer                                                                     buffer;
198                                 1u,                                                                             // deUint32                                                                     bindCount;
199                                 &sparseMemoryBind                                               // const VkSparseMemoryBind*                            pBinds;
200                         };
201
202                         const VkBindSparseInfo                          bindSparseInfo                  =
203                         {
204                                 VK_STRUCTURE_TYPE_BIND_SPARSE_INFO,             // VkStructureType                                                      sType;
205                                 DE_NULL,                                                                // const void*                                                          pNext;
206                                 0,                                                                              // deUint32                                                                     waitSemaphoreCount;
207                                 DE_NULL,                                                                // const VkSemaphore*                                           pWaitSemaphores;
208                                 1u,                                                                             // deUint32                                                                     bufferBindCount;
209                                 &sparseBufferMemoryBindInfo,                    // const VkSparseBufferMemoryBindInfo*          pBufferBinds;
210                                 0,                                                                              // deUint32                                                                     imageOpaqueBindCount;
211                                 DE_NULL,                                                                // const VkSparseImageOpaqueMemoryBindInfo*     pImageOpaqueBinds;
212                                 0,                                                                              // deUint32                                                                     imageBindCount;
213                                 DE_NULL,                                                                // const VkSparseImageMemoryBindInfo*           pImageBinds;
214                                 0,                                                                              // deUint32                                                                     signalSemaphoreCount;
215                                 DE_NULL,                                                                // const VkSemaphore*                                           pSignalSemaphores;
216                         };
217
218                         const VkFenceCreateInfo fenceParams =
219                         {
220                                 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
221                                 DE_NULL,                                                                // const void*                  pNext;
222                                 0u                                                                              // VkFenceCreateFlags   flags;
223                         };
224
225                         const vk::Unique<vk::VkFence> fence(vk::createFence(vk, vkDevice, &fenceParams));
226
227                         VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
228                         if (vk.queueBindSparse(queue, 1, &bindSparseInfo, *fence) != VK_SUCCESS)
229                                 return tcu::TestStatus::fail("Bind sparse buffer memory failed! (requested memory size: " + de::toString(size) + ")");
230
231                         VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~(0ull) /* infinity */));
232                 } else
233                         if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
234                                 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
235         }
236
237         return tcu::TestStatus::pass("Buffer test");
238 }
239
240 tcu::TestStatus BufferTestInstance::iterate (void)
241 {
242         const VkPhysicalDeviceFeatures& physicalDeviceFeatures  = m_context.getDeviceFeatures();
243
244         if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT ) && !physicalDeviceFeatures.sparseBinding)
245                 TCU_THROW(NotSupportedError, "Sparse bindings feature is not supported");
246
247         if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT ) && !physicalDeviceFeatures.sparseResidencyBuffer)
248                 TCU_THROW(NotSupportedError, "Sparse buffer residency feature is not supported");
249
250         if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT ) && !physicalDeviceFeatures.sparseResidencyAliased)
251                 TCU_THROW(NotSupportedError, "Sparse aliased residency feature is not supported");
252
253         const VkDeviceSize testSizes[] =
254         {
255                 1,
256                 1181,
257                 15991,
258                 16384
259         };
260         tcu::TestStatus                                 testStatus                      = tcu::TestStatus::pass("Buffer test");
261
262         for (int i = 0; i < DE_LENGTH_OF_ARRAY(testSizes); i++)
263         {
264                 if ((testStatus = bufferCreateAndAllocTest(testSizes[i])).getCode() != QP_TEST_RESULT_PASS)
265                         return testStatus;
266         }
267
268         if (m_testCase.usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT))
269         {
270                 const VkPhysicalDevice                                  vkPhysicalDevice        = m_context.getPhysicalDevice();
271                 const InstanceInterface&                                vkInstance                      = m_context.getInstanceInterface();
272                 VkPhysicalDeviceProperties      props;
273
274                 vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &props);
275                 testStatus = bufferCreateAndAllocTest((VkDeviceSize) props.limits.maxTexelBufferElements);
276         }
277
278         return testStatus;
279 }
280
281 } // anonymous
282
283  tcu::TestCaseGroup* createBufferTests (tcu::TestContext& testCtx)
284 {
285         const VkBufferUsageFlags bufferUsageModes[] =
286         {
287                 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
288                 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
289                 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
290                 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
291                 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
292                 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
293                 VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
294                 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
295                 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
296         };
297
298         const VkBufferCreateFlags bufferCreateFlags[] =
299         {
300                 VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
301                 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
302                 VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
303         };
304
305         de::MovePtr<tcu::TestCaseGroup> buffersTests    (new tcu::TestCaseGroup(testCtx, "buffer", "Buffer Tests"));
306
307         deUint32        numberOfBufferUsageFlags                        = DE_LENGTH_OF_ARRAY(bufferUsageModes);
308         deUint32        numberOfBufferCreateFlags                       = DE_LENGTH_OF_ARRAY(bufferCreateFlags);
309         deUint32        maximumValueOfBufferUsageFlags          = (1 << (numberOfBufferUsageFlags - 1)) - 1;
310         deUint32        maximumValueOfBufferCreateFlags         = (1 << (numberOfBufferCreateFlags)) - 1;
311
312         for (deUint32 combinedBufferCreateFlags = 0; combinedBufferCreateFlags <= maximumValueOfBufferCreateFlags; combinedBufferCreateFlags++)
313         {
314                 for (deUint32 combinedBufferUsageFlags = 1; combinedBufferUsageFlags <= maximumValueOfBufferUsageFlags; combinedBufferUsageFlags++)
315                 {
316                         if (combinedBufferCreateFlags == VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
317                         {
318                                 // spec says: If flags contains VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain at least one of
319                                 // VK_BUFFER_CREATE_SPARSE_BINDING_BIT or VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
320                                 continue;
321                         }
322                         BufferCaseParameters    testParams =
323                         {
324                                 combinedBufferUsageFlags,
325                                 combinedBufferCreateFlags,
326                                 VK_SHARING_MODE_EXCLUSIVE
327                         };
328                         std::ostringstream      testName;
329                         std::ostringstream      testDescription;
330                         testName << "createBuffer_" << combinedBufferUsageFlags << "_" << combinedBufferCreateFlags;
331                         testDescription << "vkCreateBuffer test " << combinedBufferUsageFlags << " " << combinedBufferCreateFlags;
332                         buffersTests->addChild(new BuffersTestCase(testCtx, testName.str(), testDescription.str(), testParams));
333                 }
334         }
335
336         return buffersTests.release();
337 }
338
339 } // api
340 } // vk