1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Vulkan Buffers Tests
34 *//*--------------------------------------------------------------------*/
36 #include "vktApiBufferTests.hpp"
38 #include "deStringUtil.hpp"
39 #include "gluVarType.hpp"
40 #include "tcuTestLog.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRefUtil.hpp"
44 #include "vktTestCase.hpp"
57 struct BufferCaseParameters
59 VkBufferUsageFlags usage;
60 VkBufferCreateFlags flags;
61 VkSharingMode sharingMode;
64 class BufferTestInstance : public TestInstance
67 BufferTestInstance (Context& ctx,
68 BufferCaseParameters testCase)
70 , m_testCase (testCase)
72 virtual tcu::TestStatus iterate (void);
73 tcu::TestStatus bufferCreateAndAllocTest (VkDeviceSize size);
76 BufferCaseParameters m_testCase;
79 class BuffersTestCase : public TestCase
82 BuffersTestCase (tcu::TestContext& testCtx,
83 const std::string& name,
84 const std::string& description,
85 BufferCaseParameters testCase)
86 : TestCase(testCtx, name, description)
87 , m_testCase(testCase)
90 virtual ~BuffersTestCase (void) {}
91 virtual TestInstance* createInstance (Context& ctx) const
93 tcu::TestLog& log = m_testCtx.getLog();
94 log << tcu::TestLog::Message << getBufferUsageFlagsStr(m_testCase.usage) << tcu::TestLog::EndMessage;
95 return new BufferTestInstance(ctx, m_testCase);
99 BufferCaseParameters m_testCase;
102 tcu::TestStatus BufferTestInstance::bufferCreateAndAllocTest (VkDeviceSize size)
104 const VkDevice vkDevice = m_context.getDevice();
105 const DeviceInterface& vk = m_context.getDeviceInterface();
106 Move<VkBuffer> testBuffer;
107 VkMemoryRequirements memReqs;
108 Move<VkDeviceMemory> memory;
109 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
113 const VkBufferCreateInfo bufferParams =
115 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
120 m_testCase.sharingMode,
121 1u, // deUint32 queueFamilyCount;
127 testBuffer = createBuffer(vk, vkDevice, &bufferParams, (const VkAllocationCallbacks*)DE_NULL);
129 catch (const vk::Error& error)
131 return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
134 vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs);
136 if (size > memReqs.size)
138 std::ostringstream errorMsg;
139 errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
140 return tcu::TestStatus::fail(errorMsg.str());
144 // Allocate and bind memory
146 const VkMemoryAllocateInfo memAlloc =
148 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
151 0 // deUint32 memoryTypeIndex
156 memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL);
158 catch (const vk::Error& error)
160 return tcu::TestStatus::fail("Alloc memory failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")");
163 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) ||
164 (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) ||
165 (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT))
169 vk.getDeviceQueue(vkDevice, queueFamilyIndex, 0, &queue);
171 const VkSparseMemoryBind sparseMemoryBind =
173 0, // VkDeviceSize resourceOffset;
174 memReqs.size, // VkDeviceSize size;
175 *memory, // VkDeviceMemory memory;
176 0, // VkDeviceSize memoryOffset;
177 0 // VkSparseMemoryBindFlags flags;
180 const VkSparseBufferMemoryBindInfo sparseBufferMemoryBindInfo =
182 *testBuffer, // VkBuffer buffer;
183 1u, // deUint32 bindCount;
184 &sparseMemoryBind // const VkSparseMemoryBind* pBinds;
187 const VkBindSparseInfo bindSparseInfo =
189 VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, // VkStructureType sType;
190 DE_NULL, // const void* pNext;
191 0, // deUint32 waitSemaphoreCount;
192 DE_NULL, // const VkSemaphore* pWaitSemaphores;
193 1u, // deUint32 bufferBindCount;
194 &sparseBufferMemoryBindInfo, // const VkSparseBufferMemoryBindInfo* pBufferBinds;
195 0, // deUint32 imageOpaqueBindCount;
196 DE_NULL, // const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
197 0, // deUint32 imageBindCount;
198 DE_NULL, // const VkSparseImageMemoryBindInfo* pImageBinds;
199 0, // deUint32 signalSemaphoreCount;
200 DE_NULL, // const VkSemaphore* pSignalSemaphores;
203 const VkFenceCreateInfo fenceParams =
205 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
206 DE_NULL, // const void* pNext;
207 0u // VkFenceCreateFlags flags;
210 const vk::Unique<vk::VkFence> fence(vk::createFence(vk, vkDevice, &fenceParams));
212 VK_CHECK(vk.resetFences(vkDevice, 1, &fence.get()));
213 if (vk.queueBindSparse(queue, 1, &bindSparseInfo, *fence) != VK_SUCCESS)
214 return tcu::TestStatus::fail("Bind sparse buffer memory failed! (requested memory size: " + de::toString(size) + ")");
216 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~(0ull) /* infinity */));
218 if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS)
219 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
222 return tcu::TestStatus::pass("Buffer test");
225 tcu::TestStatus BufferTestInstance::iterate (void)
227 const VkPhysicalDeviceFeatures& physicalDeviceFeatures = m_context.getDeviceFeatures();
229 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT ) && !physicalDeviceFeatures.sparseBinding)
230 TCU_THROW(NotSupportedError, "Sparse bindings feature is not supported");
232 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT ) && !physicalDeviceFeatures.sparseResidencyBuffer)
233 TCU_THROW(NotSupportedError, "Sparse buffer residency feature is not supported");
235 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT ) && !physicalDeviceFeatures.sparseResidencyAliased)
236 TCU_THROW(NotSupportedError, "Sparse aliased residency feature is not supported");
238 const VkDeviceSize testSizes[] =
245 tcu::TestStatus testStatus = tcu::TestStatus::pass("Buffer test");
247 for (int i = 0; i < DE_LENGTH_OF_ARRAY(testSizes); i++)
249 if ((testStatus = bufferCreateAndAllocTest(testSizes[i])).getCode() != QP_TEST_RESULT_PASS)
253 if (m_testCase.usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT))
255 const VkPhysicalDevice vkPhysicalDevice = m_context.getPhysicalDevice();
256 const InstanceInterface& vkInstance = m_context.getInstanceInterface();
257 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
258 VkPhysicalDeviceProperties props;
260 vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &props);
262 const VkDeviceSize maxTestBufferSize = de::min((VkDeviceSize) props.limits.maxTexelBufferElements, memoryProperties.memoryHeaps[memoryProperties.memoryTypes[0].heapIndex].size / 16);
264 testStatus = bufferCreateAndAllocTest(maxTestBufferSize);
272 tcu::TestCaseGroup* createBufferTests (tcu::TestContext& testCtx)
274 const VkBufferUsageFlags bufferUsageModes[] =
276 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
277 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
278 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
279 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
280 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
281 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
282 VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
283 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
284 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
287 const VkBufferCreateFlags bufferCreateFlags[] =
289 VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
290 VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
291 VK_BUFFER_CREATE_SPARSE_ALIASED_BIT
294 de::MovePtr<tcu::TestCaseGroup> buffersTests (new tcu::TestCaseGroup(testCtx, "buffer", "Buffer Tests"));
296 deUint32 numberOfBufferUsageFlags = DE_LENGTH_OF_ARRAY(bufferUsageModes);
297 deUint32 numberOfBufferCreateFlags = DE_LENGTH_OF_ARRAY(bufferCreateFlags);
298 deUint32 maximumValueOfBufferUsageFlags = (1 << (numberOfBufferUsageFlags - 1)) - 1;
299 deUint32 maximumValueOfBufferCreateFlags = (1 << (numberOfBufferCreateFlags)) - 1;
301 for (deUint32 combinedBufferCreateFlags = 0; combinedBufferCreateFlags <= maximumValueOfBufferCreateFlags; combinedBufferCreateFlags++)
303 for (deUint32 combinedBufferUsageFlags = 1; combinedBufferUsageFlags <= maximumValueOfBufferUsageFlags; combinedBufferUsageFlags++)
305 if (combinedBufferCreateFlags == VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
307 // spec says: If flags contains VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, it must also contain at least one of
308 // VK_BUFFER_CREATE_SPARSE_BINDING_BIT or VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT
311 BufferCaseParameters testParams =
313 combinedBufferUsageFlags,
314 combinedBufferCreateFlags,
315 VK_SHARING_MODE_EXCLUSIVE
317 std::ostringstream testName;
318 std::ostringstream testDescription;
319 testName << "createBuffer_" << combinedBufferUsageFlags << "_" << combinedBufferCreateFlags;
320 testDescription << "vkCreateBuffer test " << combinedBufferUsageFlags << " " << combinedBufferCreateFlags;
321 buffersTests->addChild(new BuffersTestCase(testCtx, testName.str(), testDescription.str(), testParams));
325 return buffersTests.release();