Fixes WSI protected swapchain allocation tests
authorMatthew Netsch <quic_mnetsch@quicinc.com>
Fri, 7 Sep 2018 17:44:55 +0000 (13:44 -0400)
committerChris Forbes <chrisforbes@google.com>
Fri, 21 Sep 2018 20:40:12 +0000 (16:40 -0400)
Will now throw not supported if swapchain config
cannot fit in the available heap space.

Changes available heap space to fixed 25% of total
reported heap size instead of the current
"total - 2 * imageSize"

Components: Vulkan
VK-GL-CTS issue: 1345

Affects:
dEQP-VK.protected_memory.interaction.wsi.android.swapchain.create.*

Change-Id: I6854ae29b4394d450e47cc78bfb905362a964ec4
(cherry picked from commit f679b545b3b5f06bfb84069a4c712e3988204326)

external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp

index 7a2c1d0..b9339c4 100644 (file)
@@ -277,7 +277,9 @@ std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (vk::w
                        // Determine the maximum memory heap space available for protected images
                        vk::VkPhysicalDeviceMemoryProperties    memoryProperties        = vk::getPhysicalDeviceMemoryProperties(context.getInstanceDriver(), context.getPhysicalDevice());
                        vk::VkDeviceSize                                                protectedHeapSize       = 0;
+                       vk::VkDeviceSize                                                maxMemoryUsage          = 0;
                        deUint32                                                                protectedHeapMask       = 0;
+
                        for (deUint32 memType = 0; memType < memoryProperties.memoryTypeCount; memType++)
                        {
                                deUint32 heapIndex      = memoryProperties.memoryTypes[memType].heapIndex;
@@ -286,15 +288,18 @@ std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (vk::w
                                        (protectedHeapMask & (1u << heapIndex)) == 0)
                                {
                                        protectedHeapSize = de::max(protectedHeapSize, memoryProperties.memoryHeaps[heapIndex].size);
+                                       maxMemoryUsage    = protectedHeapSize / 4 ; /* Use at maximum 25% of heap */
                                        protectedHeapMask |= 1u << heapIndex;
                                }
                        }
 
                        // If the implementation doesn't have a max image count, min+16 means we won't clamp.
-                       // Limit it to how many protected images we estimate can be allocated, with two images
-                       // worth of slack for alignment, swapchain-specific constraints, etc.
+                       // Limit it to how many protected images we estimate can be allocated - 25% of heap size
                        const deUint32  maxImageCount           = de::min((capabilities.maxImageCount > 0) ? capabilities.maxImageCount : capabilities.minImageCount + 16u,
-                                                                                                                 deUint32(protectedHeapSize / memoryRequirements.size) - 2);
+                                                                                                                 deUint32(maxMemoryUsage / memoryRequirements.size));
+                       if (maxImageCount < capabilities.minImageCount)
+                               TCU_THROW(NotSupportedError, "Memory heap doesn't have enough memory!.");
+
                        const deUint32  maxImageCountToTest     = de::clamp(16u, capabilities.minImageCount, maxImageCount);
                        for (deUint32 imageCount = capabilities.minImageCount; imageCount <= maxImageCountToTest; ++imageCount)
                        {
@@ -328,30 +333,154 @@ std::vector<vk::VkSwapchainCreateInfoKHR> generateSwapchainParameterCases (vk::w
                                { 117, 998 },
                        };
 
+                       const vk::DeviceInterface&                              vkd                                     = context.getDeviceInterface();
+                       vk::VkDevice                                                    device                          = context.getDevice();
+                       vk::VkPhysicalDeviceMemoryProperties    memoryProperties        = vk::getPhysicalDeviceMemoryProperties(context.getInstanceDriver(), context.getPhysicalDevice());
+                       vk::VkDeviceSize                                                protectedHeapSize       = 0;
+                       vk::VkDeviceSize                                                maxMemoryUsage          = 0;
+
+                       for (deUint32 memType = 0; memType < memoryProperties.memoryTypeCount; memType++)
+                       {
+                               deUint32 heapIndex      = memoryProperties.memoryTypes[memType].heapIndex;
+                               if (memoryProperties.memoryTypes[memType].propertyFlags & vk::VK_MEMORY_PROPERTY_PROTECTED_BIT)
+                               {
+                                       protectedHeapSize = de::max(protectedHeapSize, memoryProperties.memoryHeaps[heapIndex].size);
+                                       maxMemoryUsage    = protectedHeapSize / 4 ; /* Use at maximum 25% of heap */
+                               }
+                       }
+
                        if (platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE ||
                                platformProperties.swapchainExtent == vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SCALED_TO_WINDOW_SIZE)
                        {
                                for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testSizes); ++ndx)
                                {
-                                       cases.push_back(baseParameters);
-                                       cases.back().imageExtent.width  = de::clamp(s_testSizes[ndx].width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
-                                       cases.back().imageExtent.height = de::clamp(s_testSizes[ndx].height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
+                                       vk::VkMemoryRequirements memoryRequirements;
+                                       {
+                                               const vk::VkImageCreateInfo imageInfo =
+                                               {
+                                                       vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+                                                       DE_NULL,
+                                                       vk::VK_IMAGE_CREATE_PROTECTED_BIT,
+                                                       vk::VK_IMAGE_TYPE_2D,
+                                                       baseParameters.imageFormat,
+                                                       {
+                                                               s_testSizes[ndx].width,
+                                                               s_testSizes[ndx].height,
+                                                               1,
+                                                       },
+                                                       1,      // mipLevels
+                                                       baseParameters.imageArrayLayers,
+                                                       vk::VK_SAMPLE_COUNT_1_BIT,
+                                                       vk::VK_IMAGE_TILING_OPTIMAL,
+                                                       baseParameters.imageUsage,
+                                                       baseParameters.imageSharingMode,
+                                                       baseParameters.queueFamilyIndexCount,
+                                                       baseParameters.pQueueFamilyIndices,
+                                                       vk::VK_IMAGE_LAYOUT_UNDEFINED
+                                               };
+
+                                               vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &imageInfo);
+
+                                               memoryRequirements = vk::getImageMemoryRequirements(vkd, device, *image);
+                                       }
+
+                                       // Check for the image size requirement based on double/triple buffering
+                                       if (memoryRequirements.size  * capabilities.minImageCount < maxMemoryUsage)
+                                       {
+                                               cases.push_back(baseParameters);
+                                               cases.back().imageExtent.width  = de::clamp(s_testSizes[ndx].width, capabilities.minImageExtent.width, capabilities.maxImageExtent.width);
+                                               cases.back().imageExtent.height = de::clamp(s_testSizes[ndx].height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
+                                       }
                                }
                        }
 
                        if (platformProperties.swapchainExtent != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_SETS_WINDOW_SIZE)
                        {
-                               cases.push_back(baseParameters);
-                               cases.back().imageExtent = capabilities.currentExtent;
+                               vk::VkMemoryRequirements memoryRequirements;
+                               {
+                                       const vk::VkImageCreateInfo imageInfo =
+                                       {
+                                               vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+                                               DE_NULL,
+                                               vk::VK_IMAGE_CREATE_PROTECTED_BIT,
+                                               vk::VK_IMAGE_TYPE_2D,
+                                               baseParameters.imageFormat,
+                                               {
+                                                       capabilities.currentExtent.width,
+                                                       capabilities.currentExtent.height,
+                                                       1,
+                                               },
+                                               1,      // mipLevels
+                                               baseParameters.imageArrayLayers,
+                                               vk::VK_SAMPLE_COUNT_1_BIT,
+                                               vk::VK_IMAGE_TILING_OPTIMAL,
+                                               baseParameters.imageUsage,
+                                               baseParameters.imageSharingMode,
+                                               baseParameters.queueFamilyIndexCount,
+                                               baseParameters.pQueueFamilyIndices,
+                                               vk::VK_IMAGE_LAYOUT_UNDEFINED
+                                       };
+
+                                       vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &imageInfo);
+
+                                       memoryRequirements = vk::getImageMemoryRequirements(vkd, device, *image);
+                               }
+
+                               // Check for the image size requirement based on double/triple buffering
+                               if (memoryRequirements.size  * capabilities.minImageCount < maxMemoryUsage)
+                               {
+                                       cases.push_back(baseParameters);
+                                       cases.back().imageExtent = capabilities.currentExtent;
+                               }
                        }
 
                        if (platformProperties.swapchainExtent != vk::wsi::PlatformProperties::SWAPCHAIN_EXTENT_MUST_MATCH_WINDOW_SIZE)
                        {
-                               cases.push_back(baseParameters);
-                               cases.back().imageExtent = capabilities.minImageExtent;
+                               static const vk::VkExtent2D     s_testExtentSizes[]     =
+                               {
+                                       { capabilities.minImageExtent.width, capabilities.minImageExtent.height },
+                                       { capabilities.maxImageExtent.width, capabilities.maxImageExtent.height },
+                               };
 
-                               cases.push_back(baseParameters);
-                               cases.back().imageExtent = capabilities.maxImageExtent;
+                               for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_testExtentSizes); ++ndx)
+                               {
+                                       vk::VkMemoryRequirements memoryRequirements;
+                                       {
+                                               const vk::VkImageCreateInfo     imageInfo =
+                                               {
+                                                       vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
+                                                       DE_NULL,
+                                                       vk::VK_IMAGE_CREATE_PROTECTED_BIT,
+                                                       vk::VK_IMAGE_TYPE_2D,
+                                                       baseParameters.imageFormat,
+                                                       {
+                                                               s_testExtentSizes[ndx].width,
+                                                               s_testExtentSizes[ndx].height,
+                                                               1,
+                                                       },
+                                                       1,      // mipLevels
+                                                       baseParameters.imageArrayLayers,
+                                                       vk::VK_SAMPLE_COUNT_1_BIT,
+                                                       vk::VK_IMAGE_TILING_OPTIMAL,
+                                                       baseParameters.imageUsage,
+                                                       baseParameters.imageSharingMode,
+                                                       baseParameters.queueFamilyIndexCount,
+                                                       baseParameters.pQueueFamilyIndices,
+                                                       vk::VK_IMAGE_LAYOUT_UNDEFINED
+                                               };
+
+                                               vk::Move<vk::VkImage> image = vk::createImage(vkd, device, &imageInfo);
+
+                                               memoryRequirements = vk::getImageMemoryRequirements(vkd, device, *image);
+                                       }
+
+                                       // Check for the image size requirement based on double/triple buffering
+                                       if (memoryRequirements.size  * capabilities.minImageCount < maxMemoryUsage)
+                                       {
+                                               cases.push_back(baseParameters);
+                                               cases.back().imageExtent =s_testExtentSizes[ndx];
+                                       }
+                               }
                        }
 
                        break;