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,
86 Move<VkDeviceMemory>& memory) const = 0;
89 class BufferSuballocation : public IBufferAllocator
92 virtual tcu::TestStatus createTestBuffer (VkDeviceSize size,
93 VkBufferUsageFlags usage,
95 Move<VkBuffer>& testBuffer,
96 Move<VkDeviceMemory>& memory) const;
99 class BufferDedicatedAllocation : public IBufferAllocator
102 virtual tcu::TestStatus createTestBuffer (VkDeviceSize size,
103 VkBufferUsageFlags usage,
105 Move<VkBuffer>& testBuffer,
106 Move<VkDeviceMemory>& memory) const;
109 class BufferViewTestCase : public TestCase
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)
119 virtual ~BufferViewTestCase (void)
121 virtual TestInstance* createInstance (Context& ctx) const
123 return new BufferViewTestInstance(ctx, m_testCase);
126 BufferViewCaseParameters m_testCase;
129 tcu::TestStatus BufferSuballocation::createTestBuffer (VkDeviceSize size,
130 VkBufferUsageFlags usage,
132 Move<VkBuffer>& testBuffer,
133 Move<VkDeviceMemory>& memory) const
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 =
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;
153 testBuffer = vk::createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
155 catch (const vk::Error& error)
157 return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
160 vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
162 if (size > memReqs.size)
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());
169 const VkMemoryAllocateInfo memAlloc =
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
179 memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
181 catch (const vk::Error& error)
183 return tcu::TestStatus::fail("Alloc memory failed! (Error code: " + de::toString(error.getMessage()) + ")");
186 if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
187 return tcu::TestStatus::fail("Bind buffer memory failed!");
189 return tcu::TestStatus::incomplete();
192 tcu::TestStatus BufferDedicatedAllocation::createTestBuffer (VkDeviceSize size,
193 VkBufferUsageFlags usage,
195 Move<VkBuffer>& testBuffer,
196 Move<VkDeviceMemory>& memory) const
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();
201 TCU_THROW(NotSupportedError, "Not supported");
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 =
211 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType;
212 DE_NULL, // const void* pNext;
213 false, // VkBool32 prefersDedicatedAllocation
214 false // VkBool32 requiresDedicatedAllocation
216 VkMemoryRequirements2KHR memReqs =
218 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType
219 &dedicatedRequirements, // void* pNext
220 {0, 0, 0} // VkMemoryRequirements memoryRequirements
223 const VkBufferCreateInfo bufferParams =
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;
237 testBuffer = vk::createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
239 catch (const vk::Error& error)
241 return tcu::TestStatus::fail("Buffer creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
244 VkBufferMemoryRequirementsInfo2KHR info =
246 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType
247 DE_NULL, // const void* pNext
248 *testBuffer // VkBuffer buffer
251 vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs);
253 if (dedicatedRequirements.requiresDedicatedAllocation == VK_TRUE)
255 std::ostringstream errorMsg;
256 errorMsg << "Nonexternal objects cannot require dedicated allocation.";
257 return tcu::TestStatus::fail(errorMsg.str());
260 if (size > memReqs.memoryRequirements.size)
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());
267 deMemset(&memoryProperties, 0, sizeof(memoryProperties));
268 vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
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];
274 vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs); // get the proper size requirement
276 if (size > memReqs.memoryRequirements.size)
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());
284 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
285 VkDeviceMemory rawMemory = DE_NULL;
287 vk::VkMemoryDedicatedAllocateInfoKHR
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
296 VkMemoryAllocateInfo memoryAllocateInfo =
298 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType
299 &dedicatedInfo, // const void* pNext
300 memReqs.memoryRequirements.size, // VkDeviceSize allocationSize
301 heapTypeIndex, // deUint32 memoryTypeIndex
304 result = vk.allocateMemory(vkDevice, &memoryAllocateInfo, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
306 if (result != VK_SUCCESS)
307 return tcu::TestStatus::fail("Unable to allocate " + de::toString(memReqs.memoryRequirements.size) + " bytes of memory");
309 memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
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) + ")");
316 return tcu::TestStatus::incomplete();
319 tcu::TestStatus BufferViewTestInstance::iterate (void)
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;
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");
333 if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
335 BufferDedicatedAllocation().createTestBuffer(size, m_testCase.usage, m_context, testBuffer, testBufferMemory);
339 BufferSuballocation().createTestBuffer(size, m_testCase.usage, m_context, testBuffer, testBufferMemory);
343 // Create buffer view.
344 Move<VkBufferView> bufferView;
345 const VkBufferViewCreateInfo bufferViewCreateInfo =
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;
358 bufferView = createBufferView(vk, vkDevice, &bufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
360 catch (const vk::Error& error)
362 return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
366 // Testing complete view size.
368 Move<VkBufferView> completeBufferView;
369 VkBufferViewCreateInfo completeBufferViewCreateInfo =
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;
382 completeBufferView = createBufferView(vk, vkDevice, &completeBufferViewCreateInfo, (const VkAllocationCallbacks*)DE_NULL);
384 catch (const vk::Error& error)
386 return tcu::TestStatus::fail("Buffer View creation failed! (Error code: " + de::toString(error.getMessage()) + ")");
390 return tcu::TestStatus::pass("BufferView test");
395 tcu::TestCaseGroup* createBufferViewCreateTests (tcu::TestContext& testCtx)
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"};
402 de::MovePtr<tcu::TestCaseGroup> bufferViewTests (new tcu::TestCaseGroup(testCtx, "create", "BufferView Construction Tests"));
404 if (!bufferViewTests)
405 TCU_THROW(InternalError, "Could not create test group \"create\".");
407 de::MovePtr<tcu::TestCaseGroup> bufferViewAllocationGroupTests[ALLOCATION_KIND_LAST]
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"))
414 for (deUint32 allocationKind = 0; allocationKind < ALLOCATION_KIND_LAST; ++allocationKind)
415 for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usage); ++usageNdx)
417 de::MovePtr<tcu::TestCaseGroup> usageGroup (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], ""));
419 for (deUint32 format = vk::VK_FORMAT_UNDEFINED + 1; format < VK_CORE_FORMAT_LAST; format++)
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"));
424 const std::string testName = de::toLower(getFormatName((VkFormat)format)).substr(10);
425 const std::string testDescription = "vkBufferView test " + testName;
428 const BufferViewCaseParameters testParams =
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;
438 usageGroup->addChild(new BufferViewTestCase(testCtx, testName.c_str(), testDescription.c_str(), testParams));
441 bufferViewAllocationGroupTests[allocationKind]->addChild(usageGroup.release());
444 for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
446 bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
449 return bufferViewTests.release();