blob: a807ee44b87ffa3daa68ffa89bc2508c7605943f [file] [log] [blame]
/*-------------------------------------------------------------------------
* 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;
}
}
}