vktSparseResourcesBase.cpp revision 0abb8ae884208e3355eb68bde6cedab1dd7b773c
1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file vktSparseResourcesBase.cpp 21 * \brief Sparse Resources Base Instance 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktSparseResourcesBase.hpp" 25#include "vktSparseResourcesTestsUtil.hpp" 26#include "vkRefUtil.hpp" 27#include "vkQueryUtil.hpp" 28 29using namespace vk; 30 31namespace vkt 32{ 33namespace sparse 34{ 35 36struct QueueFamilyQueuesCount 37{ 38 QueueFamilyQueuesCount() : queueCount(0u), counter(0u) {}; 39 40 deUint32 queueCount; 41 deUint32 counter; 42}; 43 44SparseResourcesBaseInstance::SparseResourcesBaseInstance (Context &context) 45 : TestInstance(context) 46{ 47} 48 49void SparseResourcesBaseInstance::createDeviceSupportingQueues(const QueueRequirementsVec& queueRequirements) 50{ 51 const InstanceInterface& instance = m_context.getInstanceInterface(); 52 const DeviceInterface& deviceInterface = m_context.getDeviceInterface(); 53 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice(); 54 55 deUint32 queueFamilyPropertiesCount = 0u; 56 instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, DE_NULL); 57 58 if(queueFamilyPropertiesCount == 0u) 59 TCU_THROW(ResourceError, "Device reports an empty set of queue family properties"); 60 61 std::vector<VkQueueFamilyProperties> queueFamilyProperties; 62 queueFamilyProperties.resize(queueFamilyPropertiesCount); 63 64 instance.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyPropertiesCount, &queueFamilyProperties[0]); 65 66 if (queueFamilyPropertiesCount == 0u) 67 TCU_THROW(ResourceError, "Device reports an empty set of queue family properties"); 68 69 typedef std::map<deUint32, QueueFamilyQueuesCount> SelectedQueuesMap; 70 typedef std::map<deUint32, std::vector<float> > QueuePrioritiesMap; 71 72 SelectedQueuesMap selectedQueueFamilies; 73 QueuePrioritiesMap queuePriorities; 74 75 for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx) 76 { 77 const QueueRequirements queueRequirement = queueRequirements[queueReqNdx]; 78 const deUint32 queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags); 79 80 if (queueFamilyIndex == NO_MATCH_FOUND) 81 TCU_THROW(NotSupportedError, "No match found for queue requirements"); 82 83 selectedQueueFamilies[queueFamilyIndex].queueCount += queueRequirement.queueCount; 84 for (deUint32 queueNdx = 0; queueNdx < queueRequirement.queueCount; ++queueNdx) 85 { 86 queuePriorities[queueFamilyIndex].push_back(1.0f); 87 } 88 } 89 90 std::vector<VkDeviceQueueCreateInfo> queueInfos; 91 92 for (SelectedQueuesMap::iterator queueFamilyIter = selectedQueueFamilies.begin(); queueFamilyIter != selectedQueueFamilies.end(); ++queueFamilyIter) 93 { 94 VkDeviceQueueCreateInfo queueInfo; 95 deMemset(&queueInfo, 0, sizeof(queueInfo)); 96 97 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 98 queueInfo.pNext = DE_NULL; 99 queueInfo.flags = (VkDeviceQueueCreateFlags)0u; 100 queueInfo.queueFamilyIndex = queueFamilyIter->first; 101 queueInfo.queueCount = queueFamilyIter->second.queueCount; 102 queueInfo.pQueuePriorities = &queuePriorities[queueFamilyIter->first][0]; 103 104 queueInfos.push_back(queueInfo); 105 } 106 107 VkDeviceCreateInfo deviceInfo; 108 deMemset(&deviceInfo, 0, sizeof(deviceInfo)); 109 110 VkPhysicalDeviceFeatures deviceFeatures; 111 instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures); 112 113 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 114 deviceInfo.pNext = DE_NULL; 115 deviceInfo.enabledExtensionCount = 0u; 116 deviceInfo.ppEnabledExtensionNames = DE_NULL; 117 deviceInfo.enabledLayerCount = 0u; 118 deviceInfo.ppEnabledLayerNames = DE_NULL; 119 deviceInfo.pEnabledFeatures = &deviceFeatures; 120 deviceInfo.queueCreateInfoCount = (deUint32)selectedQueueFamilies.size(); 121 deviceInfo.pQueueCreateInfos = &queueInfos[0]; 122 123 m_logicalDevice = vk::createDevice(instance, physicalDevice, &deviceInfo); 124 125 for (deUint32 queueReqNdx = 0; queueReqNdx < queueRequirements.size(); ++queueReqNdx) 126 { 127 const QueueRequirements queueRequirement = queueRequirements[queueReqNdx]; 128 const deUint32 queueFamilyIndex = findMatchingQueueFamilyIndex(queueFamilyProperties, queueRequirement.queueFlags); 129 130 if (queueFamilyIndex == NO_MATCH_FOUND) 131 TCU_THROW(NotSupportedError, "No match found for queue requirements"); 132 133 for (deUint32 queueNdx = 0; queueNdx < queueRequirement.queueCount; ++queueNdx) 134 { 135 VkQueue queueHandle = 0; 136 deviceInterface.getDeviceQueue(*m_logicalDevice, queueFamilyIndex, selectedQueueFamilies[queueFamilyIndex].counter++, &queueHandle); 137 138 Queue queue; 139 queue.queueHandle = queueHandle; 140 queue.queueFamilyIndex = queueFamilyIndex; 141 142 m_queues[queueRequirement.queueFlags].push_back(queue); 143 } 144 } 145} 146 147const Queue& SparseResourcesBaseInstance::getQueue (const VkQueueFlags queueFlags, const deUint32 queueIndex) 148{ 149 return m_queues[queueFlags][queueIndex]; 150} 151 152deUint32 SparseResourcesBaseInstance::findMatchingMemoryType (const InstanceInterface& instance, 153 const VkPhysicalDevice physicalDevice, 154 const VkMemoryRequirements& objectMemoryRequirements, 155 const MemoryRequirement& memoryRequirement) const 156{ 157 const VkPhysicalDeviceMemoryProperties deviceMemoryProperties = getPhysicalDeviceMemoryProperties(instance, physicalDevice); 158 159 for (deUint32 memoryTypeNdx = 0; memoryTypeNdx < deviceMemoryProperties.memoryTypeCount; ++memoryTypeNdx) 160 { 161 if ((objectMemoryRequirements.memoryTypeBits & (1u << memoryTypeNdx)) != 0 && 162 memoryRequirement.matchesHeap(deviceMemoryProperties.memoryTypes[memoryTypeNdx].propertyFlags)) 163 { 164 return memoryTypeNdx; 165 } 166 } 167 168 return NO_MATCH_FOUND; 169} 170 171bool SparseResourcesBaseInstance::checkSparseSupportForImageType (const InstanceInterface& instance, 172 const VkPhysicalDevice physicalDevice, 173 const ImageType imageType) const 174{ 175 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(instance, physicalDevice); 176 177 if (!deviceFeatures.sparseBinding) 178 return false; 179 180 switch (mapImageType(imageType)) 181 { 182 case VK_IMAGE_TYPE_2D: 183 return deviceFeatures.sparseResidencyImage2D == VK_TRUE; 184 case VK_IMAGE_TYPE_3D: 185 return deviceFeatures.sparseResidencyImage3D == VK_TRUE; 186 default: 187 DE_ASSERT(0); 188 return false; 189 }; 190} 191 192bool SparseResourcesBaseInstance::checkSparseSupportForImageFormat (const InstanceInterface& instance, 193 const VkPhysicalDevice physicalDevice, 194 const VkImageCreateInfo& imageInfo) const 195{ 196 const std::vector<VkSparseImageFormatProperties> sparseImageFormatPropVec = getPhysicalDeviceSparseImageFormatProperties( 197 instance, physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.samples, imageInfo.usage, imageInfo.tiling); 198 199 return sparseImageFormatPropVec.size() > 0u; 200} 201 202bool SparseResourcesBaseInstance::checkImageFormatFeatureSupport (const vk::InstanceInterface& instance, 203 const vk::VkPhysicalDevice physicalDevice, 204 const vk::VkFormat format, 205 const vk::VkFormatFeatureFlags featureFlags) const 206{ 207 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format); 208 209 return (formatProperties.optimalTilingFeatures & featureFlags) == featureFlags; 210} 211 212deUint32 SparseResourcesBaseInstance::getSparseAspectRequirementsIndex (const std::vector<VkSparseImageMemoryRequirements>& requirements, 213 const VkImageAspectFlags aspectFlags) const 214{ 215 for (deUint32 memoryReqNdx = 0; memoryReqNdx < requirements.size(); ++memoryReqNdx) 216 { 217 if (requirements[memoryReqNdx].formatProperties.aspectMask & aspectFlags) 218 { 219 return memoryReqNdx; 220 } 221 } 222 223 return NO_MATCH_FOUND; 224} 225 226deUint32 SparseResourcesBaseInstance::findMatchingQueueFamilyIndex (const QueueFamilyPropertiesVec& queueFamilyProperties, 227 const VkQueueFlags queueFlags) const 228{ 229 for (deUint32 queueNdx = 0; queueNdx < queueFamilyProperties.size(); ++queueNdx) 230 { 231 if ((queueFamilyProperties[queueNdx].queueFlags & queueFlags) == queueFlags) 232 { 233 return queueNdx; 234 } 235 } 236 237 return NO_MATCH_FOUND; 238} 239 240} // sparse 241} // vkt 242