if (tiling == VK_IMAGE_TILING_OPTIMAL)
{
- const VkSampleCountFlags requiredSampleCounts = getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
- results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
+ // Vulkan API specification has changed since initial Android Nougat release.
+ // For NYC CTS we need to tolerate old behavior as well and issue compatibility
+ // warning instead.
+ //
+ // See spec issues 272, 282, 302, 445 and CTS issues 369, 440.
+ const bool requiredByNewSpec = (imageType == VK_IMAGE_TYPE_2D && !(curCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
+ ((supportedFeatures & (VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) ||
+ ((supportedFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) && deviceFeatures.shaderStorageImageMultisample)));
+
+ if (requiredByNewSpec)
+ {
+ const VkSampleCountFlags requiredSampleCounts = getRequiredOptimalTilingSampleCounts(deviceLimits, format, curUsageFlags);
+
+ results.check((properties.sampleCounts & requiredSampleCounts) == requiredSampleCounts, "Required sample counts not supported");
+ }
+ else if (properties.sampleCounts != VK_SAMPLE_COUNT_1_BIT)
+ {
+ results.addResult(QP_TEST_RESULT_COMPATIBILITY_WARNING,
+ "Implementation supports more sample counts than allowed by the spec");
+ }
}
else
results.check(properties.sampleCounts == VK_SAMPLE_COUNT_1_BIT, "sampleCounts != VK_SAMPLE_COUNT_1_BIT");
#include "vkQueryUtil.hpp"
#include "vkRefUtil.hpp"
#include "tcuImageCompare.hpp"
+#include "deSTLUtil.hpp"
namespace vkt
{
!isLinearFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat, VK_IMAGE_TILING_OPTIMAL))
throw tcu::NotSupportedError(std::string("Unsupported format for linear filtering: ") + getFormatName(imageFormat));
+ if ((samplerParams.addressModeU == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE ||
+ samplerParams.addressModeV == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE ||
+ samplerParams.addressModeW == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE) &&
+ !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_KHR_sampler_mirror_clamp_to_edge"))
+ TCU_THROW(NotSupportedError, "VK_KHR_sampler_mirror_clamp_to_edge not supported");
+
if (isCompressedFormat(imageFormat) && imageViewType == VK_IMAGE_VIEW_TYPE_3D)
{
// \todo [2016-01-22 pyry] Mandate VK_ERROR_FORMAT_NOT_SUPPORTED
VkPhysicalDevice physicalDevice,
deUint32 queueIndex,
const VkPhysicalDeviceFeatures& enabledFeatures,
+ const vector<string>& enabledExtensions,
const tcu::CommandLine& cmdLine)
{
VkDeviceQueueCreateInfo queueInfo;
VkDeviceCreateInfo deviceInfo;
vector<string> enabledLayers;
vector<const char*> layerPtrs;
+ vector<const char*> extensionPtrs;
const float queuePriority = 1.0f;
deMemset(&queueInfo, 0, sizeof(queueInfo));
for (size_t ndx = 0; ndx < enabledLayers.size(); ++ndx)
layerPtrs[ndx] = enabledLayers[ndx].c_str();
+ extensionPtrs.resize(enabledExtensions.size());
+
+ for (size_t ndx = 0; ndx < enabledExtensions.size(); ++ndx)
+ extensionPtrs[ndx] = enabledExtensions[ndx].c_str();
+
queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
queueInfo.pNext = DE_NULL;
queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
deviceInfo.pNext = DE_NULL;
deviceInfo.queueCreateInfoCount = 1u;
deviceInfo.pQueueCreateInfos = &queueInfo;
- deviceInfo.enabledExtensionCount = 0u;
- deviceInfo.ppEnabledExtensionNames = DE_NULL;
+ deviceInfo.enabledExtensionCount = (deUint32)extensionPtrs.size();
+ deviceInfo.ppEnabledExtensionNames = (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]);
deviceInfo.enabledLayerCount = (deUint32)layerPtrs.size();
deviceInfo.ppEnabledLayerNames = (layerPtrs.empty() ? DE_NULL : &layerPtrs[0]);
deviceInfo.pEnabledFeatures = &enabledFeatures;
VkDevice getDevice (void) const { return *m_device; }
const DeviceInterface& getDeviceInterface (void) const { return m_deviceInterface; }
const VkPhysicalDeviceProperties& getDeviceProperties (void) const { return m_deviceProperties; }
+ const vector<string>& getDeviceExtensions (void) const { return m_deviceExtensions; }
deUint32 getUniversalQueueFamilyIndex (void) const { return m_universalQueueFamilyIndex; }
VkQueue getUniversalQueue (void) const;
private:
static VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures);
+ static vector<string> filterDefaultDeviceExtensions (const vector<VkExtensionProperties>& deviceExtensions);
const Unique<VkInstance> m_instance;
const InstanceDriver m_instanceInterface;
const deUint32 m_universalQueueFamilyIndex;
const VkPhysicalDeviceFeatures m_deviceFeatures;
const VkPhysicalDeviceProperties m_deviceProperties;
+ const vector<string> m_deviceExtensions;
const Unique<VkDevice> m_device;
const DeviceDriver m_deviceInterface;
, m_universalQueueFamilyIndex (findQueueFamilyIndexWithCaps(m_instanceInterface, m_physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_COMPUTE_BIT))
, m_deviceFeatures (filterDefaultDeviceFeatures(getPhysicalDeviceFeatures(m_instanceInterface, m_physicalDevice)))
, m_deviceProperties (getPhysicalDeviceProperties(m_instanceInterface, m_physicalDevice))
- , m_device (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, cmdLine))
+ , m_deviceExtensions (filterDefaultDeviceExtensions(enumerateDeviceExtensionProperties(m_instanceInterface, m_physicalDevice, DE_NULL)))
+ , m_device (createDefaultDevice(m_instanceInterface, m_physicalDevice, m_universalQueueFamilyIndex, m_deviceFeatures, m_deviceExtensions, cmdLine))
, m_deviceInterface (m_instanceInterface, *m_device)
{
}
return enabledDeviceFeatures;
}
+vector<string> DefaultDevice::filterDefaultDeviceExtensions (const vector<VkExtensionProperties>& deviceExtensions)
+{
+ vector<string> enabledExtensions;
+
+ // The only extension we enable always (when supported) is
+ // VK_KHR_sampler_mirror_clamp_to_edge that is defined in
+ // the core spec and supported widely.
+ const char* const mirrorClampToEdgeExt = "VK_KHR_sampler_mirror_clamp_to_edge";
+ if (vk::isExtensionSupported(deviceExtensions, vk::RequiredExtension(mirrorClampToEdgeExt)))
+ enabledExtensions.push_back(mirrorClampToEdgeExt);
+
+ return enabledExtensions;
+}
+
// Allocator utilities
vk::Allocator* createAllocator (DefaultDevice* device)
vk::VkPhysicalDevice Context::getPhysicalDevice (void) const { return m_device->getPhysicalDevice(); }
const vk::VkPhysicalDeviceFeatures& Context::getDeviceFeatures (void) const { return m_device->getDeviceFeatures(); }
const vk::VkPhysicalDeviceProperties& Context::getDeviceProperties (void) const { return m_device->getDeviceProperties(); }
+const vector<string>& Context::getDeviceExtensions (void) const { return m_device->getDeviceExtensions(); }
vk::VkDevice Context::getDevice (void) const { return m_device->getDevice(); }
const vk::DeviceInterface& Context::getDeviceInterface (void) const { return m_device->getDeviceInterface(); }
deUint32 Context::getUniversalQueueFamilyIndex (void) const { return m_device->getUniversalQueueFamilyIndex(); }
vk::VkPhysicalDevice getPhysicalDevice (void) const;
const vk::VkPhysicalDeviceFeatures& getDeviceFeatures (void) const;
const vk::VkPhysicalDeviceProperties& getDeviceProperties (void) const;
+ const std::vector<std::string>& getDeviceExtensions (void) const;
vk::VkDevice getDevice (void) const;
const vk::DeviceInterface& getDeviceInterface (void) const;
deUint32 getUniversalQueueFamilyIndex (void) const;
void GeometryProgramQueryCase::init (void)
{
- if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") && glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+ if (!(m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader") || glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2))))
TCU_THROW(NotSupportedError, "Tests require GL_EXT_geometry_shader extension or higher context version.");
}
{
glw::GLint maxDrawBuffers = -1;
- if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
- throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+ if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+ throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
ctx.beginSection("GL_INVALID_ENUM is generated if mode is not GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MAX or GL_MIN.");
{
glw::GLint maxDrawBuffers = -1;
- if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
- throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+ if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+ throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
ctx.beginSection("GL_INVALID_ENUM is generated if modeRGB is not GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MAX or GL_MIN.");
{
glw::GLint maxDrawBuffers = -1;
- if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
- throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+ if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+ throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
ctx.beginSection("GL_INVALID_ENUM is generated if either sfactor or dfactor is not an accepted value.");
{
glw::GLint maxDrawBuffers = -1;
- if (!glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_KHR_blend_equation_advanced"))
- throw tcu::NotSupportedError("GL_KHR_blend_equation_advanced is not supported", DE_NULL, __FILE__, __LINE__);
+ if (!glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !ctx.getContextInfo().isExtensionSupported("GL_EXT_draw_buffers_indexed"))
+ throw tcu::NotSupportedError("GL_EXT_draw_buffers_indexed is not supported", DE_NULL, __FILE__, __LINE__);
ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
ctx.beginSection("GL_INVALID_ENUM is generated if srcRGB, dstRGB, srcAlpha, or dstAlpha is not an accepted value.");
ctx.glGetProgramiv (srcProgram.getProgram(), GL_LINK_STATUS, &linkStatus);
ctx.getLog() << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
ctx.getLog() << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
- TCU_CHECK(bufSize > 0);
- binaryBuf.resize(bufSize);
- ctx.glGetProgramBinary (srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
- ctx.expectError (GL_NO_ERROR);
- ctx.beginSection("GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
- ctx.glProgramBinary (dummyShader, binaryFormat, &binaryBuf[0], binaryLength);
- ctx.expectError (GL_INVALID_OPERATION);
- ctx.endSection();
+ TCU_CHECK(bufSize >= 0);
+ if (bufSize > 0)
+ {
+ binaryBuf.resize(bufSize);
+ ctx.glGetProgramBinary (srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
+ ctx.expectError (GL_NO_ERROR);
- ctx.beginSection("GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
- ctx.glProgramBinary (dstProgram, -1, &binaryBuf[0], binaryLength);
- ctx.expectError (GL_INVALID_ENUM);
- ctx.endSection();
+ ctx.beginSection("GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
+ ctx.glProgramBinary (dummyShader, binaryFormat, &binaryBuf[0], binaryLength);
+ ctx.expectError (GL_INVALID_OPERATION);
+ ctx.endSection();
+
+ ctx.beginSection("GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
+ ctx.glProgramBinary (dstProgram, -1, &binaryBuf[0], binaryLength);
+ ctx.expectError (GL_INVALID_ENUM);
+ ctx.endSection();
+ }
ctx.glDeleteShader(dummyShader);
ctx.glDeleteProgram(dstProgram);