1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Vulkan Buffer View Creation Tests
23 *//*--------------------------------------------------------------------*/
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"
47 ALLOCATION_KIND_SUBALLOCATED = 0,
48 ALLOCATION_KIND_DEDICATED,
53 class IBufferAllocator;
55 struct BufferViewCaseParameters
60 VkBufferUsageFlags usage;
61 VkFormatFeatureFlags features;
62 AllocationKind bufferAllocationKind;
65 class BufferViewTestInstance : public TestInstance
68 BufferViewTestInstance (Context& ctx,
69 BufferViewCaseParameters createInfo)
71 , m_testCase (createInfo)
73 virtual tcu::TestStatus iterate (void);
76 BufferViewCaseParameters m_testCase;
79 class IBufferAllocator
82 virtual tcu::TestStatus createTestBuffer (VkDeviceSize size,
83 VkBufferUsageFlags usage,
85 Move<VkBuffer>& testBuffer) const = 0;
88 class BufferSuballocation : public IBufferAllocator
91 virtual tcu::TestStatus createTestBuffer (VkDeviceSize size,
92 VkBufferUsageFlags usage,
94 Move<VkBuffer>& testBuffer) const;
97 class BufferDedicatedAllocation : public IBufferAllocator
100 virtual tcu::TestStatus createTestBuffer (VkDeviceSize size,
101 VkBufferUsageFlags usage,
103 Move<VkBuffer>& testBuffer) const;
106 class BufferViewTestCase : public TestCase
109 BufferViewTestCase (tcu::TestContext& testCtx,
110 const std::string& name,
111 const std::string& description,
112 BufferViewCaseParameters createInfo)
113 : TestCase (testCtx, name, description)
114 , m_testCase (createInfo)
116 virtual ~BufferViewTestCase (void)
118 virtual TestInstance* createInstance (Context& ctx) const
120 return new BufferViewTestInstance(ctx, m_testCase);
123 BufferViewCaseParameters m_testCase;
126 tcu::TestStatus BufferSuballocation::createTestBuffer (VkDeviceSize size,
127 VkBufferUsageFlags usage,
129 Move<VkBuffer>& testBuffer) const
131 const VkDevice vkDevice = context.getDevice();
132 const DeviceInterface& vk = context.getDeviceInterface();
133 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
134 VkMemoryRequirements memReqs;
135 const VkBufferCreateInfo bufferParams =
137 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
138 DE_NULL, // const void* pNext;
139 0u, // VkBufferCreateFlags flags;
140 size, // VkDeviceSize size;
141 usage, // VkBufferUsageFlags usage;
142 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
143 1u, // deUint32 queueFamilyCount;
144 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
149 testBuffer = vk::createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
151 catch (const vk::Error& error)
153 return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
156 vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
158 if (size > memReqs.size)
160 std::ostringstream errorMsg;
161 errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
162 return tcu::TestStatus::fail(errorMsg.str());
165 Move<VkDeviceMemory> memory;
166 const VkMemoryAllocateInfo memAlloc =
168 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType
169 NULL, // const void* pNext
170 memReqs.size, // VkDeviceSize allocationSize
171 (deUint32)deCtz32(memReqs.memoryTypeBits) // deUint32 memoryTypeIndex
176 memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
178 catch (const vk::Error& error)
180 return tcu::TestStatus::fail("Alloc memory failed! (Error code: " + de::toString(error.getMessage()) + ")");
183 if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
184 return tcu::TestStatus::fail("Bind buffer memory failed!");
186 return tcu::TestStatus::incomplete();
189 tcu::TestStatus BufferDedicatedAllocation::createTestBuffer (VkDeviceSize size,
190 VkBufferUsageFlags usage,
192 Move<VkBuffer>& testBuffer) const
194 const std::vector<std::string>& extensions = context.getDeviceExtensions();
195 const deBool isSupported = std::find(extensions.begin(), extensions.end(), "VK_KHR_dedicated_allocation") != extensions.end();
197 TCU_THROW(NotSupportedError, "Not supported");
199 const InstanceInterface& vkInstance = context.getInstanceInterface();
200 const VkDevice vkDevice = context.getDevice();
201 const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
202 const DeviceInterface& vk = context.getDeviceInterface();
203 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
204 VkPhysicalDeviceMemoryProperties memoryProperties;
205 VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
207 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType;
208 DE_NULL, // const void* pNext;
209 false, // VkBool32 prefersDedicatedAllocation
210 false // VkBool32 requiresDedicatedAllocation
212 VkMemoryRequirements2KHR memReqs =
214 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType
215 &dedicatedRequirements, // void* pNext
216 {0, 0, 0} // VkMemoryRequirements memoryRequirements
219 const VkBufferCreateInfo bufferParams =
221 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
222 DE_NULL, // const void* pNext;
223 0u, // VkBufferCreateFlags flags;
224 size, // VkDeviceSize size;
225 usage, // VkBufferUsageFlags usage;
226 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
227 1u, // deUint32 queueFamilyCount;
228 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
233 testBuffer = vk::createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
235 catch (const vk::Error& error)
237 return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
240 VkBufferMemoryRequirementsInfo2KHR info =
242 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType
243 DE_NULL, // const void* pNext
244 *testBuffer // VkBuffer buffer
247 vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs);
249 if (dedicatedRequirements.requiresDedicatedAllocation == VK_TRUE)
251 std::ostringstream errorMsg;
252 errorMsg << "Nonexternal objects cannot require dedicated allocation.";
253 return tcu::TestStatus::fail(errorMsg.str());
256 if (size > memReqs.memoryRequirements.size)
258 std::ostringstream errorMsg;
259 errorMsg << "Requied memory size (" << memReqs.memoryRequirements.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
260 return tcu::TestStatus::fail(errorMsg.str());
263 deMemset(&memoryProperties, 0, sizeof(memoryProperties));
264 vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
266 const deUint32 heapTypeIndex = static_cast<deUint32>(deCtz32(memReqs.memoryRequirements.memoryTypeBits));
267 //const VkMemoryType memoryType = memoryProperties.memoryTypes[heapTypeIndex];
268 //const VkMemoryHeap memoryHeap = memoryProperties.memoryHeaps[memoryType.heapIndex];
270 Move<VkDeviceMemory> memory;
271 vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs); // get the proper size requirement
273 if (size > memReqs.memoryRequirements.size)
275 std::ostringstream errorMsg;
276 errorMsg << "Requied memory size (" << memReqs.memoryRequirements.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
277 return tcu::TestStatus::fail(errorMsg.str());
281 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
282 VkDeviceMemory rawMemory = DE_NULL;
284 vk::VkMemoryDedicatedAllocateInfoKHR
287 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, // VkStructureType sType
288 DE_NULL, // const void* pNext
289 DE_NULL, // VkImage image
290 *testBuffer // VkBuffer buffer
293 VkMemoryAllocateInfo memoryAllocateInfo =
295 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType
296 &dedicatedInfo, // const void* pNext
297 memReqs.memoryRequirements.size, // VkDeviceSize allocationSize
298 heapTypeIndex, // deUint32 memoryTypeIndex
301 result = vk.allocateMemory(vkDevice, &memoryAllocateInfo, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
303 if (result != VK_SUCCESS)
304 return tcu::TestStatus::fail("Unable to allocate " + de::toString(memReqs.memoryRequirements.size) + " bytes of memory");
306 memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
310 if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
311 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
313 return tcu::TestStatus::incomplete();
316 tcu::TestStatus BufferViewTestInstance::iterate (void)
318 const VkDevice vkDevice = m_context.getDevice();
319 const DeviceInterface& vk = m_context.getDeviceInterface();
320 const VkDeviceSize size = 3 * 5 * 7 * 64;
321 Move<VkBuffer> testBuffer;
322 VkFormatProperties properties;
324 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(), m_testCase.format, &properties);
325 if (!(properties.bufferFeatures & m_testCase.features))
326 TCU_THROW(NotSupportedError, "Format not supported");
329 if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
331 BufferDedicatedAllocation().createTestBuffer(size, m_testCase.usage, m_context, testBuffer);
335 BufferSuballocation().createTestBuffer(size, m_testCase.usage, m_context, testBuffer);
339 // Create buffer view.
340 Move<VkBufferView> bufferView;
341 const VkBufferViewCreateInfo bufferViewCreateInfo =
343 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
344 NULL, // const void* pNext;
345 (VkBufferViewCreateFlags)0,
346 *testBuffer, // VkBuffer buffer;
347 m_testCase.format, // VkFormat format;
348 m_testCase.offset, // VkDeviceSize offset;
349 m_testCase.range, // VkDeviceSize range;
354 bufferView = createBufferView(vk, vkDevice, &bufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
356 catch (const vk::Error& error)
358 return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
362 // Testing complete view size.
364 Move<VkBufferView> completeBufferView;
365 VkBufferViewCreateInfo completeBufferViewCreateInfo =
367 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
368 NULL, // const void* pNext;
369 (VkBufferViewCreateFlags)0,
370 *testBuffer, // VkBuffer buffer;
371 m_testCase.format, // VkFormat format;
372 m_testCase.offset, // VkDeviceSize offset;
373 size, // VkDeviceSize range;
378 completeBufferView = createBufferView(vk, vkDevice, &completeBufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
380 catch (const vk::Error& error)
382 return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
386 return tcu::TestStatus::pass("BufferView test");
391 tcu::TestCaseGroup* createBufferViewCreateTests (tcu::TestContext& testCtx)
393 const VkDeviceSize range = VK_WHOLE_SIZE;
394 const vk::VkBufferUsageFlags usage[] = { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT };
395 const vk::VkFormatFeatureFlags feature[] = { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT };
396 const char* const usageName[] = { "uniform", "storage"};
398 de::MovePtr<tcu::TestCaseGroup> bufferViewTests (new tcu::TestCaseGroup(testCtx, "create", "BufferView Construction Tests"));
400 if (!bufferViewTests)
401 TCU_THROW(InternalError, "Could not create test group \"create\".");
403 de::MovePtr<tcu::TestCaseGroup> bufferViewAllocationGroupTests[ALLOCATION_KIND_LAST]
406 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation", "BufferView Construction Tests for Suballocated Buffer")),
407 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "BufferView Construction Tests for Dedicatedly Allocated Buffer"))
410 for (deUint32 allocationKind = 0; allocationKind < ALLOCATION_KIND_LAST; ++allocationKind)
411 for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usage); ++usageNdx)
413 de::MovePtr<tcu::TestCaseGroup> usageGroup (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], ""));
415 for (deUint32 format = vk::VK_FORMAT_UNDEFINED + 1; format < VK_CORE_FORMAT_LAST; format++)
417 const std::string formatName = de::toLower(getFormatName((VkFormat)format)).substr(10);
418 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, "suballocation", "BufferView Construction Tests for Suballocated Buffer"));
420 const std::string testName = de::toLower(getFormatName((VkFormat)format)).substr(10);
421 const std::string testDescription = "vkBufferView test " + testName;
424 const BufferViewCaseParameters testParams =
426 static_cast<vk::VkFormat>(format), // VkFormat format;
427 0, // VkDeviceSize offset;
428 range, // VkDeviceSize range;
429 usage[usageNdx], // VkBufferUsageFlags usage;
430 feature[usageNdx], // VkFormatFeatureFlags flags;
431 static_cast<AllocationKind>(allocationKind) // AllocationKind bufferAllocationKind;
434 usageGroup->addChild(new BufferViewTestCase(testCtx, testName.c_str(), testDescription.c_str(), testParams));
437 bufferViewAllocationGroupTests[allocationKind]->addChild(usageGroup.release());
440 for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
442 bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
445 return bufferViewTests.release();