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