1/*------------------------------------------------------------------------- 2* Vulkan Conformance Tests 3* ------------------------ 4* 5* Copyright (c) 2017 Khronos Group 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 21* \brief Checks vkGetPhysicalDevice*FormatProperties* API functions 22*//*--------------------------------------------------------------------*/ 23 24#include "vkDefs.hpp" 25#include "vkDeviceUtil.hpp" 26#include "vkQueryUtil.hpp" 27#include "vktTestCaseUtil.hpp" 28#include "vktApiPhysicalDeviceFormatPropertiesMaint5Tests.hpp" 29 30#include <algorithm> 31#include <array> 32 33using namespace vk; 34 35namespace vkt 36{ 37namespace api 38{ 39 40namespace 41{ 42 43constexpr deUint32 HAS_FORMAT_PARAM = 1u << 30; 44constexpr deUint32 HAS_FLAGS_PARAM = 1u << 31; 45enum class FuncIDs : deUint32 46{ 47 DeviceFormatProps = 100u | HAS_FORMAT_PARAM, 48 DeviceFormatPropsSecond = 101u | HAS_FORMAT_PARAM, 49 DeviceImageFormatProps = 200u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM, 50 DeviceImageFormatPropsSecond = 201u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM, 51 DeviceSparseImageFormatProps = 300u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM, 52 DeviceSparseImageFormatPropsSecond = 301u | HAS_FORMAT_PARAM | HAS_FLAGS_PARAM, 53}; 54 55struct TestParams 56{ 57 FuncIDs funcID; 58}; 59 60class UnsupportedParametersMaintenance5FormatInstance : public TestInstance 61{ 62public: 63 UnsupportedParametersMaintenance5FormatInstance (Context& context, const TestParams& params) 64 : TestInstance (context) 65 , m_params (params) {} 66 virtual ~UnsupportedParametersMaintenance5FormatInstance (void) override = default; 67 virtual tcu::TestStatus iterate (void) override; 68protected: 69 TestParams m_params; 70}; 71 72class UnsupportedParametersMaintenance5FlagsInstance : public TestInstance 73{ 74public: 75 UnsupportedParametersMaintenance5FlagsInstance (Context& context, const TestParams& params) 76 : TestInstance (context) 77 , m_params (params) {} 78 virtual ~UnsupportedParametersMaintenance5FlagsInstance (void) override = default; 79 virtual tcu::TestStatus iterate (void) override; 80protected: 81 TestParams m_params; 82}; 83 84class UnsupportedParametersMaintenance5TestCase : public TestCase 85{ 86public: 87 UnsupportedParametersMaintenance5TestCase (tcu::TestContext& testContext, 88 const std::string& name, 89 const TestParams& params, 90 bool testFormatOrFlags) 91 : TestCase (testContext, name) 92 , m_params (params) 93 , m_testFormatOrFlags (testFormatOrFlags) { } 94 virtual ~UnsupportedParametersMaintenance5TestCase (void) = default; 95 void checkSupport (Context& context) const override; 96 TestInstance* createInstance (Context& context) const override; 97 98protected: 99 const TestParams m_params; 100 const bool m_testFormatOrFlags; 101}; 102 103TestInstance* UnsupportedParametersMaintenance5TestCase::createInstance (Context& context) const 104{ 105 if (m_testFormatOrFlags) 106 return new UnsupportedParametersMaintenance5FormatInstance(context, m_params); 107 return new UnsupportedParametersMaintenance5FlagsInstance(context, m_params); 108} 109 110void UnsupportedParametersMaintenance5TestCase::checkSupport (Context &context) const 111{ 112 context.requireDeviceFunctionality("VK_KHR_maintenance5"); 113 if (context.getMaintenance5Features().maintenance5 != VK_TRUE) 114 { 115 TCU_THROW(NotSupportedError, "Maintenance5 feature is not supported by this implementation"); 116 } 117} 118 119bool operator==(const VkFormatProperties& l, const VkFormatProperties& r) 120{ 121 return l.bufferFeatures == r.bufferFeatures 122 && l.linearTilingFeatures == r.linearTilingFeatures 123 && l.optimalTilingFeatures == r.optimalTilingFeatures; 124} 125 126bool operator==(const VkImageFormatProperties& l, const VkImageFormatProperties& r) 127{ 128 return l.maxMipLevels == r.maxMipLevels 129 && l.maxArrayLayers == r.maxArrayLayers 130 && l.sampleCounts == r.sampleCounts 131 && l.maxResourceSize == r.maxResourceSize; 132} 133 134template<class StructType> 135StructType makeInvalidVulkanStructure (void* pNext = DE_NULL) 136{ 137 StructType s; 138 deMemset(&s, 0xFF, (size_t)(sizeof(s))); 139 s.sType = getStructureType<StructType>(); 140 s.pNext = pNext; 141 return s; 142} 143 144tcu::TestStatus UnsupportedParametersMaintenance5FormatInstance::iterate (void) 145{ 146 const VkPhysicalDevice dev = m_context.getPhysicalDevice(); 147 const InstanceInterface& inst = m_context.getInstanceInterface(); 148 VkResult res = VK_ERROR_FORMAT_NOT_SUPPORTED; 149 uint32_t propsCount = 0; 150 const VkImageUsageFlags usage = VK_IMAGE_USAGE_STORAGE_BIT; 151 const VkImageType imageType = VK_IMAGE_TYPE_2D; 152 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; 153 const VkImageCreateFlags createFlags = 0; 154 const VkSampleCountFlagBits sampling = VK_SAMPLE_COUNT_1_BIT; 155 VkFormatProperties2 props2 = initVulkanStructure(); 156 VkFormatProperties& props1 = props2.formatProperties; 157 const VkFormatProperties invalidProps = makeInvalidVulkanStructure<VkFormatProperties2>().formatProperties; 158 const VkFormatProperties emptyProps {}; 159 VkImageFormatProperties2 imageProps2 = initVulkanStructure(); 160 VkImageFormatProperties& imageProps1 = imageProps2.imageFormatProperties; 161 const VkImageFormatProperties invalidImgProps = makeInvalidVulkanStructure<VkImageFormatProperties2>().imageFormatProperties; 162 const VkImageFormatProperties emptyImgProps {}; 163 164 VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = initVulkanStructure(); 165 imageFormatInfo.format = VK_FORMAT_UNDEFINED; 166 imageFormatInfo.type = imageType; 167 imageFormatInfo.tiling = tiling; 168 imageFormatInfo.usage = usage; 169 imageFormatInfo.flags = createFlags; 170 171 VkPhysicalDeviceSparseImageFormatInfo2 sparseFormatInfo = initVulkanStructure(); 172 sparseFormatInfo.format = VK_FORMAT_UNDEFINED; 173 sparseFormatInfo.type = imageType; 174 sparseFormatInfo.samples = sampling; 175 sparseFormatInfo.usage = usage; 176 sparseFormatInfo.tiling = tiling; 177 178 const deUint32 n = 5; 179 std::array<bool, n> verdicts; 180 181 DE_ASSERT(deUint32(m_params.funcID) & HAS_FORMAT_PARAM); 182 183 for (deUint32 i = 0; i < n; ++i) 184 { 185 const VkFormat format = VkFormat(VK_FORMAT_MAX_ENUM - i); 186 187 switch (m_params.funcID) 188 { 189 case FuncIDs::DeviceFormatProps: 190 props2 = makeInvalidVulkanStructure<VkFormatProperties2>(); 191 inst.getPhysicalDeviceFormatProperties(dev, format, &props1); 192 verdicts[i] = (emptyProps == props1 || invalidProps == props1); 193 break; 194 195 case FuncIDs::DeviceFormatPropsSecond: 196 props2 = makeInvalidVulkanStructure<VkFormatProperties2>(); 197 inst.getPhysicalDeviceFormatProperties2(dev, format, &props2); 198 verdicts[i] = (emptyProps == props1 || invalidProps == props1); 199 break; 200 201 case FuncIDs::DeviceImageFormatProps: 202 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>(); 203 res = inst.getPhysicalDeviceImageFormatProperties(dev, format, imageType, tiling, usage, createFlags, &imageProps1); 204 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1); 205 break; 206 207 case FuncIDs::DeviceImageFormatPropsSecond: 208 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>(); 209 imageFormatInfo.format = format; 210 res = inst.getPhysicalDeviceImageFormatProperties2(dev, &imageFormatInfo, &imageProps2); 211 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1); 212 break; 213 214 case FuncIDs::DeviceSparseImageFormatProps: 215 propsCount = 0; 216 inst.getPhysicalDeviceSparseImageFormatProperties(dev, format, imageType, sampling, usage, tiling, &propsCount, nullptr); 217 verdicts[i] = (0 == propsCount); 218 break; 219 220 case FuncIDs::DeviceSparseImageFormatPropsSecond: 221 propsCount = 0; 222 sparseFormatInfo.format = format; 223 inst.getPhysicalDeviceSparseImageFormatProperties2(dev, &sparseFormatInfo, &propsCount, nullptr); 224 verdicts[i] = (0 == propsCount); 225 break; 226 227 default: DE_ASSERT(0); break; 228 } 229 } 230 231 return (VK_ERROR_FORMAT_NOT_SUPPORTED == res && std::all_of(verdicts.begin(), verdicts.end(), [](bool x){ return x; })) 232 ? tcu::TestStatus::pass("") 233 : tcu::TestStatus::fail(""); 234} 235 236tcu::TestStatus UnsupportedParametersMaintenance5FlagsInstance::iterate (void) 237{ 238 const VkPhysicalDevice dev = m_context.getPhysicalDevice(); 239 const InstanceInterface& inst = m_context.getInstanceInterface(); 240 VkResult res = VK_ERROR_FORMAT_NOT_SUPPORTED; 241 const VkFormat format = VK_FORMAT_R8G8B8A8_UNORM; 242 const VkImageType imageType = VK_IMAGE_TYPE_2D; 243 const VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; 244 const VkImageCreateFlags createFlags = 0; 245 const VkSampleCountFlagBits sampling = VK_SAMPLE_COUNT_1_BIT; 246 uint32_t propsCount = 0; 247 VkImageFormatProperties2 imageProps2 = initVulkanStructure(); 248 VkImageFormatProperties& imageProps1 = imageProps2.imageFormatProperties; 249 const VkImageFormatProperties invalidImgProps = makeInvalidVulkanStructure<VkImageFormatProperties2>().imageFormatProperties; 250 const VkImageFormatProperties emptyImgProps {}; 251 252 VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = initVulkanStructure(); 253 imageFormatInfo.format = format; 254 imageFormatInfo.type = imageType; 255 imageFormatInfo.tiling = tiling; 256 imageFormatInfo.usage = VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM; 257 imageFormatInfo.flags = createFlags; 258 259 VkPhysicalDeviceSparseImageFormatInfo2 sparseFormatInfo = initVulkanStructure(); 260 sparseFormatInfo.format = format; 261 sparseFormatInfo.type = imageType; 262 sparseFormatInfo.samples = sampling; 263 sparseFormatInfo.usage = VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM; 264 sparseFormatInfo.tiling = tiling; 265 266 const deUint32 n = 5; 267 std::array<bool, n> verdicts; 268 269 DE_ASSERT(deUint32(m_params.funcID) & HAS_FLAGS_PARAM); 270 271 for (deUint32 i = 0; i < n; ++i) 272 { 273 const VkImageUsageFlags usage = VkImageUsageFlags(VK_IMAGE_USAGE_FLAG_BITS_MAX_ENUM - i); 274 275 switch (m_params.funcID) 276 { 277 case FuncIDs::DeviceImageFormatProps: 278 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>(); 279 res = inst.getPhysicalDeviceImageFormatProperties(dev, format, imageType, tiling, usage, createFlags, &imageProps1); 280 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1); 281 break; 282 283 case FuncIDs::DeviceImageFormatPropsSecond: 284 imageProps2 = makeInvalidVulkanStructure<VkImageFormatProperties2>(); 285 imageFormatInfo.usage = usage; 286 res = inst.getPhysicalDeviceImageFormatProperties2(dev, &imageFormatInfo, &imageProps2); 287 verdicts[i] = (emptyImgProps == imageProps1 || invalidImgProps == imageProps1); 288 break; 289 290 case FuncIDs::DeviceSparseImageFormatProps: 291 propsCount = 0; 292 inst.getPhysicalDeviceSparseImageFormatProperties(dev, format, imageType, sampling, usage, tiling, &propsCount, nullptr); 293 /* 294 * Some of the Implementations ignore wrong flags, so at this point we consider the test passed. 295 */ 296 verdicts[i] = true; 297 break; 298 299 case FuncIDs::DeviceSparseImageFormatPropsSecond: 300 propsCount = 0; 301 sparseFormatInfo.usage = usage; 302 inst.getPhysicalDeviceSparseImageFormatProperties2(dev, &sparseFormatInfo, &propsCount, nullptr); 303 /* 304 * Some of the Implementations ignore wrong formats, so at this point we consider the test passed. 305 */ 306 verdicts[i] = true; 307 break; 308 309 default: DE_ASSERT(0); break; 310 } 311 } 312 313 return (VK_ERROR_FORMAT_NOT_SUPPORTED == res && std::all_of(verdicts.begin(), verdicts.end(), [](bool x){ return x; })) 314 ? tcu::TestStatus::pass("") 315 : tcu::TestStatus::fail(""); 316} 317 318} // unnamed namespace 319 320tcu::TestCaseGroup* createMaintenance5Tests (tcu::TestContext& testCtx) 321{ 322 const std::pair<std::string, FuncIDs> funcs[] 323 { 324 { "device_format_props", FuncIDs::DeviceFormatProps }, 325 { "device_format_props2", FuncIDs::DeviceFormatPropsSecond }, 326 { "image_format_props", FuncIDs::DeviceImageFormatProps }, 327 { "image_format_props2", FuncIDs::DeviceImageFormatPropsSecond }, 328 { "sparse_image_format_props", FuncIDs::DeviceSparseImageFormatProps }, 329 { "sparse_image_format_props2", FuncIDs::DeviceSparseImageFormatPropsSecond } 330 }; 331 // Checks vkGetPhysicalDevice*FormatProperties* API functions 332 de::MovePtr<tcu::TestCaseGroup> gRoot(new tcu::TestCaseGroup(testCtx, "maintenance5")); 333 de::MovePtr<tcu::TestCaseGroup> gFormat(new tcu::TestCaseGroup(testCtx, "format", "")); 334 de::MovePtr<tcu::TestCaseGroup> gFlags(new tcu::TestCaseGroup(testCtx, "flags", "")); 335 for (const auto& func : funcs) 336 { 337 TestParams p; 338 p.funcID = func.second; 339 340 if (deUint32(func.second) & HAS_FORMAT_PARAM) 341 gFormat->addChild(new UnsupportedParametersMaintenance5TestCase(testCtx, func.first, p, true)); 342 if (deUint32(func.second) & HAS_FLAGS_PARAM) 343 gFlags->addChild(new UnsupportedParametersMaintenance5TestCase(testCtx, func.first, p, false)); 344 } 345 gRoot->addChild(gFormat.release()); 346 gRoot->addChild(gFlags.release()); 347 return gRoot.release(); 348} 349 350} // api 351} // vkt 352