| /*------------------------------------------------------------------------- |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2015 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief Api Feature Query tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktApiFeatureInfo.hpp" |
| |
| #include "vktTestCaseUtil.hpp" |
| #include "vktTestGroupUtil.hpp" |
| #include "vktCustomInstancesDevices.hpp" |
| |
| #include "vkPlatform.hpp" |
| #include "vkStrUtil.hpp" |
| #include "vkRef.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkDeviceUtil.hpp" |
| #include "vkQueryUtil.hpp" |
| #include "vkImageUtil.hpp" |
| #include "vkApiVersion.hpp" |
| |
| #include "tcuTestLog.hpp" |
| #include "tcuFormatUtil.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "tcuResultCollector.hpp" |
| #include "tcuCommandLine.hpp" |
| |
| #include "deUniquePtr.hpp" |
| #include "deString.h" |
| #include "deStringUtil.hpp" |
| #include "deSTLUtil.hpp" |
| #include "deMemory.h" |
| #include "deMath.h" |
| |
| #include <vector> |
| #include <set> |
| #include <string> |
| #include <limits> |
| |
| namespace vkt |
| { |
| namespace api |
| { |
| namespace |
| { |
| |
| #include "vkApiExtensionDependencyInfo.inl" |
| |
| using namespace vk; |
| using std::vector; |
| using std::set; |
| using std::string; |
| using tcu::TestLog; |
| using tcu::ScopedLogSection; |
| |
| const deUint32 DEUINT32_MAX = std::numeric_limits<deUint32>::max(); |
| |
| enum |
| { |
| GUARD_SIZE = 0x20, //!< Number of bytes to check |
| GUARD_VALUE = 0xcd, //!< Data pattern |
| }; |
| |
| static const VkDeviceSize MINIMUM_REQUIRED_IMAGE_RESOURCE_SIZE = (1LLU<<31); //!< Minimum value for VkImageFormatProperties::maxResourceSize (2GiB) |
| |
| enum LimitFormat |
| { |
| LIMIT_FORMAT_SIGNED_INT, |
| LIMIT_FORMAT_UNSIGNED_INT, |
| LIMIT_FORMAT_FLOAT, |
| LIMIT_FORMAT_DEVICE_SIZE, |
| LIMIT_FORMAT_BITMASK, |
| |
| LIMIT_FORMAT_LAST |
| }; |
| |
| enum LimitType |
| { |
| LIMIT_TYPE_MIN, |
| LIMIT_TYPE_MAX, |
| LIMIT_TYPE_NONE, |
| |
| LIMIT_TYPE_LAST |
| }; |
| |
| #define LIMIT(_X_) DE_OFFSET_OF(VkPhysicalDeviceLimits, _X_), (const char*)(#_X_) |
| #define FEATURE(_X_) DE_OFFSET_OF(VkPhysicalDeviceFeatures, _X_) |
| |
| bool validateFeatureLimits(VkPhysicalDeviceProperties* properties, VkPhysicalDeviceFeatures* features, TestLog& log) |
| { |
| bool limitsOk = true; |
| VkPhysicalDeviceLimits* limits = &properties->limits; |
| deUint32 shaderStages = 3; |
| deUint32 maxPerStageResourcesMin = deMin32(128, limits->maxPerStageDescriptorUniformBuffers + |
| limits->maxPerStageDescriptorStorageBuffers + |
| limits->maxPerStageDescriptorSampledImages + |
| limits->maxPerStageDescriptorStorageImages + |
| limits->maxPerStageDescriptorInputAttachments + |
| limits->maxColorAttachments); |
| |
| if (features->tessellationShader) |
| { |
| shaderStages += 2; |
| } |
| |
| if (features->geometryShader) |
| { |
| shaderStages++; |
| } |
| |
| struct FeatureLimitTable |
| { |
| deUint32 offset; |
| const char* name; |
| deUint32 uintVal; //!< Format is UNSIGNED_INT |
| deInt32 intVal; //!< Format is SIGNED_INT |
| deUint64 deviceSizeVal; //!< Format is DEVICE_SIZE |
| float floatVal; //!< Format is FLOAT |
| LimitFormat format; |
| LimitType type; |
| deInt32 unsuppTableNdx; |
| } featureLimitTable[] = //!< Based on 1.0.28 Vulkan spec |
| { |
| { LIMIT(maxImageDimension1D), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxImageDimension2D), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxImageDimension3D), 256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxImageDimensionCube), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxImageArrayLayers), 256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTexelBufferElements), 65536, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxUniformBufferRange), 16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxStorageBufferRange), 134217728, 0, 0, 0, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxPushConstantsSize), 128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxMemoryAllocationCount), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxSamplerAllocationCount), 4000, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(bufferImageGranularity), 0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(bufferImageGranularity), 0, 0, 131072, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(sparseAddressSpaceSize), 0, 0, 2UL*1024*1024*1024, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxBoundDescriptorSets), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxPerStageDescriptorSamplers), 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxPerStageDescriptorUniformBuffers), 12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxPerStageDescriptorStorageBuffers), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxPerStageDescriptorSampledImages), 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxPerStageDescriptorStorageImages), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxPerStageDescriptorInputAttachments), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxPerStageResources), maxPerStageResourcesMin, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxDescriptorSetSamplers), shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDescriptorSetUniformBuffers), shaderStages * 12, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDescriptorSetUniformBuffersDynamic), 8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDescriptorSetStorageBuffers), shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDescriptorSetStorageBuffersDynamic), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxDescriptorSetSampledImages), shaderStages * 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDescriptorSetStorageImages), shaderStages * 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDescriptorSetInputAttachments), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxVertexInputAttributes), 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxVertexInputBindings), 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxVertexInputAttributeOffset), 2047, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxVertexInputBindingStride), 2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxVertexOutputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationGenerationLevel), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationPatchSize), 32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationControlPerVertexInputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationControlPerVertexOutputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationControlPerPatchOutputComponents), 120, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationControlTotalOutputComponents), 2048, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationEvaluationInputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxTessellationEvaluationOutputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxGeometryShaderInvocations), 32, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxGeometryInputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxGeometryOutputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxGeometryOutputVertices), 256, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxGeometryTotalOutputComponents), 1024, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxFragmentInputComponents), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxFragmentOutputAttachments), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxFragmentDualSrcAttachments), 1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxFragmentCombinedOutputResources), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeSharedMemorySize), 16384, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupCount[0]), 65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupCount[1]), 65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupCount[2]), 65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupInvocations), 128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupSize[0]), 128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupSize[1]), 128, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxComputeWorkGroupSize[2]), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(subPixelPrecisionBits), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(subTexelPrecisionBits), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(mipmapPrecisionBits), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxDrawIndexedIndexValue), (deUint32)~0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxDrawIndirectCount), 65535, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxSamplerLodBias), 0, 0, 0, 2.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxSamplerAnisotropy), 0, 0, 0, 16.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxViewports), 16, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxViewportDimensions[0]), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(maxViewportDimensions[1]), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN , -1 }, |
| { LIMIT(viewportBoundsRange[0]), 0, 0, 0, -8192.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(viewportBoundsRange[1]), 0, 0, 0, 8191.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(viewportSubPixelBits), 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minMemoryMapAlignment), 64, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minTexelBufferOffsetAlignment), 0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minTexelBufferOffsetAlignment), 0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(minUniformBufferOffsetAlignment), 0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minUniformBufferOffsetAlignment), 0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(minStorageBufferOffsetAlignment), 0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minStorageBufferOffsetAlignment), 0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(minTexelOffset), 0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(maxTexelOffset), 7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minTexelGatherOffset), 0, -8, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(maxTexelGatherOffset), 7, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(minInterpolationOffset), 0, 0, 0, -0.5f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(maxInterpolationOffset), 0, 0, 0, 0.5f - (1.0f/deFloatPow(2.0f, (float)limits->subPixelInterpolationOffsetBits)), LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(subPixelInterpolationOffsetBits), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxFramebufferWidth), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxFramebufferHeight), 4096, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxFramebufferLayers), 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(framebufferColorSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(framebufferDepthSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(framebufferStencilSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(framebufferNoAttachmentsSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxColorAttachments), 4, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(sampledImageColorSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(sampledImageIntegerSampleCounts), VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(sampledImageDepthSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(sampledImageStencilSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(storageImageSampleCounts), VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxSampleMaskWords), 1, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(timestampComputeAndGraphics), 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 }, |
| { LIMIT(timestampPeriod), 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 }, |
| { LIMIT(maxClipDistances), 8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxCullDistances), 8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(maxCombinedClipAndCullDistances), 8, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(discreteQueuePriorities), 2, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(pointSizeRange[0]), 0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(pointSizeRange[0]), 0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(pointSizeRange[1]), 0, 0, 0, 64.0f - limits->pointSizeGranularity , LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(lineWidthRange[0]), 0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(lineWidthRange[0]), 0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(lineWidthRange[1]), 0, 0, 0, 8.0f - limits->lineWidthGranularity, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(pointSizeGranularity), 0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(lineWidthGranularity), 0, 0, 0, 1.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX, -1 }, |
| { LIMIT(strictLines), 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 }, |
| { LIMIT(standardSampleLocations), 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE, -1 }, |
| { LIMIT(optimalBufferCopyOffsetAlignment), 0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1 }, |
| { LIMIT(optimalBufferCopyRowPitchAlignment), 0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE, -1 }, |
| { LIMIT(nonCoherentAtomSize), 0, 0, 1, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN, -1 }, |
| { LIMIT(nonCoherentAtomSize), 0, 0, 256, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX, -1 }, |
| }; |
| |
| const struct UnsupportedFeatureLimitTable |
| { |
| deUint32 limitOffset; |
| const char* name; |
| deUint32 featureOffset; |
| deUint32 uintVal; //!< Format is UNSIGNED_INT |
| deInt32 intVal; //!< Format is SIGNED_INT |
| deUint64 deviceSizeVal; //!< Format is DEVICE_SIZE |
| float floatVal; //!< Format is FLOAT |
| } unsupportedFeatureTable[] = |
| { |
| { LIMIT(sparseAddressSpaceSize), FEATURE(sparseBinding), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationGenerationLevel), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationPatchSize), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationControlPerVertexInputComponents), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationControlPerVertexOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationControlPerPatchOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationControlTotalOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationEvaluationInputComponents), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTessellationEvaluationOutputComponents), FEATURE(tessellationShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxGeometryShaderInvocations), FEATURE(geometryShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxGeometryInputComponents), FEATURE(geometryShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxGeometryOutputComponents), FEATURE(geometryShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxGeometryOutputVertices), FEATURE(geometryShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxGeometryTotalOutputComponents), FEATURE(geometryShader), 0, 0, 0, 0.0f }, |
| { LIMIT(maxFragmentDualSrcAttachments), FEATURE(dualSrcBlend), 0, 0, 0, 0.0f }, |
| { LIMIT(maxDrawIndexedIndexValue), FEATURE(fullDrawIndexUint32), (1<<24)-1, 0, 0, 0.0f }, |
| { LIMIT(maxDrawIndirectCount), FEATURE(multiDrawIndirect), 1, 0, 0, 0.0f }, |
| { LIMIT(maxSamplerAnisotropy), FEATURE(samplerAnisotropy), 1, 0, 0, 0.0f }, |
| { LIMIT(maxViewports), FEATURE(multiViewport), 1, 0, 0, 0.0f }, |
| { LIMIT(minTexelGatherOffset), FEATURE(shaderImageGatherExtended), 0, 0, 0, 0.0f }, |
| { LIMIT(maxTexelGatherOffset), FEATURE(shaderImageGatherExtended), 0, 0, 0, 0.0f }, |
| { LIMIT(minInterpolationOffset), FEATURE(sampleRateShading), 0, 0, 0, 0.0f }, |
| { LIMIT(maxInterpolationOffset), FEATURE(sampleRateShading), 0, 0, 0, 0.0f }, |
| { LIMIT(subPixelInterpolationOffsetBits), FEATURE(sampleRateShading), 0, 0, 0, 0.0f }, |
| { LIMIT(storageImageSampleCounts), FEATURE(shaderStorageImageMultisample), VK_SAMPLE_COUNT_1_BIT, 0, 0, 0.0f }, |
| { LIMIT(maxClipDistances), FEATURE(shaderClipDistance), 0, 0, 0, 0.0f }, |
| { LIMIT(maxCullDistances), FEATURE(shaderCullDistance), 0, 0, 0, 0.0f }, |
| { LIMIT(maxCombinedClipAndCullDistances), FEATURE(shaderClipDistance), 0, 0, 0, 0.0f }, |
| { LIMIT(pointSizeRange[0]), FEATURE(largePoints), 0, 0, 0, 1.0f }, |
| { LIMIT(pointSizeRange[1]), FEATURE(largePoints), 0, 0, 0, 1.0f }, |
| { LIMIT(lineWidthRange[0]), FEATURE(wideLines), 0, 0, 0, 1.0f }, |
| { LIMIT(lineWidthRange[1]), FEATURE(wideLines), 0, 0, 0, 1.0f }, |
| { LIMIT(pointSizeGranularity), FEATURE(largePoints), 0, 0, 0, 0.0f }, |
| { LIMIT(lineWidthGranularity), FEATURE(wideLines), 0, 0, 0, 0.0f } |
| }; |
| |
| log << TestLog::Message << *limits << TestLog::EndMessage; |
| |
| //!< First build a map from limit to unsupported table index |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| { |
| for (deUint32 unsuppNdx = 0; unsuppNdx < DE_LENGTH_OF_ARRAY(unsupportedFeatureTable); unsuppNdx++) |
| { |
| if (unsupportedFeatureTable[unsuppNdx].limitOffset == featureLimitTable[ndx].offset) |
| { |
| featureLimitTable[ndx].unsuppTableNdx = unsuppNdx; |
| break; |
| } |
| } |
| } |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| { |
| switch (featureLimitTable[ndx].format) |
| { |
| case LIMIT_FORMAT_UNSIGNED_INT: |
| { |
| deUint32 limitToCheck = featureLimitTable[ndx].uintVal; |
| if (featureLimitTable[ndx].unsuppTableNdx != -1) |
| { |
| if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE) |
| limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal; |
| } |
| |
| if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN) |
| { |
| |
| if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck) |
| { |
| log << TestLog::Message << "limit Validation failed " << featureLimitTable[ndx].name |
| << " not valid-limit type MIN - actual is " |
| << *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX) |
| { |
| if (*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MAX - actual is " |
| << *((deUint32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| break; |
| } |
| |
| case LIMIT_FORMAT_FLOAT: |
| { |
| float limitToCheck = featureLimitTable[ndx].floatVal; |
| if (featureLimitTable[ndx].unsuppTableNdx != -1) |
| { |
| if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE) |
| limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].floatVal; |
| } |
| |
| if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN) |
| { |
| if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MIN - actual is " |
| << *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX) |
| { |
| if (*((float*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MAX actual is " |
| << *((float*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| break; |
| } |
| |
| case LIMIT_FORMAT_SIGNED_INT: |
| { |
| deInt32 limitToCheck = featureLimitTable[ndx].intVal; |
| if (featureLimitTable[ndx].unsuppTableNdx != -1) |
| { |
| if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE) |
| limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].intVal; |
| } |
| if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN) |
| { |
| if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MIN actual is " |
| << *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX) |
| { |
| if (*((deInt32*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MAX actual is " |
| << *((deInt32*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| break; |
| } |
| |
| case LIMIT_FORMAT_DEVICE_SIZE: |
| { |
| deUint64 limitToCheck = featureLimitTable[ndx].deviceSizeVal; |
| if (featureLimitTable[ndx].unsuppTableNdx != -1) |
| { |
| if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE) |
| limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].deviceSizeVal; |
| } |
| |
| if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN) |
| { |
| if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) < limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MIN actual is " |
| << *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| else if (featureLimitTable[ndx].type == LIMIT_TYPE_MAX) |
| { |
| if (*((deUint64*)((deUint8*)limits+featureLimitTable[ndx].offset)) > limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type MAX actual is " |
| << *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| break; |
| } |
| |
| case LIMIT_FORMAT_BITMASK: |
| { |
| deUint32 limitToCheck = featureLimitTable[ndx].uintVal; |
| if (featureLimitTable[ndx].unsuppTableNdx != -1) |
| { |
| if (*((VkBool32*)((deUint8*)features+unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].featureOffset)) == VK_FALSE) |
| limitToCheck = unsupportedFeatureTable[featureLimitTable[ndx].unsuppTableNdx].uintVal; |
| } |
| |
| if (featureLimitTable[ndx].type == LIMIT_TYPE_MIN) |
| { |
| if ((*((deUint32*)((deUint8*)limits+featureLimitTable[ndx].offset)) & limitToCheck) != limitToCheck) |
| { |
| log << TestLog::Message << "limit validation failed, " << featureLimitTable[ndx].name |
| << " not valid-limit type bitmask actual is " |
| << *((deUint64*)((deUint8*)limits + featureLimitTable[ndx].offset)) << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| } |
| break; |
| } |
| |
| default: |
| DE_ASSERT(0); |
| limitsOk = false; |
| } |
| } |
| |
| if (limits->maxFramebufferWidth > limits->maxViewportDimensions[0] || |
| limits->maxFramebufferHeight > limits->maxViewportDimensions[1]) |
| { |
| log << TestLog::Message << "limit validation failed, maxFramebufferDimension of " |
| << "[" << limits->maxFramebufferWidth << ", " << limits->maxFramebufferHeight << "] " |
| << "is larger than maxViewportDimension of " |
| << "[" << limits->maxViewportDimensions[0] << ", " << limits->maxViewportDimensions[1] << "]" << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| |
| if (limits->viewportBoundsRange[0] > float(-2 * limits->maxViewportDimensions[0])) |
| { |
| log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits->viewportBoundsRange[0] |
| << "is larger than -2*maxViewportDimension[0] of " << -2*limits->maxViewportDimensions[0] << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| |
| if (limits->viewportBoundsRange[1] < float(2 * limits->maxViewportDimensions[1] - 1)) |
| { |
| log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits->viewportBoundsRange[1] |
| << "is less than 2*maxViewportDimension[1] of " << 2*limits->maxViewportDimensions[1] << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| |
| return limitsOk; |
| } |
| |
| void validateLimitsCheckSupport (Context& context) |
| { |
| if (!context.contextSupports(vk::ApiVersion(1, 2, 0))) |
| TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test"); |
| } |
| |
| typedef struct FeatureLimitTableItem_ |
| { |
| const void* cond; |
| const char* condName; |
| const void* ptr; |
| const char* name; |
| deUint32 uintVal; //!< Format is UNSIGNED_INT |
| deInt32 intVal; //!< Format is SIGNED_INT |
| deUint64 deviceSizeVal; //!< Format is DEVICE_SIZE |
| float floatVal; //!< Format is FLOAT |
| LimitFormat format; |
| LimitType type; |
| } FeatureLimitTableItem; |
| |
| template<typename T> |
| bool validateNumericLimit (const T limitToCheck, const T reportedValue, const LimitType limitType, const char* limitName, TestLog& log) |
| { |
| if (limitType == LIMIT_TYPE_MIN) |
| { |
| if (reportedValue < limitToCheck) |
| { |
| log << TestLog::Message << "Limit validation failed " << limitName |
| << " reported value is " << reportedValue |
| << " expected MIN " << limitToCheck |
| << TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| log << TestLog::Message << limitName |
| << "=" << reportedValue |
| << " (>=" << limitToCheck << ")" |
| << TestLog::EndMessage; |
| } |
| else if (limitType == LIMIT_TYPE_MAX) |
| { |
| if (reportedValue > limitToCheck) |
| { |
| log << TestLog::Message << "Limit validation failed " << limitName |
| << " reported value is " << reportedValue |
| << " expected MAX " << limitToCheck |
| << TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| log << TestLog::Message << limitName |
| << "=" << reportedValue |
| << " (<=" << limitToCheck << ")" |
| << TestLog::EndMessage; |
| } |
| |
| return true; |
| } |
| |
| template<typename T> |
| bool validateBitmaskLimit (const T limitToCheck, const T reportedValue, const LimitType limitType, const char* limitName, TestLog& log) |
| { |
| if (limitType == LIMIT_TYPE_MIN) |
| { |
| if ((reportedValue & limitToCheck) != limitToCheck) |
| { |
| log << TestLog::Message << "Limit validation failed " << limitName |
| << " reported value is " << reportedValue |
| << " expected MIN " << limitToCheck |
| << TestLog::EndMessage; |
| |
| return false; |
| } |
| |
| log << TestLog::Message << limitName |
| << "=" << tcu::toHex(reportedValue) |
| << " (contains " << tcu::toHex(limitToCheck) << ")" |
| << TestLog::EndMessage; |
| } |
| |
| return true; |
| } |
| |
| bool validateLimit (FeatureLimitTableItem limit, TestLog& log) |
| { |
| if (*((VkBool32*)limit.cond) == DE_FALSE) |
| { |
| log << TestLog::Message |
| << "Limit validation skipped '" << limit.name << "' due to " |
| << limit.condName << " == false'" |
| << TestLog::EndMessage; |
| |
| return true; |
| } |
| |
| switch (limit.format) |
| { |
| case LIMIT_FORMAT_UNSIGNED_INT: |
| { |
| const deUint32 limitToCheck = limit.uintVal; |
| const deUint32 reportedValue = *(deUint32*)limit.ptr; |
| |
| return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log); |
| } |
| |
| case LIMIT_FORMAT_FLOAT: |
| { |
| const float limitToCheck = limit.floatVal; |
| const float reportedValue = *(float*)limit.ptr; |
| |
| return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log); |
| } |
| |
| case LIMIT_FORMAT_SIGNED_INT: |
| { |
| const deInt32 limitToCheck = limit.intVal; |
| const deInt32 reportedValue = *(deInt32*)limit.ptr; |
| |
| return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log); |
| } |
| |
| case LIMIT_FORMAT_DEVICE_SIZE: |
| { |
| const deUint64 limitToCheck = limit.deviceSizeVal; |
| const deUint64 reportedValue = *(deUint64*)limit.ptr; |
| |
| return validateNumericLimit(limitToCheck, reportedValue, limit.type, limit.name, log); |
| } |
| |
| case LIMIT_FORMAT_BITMASK: |
| { |
| const deUint32 limitToCheck = limit.uintVal; |
| const deUint32 reportedValue = *(deUint32*)limit.ptr; |
| |
| return validateBitmaskLimit(limitToCheck, reportedValue, limit.type, limit.name, log); |
| } |
| |
| default: |
| TCU_THROW(InternalError, "Unknown LimitFormat specified"); |
| } |
| } |
| |
| #ifdef PN |
| #error PN defined |
| #else |
| #define PN(_X_) &(_X_), (const char*)(#_X_) |
| #endif |
| |
| #define LIM_MIN_UINT32(X) deUint32(X), 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MIN |
| #define LIM_MAX_UINT32(X) deUint32(X), 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_MAX |
| #define LIM_NONE_UINT32 0, 0, 0, 0.0f, LIMIT_FORMAT_UNSIGNED_INT, LIMIT_TYPE_NONE |
| #define LIM_MIN_INT32(X) 0, deInt32(X), 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MIN |
| #define LIM_MAX_INT32(X) 0, deInt32(X), 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_MAX |
| #define LIM_NONE_INT32 0, 0, 0, 0.0f, LIMIT_FORMAT_SIGNED_INT, LIMIT_TYPE_NONE |
| #define LIM_MIN_DEVSIZE(X) 0, 0, VkDeviceSize(X), 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MIN |
| #define LIM_MAX_DEVSIZE(X) 0, 0, VkDeviceSize(X), 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_MAX |
| #define LIM_NONE_DEVSIZE 0, 0, 0, 0.0f, LIMIT_FORMAT_DEVICE_SIZE, LIMIT_TYPE_NONE |
| #define LIM_MIN_FLOAT(X) 0, 0, 0, float(X), LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MIN |
| #define LIM_MAX_FLOAT(X) 0, 0, 0, float(X), LIMIT_FORMAT_FLOAT, LIMIT_TYPE_MAX |
| #define LIM_NONE_FLOAT 0, 0, 0, 0.0f, LIMIT_FORMAT_FLOAT, LIMIT_TYPE_NONE |
| #define LIM_MIN_BITI32(X) deUint32(X), 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MIN |
| #define LIM_MAX_BITI32(X) deUint32(X), 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_MAX |
| #define LIM_NONE_BITI32 0, 0, 0, 0.0f, LIMIT_FORMAT_BITMASK, LIMIT_TYPE_NONE |
| |
| tcu::TestStatus validateLimits12 (Context& context) |
| { |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| const VkPhysicalDeviceFeatures2& features2 = context.getDeviceFeatures2(); |
| const VkPhysicalDeviceFeatures& features = features2.features; |
| const VkPhysicalDeviceVulkan12Features features12 = getPhysicalDeviceVulkan12Features(vki, physicalDevice); |
| |
| const VkPhysicalDeviceProperties2& properties2 = context.getDeviceProperties2(); |
| const VkPhysicalDeviceVulkan12Properties vulkan12Properties = getPhysicalDeviceVulkan12Properties(vki, physicalDevice); |
| const VkPhysicalDeviceVulkan11Properties vulkan11Properties = getPhysicalDeviceVulkan11Properties(vki, physicalDevice); |
| const VkPhysicalDeviceLimits& limits = properties2.properties.limits; |
| |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkBool32 checkVulkan12Limit = VK_TRUE; |
| |
| deUint32 shaderStages = 3; |
| deUint32 maxPerStageResourcesMin = deMin32(128, limits.maxPerStageDescriptorUniformBuffers + |
| limits.maxPerStageDescriptorStorageBuffers + |
| limits.maxPerStageDescriptorSampledImages + |
| limits.maxPerStageDescriptorStorageImages + |
| limits.maxPerStageDescriptorInputAttachments + |
| limits.maxColorAttachments); |
| |
| if (features.tessellationShader) |
| { |
| shaderStages += 2; |
| } |
| |
| if (features.geometryShader) |
| { |
| shaderStages++; |
| } |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(limits.maxImageDimension1D), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxImageDimension2D), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxImageDimension3D), LIM_MIN_UINT32(256) }, |
| { PN(checkAlways), PN(limits.maxImageDimensionCube), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxImageArrayLayers), LIM_MIN_UINT32(256) }, |
| { PN(checkAlways), PN(limits.maxTexelBufferElements), LIM_MIN_UINT32(65536) }, |
| { PN(checkAlways), PN(limits.maxUniformBufferRange), LIM_MIN_UINT32(16384) }, |
| { PN(checkAlways), PN(limits.maxStorageBufferRange), LIM_MIN_UINT32((1<<27)) }, |
| { PN(checkAlways), PN(limits.maxPushConstantsSize), LIM_MIN_UINT32(128) }, |
| { PN(checkAlways), PN(limits.maxMemoryAllocationCount), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxSamplerAllocationCount), LIM_MIN_UINT32(4000) }, |
| { PN(checkAlways), PN(limits.bufferImageGranularity), LIM_MIN_DEVSIZE(1) }, |
| { PN(checkAlways), PN(limits.bufferImageGranularity), LIM_MAX_DEVSIZE(131072) }, |
| { PN(features.sparseBinding), PN(limits.sparseAddressSpaceSize), LIM_MIN_DEVSIZE((1ull<<31)) }, |
| { PN(checkAlways), PN(limits.maxBoundDescriptorSets), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxPerStageDescriptorSamplers), LIM_MIN_UINT32(16) }, |
| { PN(checkAlways), PN(limits.maxPerStageDescriptorUniformBuffers), LIM_MIN_UINT32(12) }, |
| { PN(checkAlways), PN(limits.maxPerStageDescriptorStorageBuffers), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxPerStageDescriptorSampledImages), LIM_MIN_UINT32(16) }, |
| { PN(checkAlways), PN(limits.maxPerStageDescriptorStorageImages), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxPerStageDescriptorInputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxPerStageResources), LIM_MIN_UINT32(maxPerStageResourcesMin) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetSamplers), LIM_MIN_UINT32(shaderStages * 16) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetUniformBuffers), LIM_MIN_UINT32(shaderStages * 12) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetUniformBuffersDynamic), LIM_MIN_UINT32(8) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetStorageBuffers), LIM_MIN_UINT32(shaderStages * 4) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetStorageBuffersDynamic), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetSampledImages), LIM_MIN_UINT32(shaderStages * 16) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetStorageImages), LIM_MIN_UINT32(shaderStages * 4) }, |
| { PN(checkAlways), PN(limits.maxDescriptorSetInputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxVertexInputAttributes), LIM_MIN_UINT32(16) }, |
| { PN(checkAlways), PN(limits.maxVertexInputBindings), LIM_MIN_UINT32(16) }, |
| { PN(checkAlways), PN(limits.maxVertexInputAttributeOffset), LIM_MIN_UINT32(2047) }, |
| { PN(checkAlways), PN(limits.maxVertexInputBindingStride), LIM_MIN_UINT32(2048) }, |
| { PN(checkAlways), PN(limits.maxVertexOutputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationGenerationLevel), LIM_MIN_UINT32(64) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationPatchSize), LIM_MIN_UINT32(32) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationControlPerVertexInputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationControlPerVertexOutputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationControlPerPatchOutputComponents), LIM_MIN_UINT32(120) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationControlTotalOutputComponents), LIM_MIN_UINT32(2048) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationEvaluationInputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.tessellationShader), PN(limits.maxTessellationEvaluationOutputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.geometryShader), PN(limits.maxGeometryShaderInvocations), LIM_MIN_UINT32(32) }, |
| { PN(features.geometryShader), PN(limits.maxGeometryInputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.geometryShader), PN(limits.maxGeometryOutputComponents), LIM_MIN_UINT32(64) }, |
| { PN(features.geometryShader), PN(limits.maxGeometryOutputVertices), LIM_MIN_UINT32(256) }, |
| { PN(features.geometryShader), PN(limits.maxGeometryTotalOutputComponents), LIM_MIN_UINT32(1024) }, |
| { PN(checkAlways), PN(limits.maxFragmentInputComponents), LIM_MIN_UINT32(64) }, |
| { PN(checkAlways), PN(limits.maxFragmentOutputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(features.dualSrcBlend), PN(limits.maxFragmentDualSrcAttachments), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(limits.maxFragmentCombinedOutputResources), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxComputeSharedMemorySize), LIM_MIN_UINT32(16384) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupCount[0]), LIM_MIN_UINT32(65535) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupCount[1]), LIM_MIN_UINT32(65535) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupCount[2]), LIM_MIN_UINT32(65535) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupInvocations), LIM_MIN_UINT32(128) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupSize[0]), LIM_MIN_UINT32(128) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupSize[1]), LIM_MIN_UINT32(128) }, |
| { PN(checkAlways), PN(limits.maxComputeWorkGroupSize[2]), LIM_MIN_UINT32(64) }, |
| { PN(checkAlways), PN(limits.subPixelPrecisionBits), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.subTexelPrecisionBits), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.mipmapPrecisionBits), LIM_MIN_UINT32(4) }, |
| { PN(features.fullDrawIndexUint32), PN(limits.maxDrawIndexedIndexValue), LIM_MIN_UINT32((deUint32)~0) }, |
| { PN(features.multiDrawIndirect), PN(limits.maxDrawIndirectCount), LIM_MIN_UINT32(65535) }, |
| { PN(checkAlways), PN(limits.maxSamplerLodBias), LIM_MIN_FLOAT(2.0f) }, |
| { PN(features.samplerAnisotropy), PN(limits.maxSamplerAnisotropy), LIM_MIN_FLOAT(16.0f) }, |
| { PN(features.multiViewport), PN(limits.maxViewports), LIM_MIN_UINT32(16) }, |
| { PN(checkAlways), PN(limits.maxViewportDimensions[0]), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxViewportDimensions[1]), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.viewportBoundsRange[0]), LIM_MAX_FLOAT(-8192.0f) }, |
| { PN(checkAlways), PN(limits.viewportBoundsRange[1]), LIM_MIN_FLOAT(8191.0f) }, |
| { PN(checkAlways), PN(limits.viewportSubPixelBits), LIM_MIN_UINT32(0) }, |
| { PN(checkAlways), PN(limits.minMemoryMapAlignment), LIM_MIN_UINT32(64) }, |
| { PN(checkAlways), PN(limits.minTexelBufferOffsetAlignment), LIM_MIN_DEVSIZE(1) }, |
| { PN(checkAlways), PN(limits.minTexelBufferOffsetAlignment), LIM_MAX_DEVSIZE(256) }, |
| { PN(checkAlways), PN(limits.minUniformBufferOffsetAlignment), LIM_MIN_DEVSIZE(1) }, |
| { PN(checkAlways), PN(limits.minUniformBufferOffsetAlignment), LIM_MAX_DEVSIZE(256) }, |
| { PN(checkAlways), PN(limits.minStorageBufferOffsetAlignment), LIM_MIN_DEVSIZE(1) }, |
| { PN(checkAlways), PN(limits.minStorageBufferOffsetAlignment), LIM_MAX_DEVSIZE(256) }, |
| { PN(checkAlways), PN(limits.minTexelOffset), LIM_MAX_INT32(-8) }, |
| { PN(checkAlways), PN(limits.maxTexelOffset), LIM_MIN_INT32(7) }, |
| { PN(features.shaderImageGatherExtended), PN(limits.minTexelGatherOffset), LIM_MAX_INT32(-8) }, |
| { PN(features.shaderImageGatherExtended), PN(limits.maxTexelGatherOffset), LIM_MIN_INT32(7) }, |
| { PN(features.sampleRateShading), PN(limits.minInterpolationOffset), LIM_MAX_FLOAT(-0.5f) }, |
| { PN(features.sampleRateShading), PN(limits.maxInterpolationOffset), LIM_MIN_FLOAT(0.5f - (1.0f/deFloatPow(2.0f, (float)limits.subPixelInterpolationOffsetBits))) }, |
| { PN(features.sampleRateShading), PN(limits.subPixelInterpolationOffsetBits), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.maxFramebufferWidth), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxFramebufferHeight), LIM_MIN_UINT32(4096) }, |
| { PN(checkAlways), PN(limits.maxFramebufferLayers), LIM_MIN_UINT32(256) }, |
| { PN(checkAlways), PN(limits.framebufferColorSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkVulkan12Limit), PN(vulkan12Properties.framebufferIntegerColorSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT) }, |
| { PN(checkAlways), PN(limits.framebufferDepthSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(limits.framebufferStencilSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(limits.framebufferNoAttachmentsSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(limits.maxColorAttachments), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(limits.sampledImageColorSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(limits.sampledImageIntegerSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT) }, |
| { PN(checkAlways), PN(limits.sampledImageDepthSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(limits.sampledImageStencilSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(features.shaderStorageImageMultisample), PN(limits.storageImageSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_1_BIT|VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(limits.maxSampleMaskWords), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(limits.timestampComputeAndGraphics), LIM_NONE_UINT32 }, |
| { PN(checkAlways), PN(limits.timestampPeriod), LIM_NONE_UINT32 }, |
| { PN(features.shaderClipDistance), PN(limits.maxClipDistances), LIM_MIN_UINT32(8) }, |
| { PN(features.shaderCullDistance), PN(limits.maxCullDistances), LIM_MIN_UINT32(8) }, |
| { PN(features.shaderClipDistance), PN(limits.maxCombinedClipAndCullDistances), LIM_MIN_UINT32(8) }, |
| { PN(checkAlways), PN(limits.discreteQueuePriorities), LIM_MIN_UINT32(2) }, |
| { PN(features.largePoints), PN(limits.pointSizeRange[0]), LIM_MIN_FLOAT(0.0f) }, |
| { PN(features.largePoints), PN(limits.pointSizeRange[0]), LIM_MAX_FLOAT(1.0f) }, |
| { PN(features.largePoints), PN(limits.pointSizeRange[1]), LIM_MIN_FLOAT(64.0f - limits.pointSizeGranularity) }, |
| { PN(features.wideLines), PN(limits.lineWidthRange[0]), LIM_MIN_FLOAT(0.0f) }, |
| { PN(features.wideLines), PN(limits.lineWidthRange[0]), LIM_MAX_FLOAT(1.0f) }, |
| { PN(features.wideLines), PN(limits.lineWidthRange[1]), LIM_MIN_FLOAT(8.0f - limits.lineWidthGranularity) }, |
| { PN(features.largePoints), PN(limits.pointSizeGranularity), LIM_MIN_FLOAT(0.0f) }, |
| { PN(features.largePoints), PN(limits.pointSizeGranularity), LIM_MAX_FLOAT(1.0f) }, |
| { PN(features.wideLines), PN(limits.lineWidthGranularity), LIM_MIN_FLOAT(0.0f) }, |
| { PN(features.wideLines), PN(limits.lineWidthGranularity), LIM_MAX_FLOAT(1.0f) }, |
| { PN(checkAlways), PN(limits.strictLines), LIM_NONE_UINT32 }, |
| { PN(checkAlways), PN(limits.standardSampleLocations), LIM_NONE_UINT32 }, |
| { PN(checkAlways), PN(limits.optimalBufferCopyOffsetAlignment), LIM_NONE_DEVSIZE }, |
| { PN(checkAlways), PN(limits.optimalBufferCopyRowPitchAlignment), LIM_NONE_DEVSIZE }, |
| { PN(checkAlways), PN(limits.nonCoherentAtomSize), LIM_MIN_DEVSIZE(1) }, |
| { PN(checkAlways), PN(limits.nonCoherentAtomSize), LIM_MAX_DEVSIZE(256) }, |
| |
| // VK_KHR_multiview |
| { PN(checkVulkan12Limit), PN(vulkan11Properties.maxMultiviewViewCount), LIM_MIN_UINT32(6) }, |
| { PN(checkVulkan12Limit), PN(vulkan11Properties.maxMultiviewInstanceIndex), LIM_MIN_UINT32((1<<27) - 1) }, |
| |
| // VK_KHR_maintenance3 |
| { PN(checkVulkan12Limit), PN(vulkan11Properties.maxPerSetDescriptors), LIM_MIN_UINT32(1024) }, |
| { PN(checkVulkan12Limit), PN(vulkan11Properties.maxMemoryAllocationSize), LIM_MIN_DEVSIZE(1<<30) }, |
| |
| // VK_EXT_descriptor_indexing |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxUpdateAfterBindDescriptorsInAllPools), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(12) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageUpdateAfterBindResources), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(shaderStages * 12) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic), LIM_MIN_UINT32(8) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic), LIM_MIN_UINT32(4) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages), LIM_MIN_UINT32(500000) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSamplers), LIM_MIN_UINT32(limits.maxPerStageDescriptorSamplers) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(limits.maxPerStageDescriptorUniformBuffers) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageBuffers) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindSampledImages), LIM_MIN_UINT32(limits.maxPerStageDescriptorSampledImages) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindStorageImages), LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageImages) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageDescriptorUpdateAfterBindInputAttachments), LIM_MIN_UINT32(limits.maxPerStageDescriptorInputAttachments) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxPerStageUpdateAfterBindResources), LIM_MIN_UINT32(limits.maxPerStageResources) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSamplers), LIM_MIN_UINT32(limits.maxDescriptorSetSamplers) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffers) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic), LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffersDynamic) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffers) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic), LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffersDynamic) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindSampledImages), LIM_MIN_UINT32(limits.maxDescriptorSetSampledImages) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindStorageImages), LIM_MIN_UINT32(limits.maxDescriptorSetStorageImages) }, |
| { PN(features12.descriptorIndexing), PN(vulkan12Properties.maxDescriptorSetUpdateAfterBindInputAttachments), LIM_MIN_UINT32(limits.maxDescriptorSetInputAttachments) }, |
| |
| // timelineSemaphore |
| { PN(checkVulkan12Limit), PN(vulkan12Properties.maxTimelineSemaphoreValueDifference), LIM_MIN_DEVSIZE((1ull<<31) - 1) }, |
| }; |
| |
| log << TestLog::Message << limits << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limits.maxFramebufferWidth > limits.maxViewportDimensions[0] || |
| limits.maxFramebufferHeight > limits.maxViewportDimensions[1]) |
| { |
| log << TestLog::Message << "limit validation failed, maxFramebufferDimension of " |
| << "[" << limits.maxFramebufferWidth << ", " << limits.maxFramebufferHeight << "] " |
| << "is larger than maxViewportDimension of " |
| << "[" << limits.maxViewportDimensions[0] << ", " << limits.maxViewportDimensions[1] << "]" << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| |
| if (limits.viewportBoundsRange[0] > float(-2 * limits.maxViewportDimensions[0])) |
| { |
| log << TestLog::Message << "limit validation failed, viewPortBoundsRange[0] of " << limits.viewportBoundsRange[0] |
| << "is larger than -2*maxViewportDimension[0] of " << -2*limits.maxViewportDimensions[0] << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| |
| if (limits.viewportBoundsRange[1] < float(2 * limits.maxViewportDimensions[1] - 1)) |
| { |
| log << TestLog::Message << "limit validation failed, viewportBoundsRange[1] of " << limits.viewportBoundsRange[1] |
| << "is less than 2*maxViewportDimension[1] of " << 2*limits.maxViewportDimensions[1] << TestLog::EndMessage; |
| limitsOk = false; |
| } |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportKhrPushDescriptor (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_KHR_push_descriptor"); |
| } |
| |
| tcu::TestStatus validateLimitsKhrPushDescriptor (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDevicePushDescriptorPropertiesKHR& pushDescriptorPropertiesKHR = context.getPushDescriptorProperties(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(pushDescriptorPropertiesKHR.maxPushDescriptors), LIM_MIN_UINT32(32) }, |
| }; |
| |
| log << TestLog::Message << pushDescriptorPropertiesKHR << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportKhrMultiview (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_KHR_multiview"); |
| } |
| |
| tcu::TestStatus validateLimitsKhrMultiview (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceMultiviewProperties& multiviewProperties = context.getMultiviewProperties(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| // VK_KHR_multiview |
| { PN(checkAlways), PN(multiviewProperties.maxMultiviewViewCount), LIM_MIN_UINT32(6) }, |
| { PN(checkAlways), PN(multiviewProperties.maxMultiviewInstanceIndex), LIM_MIN_UINT32((1<<27) - 1) }, |
| }; |
| |
| log << TestLog::Message << multiviewProperties << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtDiscardRectangles (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_discard_rectangles"); |
| } |
| |
| tcu::TestStatus validateLimitsExtDiscardRectangles (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceDiscardRectanglePropertiesEXT& discardRectanglePropertiesEXT = context.getDiscardRectanglePropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(discardRectanglePropertiesEXT.maxDiscardRectangles), LIM_MIN_UINT32(4) }, |
| }; |
| |
| log << TestLog::Message << discardRectanglePropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtSampleLocations (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_sample_locations"); |
| } |
| |
| tcu::TestStatus validateLimitsExtSampleLocations (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceSampleLocationsPropertiesEXT& sampleLocationsPropertiesEXT = context.getSampleLocationsPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(sampleLocationsPropertiesEXT.sampleLocationSampleCounts), LIM_MIN_BITI32(VK_SAMPLE_COUNT_4_BIT) }, |
| { PN(checkAlways), PN(sampleLocationsPropertiesEXT.maxSampleLocationGridSize.width), LIM_MIN_FLOAT(0.0f) }, |
| { PN(checkAlways), PN(sampleLocationsPropertiesEXT.maxSampleLocationGridSize.height), LIM_MIN_FLOAT(0.0f) }, |
| { PN(checkAlways), PN(sampleLocationsPropertiesEXT.sampleLocationCoordinateRange[0]), LIM_MAX_FLOAT(0.0f) }, |
| { PN(checkAlways), PN(sampleLocationsPropertiesEXT.sampleLocationCoordinateRange[1]), LIM_MIN_FLOAT(0.9375f) }, |
| { PN(checkAlways), PN(sampleLocationsPropertiesEXT.sampleLocationSubPixelBits), LIM_MIN_UINT32(4) }, |
| }; |
| |
| log << TestLog::Message << sampleLocationsPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtExternalMemoryHost (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_external_memory_host"); |
| } |
| |
| tcu::TestStatus validateLimitsExtExternalMemoryHost (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceExternalMemoryHostPropertiesEXT& externalMemoryHostPropertiesEXT = context.getExternalMemoryHostPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(externalMemoryHostPropertiesEXT.minImportedHostPointerAlignment), LIM_MAX_DEVSIZE(65536) }, |
| }; |
| |
| log << TestLog::Message << externalMemoryHostPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtBlendOperationAdvanced (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_blend_operation_advanced"); |
| } |
| |
| tcu::TestStatus validateLimitsExtBlendOperationAdvanced (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT& blendOperationAdvancedPropertiesEXT = context.getBlendOperationAdvancedPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(blendOperationAdvancedPropertiesEXT.advancedBlendMaxColorAttachments), LIM_MIN_UINT32(1) }, |
| }; |
| |
| log << TestLog::Message << blendOperationAdvancedPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportKhrMaintenance3 (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_KHR_maintenance3"); |
| } |
| |
| tcu::TestStatus validateLimitsKhrMaintenance3 (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceMaintenance3Properties& maintenance3Properties = context.getMaintenance3Properties(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(maintenance3Properties.maxPerSetDescriptors), LIM_MIN_UINT32(1024) }, |
| { PN(checkAlways), PN(maintenance3Properties.maxMemoryAllocationSize), LIM_MIN_DEVSIZE(1<<30) }, |
| }; |
| |
| log << TestLog::Message << maintenance3Properties << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtConservativeRasterization (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_conservative_rasterization"); |
| } |
| |
| tcu::TestStatus validateLimitsExtConservativeRasterization (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceConservativeRasterizationPropertiesEXT& conservativeRasterizationPropertiesEXT = context.getConservativeRasterizationPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(conservativeRasterizationPropertiesEXT.primitiveOverestimationSize), LIM_MIN_FLOAT(0.0f) }, |
| { PN(checkAlways), PN(conservativeRasterizationPropertiesEXT.maxExtraPrimitiveOverestimationSize), LIM_MIN_FLOAT(0.0f) }, |
| { PN(checkAlways), PN(conservativeRasterizationPropertiesEXT.extraPrimitiveOverestimationSizeGranularity), LIM_MIN_FLOAT(0.0f) }, |
| }; |
| |
| log << TestLog::Message << conservativeRasterizationPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtDescriptorIndexing (Context& context) |
| { |
| const std::string& requiredDeviceExtension = "VK_EXT_descriptor_indexing"; |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); |
| |
| if (!isExtensionSupported(deviceExtensionProperties, RequiredExtension(requiredDeviceExtension))) |
| TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported"); |
| |
| // Extension string is present, then extension is really supported and should have been added into chain in DefaultDevice properties and features |
| } |
| |
| tcu::TestStatus validateLimitsExtDescriptorIndexing (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceProperties2& properties2 = context.getDeviceProperties2(); |
| const VkPhysicalDeviceLimits& limits = properties2.properties.limits; |
| const VkPhysicalDeviceDescriptorIndexingPropertiesEXT& descriptorIndexingPropertiesEXT = context.getDescriptorIndexingProperties(); |
| const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures(); |
| const deUint32 tessellationShaderCount = (features.tessellationShader) ? 2 : 0; |
| const deUint32 geometryShaderCount = (features.geometryShader) ? 1 : 0; |
| const deUint32 shaderStages = 3 + tessellationShaderCount + geometryShaderCount; |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxUpdateAfterBindDescriptorsInAllPools), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSamplers), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(12) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSampledImages), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageImages), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageUpdateAfterBindResources), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSamplers), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(shaderStages * 12) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic), LIM_MIN_UINT32(8) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSampledImages), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageImages), LIM_MIN_UINT32(500000) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindInputAttachments), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSamplers), LIM_MIN_UINT32(limits.maxPerStageDescriptorSamplers) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(limits.maxPerStageDescriptorUniformBuffers) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageBuffers) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindSampledImages), LIM_MIN_UINT32(limits.maxPerStageDescriptorSampledImages) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindStorageImages), LIM_MIN_UINT32(limits.maxPerStageDescriptorStorageImages) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInputAttachments), LIM_MIN_UINT32(limits.maxPerStageDescriptorInputAttachments) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxPerStageUpdateAfterBindResources), LIM_MIN_UINT32(limits.maxPerStageResources) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSamplers), LIM_MIN_UINT32(limits.maxDescriptorSetSamplers) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffers), LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffers) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindUniformBuffersDynamic), LIM_MIN_UINT32(limits.maxDescriptorSetUniformBuffersDynamic) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffers), LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffers) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageBuffersDynamic), LIM_MIN_UINT32(limits.maxDescriptorSetStorageBuffersDynamic) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindSampledImages), LIM_MIN_UINT32(limits.maxDescriptorSetSampledImages) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindStorageImages), LIM_MIN_UINT32(limits.maxDescriptorSetStorageImages) }, |
| { PN(checkAlways), PN(descriptorIndexingPropertiesEXT.maxDescriptorSetUpdateAfterBindInputAttachments), LIM_MIN_UINT32(limits.maxDescriptorSetInputAttachments) }, |
| }; |
| |
| log << TestLog::Message << descriptorIndexingPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtInlineUniformBlock (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_inline_uniform_block"); |
| } |
| |
| tcu::TestStatus validateLimitsExtInlineUniformBlock (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceInlineUniformBlockPropertiesEXT& inlineUniformBlockPropertiesEXT = context.getInlineUniformBlockPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(inlineUniformBlockPropertiesEXT.maxInlineUniformBlockSize), LIM_MIN_UINT32(256) }, |
| { PN(checkAlways), PN(inlineUniformBlockPropertiesEXT.maxPerStageDescriptorInlineUniformBlocks), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(inlineUniformBlockPropertiesEXT.maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(inlineUniformBlockPropertiesEXT.maxDescriptorSetInlineUniformBlocks), LIM_MIN_UINT32(4) }, |
| { PN(checkAlways), PN(inlineUniformBlockPropertiesEXT.maxDescriptorSetUpdateAfterBindInlineUniformBlocks), LIM_MIN_UINT32(4) }, |
| }; |
| |
| log << TestLog::Message << inlineUniformBlockPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtVertexAttributeDivisor (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_vertex_attribute_divisor"); |
| } |
| |
| tcu::TestStatus validateLimitsExtVertexAttributeDivisor (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT& vertexAttributeDivisorPropertiesEXT = context.getVertexAttributeDivisorPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(vertexAttributeDivisorPropertiesEXT.maxVertexAttribDivisor), LIM_MIN_UINT32((1<<16) - 1) }, |
| }; |
| |
| log << TestLog::Message << vertexAttributeDivisorPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportNvMeshShader (Context& context) |
| { |
| const std::string& requiredDeviceExtension = "VK_NV_mesh_shader"; |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); |
| |
| if (!isExtensionSupported(deviceExtensionProperties, RequiredExtension(requiredDeviceExtension))) |
| TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported"); |
| } |
| |
| tcu::TestStatus validateLimitsNvMeshShader (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| VkPhysicalDeviceMeshShaderPropertiesNV meshShaderPropertiesNV = initVulkanStructure(); |
| VkPhysicalDeviceProperties2 properties2 = initVulkanStructure(&meshShaderPropertiesNV); |
| |
| vki.getPhysicalDeviceProperties2(physicalDevice, &properties2); |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxDrawMeshTasksCount), LIM_MIN_UINT32(deUint32((1ull<<16) - 1)) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxTaskWorkGroupInvocations), LIM_MIN_UINT32(32) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[0]), LIM_MIN_UINT32(32) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[1]), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxTaskWorkGroupSize[2]), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxTaskTotalMemorySize), LIM_MIN_UINT32(16384) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxTaskOutputCount), LIM_MIN_UINT32((1<<16) - 1) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshWorkGroupInvocations), LIM_MIN_UINT32(32) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[0]), LIM_MIN_UINT32(32) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[1]), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshWorkGroupSize[2]), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshTotalMemorySize), LIM_MIN_UINT32(16384) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshOutputVertices), LIM_MIN_UINT32(256) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshOutputPrimitives), LIM_MIN_UINT32(256) }, |
| { PN(checkAlways), PN(meshShaderPropertiesNV.maxMeshMultiviewViewCount), LIM_MIN_UINT32(1) }, |
| }; |
| |
| log << TestLog::Message << meshShaderPropertiesNV << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtTransformFeedback (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_transform_feedback"); |
| } |
| |
| tcu::TestStatus validateLimitsExtTransformFeedback (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceTransformFeedbackPropertiesEXT& transformFeedbackPropertiesEXT = context.getTransformFeedbackPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(transformFeedbackPropertiesEXT.maxTransformFeedbackStreams), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBuffers), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferSize), LIM_MIN_DEVSIZE(1ull<<27) }, |
| { PN(checkAlways), PN(transformFeedbackPropertiesEXT.maxTransformFeedbackStreamDataSize), LIM_MIN_UINT32(512) }, |
| { PN(checkAlways), PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferDataSize), LIM_MIN_UINT32(512) }, |
| { PN(checkAlways), PN(transformFeedbackPropertiesEXT.maxTransformFeedbackBufferDataStride), LIM_MIN_UINT32(512) }, |
| }; |
| |
| log << TestLog::Message << transformFeedbackPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtFragmentDensityMap (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_fragment_density_map"); |
| } |
| |
| tcu::TestStatus validateLimitsExtFragmentDensityMap (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceFragmentDensityMapPropertiesEXT& fragmentDensityMapPropertiesEXT = context.getFragmentDensityMapPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(fragmentDensityMapPropertiesEXT.minFragmentDensityTexelSize.width), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(fragmentDensityMapPropertiesEXT.minFragmentDensityTexelSize.height), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(fragmentDensityMapPropertiesEXT.maxFragmentDensityTexelSize.width), LIM_MIN_UINT32(1) }, |
| { PN(checkAlways), PN(fragmentDensityMapPropertiesEXT.maxFragmentDensityTexelSize.height), LIM_MIN_UINT32(1) }, |
| }; |
| |
| log << TestLog::Message << fragmentDensityMapPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportNvRayTracing (Context& context) |
| { |
| const std::string& requiredDeviceExtension = "VK_NV_ray_tracing"; |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); |
| |
| if (!isExtensionSupported(deviceExtensionProperties, RequiredExtension(requiredDeviceExtension))) |
| TCU_THROW(NotSupportedError, requiredDeviceExtension + " is not supported"); |
| } |
| |
| tcu::TestStatus validateLimitsNvRayTracing (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| VkPhysicalDeviceRayTracingPropertiesNV rayTracingPropertiesNV = initVulkanStructure(); |
| VkPhysicalDeviceProperties2 properties2 = initVulkanStructure(&rayTracingPropertiesNV); |
| |
| vki.getPhysicalDeviceProperties2(physicalDevice, &properties2); |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(rayTracingPropertiesNV.shaderGroupHandleSize), LIM_MIN_UINT32(16) }, |
| { PN(checkAlways), PN(rayTracingPropertiesNV.maxRecursionDepth), LIM_MIN_UINT32(31) }, |
| { PN(checkAlways), PN(rayTracingPropertiesNV.shaderGroupBaseAlignment), LIM_MIN_UINT32(64) }, |
| { PN(checkAlways), PN(rayTracingPropertiesNV.maxGeometryCount), LIM_MIN_UINT32((1<<24) - 1) }, |
| { PN(checkAlways), PN(rayTracingPropertiesNV.maxInstanceCount), LIM_MIN_UINT32((1<<24) - 1) }, |
| { PN(checkAlways), PN(rayTracingPropertiesNV.maxTriangleCount), LIM_MIN_UINT32((1<<29) - 1) }, |
| { PN(checkAlways), PN(rayTracingPropertiesNV.maxDescriptorSetAccelerationStructures), LIM_MIN_UINT32(16) }, |
| }; |
| |
| log << TestLog::Message << rayTracingPropertiesNV << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportKhrTimelineSemaphore (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_KHR_timeline_semaphore"); |
| } |
| |
| tcu::TestStatus validateLimitsKhrTimelineSemaphore (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceTimelineSemaphorePropertiesKHR& timelineSemaphorePropertiesKHR = context.getTimelineSemaphoreProperties(); |
| bool limitsOk = true; |
| TestLog& log = context.getTestContext().getLog(); |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(timelineSemaphorePropertiesKHR.maxTimelineSemaphoreValueDifference), LIM_MIN_DEVSIZE((1ull<<31) - 1) }, |
| }; |
| |
| log << TestLog::Message << timelineSemaphorePropertiesKHR << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportExtLineRasterization (Context& context) |
| { |
| context.requireDeviceFunctionality("VK_EXT_line_rasterization"); |
| } |
| |
| tcu::TestStatus validateLimitsExtLineRasterization (Context& context) |
| { |
| const VkBool32 checkAlways = VK_TRUE; |
| const VkPhysicalDeviceLineRasterizationPropertiesEXT& lineRasterizationPropertiesEXT = context.getLineRasterizationPropertiesEXT(); |
| TestLog& log = context.getTestContext().getLog(); |
| bool limitsOk = true; |
| |
| FeatureLimitTableItem featureLimitTable[] = |
| { |
| { PN(checkAlways), PN(lineRasterizationPropertiesEXT.lineSubPixelPrecisionBits), LIM_MIN_UINT32(4) }, |
| }; |
| |
| log << TestLog::Message << lineRasterizationPropertiesEXT << TestLog::EndMessage; |
| |
| for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(featureLimitTable); ndx++) |
| limitsOk = validateLimit(featureLimitTable[ndx], log) && limitsOk; |
| |
| if (limitsOk) |
| return tcu::TestStatus::pass("pass"); |
| else |
| return tcu::TestStatus::fail("fail"); |
| } |
| |
| void checkSupportFeatureBitInfluence (Context& context) |
| { |
| if (!context.contextSupports(vk::ApiVersion(1, 2, 0))) |
| TCU_THROW(NotSupportedError, "At least Vulkan 1.2 required to run test"); |
| } |
| |
| void createTestDevice (Context& context, void* pNext, const char* const* ppEnabledExtensionNames, deUint32 enabledExtensionCount) |
| { |
| const PlatformInterface& platformInterface = context.getPlatformInterface(); |
| const auto validationEnabled = context.getTestContext().getCommandLine().isValidationEnabled(); |
| const Unique<VkInstance> instance (createDefaultInstance(platformInterface, context.getUsedApiVersion())); |
| const InstanceDriver instanceDriver (platformInterface, instance.get()); |
| const VkPhysicalDevice physicalDevice = chooseDevice(instanceDriver, instance.get(), context.getTestContext().getCommandLine()); |
| const deUint32 queueFamilyIndex = 0; |
| const deUint32 queueCount = 1; |
| const deUint32 queueIndex = 0; |
| const float queuePriority = 1.0f; |
| const vector<VkQueueFamilyProperties> queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice); |
| const VkDeviceQueueCreateInfo deviceQueueCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType; |
| DE_NULL, // const void* pNext; |
| (VkDeviceQueueCreateFlags)0u, // VkDeviceQueueCreateFlags flags; |
| queueFamilyIndex, // deUint32 queueFamilyIndex; |
| queueCount, // deUint32 queueCount; |
| &queuePriority, // const float* pQueuePriorities; |
| }; |
| const VkDeviceCreateInfo deviceCreateInfo = |
| { |
| VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType; |
| pNext, // const void* pNext; |
| (VkDeviceCreateFlags)0u, // VkDeviceCreateFlags flags; |
| 1, // deUint32 queueCreateInfoCount; |
| &deviceQueueCreateInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos; |
| 0, // deUint32 enabledLayerCount; |
| DE_NULL, // const char* const* ppEnabledLayerNames; |
| enabledExtensionCount, // deUint32 enabledExtensionCount; |
| ppEnabledExtensionNames, // const char* const* ppEnabledExtensionNames; |
| DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures; |
| }; |
| const Unique<VkDevice> device (createCustomDevice(validationEnabled, platformInterface, *instance, instanceDriver, physicalDevice, &deviceCreateInfo)); |
| const DeviceDriver deviceDriver (platformInterface, instance.get(), device.get()); |
| const VkQueue queue = getDeviceQueue(deviceDriver, *device, queueFamilyIndex, queueIndex); |
| |
| VK_CHECK(deviceDriver.queueWaitIdle(queue)); |
| } |
| |
| void cleanVulkanStruct (void* structPtr, size_t structSize) |
| { |
| struct StructureBase |
| { |
| VkStructureType sType; |
| void* pNext; |
| }; |
| |
| VkStructureType sType = ((StructureBase*)structPtr)->sType; |
| |
| deMemset(structPtr, 0, structSize); |
| |
| ((StructureBase*)structPtr)->sType = sType; |
| } |
| |
| tcu::TestStatus featureBitInfluenceOnDeviceCreate (Context& context) |
| { |
| #define FEATURE_TABLE_ITEM(CORE, EXT, FIELD, STR) { &(CORE), sizeof(CORE), &(CORE.FIELD), #CORE "." #FIELD, &(EXT), sizeof(EXT), &(EXT.FIELD), #EXT "." #FIELD, STR } |
| #define DEPENDENCY_DUAL_ITEM(CORE, EXT, FIELD, PARENT) { &(CORE.FIELD), &(CORE.PARENT) }, { &(EXT.FIELD), &(EXT.PARENT) } |
| #define DEPENDENCY_SINGLE_ITEM(CORE, FIELD, PARENT) { &(CORE.FIELD), &(CORE.PARENT) } |
| |
| const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| TestLog& log = context.getTestContext().getLog(); |
| const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); |
| |
| VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(); |
| VkPhysicalDeviceVulkan11Features vulkan11Features = initVulkanStructure(); |
| VkPhysicalDeviceVulkan12Features vulkan12Features = initVulkanStructure(); |
| VkPhysicalDevice16BitStorageFeaturesKHR sixteenBitStorageFeatures = initVulkanStructure(); |
| VkPhysicalDeviceMultiviewFeatures multiviewFeatures = initVulkanStructure(); |
| VkPhysicalDeviceVariablePointersFeatures variablePointersFeatures = initVulkanStructure(); |
| VkPhysicalDeviceProtectedMemoryFeatures protectedMemoryFeatures = initVulkanStructure(); |
| VkPhysicalDeviceSamplerYcbcrConversionFeatures samplerYcbcrConversionFeatures = initVulkanStructure(); |
| VkPhysicalDeviceShaderDrawParametersFeatures shaderDrawParametersFeatures = initVulkanStructure(); |
| VkPhysicalDevice8BitStorageFeatures eightBitStorageFeatures = initVulkanStructure(); |
| VkPhysicalDeviceShaderAtomicInt64Features shaderAtomicInt64Features = initVulkanStructure(); |
| VkPhysicalDeviceShaderFloat16Int8Features shaderFloat16Int8Features = initVulkanStructure(); |
| VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexingFeatures = initVulkanStructure(); |
| VkPhysicalDeviceScalarBlockLayoutFeatures scalarBlockLayoutFeatures = initVulkanStructure(); |
| VkPhysicalDeviceImagelessFramebufferFeatures imagelessFramebufferFeatures = initVulkanStructure(); |
| VkPhysicalDeviceUniformBufferStandardLayoutFeatures uniformBufferStandardLayoutFeatures = initVulkanStructure(); |
| VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures shaderSubgroupExtendedTypesFeatures = initVulkanStructure(); |
| VkPhysicalDeviceSeparateDepthStencilLayoutsFeatures separateDepthStencilLayoutsFeatures = initVulkanStructure(); |
| VkPhysicalDeviceHostQueryResetFeatures hostQueryResetFeatures = initVulkanStructure(); |
| VkPhysicalDeviceTimelineSemaphoreFeatures timelineSemaphoreFeatures = initVulkanStructure(); |
| VkPhysicalDeviceBufferDeviceAddressFeatures bufferDeviceAddressFeatures = initVulkanStructure(); |
| VkPhysicalDeviceVulkanMemoryModelFeatures vulkanMemoryModelFeatures = initVulkanStructure(); |
| |
| struct DummyExtensionFeatures |
| { |
| VkStructureType sType; |
| void* pNext; |
| VkBool32 descriptorIndexing; |
| VkBool32 samplerFilterMinmax; |
| } dummyExtensionFeatures; |
| |
| struct FeatureTable |
| { |
| void* coreStructPtr; |
| size_t coreStructSize; |
| VkBool32* coreFieldPtr; |
| const char* coreFieldName; |
| void* extStructPtr; |
| size_t extStructSize; |
| VkBool32* extFieldPtr; |
| const char* extFieldName; |
| const char* extString; |
| } |
| featureTable[] = |
| { |
| FEATURE_TABLE_ITEM(vulkan11Features, sixteenBitStorageFeatures, storageBuffer16BitAccess, "VK_KHR_16bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan11Features, sixteenBitStorageFeatures, uniformAndStorageBuffer16BitAccess, "VK_KHR_16bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan11Features, sixteenBitStorageFeatures, storagePushConstant16, "VK_KHR_16bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan11Features, sixteenBitStorageFeatures, storageInputOutput16, "VK_KHR_16bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan11Features, multiviewFeatures, multiview, "VK_KHR_multiview"), |
| FEATURE_TABLE_ITEM(vulkan11Features, multiviewFeatures, multiviewGeometryShader, "VK_KHR_multiview"), |
| FEATURE_TABLE_ITEM(vulkan11Features, multiviewFeatures, multiviewTessellationShader, "VK_KHR_multiview"), |
| FEATURE_TABLE_ITEM(vulkan11Features, variablePointersFeatures, variablePointersStorageBuffer, "VK_KHR_variable_pointers"), |
| FEATURE_TABLE_ITEM(vulkan11Features, variablePointersFeatures, variablePointers, "VK_KHR_variable_pointers"), |
| FEATURE_TABLE_ITEM(vulkan11Features, protectedMemoryFeatures, protectedMemory, DE_NULL), |
| FEATURE_TABLE_ITEM(vulkan11Features, samplerYcbcrConversionFeatures, samplerYcbcrConversion, "VK_KHR_sampler_ycbcr_conversion"), |
| FEATURE_TABLE_ITEM(vulkan11Features, shaderDrawParametersFeatures, shaderDrawParameters, DE_NULL), |
| FEATURE_TABLE_ITEM(vulkan12Features, eightBitStorageFeatures, storageBuffer8BitAccess, "VK_KHR_8bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan12Features, eightBitStorageFeatures, uniformAndStorageBuffer8BitAccess, "VK_KHR_8bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan12Features, eightBitStorageFeatures, storagePushConstant8, "VK_KHR_8bit_storage"), |
| FEATURE_TABLE_ITEM(vulkan12Features, shaderAtomicInt64Features, shaderBufferInt64Atomics, "VK_KHR_shader_atomic_int64"), |
| FEATURE_TABLE_ITEM(vulkan12Features, shaderAtomicInt64Features, shaderSharedInt64Atomics, "VK_KHR_shader_atomic_int64"), |
| FEATURE_TABLE_ITEM(vulkan12Features, shaderFloat16Int8Features, shaderFloat16, "VK_KHR_shader_float16_int8"), |
| FEATURE_TABLE_ITEM(vulkan12Features, shaderFloat16Int8Features, shaderInt8, "VK_KHR_shader_float16_int8"), |
| FEATURE_TABLE_ITEM(vulkan12Features, dummyExtensionFeatures, descriptorIndexing, DE_NULL), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderInputAttachmentArrayDynamicIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderUniformTexelBufferArrayDynamicIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderStorageTexelBufferArrayDynamicIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderUniformBufferArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderSampledImageArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderStorageBufferArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderStorageImageArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderInputAttachmentArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderUniformTexelBufferArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, shaderStorageTexelBufferArrayNonUniformIndexing, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingUniformBufferUpdateAfterBind, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingSampledImageUpdateAfterBind, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingStorageImageUpdateAfterBind, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingStorageBufferUpdateAfterBind, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingUniformTexelBufferUpdateAfterBind, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingStorageTexelBufferUpdateAfterBind, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingUpdateUnusedWhilePending, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingPartiallyBound, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, descriptorBindingVariableDescriptorCount, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, descriptorIndexingFeatures, runtimeDescriptorArray, "VK_EXT_descriptor_indexing"), |
| FEATURE_TABLE_ITEM(vulkan12Features, dummyExtensionFeatures, samplerFilterMinmax, "VK_EXT_sampler_filter_minmax"), |
| FEATURE_TABLE_ITEM(vulkan12Features, scalarBlockLayoutFeatures, scalarBlockLayout, "VK_EXT_scalar_block_layout"), |
| FEATURE_TABLE_ITEM(vulkan12Features, imagelessFramebufferFeatures, imagelessFramebuffer, "VK_KHR_imageless_framebuffer"), |
| FEATURE_TABLE_ITEM(vulkan12Features, uniformBufferStandardLayoutFeatures, uniformBufferStandardLayout, "VK_KHR_uniform_buffer_standard_layout"), |
| FEATURE_TABLE_ITEM(vulkan12Features, shaderSubgroupExtendedTypesFeatures, shaderSubgroupExtendedTypes, "VK_KHR_shader_subgroup_extended_types"), |
| FEATURE_TABLE_ITEM(vulkan12Features, separateDepthStencilLayoutsFeatures, separateDepthStencilLayouts, "VK_KHR_separate_depth_stencil_layouts"), |
| FEATURE_TABLE_ITEM(vulkan12Features, hostQueryResetFeatures, hostQueryReset, "VK_EXT_host_query_reset"), |
| FEATURE_TABLE_ITEM(vulkan12Features, timelineSemaphoreFeatures, timelineSemaphore, "VK_KHR_timeline_semaphore"), |
| FEATURE_TABLE_ITEM(vulkan12Features, bufferDeviceAddressFeatures, bufferDeviceAddress, "VK_EXT_buffer_device_address"), |
| FEATURE_TABLE_ITEM(vulkan12Features, bufferDeviceAddressFeatures, bufferDeviceAddressCaptureReplay, "VK_EXT_buffer_device_address"), |
| FEATURE_TABLE_ITEM(vulkan12Features, bufferDeviceAddressFeatures, bufferDeviceAddressMultiDevice, "VK_EXT_buffer_device_address"), |
| FEATURE_TABLE_ITEM(vulkan12Features, vulkanMemoryModelFeatures, vulkanMemoryModel, "VK_KHR_vulkan_memory_model"), |
| FEATURE_TABLE_ITEM(vulkan12Features, vulkanMemoryModelFeatures, vulkanMemoryModelDeviceScope, "VK_KHR_vulkan_memory_model"), |
| FEATURE_TABLE_ITEM(vulkan12Features, vulkanMemoryModelFeatures, vulkanMemoryModelAvailabilityVisibilityChains, "VK_KHR_vulkan_memory_model"), |
| }; |
| struct FeatureDependencyTable |
| { |
| VkBool32* featurePtr; |
| VkBool32* dependOnPtr; |
| } |
| featureDependencyTable[] = |
| { |
| DEPENDENCY_DUAL_ITEM (vulkan11Features, multiviewFeatures, multiviewGeometryShader, multiview), |
| DEPENDENCY_DUAL_ITEM (vulkan11Features, multiviewFeatures, multiviewTessellationShader, multiview), |
| DEPENDENCY_DUAL_ITEM (vulkan11Features, variablePointersFeatures, variablePointers, variablePointersStorageBuffer), |
| DEPENDENCY_DUAL_ITEM (vulkan12Features, bufferDeviceAddressFeatures, bufferDeviceAddressCaptureReplay, bufferDeviceAddress), |
| DEPENDENCY_DUAL_ITEM (vulkan12Features, bufferDeviceAddressFeatures, bufferDeviceAddressMultiDevice, bufferDeviceAddress), |
| DEPENDENCY_DUAL_ITEM (vulkan12Features, vulkanMemoryModelFeatures, vulkanMemoryModelDeviceScope, vulkanMemoryModel), |
| DEPENDENCY_DUAL_ITEM (vulkan12Features, vulkanMemoryModelFeatures, vulkanMemoryModelAvailabilityVisibilityChains, vulkanMemoryModel), |
| }; |
| |
| deMemset(&dummyExtensionFeatures, 0, sizeof(dummyExtensionFeatures)); |
| |
| for (size_t featureTableNdx = 0; featureTableNdx < DE_LENGTH_OF_ARRAY(featureTable); ++featureTableNdx) |
| { |
| FeatureTable& testedFeature = featureTable[featureTableNdx]; |
| VkBool32 coreFeatureState= DE_FALSE; |
| VkBool32 extFeatureState = DE_FALSE; |
| |
| // Core test |
| { |
| void* structPtr = testedFeature.coreStructPtr; |
| size_t structSize = testedFeature.coreStructSize; |
| VkBool32* featurePtr = testedFeature.coreFieldPtr; |
| |
| if (structPtr != &dummyExtensionFeatures) |
| features2.pNext = structPtr; |
| |
| vki.getPhysicalDeviceFeatures2(physicalDevice, &features2); |
| |
| coreFeatureState = featurePtr[0]; |
| |
| log << TestLog::Message |
| << "Feature status " |
| << testedFeature.coreFieldName << "=" << coreFeatureState |
| << TestLog::EndMessage; |
| |
| if (coreFeatureState) |
| { |
| cleanVulkanStruct(structPtr, structSize); |
| |
| featurePtr[0] = DE_TRUE; |
| |
| for (size_t featureDependencyTableNdx = 0; featureDependencyTableNdx < DE_LENGTH_OF_ARRAY(featureDependencyTable); ++featureDependencyTableNdx) |
| if (featureDependencyTable[featureDependencyTableNdx].featurePtr == featurePtr) |
| featureDependencyTable[featureDependencyTableNdx].dependOnPtr[0] = DE_TRUE; |
| |
| createTestDevice(context, &features2, DE_NULL, 0u); |
| } |
| } |
| |
| // ext test |
| { |
| void* structPtr = testedFeature.extStructPtr; |
| size_t structSize = testedFeature.extStructSize; |
| VkBool32* featurePtr = testedFeature.extFieldPtr; |
| const char* extStringPtr = testedFeature.extString; |
| |
| if (structPtr != &dummyExtensionFeatures) |
| features2.pNext = structPtr; |
| |
| if (extStringPtr == DE_NULL || isExtensionSupported(deviceExtensionProperties, RequiredExtension(extStringPtr))) |
| { |
| vki.getPhysicalDeviceFeatures2(physicalDevice, &features2); |
| |
| extFeatureState = *featurePtr; |
| |
| log << TestLog::Message |
| << "Feature status " |
| << testedFeature.extFieldName << "=" << extFeatureState |
| << TestLog::EndMessage; |
| |
| if (extFeatureState) |
| { |
| cleanVulkanStruct(structPtr, structSize); |
| |
| featurePtr[0] = DE_TRUE; |
| |
| for (size_t featureDependencyTableNdx = 0; featureDependencyTableNdx < DE_LENGTH_OF_ARRAY(featureDependencyTable); ++featureDependencyTableNdx) |
| if (featureDependencyTable[featureDependencyTableNdx].featurePtr == featurePtr) |
| featureDependencyTable[featureDependencyTableNdx].dependOnPtr[0] = DE_TRUE; |
| |
| createTestDevice(context, &features2, &extStringPtr, (extStringPtr == DE_NULL) ? 0u : 1u ); |
| } |
| } |
| } |
| } |
| |
| return tcu::TestStatus::pass("pass"); |
| } |
| |
| template<typename T> |
| class CheckIncompleteResult |
| { |
| public: |
| virtual ~CheckIncompleteResult (void) {} |
| virtual void getResult (Context& context, T* data) = 0; |
| |
| void operator() (Context& context, tcu::ResultCollector& results, const std::size_t expectedCompleteSize) |
| { |
| if (expectedCompleteSize == 0) |
| return; |
| |
| vector<T> outputData (expectedCompleteSize); |
| const deUint32 usedSize = static_cast<deUint32>(expectedCompleteSize / 3); |
| |
| ValidateQueryBits::fillBits(outputData.begin(), outputData.end()); // unused entries should have this pattern intact |
| m_count = usedSize; |
| m_result = VK_SUCCESS; |
| |
| getResult(context, &outputData[0]); // update m_count and m_result |
| |
| if (m_count != usedSize || m_result != VK_INCOMPLETE || !ValidateQueryBits::checkBits(outputData.begin() + m_count, outputData.end())) |
| results.fail("Query didn't return VK_INCOMPLETE"); |
| } |
| |
| protected: |
| deUint32 m_count; |
| VkResult m_result; |
| }; |
| |
| struct CheckEnumeratePhysicalDevicesIncompleteResult : public CheckIncompleteResult<VkPhysicalDevice> |
| { |
| void getResult (Context& context, VkPhysicalDevice* data) |
| { |
| m_result = context.getInstanceInterface().enumeratePhysicalDevices(context.getInstance(), &m_count, data); |
| } |
| }; |
| |
| struct CheckEnumeratePhysicalDeviceGroupsIncompleteResult : public CheckIncompleteResult<VkPhysicalDeviceGroupProperties> |
| { |
| void getResult (Context& context, VkPhysicalDeviceGroupProperties* data) |
| { |
| m_result = context.getInstanceInterface().enumeratePhysicalDeviceGroups(context.getInstance(), &m_count, data); |
| } |
| }; |
| |
| struct CheckEnumerateInstanceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties> |
| { |
| void getResult (Context& context, VkLayerProperties* data) |
| { |
| m_result = context.getPlatformInterface().enumerateInstanceLayerProperties(&m_count, data); |
| } |
| }; |
| |
| struct CheckEnumerateDeviceLayerPropertiesIncompleteResult : public CheckIncompleteResult<VkLayerProperties> |
| { |
| void getResult (Context& context, VkLayerProperties* data) |
| { |
| m_result = context.getInstanceInterface().enumerateDeviceLayerProperties(context.getPhysicalDevice(), &m_count, data); |
| } |
| }; |
| |
| struct CheckEnumerateInstanceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties> |
| { |
| CheckEnumerateInstanceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {} |
| |
| void getResult (Context& context, VkExtensionProperties* data) |
| { |
| const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL); |
| m_result = context.getPlatformInterface().enumerateInstanceExtensionProperties(pLayerName, &m_count, data); |
| } |
| |
| private: |
| const std::string m_layerName; |
| }; |
| |
| struct CheckEnumerateDeviceExtensionPropertiesIncompleteResult : public CheckIncompleteResult<VkExtensionProperties> |
| { |
| CheckEnumerateDeviceExtensionPropertiesIncompleteResult (std::string layerName = std::string()) : m_layerName(layerName) {} |
| |
| void getResult (Context& context, VkExtensionProperties* data) |
| { |
| const char* pLayerName = (m_layerName.length() != 0 ? m_layerName.c_str() : DE_NULL); |
| m_result = context.getInstanceInterface().enumerateDeviceExtensionProperties(context.getPhysicalDevice(), pLayerName, &m_count, data); |
| } |
| |
| private: |
| const std::string m_layerName; |
| }; |
| |
| tcu::TestStatus enumeratePhysicalDevices (Context& context) |
| { |
| TestLog& log = context.getTestContext().getLog(); |
| tcu::ResultCollector results (log); |
| const vector<VkPhysicalDevice> devices = enumeratePhysicalDevices(context.getInstanceInterface(), context.getInstance()); |
| |
| log << TestLog::Integer("NumDevices", "Number of devices", "", QP_KEY_TAG_NONE, deInt64(devices.size())); |
| |
| for (size_t ndx = 0; ndx < devices.size(); ndx++) |
| log << TestLog::Message << ndx << ": " << devices[ndx] << TestLog::EndMessage; |
| |
| CheckEnumeratePhysicalDevicesIncompleteResult()(context, results, devices.size()); |
| |
| return tcu::TestStatus(results.getResult(), results.getMessage()); |
| } |
| |
| tcu::TestStatus enumeratePhysicalDeviceGroups (Context& context) |
| { |
| TestLog& log = context.getTestContext().getLog(); |
| tcu::ResultCollector results (log); |
| const CustomInstance instance (createCustomInstanceWithExtension(context, "VK_KHR_device_group_creation")); |
| const InstanceDriver& vki (instance.getDriver()); |
| const vector<VkPhysicalDeviceGroupProperties> devicegroups = enumeratePhysicalDeviceGroups(vki, instance); |
| |
| log << TestLog::Integer("NumDevices", "Number of device groups", "", QP_KEY_TAG_NONE, deInt64(devicegroups.size())); |
| |
| for (size_t ndx = 0; ndx < devicegroups.size(); ndx++) |
| log << TestLog::Message << ndx << ": " << devicegroups[ndx] << TestLog::EndMessage; |
| |
| CheckEnumeratePhysicalDeviceGroupsIncompleteResult()(context, results, devicegroups.size()); |
| |
| return tcu::TestStatus(results.getResult(), results.getMessage()); |
| } |
| |
| template<typename T> |
| void collectDuplicates (set<T>& duplicates, const vector<T>& values) |
| { |
| set<T> seen; |
| |
| for (size_t ndx = 0; ndx < values.size(); ndx++) |
| { |
| const T& value = values[ndx]; |
| |
| if (!seen.insert(value).second) |
| duplicates.insert(value); |
| } |
| } |
| |
| void checkDuplicates (tcu::ResultCollector& results, const char* what, const vector<string>& values) |
| { |
| set<string> duplicates; |
| |
| collectDuplicates(duplicates, values); |
| |
| for (set<string>::const_iterator iter = duplicates.begin(); iter != duplicates.end(); ++iter) |
| { |
| std::ostringstream msg; |
| msg << "Duplicate " << what << ": " << *iter; |
| results.fail(msg.str()); |
| } |
| } |
| |
| void checkDuplicateExtensions (tcu::ResultCollector& results, const vector<string>& extensions) |
| { |
| checkDuplicates(results, "extension", extensions); |
| } |
| |
| void checkDuplicateLayers (tcu::ResultCollector& results, const vector<string>& layers) |
| { |
| checkDuplicates(results, "layer", layers); |
| } |
| |
| void checkKhrExtensions (tcu::ResultCollector& results, |
| const vector<string>& extensions, |
| const int numAllowedKhrExtensions, |
| const char* const* allowedKhrExtensions) |
| { |
| const set<string> allowedExtSet (allowedKhrExtensions, allowedKhrExtensions+numAllowedKhrExtensions); |
| |
| for (vector<string>::const_iterator extIter = extensions.begin(); extIter != extensions.end(); ++extIter) |
| { |
| // Only Khronos-controlled extensions are checked |
| if (de::beginsWith(*extIter, "VK_KHR_") && |
| !de::contains(allowedExtSet, *extIter)) |
| { |
| results.fail("Unknown extension " + *extIter); |
| } |
| } |
| } |
| |
| void checkInstanceExtensions (tcu::ResultCollector& results, const vector<string>& extensions) |
| { |
| #include "vkInstanceExtensions.inl" |
| |
| checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedInstanceKhrExtensions), s_allowedInstanceKhrExtensions); |
| checkDuplicateExtensions(results, extensions); |
| } |
| |
| void checkDeviceExtensions (tcu::ResultCollector& results, const vector<string>& extensions) |
| { |
| #include "vkDeviceExtensions.inl" |
| |
| checkKhrExtensions(results, extensions, DE_LENGTH_OF_ARRAY(s_allowedDeviceKhrExtensions), s_allowedDeviceKhrExtensions); |
| checkDuplicateExtensions(results, extensions); |
| } |
| |
| void checkInstanceExtensionDependencies(tcu::ResultCollector& results, |
| int dependencyLength, |
| const std::tuple<deUint32, deUint32, const char*, const char*>* dependencies, |
| deUint32 versionMajor, |
| deUint32 versionMinor, |
| const vector<VkExtensionProperties>& extensionProperties) |
| { |
| for (int ndx = 0; ndx < dependencyLength; ndx++) |
| { |
| deUint32 currentVersionMajor, currentVersionMinor; |
| const char* extensionFirst; |
| const char* extensionSecond; |
| std::tie(currentVersionMajor, currentVersionMinor, extensionFirst, extensionSecond) = dependencies[ndx]; |
| if (currentVersionMajor != versionMajor || currentVersionMinor != versionMinor) |
| continue; |
| if (isExtensionSupported(extensionProperties, RequiredExtension(extensionFirst)) && |
| !isExtensionSupported(extensionProperties, RequiredExtension(extensionSecond))) |
| { |
| results.fail("Extension " + string(extensionFirst) + " is missing dependency: " + string(extensionSecond)); |
| } |
| } |
| } |
| |
| void checkDeviceExtensionDependencies(tcu::ResultCollector& results, |
| int dependencyLength, |
| const std::tuple<deUint32, deUint32, const char*, const char*>* dependencies, |
| deUint32 versionMajor, |
| deUint32 versionMinor, |
| const vector<VkExtensionProperties>& instanceExtensionProperties, |
| const vector<VkExtensionProperties>& deviceExtensionProperties) |
| { |
| for (int ndx = 0; ndx < dependencyLength; ndx++) |
| { |
| deUint32 currentVersionMajor, currentVersionMinor; |
| const char* extensionFirst; |
| const char* extensionSecond; |
| std::tie(currentVersionMajor, currentVersionMinor, extensionFirst, extensionSecond) = dependencies[ndx]; |
| if (currentVersionMajor != versionMajor || currentVersionMinor != versionMinor) |
| continue; |
| if (isExtensionSupported(deviceExtensionProperties, RequiredExtension(extensionFirst)) && |
| !isExtensionSupported(deviceExtensionProperties, RequiredExtension(extensionSecond)) && |
| !isExtensionSupported(instanceExtensionProperties, RequiredExtension(extensionSecond))) |
| { |
| results.fail("Extension " + string(extensionFirst) + " is missing dependency: " + string(extensionSecond)); |
| } |
| } |
| } |
| |
| tcu::TestStatus enumerateInstanceLayers (Context& context) |
| { |
| TestLog& log = context.getTestContext().getLog(); |
| tcu::ResultCollector results (log); |
| const vector<VkLayerProperties> properties = enumerateInstanceLayerProperties(context.getPlatformInterface()); |
| vector<string> layerNames; |
| |
| for (size_t ndx = 0; ndx < properties.size(); ndx++) |
| { |
| log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage; |
| |
| layerNames.push_back(properties[ndx].layerName); |
| } |
| |
| checkDuplicateLayers(results, layerNames); |
| CheckEnumerateInstanceLayerPropertiesIncompleteResult()(context, results, layerNames.size()); |
| |
| return tcu::TestStatus(results.getResult(), results.getMessage()); |
| } |
| |
| tcu::TestStatus enumerateInstanceExtensions (Context& context) |
| { |
| TestLog& log = context.getTestContext().getLog(); |
| tcu::ResultCollector results (log); |
| |
| { |
| const ScopedLogSection section (log, "Global", "Global Extensions"); |
| const vector<VkExtensionProperties> properties = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL); |
| vector<string> extensionNames; |
| |
| for (size_t ndx = 0; ndx < properties.size(); ndx++) |
| { |
| log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage; |
| |
| extensionNames.push_back(properties[ndx].extensionName); |
| } |
| |
| checkInstanceExtensions(results, extensionNames); |
| CheckEnumerateInstanceExtensionPropertiesIncompleteResult()(context, results, properties.size()); |
| |
| for (const auto& version : releasedApiVersions) |
| { |
| deUint32 versionMajor, versionMinor; |
| std::tie(std::ignore, versionMajor, versionMinor) = version; |
| if (context.contextSupports(vk::ApiVersion(versionMajor, versionMinor, 0))) |
| { |
| checkInstanceExtensionDependencies(results, |
| DE_LENGTH_OF_ARRAY(instanceExtensionDependencies), |
| instanceExtensionDependencies, |
| versionMajor, |
| versionMinor, |
| properties); |
| break; |
| } |
| } |
| } |
| |
| { |
| const vector<VkLayerProperties> layers = enumerateInstanceLayerProperties(context.getPlatformInterface()); |
| |
| for (vector<VkLayerProperties>::const_iterator layer = layers.begin(); layer != layers.end(); ++layer) |
| { |
| const ScopedLogSection section (log, layer->layerName, string("Layer: ") + layer->layerName); |
| const vector<VkExtensionProperties> properties = enumerateInstanceExtensionProperties(context.getPlatformInterface(), layer->layerName); |
| vector<string> extensionNames; |
| |
| for (size_t extNdx = 0; extNdx < properties.size(); extNdx++) |
| { |
| log << TestLog::Message << extNdx << ": " << properties[extNdx] << TestLog::EndMessage; |
| |
| extensionNames.push_back(properties[extNdx].extensionName); |
| } |
| |
| checkInstanceExtensions(results, extensionNames); |
| CheckEnumerateInstanceExtensionPropertiesIncompleteResult(layer->layerName)(context, results, properties.size()); |
| } |
| } |
| |
| return tcu::TestStatus(results.getResult(), results.getMessage()); |
| } |
| |
| tcu::TestStatus testNoKhxExtensions (Context& context) |
| { |
| VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); |
| const PlatformInterface& vkp = context.getPlatformInterface(); |
| const InstanceInterface& vki = context.getInstanceInterface(); |
| |
| tcu::ResultCollector results(context.getTestContext().getLog()); |
| bool testSucceeded = true; |
| deUint32 instanceExtensionsCount; |
| deUint32 deviceExtensionsCount; |
| |
| // grab number of instance and device extensions |
| vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, DE_NULL); |
| vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, DE_NULL); |
| vector<VkExtensionProperties> extensionsProperties(instanceExtensionsCount + deviceExtensionsCount); |
| |
| // grab instance and device extensions into single vector |
| if (instanceExtensionsCount) |
| vkp.enumerateInstanceExtensionProperties(DE_NULL, &instanceExtensionsCount, &extensionsProperties[0]); |
| if (deviceExtensionsCount) |
| vki.enumerateDeviceExtensionProperties(physicalDevice, DE_NULL, &deviceExtensionsCount, &extensionsProperties[instanceExtensionsCount]); |
| |
| // iterate over all extensions and verify their names |
| vector<VkExtensionProperties>::const_iterator extension = extensionsProperties.begin(); |
| while (extension != extensionsProperties.end()) |
| { |
| // KHX author ID is no longer used, all KHX extensions have been promoted to KHR status |
| std::string extensionName(extension->extensionName); |
| bool caseFailed = de::beginsWith(extensionName, "VK_KHX_"); |
| if (caseFailed) |
| { |
| results.fail("Invalid extension name " + extensionName); |
| testSucceeded = false; |
| } |
| ++extension; |
| } |
| |
| if (testSucceeded) |
| return tcu::TestStatus::pass("No extensions begining with \"VK_KHX\""); |
| return tcu::TestStatus::fail("One or more extensions begins with \"VK_KHX\""); |
| } |
| |
| tcu::TestStatus enumerateDeviceLayers (Context& context) |
| { |
| TestLog& log = context.getTestContext().getLog(); |
| tcu::ResultCollector results (log); |
| const vector<VkLayerProperties> properties = enumerateDeviceLayerProperties(context.getInstanceInterface(), context.getPhysicalDevice()); |
| vector<string> layerNames; |
| |
| for (size_t ndx = 0; ndx < properties.size(); ndx++) |
| { |
| log << TestLog::Message << ndx << ": " << properties[ndx] << TestLog::EndMessage; |
| |
| layerNames.push_back(properties[ndx].layerName); |
| } |
| |
| checkDuplicateLayers(results, layerNames); |
| CheckEnumerateDeviceLayerPropertiesIncompleteResult()(context, results, layerNames.size()); |
| |
| return tcu::TestStatus(results.getResult(), results.getMessage()); |
| } |
| |
| tcu::TestStatus enumerateDeviceExtensions (Context& context) |
| { |
| TestLog& log = context.getTestContext().getLog(); |
| tcu::ResultCollector results (log); |
| |
| { |
| const ScopedLogSection section (log, "Global", "Global Extensions"); |
| const vector<VkExtensionProperties> instanceExtensionProperties = enumerateInstanceExtensionProperties(context.getPlatformInterface(), DE_NULL); |
| const vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice(), DE_NULL); |
| vector<string> deviceExtensionNames; |
| |
| for (size_t ndx = 0; ndx < deviceExtensionProperties.size(); ndx++) |
| { |
| log << TestLog::Message << ndx << ": " << deviceExtensionProperties[ndx] << TestLog::EndMessage; |
| |
| deviceExtensionNames.push_back(deviceExtensionProperties[ndx].extensionName); |
| } |
| |
| checkDeviceExtensions(results, deviceExtensionNames); |
| CheckEnumerateDeviceExtensionPropertiesIncompleteResult()(context, results, deviceExtensionProperties.size()); |
| |
| for (const auto& version : releasedApiVersions) |
| { |
| deUint32 versionMajor, versionMinor; |
| std::tie(std::ignore, versionMajor, versionMinor) = version; |
| if (context.contextSupports(vk::ApiVersion(versionMajor, versionMinor, 0))) |
| { |
| checkDeviceExtensionDependencies(results, |
| DE_LENGTH_OF_ARRAY(deviceExtensionDependencies), |
| deviceExtensionDependencies, |
| versionMajor, |
| versionMinor, |
| instanceExtensionProperties, |
| deviceExtensionProperties); |
| break; |
| } |
| } |
| } |
| |
|