const std::vector<std::string>& instanceExtensions,
const std::vector<std::string>& deviceExtensions)
{
- VkPhysicalDeviceRobustness2FeaturesEXT* robustness2Features = nullptr;
- VkPhysicalDeviceImageRobustnessFeaturesEXT* imageRobustnessFeatures = nullptr;
+ VkPhysicalDeviceRobustness2FeaturesEXT* robustness2Features = nullptr;
+ VkPhysicalDeviceImageRobustnessFeaturesEXT* imageRobustnessFeatures = nullptr;
+ VkPhysicalDeviceFragmentShadingRateFeaturesKHR* fragmentShadingRateFeatures = nullptr;
+ VkPhysicalDeviceShadingRateImageFeaturesNV* shadingRateImageFeatures = nullptr;
+ VkPhysicalDeviceFragmentDensityMapFeaturesEXT* fragmentDensityMapFeatures = nullptr;
m_coreFeatures2 = initVulkanStructure();
m_vulkan11Features = initVulkanStructure();
featuresToFillFromBlob.push_back(p);
else
{
- if (p->getFeatureDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
- robustness2Features = reinterpret_cast<VkPhysicalDeviceRobustness2FeaturesEXT*>(p->getFeatureTypeRaw());
- else if (p->getFeatureDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)
- imageRobustnessFeatures = reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT*>(p->getFeatureTypeRaw());
+ VkStructureType structType = p->getFeatureDesc().sType;
+ void* rawStructPtr = p->getFeatureTypeRaw();
+
+ if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
+ robustness2Features = reinterpret_cast<VkPhysicalDeviceRobustness2FeaturesEXT*>(rawStructPtr);
+ else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)
+ imageRobustnessFeatures = reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT*>(rawStructPtr);
+ else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR)
+ fragmentShadingRateFeatures = reinterpret_cast<VkPhysicalDeviceFragmentShadingRateFeaturesKHR*>(rawStructPtr);
+ else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV)
+ shadingRateImageFeatures = reinterpret_cast<VkPhysicalDeviceShadingRateImageFeaturesNV*>(rawStructPtr);
+ else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT)
+ fragmentDensityMapFeatures = reinterpret_cast<VkPhysicalDeviceFragmentDensityMapFeaturesEXT*>(rawStructPtr);
// add to chain
- *nextPtr = p->getFeatureTypeRaw();
- nextPtr = p->getFeatureTypeNext();
+ *nextPtr = rawStructPtr;
+ nextPtr = p->getFeatureTypeNext();
}
m_features.push_back(p);
}
imageRobustnessFeatures->robustImageAccess = false;
}
m_coreFeatures2.features.robustBufferAccess = false;
+
+ // Disable VK_EXT_fragment_density_map and VK_NV_shading_rate_image features
+ // that must: not be enabled if KHR fragment shading rate features are enabled.
+ if (fragmentShadingRateFeatures &&
+ (fragmentShadingRateFeatures->pipelineFragmentShadingRate ||
+ fragmentShadingRateFeatures->primitiveFragmentShadingRate ||
+ fragmentShadingRateFeatures->attachmentFragmentShadingRate))
+ {
+ if (shadingRateImageFeatures)
+ shadingRateImageFeatures->shadingRateImage = false;
+ if (fragmentDensityMapFeatures)
+ fragmentDensityMapFeatures->fragmentDensityMap = false;
+ }
}
bool DeviceFeatures::verifyFeatureAddCriteria (const FeatureStructCreationData& item, const std::vector<VkExtensionProperties>& properties)
#include "vktTestGroupUtil.hpp"
#include "vktTestCase.hpp"
+#include "vktCustomInstancesDevices.hpp"
#include "deDefs.h"
#include "deMath.h"
#include "tcuTestCase.hpp"
#include "tcuTestLog.hpp"
+#include "tcuCommandLine.hpp"
#include <string>
#include <sstream>
INT_SHADING_RATE_UNORDERED,
} Interlock;
+de::SharedPtr<Move<vk::VkDevice>> g_singletonDevice;
+
+VkDevice getDevice(Context& context, Interlock interlock)
+{
+ if (interlock == INT_SHADING_RATE_ORDERED || interlock == INT_SHADING_RATE_UNORDERED)
+ {
+ if (!g_singletonDevice)
+ {
+ const float queuePriority = 1.0f;
+
+ // Create a universal queue that supports graphics and compute
+ const VkDeviceQueueCreateInfo queueParams =
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkDeviceQueueCreateFlags flags;
+ context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex;
+ 1u, // deUint32 queueCount;
+ &queuePriority // const float* pQueuePriorities;
+ };
+
+ const char * extensions[] =
+ {
+ "VK_EXT_fragment_shader_interlock",
+ "VK_NV_shading_rate_image",
+ };
+
+ VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT fragmentShaderInterlockFeatures = initVulkanStructure();
+ VkPhysicalDeviceShadingRateImageFeaturesNV shadingRateImageFeatures = initVulkanStructure(&fragmentShaderInterlockFeatures);
+ VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&shadingRateImageFeatures);
+
+ context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
+
+ const VkDeviceCreateInfo deviceCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
+ &features2, //pNext;
+ (VkDeviceCreateFlags)0u, //flags
+ 1, //queueRecordCount;
+ &queueParams, //pRequestedQueues;
+ 0, //layerCount;
+ DE_NULL, //ppEnabledLayerNames;
+ DE_LENGTH_OF_ARRAY(extensions), // deUint32 enabledExtensionCount;
+ extensions, // const char* const* ppEnabledExtensionNames;
+ DE_NULL, //pEnabledFeatures;
+ };
+
+ Move<VkDevice> device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceCreateInfo);
+ g_singletonDevice = de::SharedPtr<Move<VkDevice>>(new Move<VkDevice>(device));
+ }
+
+ return g_singletonDevice->get();
+ }
+
+ return context.getDevice();
+}
+
struct CaseDef
{
deUint32 dim;
TCU_THROW(NotSupportedError, "Fragment shader pixel interlock not supported");
}
- if ((m_data.interlock == INT_SHADING_RATE_ORDERED || m_data.interlock == INT_SHADING_RATE_UNORDERED) &&
- !context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderShadingRateInterlock)
+ if ((m_data.interlock == INT_SHADING_RATE_ORDERED || m_data.interlock == INT_SHADING_RATE_UNORDERED))
{
- TCU_THROW(NotSupportedError, "Fragment shader shading rate interlock not supported");
- }
+ if (!context.getFragmentShaderInterlockFeaturesEXT().fragmentShaderShadingRateInterlock)
+ TCU_THROW(NotSupportedError, "Fragment shader shading rate interlock not supported");
- if ((m_data.interlock == INT_SHADING_RATE_ORDERED || m_data.interlock == INT_SHADING_RATE_UNORDERED) &&
- !context.getShadingRateImageFeatures().shadingRateImage)
- {
- TCU_THROW(NotSupportedError, "Shading rate image not supported");
+ context.requireDeviceFunctionality("VK_NV_shading_rate_image");
+
+ // We need to query the VK_NV_shading_rate_image features because they might be disabled
+ // in the default context due to a conflict with VK_KHR_fragment_shading_rate.
+ VkPhysicalDeviceShadingRateImageFeaturesNV shadingRateImageFeatures = initVulkanStructure();
+ VkPhysicalDeviceFeatures2KHR features2 = initVulkanStructure(&shadingRateImageFeatures);
+
+ context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
+
+ if (!shadingRateImageFeatures.shadingRateImage)
+ TCU_THROW(NotSupportedError, "Shading rate image not supported");
}
}
tcu::TestStatus FSITestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
- const VkDevice device = m_context.getDevice();
+ const VkDevice device = getDevice(m_context, m_data.interlock);
Allocator& allocator = m_context.getDefaultAllocator();
VkFlags allShaderStages = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
VkFlags allPipelineStages = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
flushAlloc(vk, device, buffer->getAllocation());
- const VkQueue queue = m_context.getUniversalQueue();
+ const VkQueue queue = getDeviceQueue(vk, device, m_context.getUniversalQueueFamilyIndex(), 0);
Move<VkCommandPool> cmdPool = createCommandPool(vk, device, 0, m_context.getUniversalQueueFamilyIndex());
Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
return group.release();
}
+void cleanupDevice()
+{
+ g_singletonDevice.clear();
+}
+
} // FragmentShaderInterlock
} // vkt
#include "pipeline/vktPipelineImageUtil.hpp"
#include "deMath.h"
#include "vktTestCase.hpp"
+#include "vktTestGroupUtil.hpp"
+#include "vktCustomInstancesDevices.hpp"
#include "vkImageUtil.hpp"
#include "vkQueryUtil.hpp"
#include "vkCmdUtil.hpp"
#include "vkObjUtil.hpp"
#include "vkBarrierUtil.hpp"
#include "vkBuilderUtil.hpp"
+#include "tcuCommandLine.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTestLog.hpp"
#include <sstream>
#include <vector>
+#include <set>
// Each test generates an image with a color gradient where all colors should be unique when rendered without density map
// ( and for multi_view tests - the quantity of each color in a histogram should be 2 instead of 1 ).
tcu::Vec4 color;
};
+de::SharedPtr<Move<vk::VkDevice>> g_singletonDevice;
+
+static std::vector<std::string> removeExtensions (const std::vector<std::string>& a, const std::vector<const char*>& b)
+{
+ std::vector<std::string> res;
+ std::set<std::string> removeExts (b.begin(), b.end());
+
+ for (std::vector<std::string>::const_iterator aIter = a.begin(); aIter != a.end(); ++aIter)
+ {
+ if (!de::contains(removeExts, *aIter))
+ res.push_back(*aIter);
+ }
+
+ return res;
+}
+
+VkDevice getDevice(Context& context)
+{
+ if (!g_singletonDevice)
+ {
+ const float queuePriority = 1.0f;
+
+ // Create a universal queue that supports graphics and compute
+ const VkDeviceQueueCreateInfo queueParams =
+ {
+ VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
+ DE_NULL, // const void* pNext;
+ 0u, // VkDeviceQueueCreateFlags flags;
+ context.getUniversalQueueFamilyIndex(), // deUint32 queueFamilyIndex;
+ 1u, // deUint32 queueCount;
+ &queuePriority // const float* pQueuePriorities;
+ };
+
+ // \note Extensions in core are not explicitly enabled even though
+ // they are in the extension list advertised to tests.
+ std::vector<const char*> extensionPtrs;
+ std::vector<const char*> coreExtensions;
+ getCoreDeviceExtensions(context.getUsedApiVersion(), coreExtensions);
+ std::vector<std::string> nonCoreExtensions(removeExtensions(context.getDeviceExtensions(), coreExtensions));
+
+ extensionPtrs.resize(nonCoreExtensions.size());
+
+ for (size_t ndx = 0; ndx < nonCoreExtensions.size(); ++ndx)
+ extensionPtrs[ndx] = nonCoreExtensions[ndx].c_str();
+
+ VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures = initVulkanStructure();
+ VkPhysicalDeviceFragmentDensityMap2FeaturesEXT fragmentDensityMap2Features = initVulkanStructure(&fragmentDensityMapFeatures);
+ VkPhysicalDeviceFeatures2 features2 = initVulkanStructure(&fragmentDensityMap2Features);
+
+ context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
+ const VkPhysicalDeviceFeatures2 & feature2ptr = context.getDeviceFeatures2();
+
+ const VkDeviceCreateInfo deviceCreateInfo =
+ {
+ VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, //sType;
+ &feature2ptr, //pNext;
+ (VkDeviceCreateFlags)0u, //flags
+ 1, //queueRecordCount;
+ &queueParams, //pRequestedQueues;
+ 0, //layerCount;
+ DE_NULL, //ppEnabledLayerNames;
+ (deUint32)extensionPtrs.size(), // deUint32 enabledExtensionCount;
+ (extensionPtrs.empty() ? DE_NULL : &extensionPtrs[0]), // const char* const* ppEnabledExtensionNames;
+ DE_NULL, //pEnabledFeatures;
+ };
+
+ Move<VkDevice> device = createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(), context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceCreateInfo);
+ g_singletonDevice = de::SharedPtr<Move<VkDevice>>(new Move<VkDevice>(device));
+ }
+
+ return g_singletonDevice->get();
+}
+
std::vector<Vertex4RGBA> createFullscreenMesh(deUint32 viewCount, tcu::Vec2 redGradient, tcu::Vec2 greenGradient)
{
DE_ASSERT(viewCount > 0);
#else
context.requireDeviceFunctionality("VK_EXT_fragment_density_map");
- const auto& fragmentDensityMapFeatures = context.getFragmentDensityMapFeaturesEXT();
+
+
+ VkPhysicalDeviceFragmentDensityMapFeaturesEXT fragmentDensityMapFeatures = initVulkanStructure();
+ VkPhysicalDeviceFragmentDensityMap2FeaturesEXT fragmentDensityMap2Features = initVulkanStructure(&fragmentDensityMapFeatures);
+ VkPhysicalDeviceFeatures2KHR features2 = initVulkanStructure(&fragmentDensityMap2Features);
+
+ context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
+
const auto& fragmentDensityMap2Properties = context.getFragmentDensityMap2PropertiesEXT();
if (!fragmentDensityMapFeatures.fragmentDensityMap)
if (m_testParams.deferredDensityMap)
{
context.requireDeviceFunctionality("VK_EXT_fragment_density_map2");
- if (!context.getFragmentDensityMap2FeaturesEXT().fragmentDensityMapDeferred)
+ if (!fragmentDensityMap2Features.fragmentDensityMapDeferred)
TCU_THROW(NotSupportedError, "fragmentDensityMapDeferred feature is not supported");
}
if (m_testParams.subsampledLoads)
m_viewMask = (m_testParams.viewCount > 1) ? ((1u << m_testParams.viewCount) - 1u) : 0u;
const DeviceInterface& vk = m_context.getDeviceInterface();
- const VkDevice vkDevice = m_context.getDevice();
+ const VkDevice vkDevice = getDevice(m_context);
const VkPhysicalDevice vkPhysicalDevice = m_context.getPhysicalDevice();
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ const VkQueue queue = getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), vkPhysicalDevice));
const VkComponentMapping componentMappingRGBA = makeComponentMappingRGBA();
copyBufferToImage
(
- vk, vkDevice, m_context.getUniversalQueue(), queueFamilyIndex,
+ vk, vkDevice, queue, queueFamilyIndex,
*stagingBuffer, stagingBufferSize,
densityMapImageSize, densityMapImageLayers, **m_densityMapImages[mapIndex]
);
tcu::TestStatus FragmentDensityMapTestInstance::iterate (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
- const VkDevice vkDevice = m_context.getDevice();
- const VkQueue queue = m_context.getUniversalQueue();
+ const VkDevice vkDevice = getDevice(m_context);
+ const VkQueue queue = getDeviceQueue(vk, vkDevice, m_context.getUniversalQueueFamilyIndex(), 0);
submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
tcu::TestStatus FragmentDensityMapTestInstance::verifyImage (void)
{
const DeviceInterface& vk = m_context.getDeviceInterface();
- const VkDevice vkDevice = m_context.getDevice();
- const VkQueue queue = m_context.getUniversalQueue();
+ const VkDevice vkDevice = getDevice(m_context);
const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
+ const VkQueue queue = getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
tcu::UVec2 renderSize (m_renderSize.x(), m_renderSize.y());
de::UniquePtr<tcu::TextureLevel> outputImage (pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_outputImage, VK_FORMAT_R8G8B8A8_UNORM, renderSize).release());
} // anonymous
-tcu::TestCaseGroup* createFragmentDensityMapTests (tcu::TestContext& testCtx)
+static void createChildren (tcu::TestCaseGroup* fdmTests)
{
- de::MovePtr<tcu::TestCaseGroup> fdmTests(new tcu::TestCaseGroup(testCtx, "fragment_density_map", "VK_EXT_fragment_density_map and VK_EXT_fragment_density_map2 extensions tests"));
+ tcu::TestContext& testCtx = fdmTests->getTestContext();
const struct
{
params.coarseReconstruction = true;
propertiesGroup->addChild(new FragmentDensityMapTest(testCtx, "subsampled_coarse_reconstruction", "", params));
fdmTests->addChild(propertiesGroup.release());
+}
- return fdmTests.release();
+static void cleanupGroup (tcu::TestCaseGroup* group)
+{
+ DE_UNREF(group);
+ // Destroy singleton objects.
+ g_singletonDevice.clear();
+}
+
+tcu::TestCaseGroup* createFragmentDensityMapTests (tcu::TestContext& testCtx)
+{
+ return createTestGroup(testCtx, "fragment_density_map", "VK_EXT_fragment_density_map and VK_EXT_fragment_density_map2 extensions tests", createChildren, cleanupGroup);
}
} // renderpass