blob: acb5d9889c4d0da1e21e5b42800b72f1b9e97eee [file] [log] [blame]
/*-------------------------------------------------------------------------
* Vulkan Conformance Tests
* ------------------------
*
* Copyright (c) 2017 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 Utilities for Vulkan SPIR-V assembly tests
*//*--------------------------------------------------------------------*/
#include "vktSpvAsmUtils.hpp"
#include "deMemory.h"
#include "deSTLUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "vkPlatform.hpp"
namespace vkt
{
namespace SpirVAssembly
{
using namespace vk;
bool is8BitStorageFeaturesSupported (const Context& context, Extension8BitStorageFeatures toCheck)
{
VkPhysicalDevice8BitStorageFeaturesKHR extensionFeatures = context.get8BitStorageFeatures();
if ((toCheck & EXT8BITSTORAGEFEATURES_STORAGE_BUFFER) != 0 && extensionFeatures.storageBuffer8BitAccess == VK_FALSE)
TCU_FAIL("storageBuffer8BitAccess has to be supported");
if ((toCheck & EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER) != 0 && extensionFeatures.uniformAndStorageBuffer8BitAccess == VK_FALSE)
return false;
if ((toCheck & EXT8BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant8 == VK_FALSE)
return false;
return true;
}
#define IS_CORE_FEATURE_AVAILABLE(CHECKED, AVAILABLE, FEATURE) \
if ((CHECKED.FEATURE != DE_FALSE) && (AVAILABLE.FEATURE == DE_FALSE)) { *missingFeature = #FEATURE; return false; }
bool isCoreFeaturesSupported (const Context& context,
const vk::VkPhysicalDeviceFeatures& toCheck,
const char** missingFeature)
{
const VkPhysicalDeviceFeatures& availableFeatures = context.getDeviceFeatures();
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, robustBufferAccess);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fullDrawIndexUint32);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, imageCubeArray);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, independentBlend);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, geometryShader);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, tessellationShader);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sampleRateShading);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, dualSrcBlend);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, logicOp);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, multiDrawIndirect);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, drawIndirectFirstInstance);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthClamp);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthBiasClamp);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fillModeNonSolid);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthBounds);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, wideLines);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, largePoints);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, alphaToOne);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, multiViewport);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, samplerAnisotropy);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionETC2);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionASTC_LDR);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionBC);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, occlusionQueryPrecise);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, pipelineStatisticsQuery);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, vertexPipelineStoresAndAtomics);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fragmentStoresAndAtomics);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderTessellationAndGeometryPointSize);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderImageGatherExtended);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageExtendedFormats);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageMultisample);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageReadWithoutFormat);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageWriteWithoutFormat);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderUniformBufferArrayDynamicIndexing);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderSampledImageArrayDynamicIndexing);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageBufferArrayDynamicIndexing);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageArrayDynamicIndexing);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderClipDistance);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderCullDistance);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderFloat64);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderInt64);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderInt16);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderResourceResidency);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderResourceMinLod);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseBinding);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyBuffer);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyImage2D);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyImage3D);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency2Samples);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency4Samples);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency8Samples);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency16Samples);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyAliased);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, variableMultisampleRate);
IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, inheritedQueries);
return true;
}
bool is16BitStorageFeaturesSupported (const Context& context, Extension16BitStorageFeatures toCheck)
{
const VkPhysicalDevice16BitStorageFeatures& extensionFeatures = context.get16BitStorageFeatures();
if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE)
return false;
if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE)
return false;
if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE)
return false;
if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE)
return false;
return true;
}
bool isVariablePointersFeaturesSupported (const Context& context, ExtensionVariablePointersFeatures toCheck)
{
const VkPhysicalDeviceVariablePointerFeatures& extensionFeatures = context.getVariablePointerFeatures();
if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
return false;
if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
return false;
return true;
}
bool isFloat16Int8FeaturesSupported (const Context& context, ExtensionFloat16Int8Features toCheck)
{
const VkPhysicalDeviceFloat16Int8FeaturesKHR& extensionFeatures = context.getFloat16Int8Features();
if ((toCheck & EXTFLOAT16INT8FEATURES_FLOAT16) != 0 && extensionFeatures.shaderFloat16 == VK_FALSE)
return false;
if ((toCheck & EXTFLOAT16INT8FEATURES_INT8) != 0 && extensionFeatures.shaderInt8 == VK_FALSE)
return false;
return true;
}
bool isFloatControlsFeaturesSupported (const Context& context, const ExtensionFloatControlsFeatures& toCheck)
{
ExtensionFloatControlsFeatures refControls;
deMemset(&refControls, 0, sizeof(ExtensionFloatControlsFeatures));
// compare with all flags set to false to verify if any float control features are actualy requested by the test
if (deMemCmp(&toCheck, &refControls, sizeof(ExtensionFloatControlsFeatures)) == 0)
return true;
// return false when float control features are requested and proper extension is not supported
const std::vector<std::string>& deviceExtensions = context.getDeviceExtensions();
if (!isDeviceExtensionSupported(context.getUsedApiVersion(), deviceExtensions, "VK_KHR_shader_float_controls"))
return false;
// perform query to get supported float control properties
{
refControls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
refControls.pNext = DE_NULL;
VkPhysicalDeviceProperties2 deviceProperties;
deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
deviceProperties.pNext = &refControls;
const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
const vk::InstanceInterface& instanceInterface = context.getInstanceInterface();
instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
}
// check if flags needed by the test are not supported by the device
bool requiredFeaturesNotSupported =
(toCheck.shaderDenormFlushToZeroFloat16 && !refControls.shaderDenormFlushToZeroFloat16) ||
(toCheck.shaderDenormPreserveFloat16 && !refControls.shaderDenormPreserveFloat16) ||
(toCheck.shaderRoundingModeRTEFloat16 && !refControls.shaderRoundingModeRTEFloat16) ||
(toCheck.shaderRoundingModeRTZFloat16 && !refControls.shaderRoundingModeRTZFloat16) ||
(toCheck.shaderSignedZeroInfNanPreserveFloat16 && !refControls.shaderSignedZeroInfNanPreserveFloat16) ||
(toCheck.shaderDenormFlushToZeroFloat32 && !refControls.shaderDenormFlushToZeroFloat32) ||
(toCheck.shaderDenormPreserveFloat32 && !refControls.shaderDenormPreserveFloat32) ||
(toCheck.shaderRoundingModeRTEFloat32 && !refControls.shaderRoundingModeRTEFloat32) ||
(toCheck.shaderRoundingModeRTZFloat32 && !refControls.shaderRoundingModeRTZFloat32) ||
(toCheck.shaderSignedZeroInfNanPreserveFloat32 && !refControls.shaderSignedZeroInfNanPreserveFloat32) ||
(toCheck.shaderDenormFlushToZeroFloat64 && !refControls.shaderDenormFlushToZeroFloat64) ||
(toCheck.shaderDenormPreserveFloat64 && !refControls.shaderDenormPreserveFloat64) ||
(toCheck.shaderRoundingModeRTEFloat64 && !refControls.shaderRoundingModeRTEFloat64) ||
(toCheck.shaderRoundingModeRTZFloat64 && !refControls.shaderRoundingModeRTZFloat64) ||
(toCheck.shaderSignedZeroInfNanPreserveFloat64 && !refControls.shaderSignedZeroInfNanPreserveFloat64);
// we checked if required features are not supported - we need to
// negate the result to know if all required features are available
return !requiredFeaturesNotSupported;
}
deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
{
switch(version)
{
case SPIRV_VERSION_1_0:
return VK_API_VERSION_1_0;
case SPIRV_VERSION_1_1:
case SPIRV_VERSION_1_2:
case SPIRV_VERSION_1_3:
return VK_API_VERSION_1_1;
default:
DE_ASSERT(0);
}
return 0u;
}
std::string getVulkanName (const deUint32 version)
{
return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
}
} // SpirVAssembly
} // vkt