X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=external%2Fvulkancts%2Fmodules%2Fvulkan%2Fapi%2FvktApiBufferTests.cpp;h=1cebc7d954ddcb9f4e527460384c5a59e45cadb1;hb=b7e64d87c14fcbcf8ffad74fe560b1efe6d972f8;hp=29a3c5ac488cc1ad57f56470bade0e44bf1f8cc7;hpb=95b7e678dd850853354f5211bab015d900fd8e93;p=platform%2Fupstream%2FVK-GL-CTS.git diff --git a/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp b/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp index 29a3c5a..1cebc7d 100644 --- a/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp +++ b/external/vulkancts/modules/vulkan/api/vktApiBufferTests.cpp @@ -32,19 +32,44 @@ #include "vkRefUtil.hpp" #include "vkPlatform.hpp" #include "vktTestCase.hpp" +#include "tcuPlatform.hpp" namespace vkt { - +namespace api +{ +namespace +{ using namespace vk; -namespace api +PlatformMemoryLimits getPlatformMemoryLimits (Context& context) { + PlatformMemoryLimits memoryLimits; -namespace + context.getTestContext().getPlatform().getVulkanPlatform().getMemoryLimits(memoryLimits); + + return memoryLimits; +} + +VkDeviceSize getMaxBufferSize(const VkDeviceSize& bufferSize, + const VkDeviceSize& alignment, + const PlatformMemoryLimits& limits) { + VkDeviceSize size = bufferSize; -static const deUint32 MAX_BUFFER_SIZE_DIVISOR = 16; + if (limits.totalDeviceLocalMemory == 0) + { + // 'UMA' systems where device memory counts against system memory + size = std::min(bufferSize, limits.totalSystemMemory - alignment); + } + else + { + // 'LMA' systems where device memory is local to the GPU + size = std::min(bufferSize, limits.totalDeviceLocalMemory - alignment); + } + + return size; +} struct BufferCaseParameters { @@ -204,155 +229,190 @@ private: BufferCaseParameters m_testCase; }; - +inline VkDeviceSize alignDeviceSize (VkDeviceSize val, VkDeviceSize align) +{ + DE_ASSERT(deIsPowerOfTwo64(align)); + DE_ASSERT(val + align >= val); // crash on overflow + return (val + align - 1) & ~(align - 1); +} tcu::TestStatus BufferTestInstance::bufferCreateAndAllocTest (VkDeviceSize size) { - const VkPhysicalDevice vkPhysicalDevice = getPhysicalDevice(); - const InstanceInterface& vkInstance = getInstanceInterface(); - const VkDevice vkDevice = getDevice(); - const DeviceInterface& vk = getDeviceInterface(); - Move testBuffer; - VkMemoryRequirements memReqs; - Move memory; - const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); - const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice); - - // Create buffer + const VkPhysicalDevice vkPhysicalDevice = getPhysicalDevice(); + const InstanceInterface& vkInstance = getInstanceInterface(); + const VkDevice vkDevice = getDevice(); + const DeviceInterface& vk = getDeviceInterface(); + const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex(); + const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice); + const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vkInstance, vkPhysicalDevice).limits; + Move buffer; + Move memory; + VkMemoryRequirements memReqs; + + if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0) + size = std::min(size, limits.sparseAddressSpaceSize); + + // Create the test buffer and a memory allocation for it { - VkBufferCreateInfo bufferParams = + // Create a minimal buffer first to get the supported memory types + VkBufferCreateInfo bufferParams = { - VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, - DE_NULL, - m_testCase.flags, - size, - m_testCase.usage, - m_testCase.sharingMode, - 1u, // deUint32 queueFamilyCount; - &queueFamilyIndex, + VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + m_testCase.flags, // VkBufferCreateFlags flags; + 1u, // VkDeviceSize size; + m_testCase.usage, // VkBufferUsageFlags usage; + m_testCase.sharingMode, // VkSharingMode sharingMode; + 1u, // uint32_t queueFamilyIndexCount; + &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices; }; - try - { - testBuffer = createBuffer(vk, vkDevice, &bufferParams); - } - catch (const vk::Error& error) - { - return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")"); - } - - vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs); + buffer = createBuffer(vk, vkDevice, &bufferParams); + vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs); const deUint32 heapTypeIndex = (deUint32)deCtz32(memReqs.memoryTypeBits); const VkMemoryType memoryType = memoryProperties.memoryTypes[heapTypeIndex]; const VkMemoryHeap memoryHeap = memoryProperties.memoryHeaps[memoryType.heapIndex]; - const VkDeviceSize maxBufferSize = memoryHeap.size / MAX_BUFFER_SIZE_DIVISOR; - // If the requested size is too large, clamp it based on the selected heap size - if (size > maxBufferSize) + const deUint32 shrinkBits = 4; // number of bits to shift when reducing the size with each iteration + + // Buffer size - Choose half of the reported heap size for the maximum buffer size, we + // should attempt to test as large a portion as possible. + // + // However on a system where device memory is shared with the system, the maximum size + // should be tested against the platform memory limits as significant portion of the heap + // may already be in use by the operating system and other running processes. + const VkDeviceSize availableBufferSize = getMaxBufferSize(memoryHeap.size, + memReqs.alignment, + getPlatformMemoryLimits(m_context)); + + // For our test buffer size, halve the maximum available size and align + const VkDeviceSize maxBufferSize = alignDeviceSize(availableBufferSize >> 1, memReqs.alignment); + + size = std::min(size, maxBufferSize); + + while (*memory == DE_NULL) { - size = maxBufferSize; - bufferParams.size = size; - try + // Create the buffer { - // allocate a new buffer with the adjusted size, the old one will be destroyed by the smart pointer - testBuffer = createBuffer(vk, vkDevice, &bufferParams); + VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY; + VkBuffer rawBuffer = DE_NULL; + + bufferParams.size = size; + buffer = Move(); // free the previous buffer, if any + result = vk.createBuffer(vkDevice, &bufferParams, (VkAllocationCallbacks*)DE_NULL, &rawBuffer); + + if (result != VK_SUCCESS) + { + size = alignDeviceSize(size >> shrinkBits, memReqs.alignment); + + if (size == 0 || bufferParams.size == memReqs.alignment) + return tcu::TestStatus::fail("Buffer creation failed! (" + de::toString(getResultName(result)) + ")"); + + continue; // didn't work, try with a smaller buffer + } + + buffer = Move(check(rawBuffer), Deleter(vk, vkDevice, DE_NULL)); } - catch (const vk::Error& error) + + vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs); // get the proper size requirement + + if (size > memReqs.size) { - return tcu::TestStatus::fail("Buffer creation failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")"); + std::ostringstream errorMsg; + errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!"; + return tcu::TestStatus::fail(errorMsg.str()); } - vk.getBufferMemoryRequirements(vkDevice, *testBuffer, &memReqs); - } - if (size > memReqs.size) - { - std::ostringstream errorMsg; - errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!"; - return tcu::TestStatus::fail(errorMsg.str()); - } + // Allocate the memory + { + VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY; + VkDeviceMemory rawMemory = DE_NULL; + + const VkMemoryAllocateInfo memAlloc = + { + VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType; + NULL, // const void* pNext; + memReqs.size, // VkDeviceSize allocationSize; + heapTypeIndex, // uint32_t memoryTypeIndex; + }; + + result = vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory); + + if (result != VK_SUCCESS) + { + size = alignDeviceSize(size >> shrinkBits, memReqs.alignment); + + if (size == 0 || memReqs.size == memReqs.alignment) + return tcu::TestStatus::fail("Unable to allocate " + de::toString(memReqs.size) + " bytes of memory"); + + continue; // didn't work, try with a smaller allocation (and a smaller buffer) + } + + memory = Move(check(rawMemory), Deleter(vk, vkDevice, DE_NULL)); + } + } // while } - // Allocate and bind memory + // Bind the memory + if ((m_testCase.flags & (VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)) != 0) { - const VkMemoryAllocateInfo memAlloc = + VkQueue queue = DE_NULL; + + vk.getDeviceQueue(vkDevice, queueFamilyIndex, 0, &queue); + + const VkSparseMemoryBind sparseMemoryBind = { - VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - NULL, - memReqs.size, - (deUint32)deCtz32(memReqs.memoryTypeBits) // deUint32 memoryTypeIndex + 0, // VkDeviceSize resourceOffset; + memReqs.size, // VkDeviceSize size; + *memory, // VkDeviceMemory memory; + 0, // VkDeviceSize memoryOffset; + 0 // VkSparseMemoryBindFlags flags; }; - try - { - memory = allocateMemory(vk, vkDevice, &memAlloc, (const VkAllocationCallbacks*)DE_NULL); - } - catch (const vk::Error& error) + const VkSparseBufferMemoryBindInfo sparseBufferMemoryBindInfo = { - return tcu::TestStatus::fail("Alloc memory failed! (requested memory size: " + de::toString(size) + ", Error code: " + de::toString(error.getMessage()) + ")"); - } + *buffer, // VkBuffer buffer; + 1u, // deUint32 bindCount; + &sparseMemoryBind // const VkSparseMemoryBind* pBinds; + }; - if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || - (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) || - (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)) + const VkBindSparseInfo bindSparseInfo = { - VkQueue queue = 0; - - vk.getDeviceQueue(vkDevice, queueFamilyIndex, 0, &queue); - - const VkSparseMemoryBind sparseMemoryBind = - { - 0, // VkDeviceSize resourceOffset; - memReqs.size, // VkDeviceSize size; - *memory, // VkDeviceMemory memory; - 0, // VkDeviceSize memoryOffset; - 0 // VkSparseMemoryBindFlags flags; - }; - - const VkSparseBufferMemoryBindInfo sparseBufferMemoryBindInfo = - { - *testBuffer, // VkBuffer buffer; - 1u, // deUint32 bindCount; - &sparseMemoryBind // const VkSparseMemoryBind* pBinds; - }; + VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0, // deUint32 waitSemaphoreCount; + DE_NULL, // const VkSemaphore* pWaitSemaphores; + 1u, // deUint32 bufferBindCount; + &sparseBufferMemoryBindInfo, // const VkSparseBufferMemoryBindInfo* pBufferBinds; + 0, // deUint32 imageOpaqueBindCount; + DE_NULL, // const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; + 0, // deUint32 imageBindCount; + DE_NULL, // const VkSparseImageMemoryBindInfo* pImageBinds; + 0, // deUint32 signalSemaphoreCount; + DE_NULL, // const VkSemaphore* pSignalSemaphores; + }; - const VkBindSparseInfo bindSparseInfo = - { - VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0, // deUint32 waitSemaphoreCount; - DE_NULL, // const VkSemaphore* pWaitSemaphores; - 1u, // deUint32 bufferBindCount; - &sparseBufferMemoryBindInfo, // const VkSparseBufferMemoryBindInfo* pBufferBinds; - 0, // deUint32 imageOpaqueBindCount; - DE_NULL, // const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds; - 0, // deUint32 imageBindCount; - DE_NULL, // const VkSparseImageMemoryBindInfo* pImageBinds; - 0, // deUint32 signalSemaphoreCount; - DE_NULL, // const VkSemaphore* pSignalSemaphores; - }; - - const VkFenceCreateInfo fenceParams = - { - VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; - DE_NULL, // const void* pNext; - 0u // VkFenceCreateFlags flags; - }; + const VkFenceCreateInfo fenceParams = + { + VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u // VkFenceCreateFlags flags; + }; - const vk::Unique fence(vk::createFence(vk, vkDevice, &fenceParams)); + const vk::Unique fence(vk::createFence(vk, vkDevice, &fenceParams)); - if (vk.queueBindSparse(queue, 1, &bindSparseInfo, *fence) != VK_SUCCESS) - return tcu::TestStatus::fail("Bind sparse buffer memory failed! (requested memory size: " + de::toString(size) + ")"); + if (vk.queueBindSparse(queue, 1, &bindSparseInfo, *fence) != VK_SUCCESS) + return tcu::TestStatus::fail("Bind sparse buffer memory failed! (requested memory size: " + de::toString(size) + ")"); - VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~(0ull) /* infinity */)); - } - else - { - if (vk.bindBufferMemory(vkDevice, *testBuffer, *memory, 0) != VK_SUCCESS) - return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")"); - } + VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~(0ull) /* infinity */)); + } + else + { + if (vk.bindBufferMemory(vkDevice, *buffer, *memory, 0) != VK_SUCCESS) + return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")"); } - return tcu::TestStatus::pass("Buffer test"); + return tcu::TestStatus::pass("Pass"); } tcu::TestStatus BufferTestInstance::iterate (void) @@ -373,27 +433,19 @@ tcu::TestStatus BufferTestInstance::iterate (void) 1, 1181, 15991, - 16384 + 16384, + ~0ull, // try to exercise a very large buffer too (will be clamped to a sensible size later) }; - tcu::TestStatus testStatus = tcu::TestStatus::pass("Buffer test"); - for (int i = 0; i < DE_LENGTH_OF_ARRAY(testSizes); i++) + for (int i = 0; i < DE_LENGTH_OF_ARRAY(testSizes); ++i) { - if ((testStatus = bufferCreateAndAllocTest(testSizes[i])).getCode() != QP_TEST_RESULT_PASS) - return testStatus; - } - - if (m_testCase.usage & (VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)) - { - const VkPhysicalDevice vkPhysicalDevice = getPhysicalDevice(); - const InstanceInterface& vkInstance = getInstanceInterface(); - VkPhysicalDeviceProperties props; + const tcu::TestStatus testStatus = bufferCreateAndAllocTest(testSizes[i]); - vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &props); - testStatus = bufferCreateAndAllocTest((VkDeviceSize) props.limits.maxTexelBufferElements); + if (testStatus.getCode() != QP_TEST_RESULT_PASS) + return testStatus; } - return testStatus; + return tcu::TestStatus::pass("Pass"); } } // anonymous