Merge vk-gl-cts/vulkan-cts-1.0.2 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiBufferViewCreateTests.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 Buffer View Creation Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktApiBufferViewCreateTests.hpp"
26 #include "deStringUtil.hpp"
27 #include "deSharedPtr.hpp"
28 #include "gluVarType.hpp"
29 #include "tcuTestLog.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vktTestCase.hpp"
33
34 namespace vkt
35 {
36
37 using namespace vk;
38
39 namespace api
40 {
41
42 namespace
43 {
44
45 enum AllocationKind
46 {
47         ALLOCATION_KIND_SUBALLOCATED = 0,
48         ALLOCATION_KIND_DEDICATED,
49
50         ALLOCATION_KIND_LAST,
51 };
52
53 class IBufferAllocator;
54
55 struct BufferViewCaseParameters
56 {
57         VkFormat                                                        format;
58         VkDeviceSize                                            offset;
59         VkDeviceSize                                            range;
60         VkBufferUsageFlags                                      usage;
61         VkFormatFeatureFlags                            features;
62         AllocationKind                                          bufferAllocationKind;
63 };
64
65 class BufferViewTestInstance : public TestInstance
66 {
67 public:
68                                                                                 BufferViewTestInstance                  (Context&                                       ctx,
69                                                                                                                                                  BufferViewCaseParameters       createInfo)
70                                                                                 : TestInstance                                  (ctx)
71                                                                                 , m_testCase                                    (createInfo)
72         {}
73         virtual tcu::TestStatus                         iterate                                                 (void);
74
75 protected:
76         BufferViewCaseParameters                        m_testCase;
77 };
78
79 class IBufferAllocator
80 {
81 public:
82         virtual tcu::TestStatus                         createTestBuffer                                (VkDeviceSize                           size,
83                                                                                                                                                  VkBufferUsageFlags                     usage,
84                                                                                                                                                  Context&                                       context,
85                                                                                                                                                  Move<VkBuffer>&                        testBuffer,
86                                                                                                                                                  Move<VkDeviceMemory>&          memory) const = 0;
87 };
88
89 class BufferSuballocation : public IBufferAllocator
90 {
91 public:
92         virtual tcu::TestStatus                         createTestBuffer                                (VkDeviceSize                           size,
93                                                                                                                                                  VkBufferUsageFlags                     usage,
94                                                                                                                                                  Context&                                       context,
95                                                                                                                                                  Move<VkBuffer>&                        testBuffer,
96                                                                                                                                                  Move<VkDeviceMemory>&          memory) const;
97 };
98
99 class BufferDedicatedAllocation : public IBufferAllocator
100 {
101 public:
102         virtual tcu::TestStatus                         createTestBuffer                                (VkDeviceSize                           size,
103                                                                                                                                                  VkBufferUsageFlags                     usage,
104                                                                                                                                                  Context&                                       context,
105                                                                                                                                                  Move<VkBuffer>&                        testBuffer,
106                                                                                                                                                  Move<VkDeviceMemory>&          memory) const;
107 };
108
109 class BufferViewTestCase : public TestCase
110 {
111 public:
112                                                                                 BufferViewTestCase                              (tcu::TestContext&                      testCtx,
113                                                                                                                                                  const std::string&                     name,
114                                                                                                                                                  const std::string&                     description,
115                                                                                                                                                  BufferViewCaseParameters       createInfo)
116                                                                                 : TestCase                                              (testCtx, name, description)
117                                                                                 , m_testCase                                    (createInfo)
118         {}
119         virtual                                                         ~BufferViewTestCase                             (void)
120         {}
121         virtual TestInstance*                           createInstance                                  (Context&                                       ctx) const
122         {
123                 return new BufferViewTestInstance(ctx, m_testCase);
124         }
125 private:
126         BufferViewCaseParameters                        m_testCase;
127 };
128
129 tcu::TestStatus BufferSuballocation::createTestBuffer                                   (VkDeviceSize                           size,
130                                                                                                                                                  VkBufferUsageFlags                     usage,
131                                                                                                                                                  Context&                                       context,
132                                                                                                                                                  Move<VkBuffer>&                        testBuffer,
133                                                                                                                                                  Move<VkDeviceMemory>&          memory) const
134 {
135         const VkDevice                                          vkDevice                                                = context.getDevice();
136         const DeviceInterface&                          vk                                                              = context.getDeviceInterface();
137         const deUint32                                          queueFamilyIndex                                = context.getUniversalQueueFamilyIndex();
138         VkMemoryRequirements                            memReqs;
139         const VkBufferCreateInfo                        bufferParams                                    =
140         {
141                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                                   //      VkStructureType                 sType;
142                 DE_NULL,                                                                                                                //      const void*                             pNext;
143                 0u,                                                                                                                             //      VkBufferCreateFlags             flags;
144                 size,                                                                                                                   //      VkDeviceSize                    size;
145                 usage,                                                                                                                  //      VkBufferUsageFlags              usage;
146                 VK_SHARING_MODE_EXCLUSIVE,                                                                              //      VkSharingMode                   sharingMode;
147                 1u,                                                                                                                             //      deUint32                                queueFamilyCount;
148                 &queueFamilyIndex,                                                                                              //      const deUint32*                 pQueueFamilyIndices;
149         };
150
151         try
152         {
153                 testBuffer = vk::createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
154         }
155         catch (const vk::Error& error)
156         {
157                 return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
158         }
159
160         vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
161
162         if (size > memReqs.size)
163         {
164                 std::ostringstream errorMsg;
165                 errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
166                 return tcu::TestStatus::fail(errorMsg.str());
167         }
168
169         const VkMemoryAllocateInfo                      memAlloc                                                =
170         {
171                 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,                                                 //      VkStructureType                 sType
172                 NULL,                                                                                                                   //      const void*                             pNext
173                 memReqs.size,                                                                                                   //      VkDeviceSize                    allocationSize
174                 (deUint32)deCtz32(memReqs.memoryTypeBits)                                               //      deUint32                                memoryTypeIndex
175         };
176
177         try
178         {
179                 memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
180         }
181         catch (const vk::Error& error)
182         {
183                 return tcu::TestStatus::fail("Alloc memory failed! (Error code: " + de::toString(error.getMessage()) + ")");
184         }
185
186         if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
187                 return tcu::TestStatus::fail("Bind buffer memory failed!");
188
189         return tcu::TestStatus::incomplete();
190 }
191
192 tcu::TestStatus BufferDedicatedAllocation::createTestBuffer                             (VkDeviceSize                           size,
193                                                                                                                                                  VkBufferUsageFlags                     usage,
194                                                                                                                                                  Context&                                       context,
195                                                                                                                                                  Move<VkBuffer>&                        testBuffer,
196                                                                                                                                                  Move<VkDeviceMemory>&          memory) const
197 {
198         const std::vector<std::string>&         extensions                                              = context.getDeviceExtensions();
199         const deBool                                            isSupported                                             = std::find(extensions.begin(), extensions.end(), "VK_KHR_dedicated_allocation") != extensions.end();
200         if (!isSupported)
201                 TCU_THROW(NotSupportedError, "Not supported");
202
203         const InstanceInterface&                        vkInstance                                              = context.getInstanceInterface();
204         const VkDevice                                          vkDevice                                                = context.getDevice();
205         const VkPhysicalDevice                          vkPhysicalDevice                                = context.getPhysicalDevice();
206         const DeviceInterface&                          vk                                                              = context.getDeviceInterface();
207         const deUint32                                          queueFamilyIndex                                = context.getUniversalQueueFamilyIndex();
208         VkPhysicalDeviceMemoryProperties        memoryProperties;
209         VkMemoryDedicatedRequirementsKHR        dedicatedRequirements                   =
210         {
211                 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR,                    // VkStructureType              sType;
212                 DE_NULL,                                                                                                                // const void*                  pNext;
213                 false,                                                                                                                  // VkBool32                             prefersDedicatedAllocation
214                 false                                                                                                                   // VkBool32                             requiresDedicatedAllocation
215         };
216         VkMemoryRequirements2KHR                        memReqs                                                 =
217         {
218                 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR,                                    // VkStructureType              sType
219                 &dedicatedRequirements,                                                                                 // void*                                pNext
220                 {0, 0, 0}                                                                                                               // VkMemoryRequirements memoryRequirements
221         };
222
223         const VkBufferCreateInfo                        bufferParams                                    =
224         {
225                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                                   //      VkStructureType                 sType;
226                 DE_NULL,                                                                                                                //      const void*                             pNext;
227                 0u,                                                                                                                             //      VkBufferCreateFlags             flags;
228                 size,                                                                                                                   //      VkDeviceSize                    size;
229                 usage,                                                                                                                  //      VkBufferUsageFlags              usage;
230                 VK_SHARING_MODE_EXCLUSIVE,                                                                              //      VkSharingMode                   sharingMode;
231                 1u,                                                                                                                             //      deUint32                                queueFamilyCount;
232                 &queueFamilyIndex,                                                                                              //      const deUint32*                 pQueueFamilyIndices;
233         };
234
235         try
236         {
237                 testBuffer = vk::createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
238         }
239         catch (const vk::Error& error)
240         {
241                 return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
242         }
243
244         VkBufferMemoryRequirementsInfo2KHR      info                                                    =
245         {
246                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR,                // VkStructureType              sType
247                 DE_NULL,                                                                                                                // const void*                  pNext
248                 *testBuffer                                                                                                             // VkBuffer                             buffer
249         };
250
251         vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs);
252
253         if (dedicatedRequirements.requiresDedicatedAllocation == VK_TRUE)
254         {
255                 std::ostringstream                              errorMsg;
256                 errorMsg << "Nonexternal objects cannot require dedicated allocation.";
257                 return tcu::TestStatus::fail(errorMsg.str());
258         }
259
260         if (size > memReqs.memoryRequirements.size)
261         {
262                 std::ostringstream                              errorMsg;
263                 errorMsg << "Requied memory size (" << memReqs.memoryRequirements.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
264                 return tcu::TestStatus::fail(errorMsg.str());
265         }
266
267         deMemset(&memoryProperties, 0, sizeof(memoryProperties));
268         vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
269
270         const deUint32                                          heapTypeIndex                                   = static_cast<deUint32>(deCtz32(memReqs.memoryRequirements.memoryTypeBits));
271         //const VkMemoryType                                    memoryType                                              = memoryProperties.memoryTypes[heapTypeIndex];
272         //const VkMemoryHeap                                    memoryHeap                                              = memoryProperties.memoryHeaps[memoryType.heapIndex];
273
274         vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs); // get the proper size requirement
275
276         if (size > memReqs.memoryRequirements.size)
277         {
278                 std::ostringstream                              errorMsg;
279                 errorMsg << "Requied memory size (" << memReqs.memoryRequirements.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
280                 return tcu::TestStatus::fail(errorMsg.str());
281         }
282
283         {
284                 VkResult                                                result                                                  = VK_ERROR_OUT_OF_HOST_MEMORY;
285                 VkDeviceMemory                                  rawMemory                                               = DE_NULL;
286
287                 vk::VkMemoryDedicatedAllocateInfoKHR
288                                                                                 dedicatedInfo                                   =
289                 {
290                         VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR,           // VkStructureType                      sType
291                         DE_NULL,                                                                                                        // const void*                          pNext
292                         DE_NULL,                                                                                                        // VkImage                                      image
293                         *testBuffer                                                                                                     // VkBuffer                                     buffer
294                 };
295
296                 VkMemoryAllocateInfo                    memoryAllocateInfo                              =
297                 {
298                         VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,                                         // VkStructureType                      sType
299                         &dedicatedInfo,                                                                                         // const void*                          pNext
300                         memReqs.memoryRequirements.size,                                                        // VkDeviceSize                         allocationSize
301                         heapTypeIndex,                                                                                          // deUint32                                     memoryTypeIndex
302                 };
303
304                 result = vk.allocateMemory(vkDevice, &memoryAllocateInfo, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
305
306                 if (result != VK_SUCCESS)
307                         return tcu::TestStatus::fail("Unable to allocate " + de::toString(memReqs.memoryRequirements.size) + " bytes of memory");
308
309                 memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
310         }
311
312
313         if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
314                 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
315
316         return tcu::TestStatus::incomplete();
317 }
318
319 tcu::TestStatus BufferViewTestInstance::iterate                                                 (void)
320 {
321         const VkDevice                                          vkDevice                                                = m_context.getDevice();
322         const DeviceInterface&                          vk                                                              = m_context.getDeviceInterface();
323         const VkDeviceSize                                      size                                                    = 3 * 5 * 7 * 64;
324         Move<VkBuffer>                                          testBuffer;
325         Move<VkDeviceMemory>                            testBufferMemory;
326         VkFormatProperties                                      properties;
327
328         m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), m_testCase.format, &properties);
329         if (!(properties.bufferFeatures & m_testCase.features))
330                 TCU_THROW(NotSupportedError, "Format not supported");
331
332         // Create buffer
333         if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
334         {
335                 BufferDedicatedAllocation().createTestBuffer(size, m_testCase.usage, m_context, testBuffer, testBufferMemory);
336         }
337         else
338         {
339                 BufferSuballocation().createTestBuffer(size, m_testCase.usage, m_context, testBuffer, testBufferMemory);
340         }
341
342         {
343                 // Create buffer view.
344                 Move<VkBufferView>                              bufferView;
345                 const VkBufferViewCreateInfo    bufferViewCreateInfo                    =
346                 {
347                         VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,                                      //      VkStructureType                 sType;
348                         NULL,                                                                                                           //      const void*                             pNext;
349                         (VkBufferViewCreateFlags)0,
350                         *testBuffer,                                                                                            //      VkBuffer                                buffer;
351                         m_testCase.format,                                                                                      //      VkFormat                                format;
352                         m_testCase.offset,                                                                                      //      VkDeviceSize                    offset;
353                         m_testCase.range,                                                                                       //      VkDeviceSize                    range;
354                 };
355
356                 try
357                 {
358                         bufferView = createBufferView(vk, vkDevice, &bufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
359                 }
360                 catch (const vk::Error& error)
361                 {
362                         return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
363                 }
364         }
365
366         // Testing complete view size.
367         {
368                 Move<VkBufferView>                              completeBufferView;
369                 VkBufferViewCreateInfo                  completeBufferViewCreateInfo    =
370                 {
371                         VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,                                      //      VkStructureType                 sType;
372                         NULL,                                                                                                           //      const void*                             pNext;
373                         (VkBufferViewCreateFlags)0,
374                         *testBuffer,                                                                                            //      VkBuffer                                buffer;
375                         m_testCase.format,                                                                                      //      VkFormat                                format;
376                         m_testCase.offset,                                                                                      //      VkDeviceSize                    offset;
377                         size,                                                                                                           //      VkDeviceSize                    range;
378                 };
379
380                 try
381                 {
382                         completeBufferView = createBufferView(vk, vkDevice, &completeBufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
383                 }
384                 catch (const vk::Error& error)
385                 {
386                         return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
387                 }
388         }
389
390         return tcu::TestStatus::pass("BufferView test");
391 }
392
393 } // anonymous
394
395  tcu::TestCaseGroup* createBufferViewCreateTests                                                (tcu::TestContext& testCtx)
396 {
397         const VkDeviceSize                                      range                                                   = VK_WHOLE_SIZE;
398         const vk::VkBufferUsageFlags            usage[]                                                 = { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT };
399         const vk::VkFormatFeatureFlags          feature[]                                               = { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT };
400         const char* const                                       usageName[]                                             = { "uniform", "storage"};
401
402         de::MovePtr<tcu::TestCaseGroup>         bufferViewTests                                 (new tcu::TestCaseGroup(testCtx, "create", "BufferView Construction Tests"));
403
404         if (!bufferViewTests)
405                 TCU_THROW(InternalError, "Could not create test group \"create\".");
406
407         de::MovePtr<tcu::TestCaseGroup>         bufferViewAllocationGroupTests[ALLOCATION_KIND_LAST]
408                                                                                                                                                 =
409         {
410                 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation", "BufferView Construction Tests for Suballocated Buffer")),
411                 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "BufferView Construction Tests for Dedicatedly Allocated Buffer"))
412         };
413
414         for (deUint32 allocationKind = 0; allocationKind < ALLOCATION_KIND_LAST; ++allocationKind)
415         for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usage); ++usageNdx)
416         {
417                 de::MovePtr<tcu::TestCaseGroup> usageGroup              (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], ""));
418
419                 for (deUint32 format = vk::VK_FORMAT_UNDEFINED + 1; format < VK_CORE_FORMAT_LAST; format++)
420                 {
421                         const std::string                               formatName              = de::toLower(getFormatName((VkFormat)format)).substr(10);
422                         de::MovePtr<tcu::TestCaseGroup> formatGroup             (new tcu::TestCaseGroup(testCtx, "suballocation", "BufferView Construction Tests for Suballocated Buffer"));
423
424                         const std::string                               testName                = de::toLower(getFormatName((VkFormat)format)).substr(10);
425                         const std::string                               testDescription = "vkBufferView test " + testName;
426
427                         {
428                                 const BufferViewCaseParameters  testParams                                      =
429                                 {
430                                         static_cast<vk::VkFormat>(format),                                              // VkFormat                                     format;
431                                         0,                                                                                                              // VkDeviceSize                         offset;
432                                         range,                                                                                                  // VkDeviceSize                         range;
433                                         usage[usageNdx],                                                                                // VkBufferUsageFlags           usage;
434                                         feature[usageNdx],                                                                              // VkFormatFeatureFlags         flags;
435                                         static_cast<AllocationKind>(allocationKind)                             // AllocationKind                       bufferAllocationKind;
436                                 };
437
438                                 usageGroup->addChild(new BufferViewTestCase(testCtx, testName.c_str(), testDescription.c_str(), testParams));
439                         }
440                 }
441                 bufferViewAllocationGroupTests[allocationKind]->addChild(usageGroup.release());
442         }
443
444         for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
445         {
446                 bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
447         }
448
449         return bufferViewTests.release();
450 }
451
452 } // api
453 } // vk