Early support check for tests (part 1)
authorAri Suonpaa <ari.suonpaa@siru.fi>
Thu, 6 Jun 2019 12:14:36 +0000 (15:14 +0300)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Sun, 16 Jun 2019 18:16:48 +0000 (14:16 -0400)
Moved feature and extension checks into checkSupport function
which gets called before initPrograms. This speeds up the
test execution in case a test is not supported.

This change is divided into multiple parts to avoid touching
all test groups at once.

Affects:

dEQP-VK.rasterization.*
dEQP-VK.protected_memory.*
dEQP-VK.sparse_resources.*
dEQP-VK.api.*
dEQP-VK.conditional_rendering.*
dEQP-VK.descriptor_indexing.*
dEQP-VK.device_group.*
dEQP-VK.draw.*

Components: Vulkan, Framework

VK-GL-CTS issue: 1786
Change-Id: Ib8ff54e501a843b346ac15c037e0e46e1eed2a24

46 files changed:
external/vulkancts/modules/vulkan/api/vktApiDriverPropertiesTests.cpp
external/vulkancts/modules/vulkan/api/vktApiImageClearingTests.cpp
external/vulkancts/modules/vulkan/api/vktApiMaintenance3Check.cpp
external/vulkancts/modules/vulkan/binding_model/vktBindingBufferDeviceAddressTests.cpp
external/vulkancts/modules/vulkan/conditional_rendering/vktConditionalDrawAndClearTests.cpp
external/vulkancts/modules/vulkan/descriptor_indexing/vktDescriptorSetsIndexingTests.cpp
external/vulkancts/modules/vulkan/draw/vktBasicDrawTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawDiscardRectanglesTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawIndirectTest.cpp
external/vulkancts/modules/vulkan/draw/vktDrawInstancedTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawInvertedDepthRangesTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawMultipleInterpolationTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawNegativeViewportHeightTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawScissorTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawShaderDrawParametersTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawShaderLayerTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawShaderViewportIndexTests.cpp
external/vulkancts/modules/vulkan/draw/vktDrawTestCaseUtil.hpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemAttachmentClearTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemAttachmentLoadTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemBlitImageTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemClearColorImageTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemCopyBufferToImageTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemCopyImageTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemCopyImageToBufferTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemFillUpdateCopyBufferTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemShaderImageAccessTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemStorageBufferTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemUtils.hpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWorkgroupStorageTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemWsiSwapchainTests.cpp
external/vulkancts/modules/vulkan/protected_memory/vktProtectedMemYCbCrConversionTests.cpp
external/vulkancts/modules/vulkan/rasterization/vktRasterizationTests.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferMemoryAliasing.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferSparseBinding.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesBufferTests.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageAlignedMipSize.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageBlockShapes.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageMemoryAliasing.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesImageSparseBinding.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesMipmapSparseResidency.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesQueueBindSparseTests.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.cpp
external/vulkancts/modules/vulkan/sparse_resources/vktSparseResourcesShaderIntrinsicsBase.hpp
external/vulkancts/modules/vulkan/vktTestCaseUtil.hpp

index 03ec94e..f81a9d6 100644 (file)
@@ -82,13 +82,13 @@ DE_INLINE bool operator==(const VkConformanceVersionKHR& a, const VkConformanceV
                        (a.patch == b.patch));
 }
 
-tcu::TestStatus testQueryProperties (Context& context)
+void checkSupport (Context& context)
 {
-       // Check extension support
-
-       if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_driver_properties"))
-               TCU_THROW(NotSupportedError, "Unsupported extension: VK_KHR_driver_properties");
+       context.requireDeviceExtension("VK_KHR_driver_properties");
+}
 
+tcu::TestStatus testQueryProperties (Context& context)
+{
        // Query the driver properties
 
        const VkPhysicalDevice                          physDevice                      = context.getPhysicalDevice();
@@ -151,7 +151,7 @@ tcu::TestStatus testQueryProperties (Context& context)
 
 void createTestCases (tcu::TestCaseGroup* group)
 {
-       addFunctionCase(group, "properties", "Query VkPhysicalDeviceDriverPropertiesKHR and check its values", testQueryProperties);
+       addFunctionCase(group, "properties", "Query VkPhysicalDeviceDriverPropertiesKHR and check its values", checkSupport, testQueryProperties);
 }
 
 } // anonymous
index 2729a22..b89394f 100644 (file)
@@ -574,10 +574,7 @@ ImageClearingTestInstance::ImageClearingTestInstance (Context& context, const Te
        , m_frameBuffer                         (m_isAttachmentFormat ? createFrameBuffer(*m_imageView, *m_renderPass, params.imageExtent.width, params.imageExtent.height, params.imageViewLayerRange.layerCount) : vk::Move<vk::VkFramebuffer>())
 {
        if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
-       {
-               if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_dedicated_allocation"))
-                       TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
-       }
+               context.requireDeviceExtension("VK_KHR_dedicated_allocation");
 }
 
 ImageClearingTestInstance::ViewType ImageClearingTestInstance::getViewType (deUint32 imageLayerCount) const
index 67694ef..9cccad0 100644 (file)
@@ -47,15 +47,6 @@ typedef vk::VkPhysicalDeviceProperties DevProp1;
 typedef vk::VkPhysicalDeviceProperties2  DevProp2;
 typedef vk::VkPhysicalDeviceMaintenance3Properties MainDevProp3;
 
-
-void                                                                           checkSupport                                                    (const Context& m_context)
-{
-       const vector<string>                                    extensions                                                              = m_context.getDeviceExtensions();
-
-       if (!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_maintenance3"))
-               TCU_THROW(NotSupportedError, "VK_KHR_maintenance3 extension is not supported");
-}
-
 class Maintenance3StructTestInstance : public TestInstance
 {
 public:
@@ -64,7 +55,6 @@ public:
        {}
        virtual tcu::TestStatus                                 iterate                                                                 (void)
        {
-               checkSupport(m_context);
                tcu::TestLog&                                           log                                                                             = m_context.getTestContext().getLog();
 
                // these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
@@ -108,6 +98,10 @@ public:
 
        virtual                                                                 ~Maintenance3StructTestCase                             (void)
        {}
+       virtual void                                                    checkSupport                                                    (Context&       ctx) const
+       {
+               ctx.requireDeviceExtension("VK_KHR_maintenance3");
+       }
        virtual TestInstance*                                   createInstance                                                  (Context&       ctx) const
        {
                return new Maintenance3StructTestInstance(ctx);
@@ -124,8 +118,6 @@ public:
        {}
        virtual tcu::TestStatus                                 iterate                                                                 (void)
        {
-               checkSupport(m_context);
-
                // these variables are equal to minimal values for maxMemoryAllocationSize and maxPerSetDescriptors
                const deUint32                                          maxMemoryAllocationSize                                 = 1073741824u;
                const deUint32                                          maxDescriptorsInSet                                             = 1024u;
@@ -279,6 +271,10 @@ public:
        {}
        virtual                                                                 ~Maintenance3DescriptorTestCase                 (void)
        {}
+       virtual void                                                    checkSupport                                                    (Context&       ctx) const
+       {
+               ctx.requireDeviceExtension("VK_KHR_maintenance3");
+       }
        virtual TestInstance*                                   createInstance                                                  (Context&       ctx) const
        {
                return new Maintenance3DescriptorTestInstance(ctx);
index df4d52b..ed95cbb 100644 (file)
@@ -102,12 +102,12 @@ struct CaseDef
 class BufferAddressTestInstance : public TestInstance
 {
 public:
-                                               BufferAddressTestInstance               (Context& context, const CaseDef& data);
+                                               BufferAddressTestInstance       (Context& context, const CaseDef& data);
                                                ~BufferAddressTestInstance      (void);
-       tcu::TestStatus         iterate                                                         (void);
-       virtual void                            fillBuffer                                      (const std::vector<deUint8 *>& cpuAddrs,
-                                                                                                                        const std::vector<deUint64>& gpuAddrs,
-                                                                                                                        deUint32 bufNum, deUint32 curDepth) const;
+       tcu::TestStatus         iterate                                         (void);
+       virtual void            fillBuffer                                      (const std::vector<deUint8 *>& cpuAddrs,
+                                                                                                        const std::vector<deUint64>& gpuAddrs,
+                                                                                                        deUint32 bufNum, deUint32 curDepth) const;
 private:
        CaseDef                         m_data;
 
@@ -131,12 +131,12 @@ BufferAddressTestInstance::~BufferAddressTestInstance (void)
 class BufferAddressTestCase : public TestCase
 {
        public:
-                                                               BufferAddressTestCase           (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
-                                                               ~BufferAddressTestCase  (void);
-       virtual void                            initPrograms                                    (SourceCollections& programCollection) const;
-       virtual TestInstance*           createInstance                                  (Context& context) const;
-       virtual void                            checkSupport                                    (Context& context) const;
-       virtual void                            checkBuffer                                     (std::stringstream& checks, deUint32 bufNum, deUint32 curDepth, const std::string &prefix) const;
+                                                       BufferAddressTestCase   (tcu::TestContext& context, const char* name, const char* desc, const CaseDef data);
+                                                       ~BufferAddressTestCase  (void);
+       virtual void                    initPrograms                    (SourceCollections& programCollection) const;
+       virtual TestInstance*   createInstance                  (Context& context) const;
+       virtual void                    checkSupport                    (Context& context) const;
+       virtual void                    checkBuffer                             (std::stringstream& checks, deUint32 bufNum, deUint32 curDepth, const std::string &prefix) const;
 
 private:
        CaseDef                                 m_data;
@@ -152,13 +152,13 @@ BufferAddressTestCase::~BufferAddressTestCase     (void)
 {
 }
 
-void BufferAddressTestCase::checkSupport(Context& context) const
+void BufferAddressTestCase::checkSupport (Context& context) const
 {
        if (!context.getBufferDeviceAddressFeatures().bufferDeviceAddress)
                TCU_THROW(NotSupportedError, "Physical storage buffer pointers not supported");
 
        if (m_data.stage == STAGE_VERTEX && !context.getDeviceFeatures().vertexPipelineStoresAndAtomics)
-               return TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
+               TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
 
        if (m_data.set >= context.getDeviceProperties().limits.maxBoundDescriptorSets)
                TCU_THROW(NotSupportedError, "descriptor set number not supported");
@@ -173,7 +173,9 @@ void BufferAddressTestCase::checkSupport(Context& context) const
 #if ENABLE_RAYTRACING
        if (m_data.stage == STAGE_RAYGEN &&
                !isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_NV_ray_tracing"))
-               return TCU_THROW(NotSupportedError, "Ray tracing not supported");
+       {
+               TCU_THROW(NotSupportedError, "Ray tracing not supported");
+       }
 #endif
 }
 
index 93c8574..721d4a7 100644 (file)
@@ -295,8 +295,6 @@ ConditionalRenderingBaseTestInstance::ConditionalRenderingBaseTestInstance (Cont
        , m_physicalDevice                              (m_context.getPhysicalDevice())
        , m_queue                                               (m_context.getUniversalQueue())
 {
-       if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_conditional_rendering"))
-               TCU_THROW(NotSupportedError, "VK_EXT_conditional_rendering is not supported");
 }
 
 void ConditionalRenderingBaseTestInstance::createInitBufferWithPredicate (bool discard, bool invert, deUint32 offsetMultiplier = 0, VkBufferUsageFlagBits extraUsage = (VkBufferUsageFlagBits)0)
@@ -1352,6 +1350,11 @@ struct AddProgramsUpdateBufferUsingRendering
        }
 };
 
+void checkSupport (Context& context)
+{
+       context.requireDeviceExtension("VK_EXT_conditional_rendering");
+}
+
 } // unnamed namespace
 
 ConditionalRenderingDrawAndClearTests::ConditionalRenderingDrawAndClearTests (tcu::TestContext &testCtx)
@@ -1362,32 +1365,28 @@ ConditionalRenderingDrawAndClearTests::ConditionalRenderingDrawAndClearTests (tc
 
 void ConditionalRenderingDrawAndClearTests::init (void)
 {
-       tcu::TestCaseGroup*             clear                   = new tcu::TestCaseGroup(m_testCtx, "clear", "Tests using vkCmdClearAttachments.");
-       tcu::TestCaseGroup*             color                   = new tcu::TestCaseGroup(m_testCtx, "color", "Test color clear.");
-       tcu::TestCaseGroup*             depth                   = new tcu::TestCaseGroup(m_testCtx, "depth", "Test depth clear.");
-       tcu::TestCaseGroup*             draw                    = new tcu::TestCaseGroup(m_testCtx, "draw", "Test drawing.");
+       tcu::TestCaseGroup*     clear   = new tcu::TestCaseGroup(m_testCtx, "clear", "Tests using vkCmdClearAttachments.");
+       tcu::TestCaseGroup*     color   = new tcu::TestCaseGroup(m_testCtx, "color", "Test color clear.");
+       tcu::TestCaseGroup*     depth   = new tcu::TestCaseGroup(m_testCtx, "depth", "Test depth clear.");
+       tcu::TestCaseGroup*     draw    = new tcu::TestCaseGroup(m_testCtx, "draw", "Test drawing.");
 
        for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearColorTestGrid); testNdx++)
-               color->addChild(new InstanceFactory1<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, generateClearTestName(clearColorTestGrid[testNdx]),
-                                                                                                                                                                                                                               "Color clear test.", clearColorTestGrid[testNdx]));
+               color->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, generateClearTestName(clearColorTestGrid[testNdx]), "Color clear test.", clearColorTestGrid[testNdx], checkSupport));
 
        for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearDepthTestGrid); testNdx++)
-               depth->addChild(new InstanceFactory1<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, generateClearTestName(clearDepthTestGrid[testNdx]),
-                                                                                                                                                                                                                               "Depth clear test.", clearDepthTestGrid[testNdx]));
+               depth->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, generateClearTestName(clearDepthTestGrid[testNdx]), "Depth clear test.", clearDepthTestGrid[testNdx], checkSupport));
 
        for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearColorTwiceGrid); testNdx++)
-               color->addChild(new InstanceFactory1<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "clear_attachment_twice_" + generateClearTestName(clearColorTwiceGrid[testNdx]),
-                                                                                                                                                                                                                               "Color clear test.", clearColorTwiceGrid[testNdx]));
+               color->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "clear_attachment_twice_" + generateClearTestName(clearColorTwiceGrid[testNdx]), "Color clear test.", clearColorTwiceGrid[testNdx], checkSupport));
 
        for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearDepthTwiceGrid); testNdx++)
-               depth->addChild(new InstanceFactory1<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "clear_attachment_twice_" + generateClearTestName(clearDepthTwiceGrid[testNdx]),
-                                                                                                                                                                                                                               "Depth clear test.", clearDepthTwiceGrid[testNdx]));
+               depth->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance, ClearTestParams, FunctionSupport0>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "clear_attachment_twice_" + generateClearTestName(clearDepthTwiceGrid[testNdx]), "Depth clear test.", clearDepthTwiceGrid[testNdx], checkSupport));
 
        for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(drawTestGrid); testNdx++)
-               draw->addChild(new InstanceFactory1<ConditionalRenderingDrawTestInstance, DrawTestParams, AddProgramsDraw>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "case_" + de::toString(testNdx), "Draw test.", AddProgramsDraw(), drawTestGrid[testNdx]));
+               draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingDrawTestInstance, DrawTestParams, FunctionSupport0, AddProgramsDraw>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "case_" + de::toString(testNdx), "Draw test.", AddProgramsDraw(), drawTestGrid[testNdx], checkSupport));
 
-       draw->addChild(new InstanceFactory1<ConditionalRenderingUpdateBufferWithDrawTestInstance, bool, AddProgramsUpdateBufferUsingRendering>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "update_with_rendering_no_discard", "Draw test.", AddProgramsUpdateBufferUsingRendering(), true));
-       draw->addChild(new InstanceFactory1<ConditionalRenderingUpdateBufferWithDrawTestInstance, bool, AddProgramsUpdateBufferUsingRendering>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "update_with_rendering_discard", "Draw test.", AddProgramsUpdateBufferUsingRendering(), false));
+       draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingUpdateBufferWithDrawTestInstance, bool, FunctionSupport0, AddProgramsUpdateBufferUsingRendering>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "update_with_rendering_no_discard", "Draw test.", AddProgramsUpdateBufferUsingRendering(), true, checkSupport));
+       draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingUpdateBufferWithDrawTestInstance, bool, FunctionSupport0, AddProgramsUpdateBufferUsingRendering>(m_testCtx, tcu::NODETYPE_SELF_VALIDATE, "update_with_rendering_discard", "Draw test.", AddProgramsUpdateBufferUsingRendering(), false, checkSupport));
 
        clear->addChild(color);
        clear->addChild(depth);
index afd7b77..aaa64a2 100644 (file)
@@ -220,8 +220,6 @@ public:
                                                                CommonDescriptorInstance                (Context&                                                                       context,
                                                                                                                                const TestParams&                                                       testParams);
 
-       void                                            checkIndexingAvailable                  (const ut::DeviceProperties&                            devProps) const;
-
        deUint32                                        computeAvailableDescriptorCount (VkDescriptorType                                                       descriptorType) const;
 
        Move<VkDescriptorSetLayout>     createDescriptorSetLayout               (deUint32&                                                                      descriptorCount) const;
@@ -520,12 +518,6 @@ CommonDescriptorInstance::CommonDescriptorInstance                                 (Context&                                                               context,
 {
 }
 
-void CommonDescriptorInstance::checkIndexingAvailable                          (const ut::DeviceProperties&                    devProps) const
-{
-       DE_UNREF(devProps);
-       m_context.requireDeviceExtension("VK_EXT_descriptor_indexing");
-}
-
 deUint32 CommonDescriptorInstance::computeAvailableDescriptorCount     (VkDescriptorType                                               descriptorType) const
 {
        DE_UNREF(descriptorType);
@@ -1813,20 +1805,6 @@ StorageBufferInstance::StorageBufferInstance                                             (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT&        feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
-
-       if (m_testParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingStorageBufferUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
-       }
 }
 
 void StorageBufferInstance::createAndPopulateDescriptors                       (IterateCommonVariables&                                        variables)
@@ -1902,20 +1880,6 @@ UniformBufferInstance::UniformBufferInstance                                             (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
-
-       if (m_testParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingUniformBufferUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
-       }
 }
 
 void UniformBufferInstance::createAndPopulateDescriptors                       (IterateCommonVariables&                                        variables)
@@ -1961,20 +1925,6 @@ StorageTexelInstance::StorageTexelInstance                                                       (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
-
-       if (m_testParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingStorageTexelBufferUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
-       }
 }
 
 void StorageTexelInstance::createAndPopulateDescriptors                        (IterateCommonVariables&                                        variables)
@@ -2039,20 +1989,6 @@ UniformTexelInstance::UniformTexelInstance                                                       (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
-
-       if (m_testParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingUniformTexelBufferUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
-       }
 }
 
 void UniformTexelInstance::createAndPopulateDescriptors                                (IterateCommonVariables&                                        variables)
@@ -2205,19 +2141,6 @@ DynamicStorageBufferInstance::DynamicStorageBufferInstance                       (Context&                                       conte
                        testCaseParams)),
                        DynamicBuffersInstance(context, m_testParams), StorageBufferInstance(context, testCaseParams)
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
-       }
 }
 
 tcu::TestStatus        DynamicStorageBufferInstance::iterate(void)
@@ -2263,19 +2186,6 @@ DynamicUniformBufferInstance::DynamicUniformBufferInstance                       (Context&                                       conte
                        testCaseParams)),
                        DynamicBuffersInstance(context, m_testParams), UniformBufferInstance(context, testCaseParams)
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
-       }
 }
 
 tcu::TestStatus DynamicUniformBufferInstance::iterate(void)
@@ -2318,19 +2228,6 @@ InputAttachmentInstance::InputAttachmentInstance                                 (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-
-       if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
-       }
 }
 
 void InputAttachmentInstance::createAndPopulateDescriptors                     (IterateCommonVariables&                                        variables)
@@ -2466,21 +2363,6 @@ SamplerInstance::SamplerInstance                                                                 (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-       // Note: common flags for SAMPLER, SAMPLED_IMAGE, COMBINED_IMAGE_SAMPLER
-
-       if (!(feats.shaderSampledImageArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingSampledImageUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
-       }
 }
 
 void SamplerInstance::updateDescriptors                                                                (IterateCommonVariables&                                        variables)
@@ -2594,21 +2476,6 @@ SampledImageInstance::SampledImageInstance                                                       (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-       // Note: common flags for SAMPLER, SAMPLED_IMAGE, COMBINED_IMAGE_SAMPLER
-
-       if (!(feats.shaderSampledImageArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingSampledImageUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
-       }
 }
 
 void SampledImageInstance::updateDescriptors                                           (IterateCommonVariables&                                        variables)
@@ -2724,21 +2591,6 @@ CombinedImageInstance::CombinedImageInstance                                             (Context&                                                                       context,
                        performWritesInVertex(testCaseParams.descriptorType),
                        testCaseParams))
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT&    feats = dp.descriptorIndexingFeatures();
-       // Note: common flags for SAMPLER, SAMPLED_IMAGE, COMBINED_IMAGE_SAMPLER
-
-       if (!(feats.shaderSampledImageArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               if (!(feats.descriptorBindingSampledImageUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
-       }
 }
 
 void CombinedImageInstance::updateDescriptors                                          (IterateCommonVariables&                                        variables)
@@ -2861,20 +2713,6 @@ StorageImageInstance::StorageImageInstance                                                       (Context&                                                                       context,
        , m_buffer              ()
        , m_fillColor   (10)
 {
-       ut::DeviceProperties dp(context);
-
-       checkIndexingAvailable(dp);
-
-       const VkPhysicalDeviceDescriptorIndexingFeaturesEXT& features = dp.descriptorIndexingFeatures();
-
-       if (!(features.shaderStorageImageArrayNonUniformIndexing))
-               TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
-
-       if (testCaseParams.updateAfterBind)
-       {
-               if (!(features.descriptorBindingStorageImageUpdateAfterBind))
-                       TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
-       }
 }
 
 void StorageImageInstance::updateDescriptors                                           (IterateCommonVariables&                                        variables)
@@ -3022,13 +2860,13 @@ class DescriptorIndexingTestCase : public TestCase
 {
        const TestCaseParams m_testCaseParams;
 public:
-       DescriptorIndexingTestCase(tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
+       DescriptorIndexingTestCase (tcu::TestContext &context, const char *name, const char *description, const TestCaseParams& testCaseParams)
                : TestCase(context, name, description)
                , m_testCaseParams(testCaseParams)
        {
        }
 
-       vkt::TestInstance* createInstance(vkt::Context& context) const // override
+       vkt::TestInstance* createInstance (vkt::Context& context) const // override
        {
                switch (m_testCaseParams.descriptorType)
                {
@@ -3060,7 +2898,98 @@ public:
                return DE_NULL;
        }
 
-       virtual void initPrograms(SourceCollections& programCollection) const
+       virtual void checkSupport (vkt::Context& context) const
+       {
+               context.requireDeviceExtension("VK_EXT_descriptor_indexing");
+
+               const vk::VkPhysicalDeviceDescriptorIndexingFeaturesEXT& feats = context.getDescriptorIndexingFeatures();
+
+               switch (m_testCaseParams.descriptorType)
+               {
+               case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
+                       if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageBufferUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for storage buffer descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
+                       if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform buffer descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformBufferUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for uniform buffer descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
+                       if (!(feats.shaderStorageTexelBufferArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing for storage texel buffer descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageTexelBufferUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for storage texel buffer descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
+                       if (!(feats.shaderUniformTexelBufferArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing for uniform texel buffer descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingUniformTexelBufferUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for uniform texel buffer descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
+                       if (!(feats.shaderStorageBufferArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over storage buffer dynamic descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for storage buffer dynamic descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
+                       if (!(feats.shaderUniformBufferArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over uniform buffer dynamic descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for uniform buffer dynamic descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
+                       if (!(feats.shaderInputAttachmentArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over input attachment descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for input attachment descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_SAMPLER:
+                       if (!(feats.shaderSampledImageArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over sampler descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for sampler descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
+                       if (!(feats.shaderSampledImageArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over sampled image descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for sampled image descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
+                       if (!(feats.shaderSampledImageArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over combined image sampler descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingSampledImageUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for combined image sampler descriptors is not supported.");
+                       break;
+               case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
+                       if (!(feats.shaderStorageImageArrayNonUniformIndexing))
+                               TCU_THROW(NotSupportedError, "Non-uniform indexing over storage image descriptor arrays is not supported.");
+
+                       if (m_testCaseParams.updateAfterBind && !feats.descriptorBindingStorageImageUpdateAfterBind)
+                               TCU_THROW(NotSupportedError, "Update after bind for storage image descriptors is not supported.");
+                       break;
+               default:
+                       DE_FATAL("Unknown Descriptor Type");
+                       break;
+               }
+       }
+
+       virtual void initPrograms (SourceCollections& programCollection) const
        {
                std::string(*genShaderSource)(VkShaderStageFlagBits, const TestCaseParams&, bool) = &CommonDescriptorInstance::getShaderSource;
 
index c220ff6..997d865 100644 (file)
@@ -322,18 +322,6 @@ void DrawTestInstanceBase::initialize (const DrawParamsBase& data)
        const vk::VkDevice      device                          = m_context.getDevice();
        const deUint32          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
 
-       const vk::VkPhysicalDeviceFeatures features = m_context.getDeviceFeatures();
-
-       if (features.geometryShader == VK_FALSE &&
-               (m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ||
-                m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
-                m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ||
-                m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY)
-               )
-       {
-               TCU_THROW(NotSupportedError, "Geometry Not Supported");
-       }
-
        const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
        m_pipelineLayout                                                = vk::createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo);
 
@@ -551,6 +539,7 @@ class DrawTestCase : public TestCase
                                                                        ~DrawTestCase           (void);
        virtual void                                    initPrograms            (vk::SourceCollections& programCollection) const;
        virtual void                                    initShaderSources       (void);
+       virtual void                                    checkSupport            (Context& context) const;
        virtual TestInstance*                   createInstance          (Context& context) const;
 
 private:
@@ -580,6 +569,18 @@ void DrawTestCase<T>::initPrograms (vk::SourceCollections& programCollection) co
 }
 
 template<typename T>
+void DrawTestCase<T>::checkSupport (Context& context) const
+{
+       if (m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY ||
+               m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
+               m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY ||
+               m_data.topology == vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY)
+       {
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
+       }
+}
+
+template<typename T>
 void DrawTestCase<T>::initShaderSources (void)
 {
        std::stringstream vertShader;
index 3f3588f..aed04ca 100644 (file)
@@ -655,8 +655,6 @@ tcu::TestStatus DiscardRectanglesTestInstance::iterate      (void)
 
        // Check for VK_EXT_discard_rectangles support and maximum number of active discard rectangles
        {
-               m_context.requireDeviceExtension("VK_EXT_discard_rectangles");
-
                VkPhysicalDeviceDiscardRectanglePropertiesEXT discardRectangleProperties;
                deMemset(&discardRectangleProperties, 0, sizeof(VkPhysicalDeviceDiscardRectanglePropertiesEXT));
                discardRectangleProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT;
@@ -801,6 +799,7 @@ public:
 
        virtual TestInstance*           createInstance                          (Context& context)      const;
        virtual void                            initPrograms                            (SourceCollections& programCollection) const;
+       virtual void                            checkSupport                            (Context& context) const;
 
 private:
        const TestParams                        m_params;
@@ -853,18 +852,23 @@ void DiscardRectanglesTestCase::initPrograms(SourceCollections& programCollectio
        }
 }
 
-vkt::TestInstance* DiscardRectanglesTestCase::createInstance (vkt::Context& context) const
+void DiscardRectanglesTestCase::checkSupport (Context& context) const
+{
+       context.requireDeviceExtension("VK_EXT_discard_rectangles");
+}
+
+TestInstance* DiscardRectanglesTestCase::createInstance (Context& context) const
 {
        return new DiscardRectanglesTestInstance(context, m_params);
 }
 
 void createTests (tcu::TestCaseGroup* testGroup)
 {
-       tcu::TestContext&       testCtx                         = testGroup->getTestContext();
-       deUint32                numRect [NUM_RECT_TESTS]        = { 1, 2, 3, 4,  8, 16};
-       std::string             modeName [TEST_MODE_COUNT]      = { "inclusive_", "exclusive_" };
-       std::string             scissorName [TEST_SCISSOR_MODE_COUNT]   = { "", "scissor_", "dynamic_scissor_" };
-       std::string             dynamicName [NUM_DYNAMIC_DISCARD_TYPE_TESTS]    = { "", "dynamic_discard_" };
+       tcu::TestContext&       testCtx                                                                                 = testGroup->getTestContext();
+       deUint32                        numRect [NUM_RECT_TESTS]                                                = { 1, 2, 3, 4,  8, 16};
+       std::string                     modeName [TEST_MODE_COUNT]                                              = { "inclusive_", "exclusive_" };
+       std::string                     scissorName [TEST_SCISSOR_MODE_COUNT]                   = { "", "scissor_", "dynamic_scissor_" };
+       std::string                     dynamicName [NUM_DYNAMIC_DISCARD_TYPE_TESTS]    = { "", "dynamic_discard_" };
 
        for (deUint32 dynamic = 0 ; dynamic < NUM_DYNAMIC_DISCARD_TYPE_TESTS; dynamic++)
        {
index cc28bec..f1877da 100644 (file)
@@ -244,9 +244,6 @@ IndirectDraw::IndirectDraw (Context &context, TestSpec testSpec)
        , m_drawType                                            (testSpec.drawType)
        , m_testFirstInstanceNdx                        (testSpec.testFirstInstanceNdx)
 {
-       if (m_testIndirectCountExt && !vk::isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_draw_indirect_count"))
-               TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_draw_indirect_count");
-
        if (m_testFirstInstanceNdx)
                setFirstInstanceVertexBuffer();
        else
@@ -920,6 +917,11 @@ tcu::TestStatus IndirectDrawInstanced<FirstInstanceSupport>::iterate (void)
        return tcu::TestStatus(res, qpGetTestResultName(res));
 }
 
+void checkIndirectCountExt (Context& context)
+{
+       context.requireDeviceExtension("VK_KHR_draw_indirect_count");
+}
+
 }      // anonymous
 
 IndirectDrawTests::IndirectDrawTests (tcu::TestContext& testCtx)
@@ -964,9 +966,9 @@ void IndirectDrawTests::init (void)
 
                                testSpec.testIndirectCountExt = true;
                                testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-                               indirectDrawCountGroup->addChild(new InstanceFactory<IndirectDraw>(m_testCtx, "triangle_list", "Draws triangle list", testSpec));
+                               indirectDrawCountGroup->addChild(new InstanceFactory<IndirectDraw, FunctionSupport0>(m_testCtx, "triangle_list", "Draws triangle list", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
-                               indirectDrawCountGroup->addChild(new InstanceFactory<IndirectDraw>(m_testCtx, "triangle_strip", "Draws triangle strip", testSpec));
+                               indirectDrawCountGroup->addChild(new InstanceFactory<IndirectDraw, FunctionSupport0>(m_testCtx, "triangle_strip", "Draws triangle strip", testSpec, FunctionSupport0(checkIndirectCountExt)));
                        }
                        drawTypeGroup->addChild(indirectDrawGroup);
                        drawTypeGroup->addChild(indirectDrawCountGroup);
@@ -987,9 +989,9 @@ void IndirectDrawTests::init (void)
 
                                        testSpec.testIndirectCountExt = true;
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDraw>(m_testCtx, "triangle_list", "Draws triangle list", testSpec));
+                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDraw, FunctionSupport0>(m_testCtx, "triangle_list", "Draws triangle list", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
-                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDraw>(m_testCtx, "triangle_strip", "Draws triangle strip", testSpec));
+                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDraw, FunctionSupport0>(m_testCtx, "triangle_strip", "Draws triangle strip", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                }
                                drawTypeGroup->addChild(indirectDrawFirstInstanceGroup);
                                drawTypeGroup->addChild(indirectDrawCountFirstInstanceGroup);
@@ -1011,12 +1013,11 @@ void IndirectDrawTests::init (void)
                                        indirectDrawNoFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceNotSupported> >(m_testCtx, "triangle_list", "Draws an instanced triangle list", testSpec));
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
                                        indirectDrawNoFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceNotSupported> >(m_testCtx, "triangle_strip", "Draws an instanced triangle strip", testSpec));
-
                                        testSpec.testIndirectCountExt = true;
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-                                       indirectDrawCountNoFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceNotSupported> >(m_testCtx, "triangle_list", "Draws an instanced triangle list", testSpec));
+                                       indirectDrawCountNoFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceNotSupported>, FunctionSupport0>(m_testCtx, "triangle_list", "Draws an instanced triangle list", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
-                                       indirectDrawCountNoFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceNotSupported> >(m_testCtx, "triangle_strip", "Draws an instanced triangle strip", testSpec));
+                                       indirectDrawCountNoFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceNotSupported>, FunctionSupport0>(m_testCtx, "triangle_strip", "Draws an instanced triangle strip", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                }
                                indirectDrawInstancedGroup->addChild(indirectDrawNoFirstInstanceGroup);
                                indirectDrawCountInstancedGroup->addChild(indirectDrawCountNoFirstInstanceGroup);
@@ -1037,9 +1038,9 @@ void IndirectDrawTests::init (void)
 
                                        testSpec.testIndirectCountExt = true;
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
-                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceSupported> >(m_testCtx, "triangle_list", "Draws an instanced triangle list", testSpec));
+                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceSupported>, FunctionSupport0>(m_testCtx, "triangle_list", "Draws an instanced triangle list", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                        testSpec.topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
-                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceSupported> >(m_testCtx, "triangle_strip", "Draws an instanced triangle strip", testSpec));
+                                       indirectDrawCountFirstInstanceGroup->addChild(new InstanceFactory<IndirectDrawInstanced<FirstInstanceSupported>, FunctionSupport0>(m_testCtx, "triangle_strip", "Draws an instanced triangle strip", testSpec, FunctionSupport0(checkIndirectCountExt)));
                                }
                                indirectDrawInstancedGroup->addChild(indirectDrawFirstInstanceGroup);
                                indirectDrawCountInstancedGroup->addChild(indirectDrawCountFirstInstanceGroup);
index 0805c81..e459779 100644 (file)
@@ -286,33 +286,38 @@ public:
                                "}\n";
        }
 
-       TestInstance* createInstance (Context& context) const
+       virtual void    checkSupport    (Context& context) const
        {
                if (m_params.testAttribDivisor)
                {
+                       context.requireDeviceExtension("VK_EXT_vertex_attribute_divisor");
+
                        const vk::VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT& vertexAttributeDivisorFeatures = context.getVertexAttributeDivisorFeatures();
-                       if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_vertex_attribute_divisor"))
-                               TCU_THROW(NotSupportedError, "Implementation does not support VK_EXT_vertex_attribute_divisor");
 
                        if (m_params.attribDivisor != 1 && !vertexAttributeDivisorFeatures.vertexAttributeInstanceRateDivisor)
                                TCU_THROW(NotSupportedError, "Implementation does not support vertexAttributeInstanceRateDivisor");
 
                        if (m_params.attribDivisor == 0 && !vertexAttributeDivisorFeatures.vertexAttributeInstanceRateZeroDivisor)
                                TCU_THROW(NotSupportedError, "Implementation does not support vertexAttributeInstanceRateDivisorZero");
+
                        if (m_params.testMultiview)
                        {
-                               if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_multiview"))
-                                       TCU_THROW(NotSupportedError, "Implementation does not support VK_KHR_multiview");
+                               context.requireDeviceExtension("VK_KHR_multiview");
+
                                const vk::VkPhysicalDeviceMultiviewFeatures& multiviewFeatures = context.getMultiviewFeatures();
+
                                if (!multiviewFeatures.multiview)
                                        TCU_THROW(NotSupportedError, "Implementation does not support multiview feature");
                        }
                }
+       }
 
+       TestInstance*   createInstance  (Context& context) const
+       {
                return new InstancedDrawInstance(context, m_params);
        }
 
-       virtual void initPrograms (vk::SourceCollections& programCollection) const
+       virtual void    initPrograms    (vk::SourceCollections& programCollection) const
        {
                programCollection.glslSources.add("InstancedDrawVert") << glu::VertexSource(m_vertexShader);
                programCollection.glslSources.add("InstancedDrawFrag") << glu::FragmentSource(m_fragmentShader);
index 0dcf9aa..2ce792d 100644 (file)
@@ -87,18 +87,6 @@ InvertedDepthRangesTestInstance::InvertedDepthRangesTestInstance (Context& conte
        const DeviceInterface&  vk              = m_context.getDeviceInterface();
        const VkDevice                  device  = m_context.getDevice();
 
-       if (m_params.depthClampEnable && !m_context.getDeviceFeatures().depthClamp)
-               TCU_THROW(NotSupportedError, "DepthClamp device feature not supported.");
-
-       if (params.minDepth > 1.0f      ||
-               params.minDepth < 0.0f  ||
-               params.maxDepth > 1.0f  ||
-               params.maxDepth < 0.0f)
-       {
-               if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_depth_range_unrestricted"))
-                       throw tcu::NotSupportedError("Test variant with minDepth/maxDepth outside 0..1 requires the VK_EXT_depth_range_unrestricted extension");
-       }
-
        // Vertex data
        {
                std::vector<Vec4> vertexData;
@@ -400,6 +388,15 @@ public:
                }
        }
 
+       virtual void checkSupport (Context& context) const
+       {
+               if (m_params.depthClampEnable)
+                       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DEPTH_CLAMP);
+
+               if (m_params.minDepth > 1.0f || m_params.minDepth < 0.0f || m_params.maxDepth > 1.0f || m_params.maxDepth < 0.0f)
+                       context.requireDeviceExtension("VK_EXT_depth_range_unrestricted");
+       }
+
        virtual TestInstance* createInstance (Context& context) const
        {
                return new InvertedDepthRangesTestInstance(context, m_params);
index a38f63c..20fd272 100644 (file)
@@ -108,6 +108,7 @@ public:
                                                                                         const DrawParams       params);
                                                        ~DrawTestCase   (void);
        virtual void                    initPrograms    (vk::SourceCollections& programCollection) const;
+       virtual void                    checkSupport    (Context& context) const;
        virtual TestInstance*   createInstance  (Context& context) const;
 private:
        const DrawParams                m_params;
@@ -204,15 +205,14 @@ void DrawTestCase::initPrograms (vk::SourceCollections& programCollection) const
        programCollection.glslSources.add("frag_centroid")              << glu::FragmentSource(fragShader_single.specialize(centroid));
 }
 
-TestInstance* DrawTestCase::createInstance (Context& context) const
+void DrawTestCase::checkSupport (Context& context) const
 {
-       const vk::InstanceInterface&            vki             = context.getInstanceInterface();
-       const vk::VkPhysicalDevice                      device  = context.getPhysicalDevice();
-       const vk::VkPhysicalDeviceLimits        limits  = getPhysicalDeviceProperties(vki, device).limits;
-
-       if (!(m_params.samples & limits.framebufferColorSampleCounts))
+       if (!(m_params.samples & context.getDeviceProperties().limits.framebufferColorSampleCounts))
                throw tcu::NotSupportedError("Multisampling with " + de::toString(m_params.samples) + " samples not supported");
+}
 
+TestInstance* DrawTestCase::createInstance (Context& context) const
+{
        return new DrawTestInstance(context, m_params);
 }
 
index b38a741..5571350 100644 (file)
@@ -397,11 +397,6 @@ std::string getCullModeStr (const VkCullModeFlagBits cullMode)
 
 tcu::TestStatus NegativeViewportHeightTestInstance::iterate (void)
 {
-       // Check requirements
-
-       if(!isDeviceExtensionSupported(m_context.getUsedApiVersion(), m_context.getDeviceExtensions(), "VK_KHR_maintenance1"))
-               TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_maintenance1");
-
        // Set up the viewport and draw
 
        const VkViewport viewport =
@@ -503,6 +498,11 @@ public:
                }
        }
 
+       virtual void checkSupport (Context& context) const
+       {
+               context.requireDeviceExtension("VK_KHR_maintenance1");
+       }
+
        virtual TestInstance* createInstance (Context& context) const
        {
                return new NegativeViewportHeightTestInstance(context, m_params);
index c4b8f8b..05ecb6a 100644 (file)
@@ -276,6 +276,7 @@ class ScissorTestCase : public TestCase
                                                        ~ScissorTestCase        (void);
        virtual void                    initPrograms            (SourceCollections& programCollection) const;
        virtual TestInstance*   createInstance          (Context& context) const;
+       virtual void                    checkSupport            (Context& context) const;
 
 private:
        TestParams                              m_params;
@@ -296,6 +297,15 @@ ScissorTestCase::~ScissorTestCase (void)
 {
 }
 
+void ScissorTestCase::checkSupport (Context& context) const
+{
+       if (m_params.usesMultipleScissors)
+       {
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_VIEWPORT);
+       }
+}
+
 void ScissorTestCase::initPrograms (SourceCollections& programCollection) const
 {
        programCollection.glslSources.add("vert") << glu::VertexSource(
@@ -353,7 +363,6 @@ TestStatus ScissorTestInstance::iterate (void)
        TestLog&                                                log                                             = m_context.getTestContext().getLog();
        const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
        const VkDevice                                  device                                  = m_context.getDevice();
-       const VkPhysicalDeviceFeatures  features                                = getPhysicalDeviceFeatures(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
        const CmdPoolCreateInfo                 cmdPoolCreateInfo               (m_context.getUniversalQueueFamilyIndex());
        Move<VkCommandPool>                             cmdPool                                 = createCommandPool(vk, device, &cmdPoolCreateInfo);
        Move<VkCommandBuffer>                   cmdBuffer                               = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
@@ -370,15 +379,7 @@ TestStatus ScissorTestInstance::iterate (void)
        TextureLevel                                    refImage;
 
        if (m_params.usesMultipleScissors)
-       {
-               if (!features.geometryShader)
-                       throw NotSupportedError("Geometry shader not supported");
-
-               if (!features.multiViewport)
-                       throw NotSupportedError("Multi viewport not supported");
-
                gs = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0);
-       }
 
        // Create color buffer image
        {
index 83050e5..100b46b 100644 (file)
@@ -109,44 +109,6 @@ DrawTest::DrawTest (Context &context, TestSpec testSpec)
        DE_ASSERT(!isMultiDraw()     || isIndirect());
        DE_ASSERT(!isFirstInstance() || (isIndirect() && isInstanced()));
 
-       // Requirements
-       {
-               if (!vk::isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_shader_draw_parameters"))
-                       TCU_THROW(NotSupportedError, "Missing extension: VK_KHR_shader_draw_parameters");
-
-               // Shader draw parameters is part of Vulkan 1.1 but is optional
-               if ( context.contextSupports(vk::ApiVersion(1, 1, 0)) )
-               {
-                       // Check if shader draw parameters is supported on the physical device.
-                       vk::VkPhysicalDeviceShaderDrawParametersFeatures        drawParameters =
-                       {
-                               vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,  // sType
-                               DE_NULL,                                                                                                                                // pNext
-                               VK_FALSE                                                                                                                                // shaderDrawParameters
-                       };
-                       vk::VkPhysicalDeviceFeatures                                    features;
-                       deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
-
-                       vk::VkPhysicalDeviceFeatures2                                   featuresExt             =
-                       {
-                               vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,                                       // sType
-                               &drawParameters,                                                                                                        // pNext
-                               features
-                       };
-
-                       context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &featuresExt);
-
-                       if (drawParameters.shaderDrawParameters == VK_FALSE)
-                               TCU_THROW(NotSupportedError, "shaderDrawParameters feature not supported by the device");
-               }
-
-               if (isMultiDraw() && !m_context.getDeviceFeatures().multiDrawIndirect)
-                       TCU_THROW(NotSupportedError, "Missing feature: multiDrawIndirect");
-
-               if (isFirstInstance() && !m_context.getDeviceFeatures().drawIndirectFirstInstance)
-                       TCU_THROW(NotSupportedError, "Missing feature: drawIndirectFirstInstance");
-       }
-
        // Vertex data
        {
                int refIndex = NDX_FIRST_VERTEX - OFFSET_FIRST_INDEX;
@@ -349,6 +311,44 @@ tcu::TestStatus DrawTest::iterate (void)
        }
 }
 
+void checkSupport (Context& context, TestFlags flags)
+{
+       context.requireDeviceExtension("VK_KHR_shader_draw_parameters");
+
+       // Shader draw parameters is part of Vulkan 1.1 but is optional
+       if (context.contextSupports(vk::ApiVersion(1, 1, 0)) )
+       {
+               // Check if shader draw parameters is supported on the physical device.
+               vk::VkPhysicalDeviceShaderDrawParametersFeatures        drawParameters  =
+               {
+                       vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES,  // sType
+                       DE_NULL,                                                                                                                                // pNext
+                       VK_FALSE                                                                                                                                // shaderDrawParameters
+               };
+
+               vk::VkPhysicalDeviceFeatures                                            features;
+               deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
+
+               vk::VkPhysicalDeviceFeatures2                                           featuresExt             =
+               {
+                       vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,                                       // sType
+                       &drawParameters,                                                                                                        // pNext
+                       features
+               };
+
+               context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &featuresExt);
+
+               if (drawParameters.shaderDrawParameters == VK_FALSE)
+                       TCU_THROW(NotSupportedError, "shaderDrawParameters feature not supported by the device");
+       }
+
+       if (flags & TEST_FLAG_MULTIDRAW)
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_DRAW_INDIRECT);
+
+       if (flags & TEST_FLAG_FIRST_INSTANCE)
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_DRAW_INDIRECT_FIRST_INSTANCE);
+}
+
 void addDrawCase (tcu::TestCaseGroup* group, const DrawTest::TestSpec testSpec, const TestFlags flags)
 {
        std::ostringstream name;
@@ -359,7 +359,7 @@ void addDrawCase (tcu::TestCaseGroup* group, const DrawTest::TestSpec testSpec,
        if (flags & TEST_FLAG_INSTANCED)                name << "_instanced";
        if (flags & TEST_FLAG_FIRST_INSTANCE)   name << "_first_instance";
 
-       group->addChild(new InstanceFactory<DrawTest>(group->getTestContext(), name.str(), "", addFlags(testSpec, flags)));
+       group->addChild(new InstanceFactory<DrawTest, FunctionSupport1<TestFlags>>(group->getTestContext(), name.str(), "", addFlags(testSpec, flags), FunctionSupport1<TestFlags>::Args(checkSupport, flags)));
 }
 
 }      // anonymous
index 8e1cd42..ea15401 100644 (file)
@@ -755,29 +755,22 @@ private:
        Renderer&       operator=       (const Renderer&);
 };
 
-void checkRequirements (const Context& context)
+void checkRequirements (Context& context, const int)
 {
-       const VkPhysicalDeviceFeatures  features                = getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
-       const VkPhysicalDeviceLimits    limits                  = getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits;
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_VIEWPORT);
+       context.requireDeviceExtension("VK_EXT_shader_viewport_index_layer");
 
-       if (!features.multiViewport)
-               TCU_THROW(NotSupportedError, "Required feature is not supported: multiViewport");
+       const VkPhysicalDeviceLimits    limits  = context.getDeviceProperties().limits;
 
        if (limits.maxFramebufferLayers < MIN_MAX_FRAMEBUFFER_LAYERS)
                TCU_FAIL("maxFramebuffersLayers is less than the minimum required");
 
        if (limits.maxViewports < MIN_MAX_VIEWPORTS)
                TCU_FAIL("multiViewport supported but maxViewports is less than the minimum required");
-
-       const std::vector<std::string>& extensions              = context.getDeviceExtensions();
-       if (!isDeviceExtensionSupported(context.getUsedApiVersion(), extensions, "VK_EXT_shader_viewport_index_layer"))
-               TCU_THROW(NotSupportedError, "Extension VK_EXT_shader_viewport_index_layer not supported");
 }
 
 tcu::TestStatus testVertexShader (Context& context, const int numLayers)
 {
-       checkRequirements(context);
-
        const DeviceInterface&                                  vk                                      = context.getDeviceInterface();
        const VkDevice                                                  device                          = context.getDevice();
        Allocator&                                                              allocator                       = context.getDefaultAllocator();
@@ -834,8 +827,6 @@ tcu::TestStatus testVertexShader (Context& context, const int numLayers)
 
 tcu::TestStatus testTessellationShader (Context& context, const int numLayers)
 {
-       checkRequirements(context);
-
        const VkPhysicalDeviceFeatures&                 features                        = context.getDeviceFeatures();
        if (!features.tessellationShader)
                TCU_THROW(NotSupportedError, "Required feature is not supported: tessellationShader");
@@ -915,13 +906,13 @@ tcu::TestCaseGroup* createShaderLayerTests        (tcu::TestContext& testCtx)
        for (int i = 0; i < DE_LENGTH_OF_ARRAY(numLayersToTest); ++i)
        {
                int numLayers = numLayersToTest[i];
-               addFunctionCaseWithPrograms(group.get(), "vertex_shader_" + de::toString(numLayers), "", initVertexTestPrograms, testVertexShader, numLayers);
+               addFunctionCaseWithPrograms(group.get(), "vertex_shader_" + de::toString(numLayers), "", checkRequirements, initVertexTestPrograms, testVertexShader, numLayers);
        }
 
        for (int i = 0; i < DE_LENGTH_OF_ARRAY(numLayersToTest); ++i)
        {
                int numLayers = numLayersToTest[i];
-               addFunctionCaseWithPrograms(group.get(), "tessellation_shader_" + de::toString(numLayers), "", initTessellationTestPrograms, testTessellationShader, numLayers);
+               addFunctionCaseWithPrograms(group.get(), "tessellation_shader_" + de::toString(numLayers), "", checkRequirements, initTessellationTestPrograms, testTessellationShader, numLayers);
        }
 
        return group.release();
index 4d298e1..c6829ca 100644 (file)
@@ -743,27 +743,8 @@ private:
        Renderer&       operator=       (const Renderer&);
 };
 
-void requireShaderViewportIndexLayer (const Context& context)
-{
-       const VkPhysicalDeviceFeatures  features        = getPhysicalDeviceFeatures(context.getInstanceInterface(), context.getPhysicalDevice());
-       const VkPhysicalDeviceLimits    limits          = getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits;
-
-       if (!features.multiViewport)
-               TCU_THROW(NotSupportedError, "Required feature is not supported: multiViewport");
-
-       if (limits.maxViewports < MIN_MAX_VIEWPORTS)
-               TCU_FAIL("multiViewport supported but maxViewports is less than the minimum required");
-
-       const std::vector<std::string>&         extensions      = context.getDeviceExtensions();
-       if (!isDeviceExtensionSupported(context.getUsedApiVersion(), extensions, "VK_EXT_shader_viewport_index_layer"))
-               TCU_THROW(NotSupportedError, "Extension VK_EXT_shader_viewport_index_layer not supported");
-
-}
-
 tcu::TestStatus testVertexShader (Context& context, const int numViewports)
 {
-       requireShaderViewportIndexLayer(context);
-
        const DeviceInterface&                  vk                                      = context.getDeviceInterface();
        const VkDevice                                  device                          = context.getDevice();
        Allocator&                                              allocator                       = context.getDefaultAllocator();
@@ -815,12 +796,6 @@ tcu::TestStatus testVertexShader (Context& context, const int numViewports)
 
 tcu::TestStatus testTessellationShader (Context& context, const int numViewports)
 {
-       requireShaderViewportIndexLayer(context);
-
-       const VkPhysicalDeviceFeatures&         features        = context.getDeviceFeatures();
-       if (!features.tessellationShader)
-               TCU_THROW(NotSupportedError, "Required feature is not supported: tessellationShader");
-
        const DeviceInterface&                  vk                                      = context.getDeviceInterface();
        const VkDevice                                  device                          = context.getDevice();
        Allocator&                                              allocator                       = context.getDefaultAllocator();
@@ -870,6 +845,21 @@ tcu::TestStatus testTessellationShader (Context& context, const int numViewports
        return tcu::TestStatus::pass("OK");
 }
 
+void checkSupportVertex (Context& context, const int)
+{
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_MULTI_VIEWPORT);
+       context.requireDeviceExtension("VK_EXT_shader_viewport_index_layer");
+
+       if (context.getDeviceProperties().limits.maxViewports < MIN_MAX_VIEWPORTS)
+               TCU_FAIL("multiViewport supported but maxViewports is less than the minimum required");
+}
+
+void checkSupportTessellation (Context& context, const int)
+{
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
+
+       checkSupportVertex(context, 0);
+}
 
 } // anonymous
 
@@ -878,10 +868,10 @@ tcu::TestCaseGroup* createShaderViewportIndexTests        (tcu::TestContext& testCtx)
        MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "shader_viewport_index", ""));
 
        for (int numViewports = 1; numViewports <= MIN_MAX_VIEWPORTS; ++numViewports)
-               addFunctionCaseWithPrograms(group.get(), "vertex_shader_" + de::toString(numViewports), "", initVertexTestPrograms, testVertexShader, numViewports);
+               addFunctionCaseWithPrograms(group.get(), "vertex_shader_" + de::toString(numViewports), "", checkSupportVertex, initVertexTestPrograms, testVertexShader, numViewports);
 
        for (int numViewports = 1; numViewports <= MIN_MAX_VIEWPORTS; ++numViewports)
-               addFunctionCaseWithPrograms(group.get(), "tessellation_shader_" + de::toString(numViewports), "", initTessellationTestPrograms, testTessellationShader, numViewports);
+               addFunctionCaseWithPrograms(group.get(), "tessellation_shader_" + de::toString(numViewports), "", checkSupportTessellation, initTessellationTestPrograms, testTessellationShader, numViewports);
 
        return group.release();
 }
index 0731327..fd71f1f 100644 (file)
@@ -50,22 +50,30 @@ struct TestSpecBase
        vk::VkPrimitiveTopology topology;
 };
 
-template<typename Instance>
+template<typename Instance, typename Support = NoSupport0>
 class InstanceFactory : public TestCase
 {
 public:
        InstanceFactory (tcu::TestContext& testCtx, const std::string& name, const std::string& desc, typename Instance::TestSpec testSpec)
                : TestCase              (testCtx, name, desc)
                , m_testSpec    (testSpec)
+               , m_support             ()
        {
        }
 
-       TestInstance* createInstance (Context& context) const
+       InstanceFactory (tcu::TestContext& testCtx, const std::string& name, const std::string& desc, typename Instance::TestSpec testSpec, const Support& support)
+               : TestCase              (testCtx, name, desc)
+               , m_testSpec    (testSpec)
+               , m_support             (support)
+       {
+       }
+
+       TestInstance*   createInstance  (Context& context) const
        {
                return new Instance(context, m_testSpec);
        }
 
-       virtual void initPrograms (vk::SourceCollections& programCollection) const
+       virtual void    initPrograms    (vk::SourceCollections& programCollection) const
        {
                for (ShaderMap::const_iterator i = m_testSpec.shaders.begin(); i != m_testSpec.shaders.end(); ++i)
                {
@@ -74,8 +82,14 @@ public:
                }
        }
 
+       virtual void    checkSupport    (Context& context) const
+       {
+               m_support.checkSupport(context);
+       }
+
 private:
-       const typename Instance::TestSpec m_testSpec;
+       const typename Instance::TestSpec       m_testSpec;
+       const Support                                           m_support;
 };
 
 } // Draw
index cb6eb6c..fc6f7fd 100644 (file)
@@ -96,6 +96,10 @@ public:
                                                        {
                                                                m_validator.initPrograms(programCollection);
                                                        }
+       virtual void                    checkSupport                            (Context& context) const
+                                                       {
+                                                               checkProtectedQueueSupport(context);
+                                                       }
 private:
        vk::VkClearValue                m_clearValue;
        ValidationData                  m_refData;
index cf3a45f..fb5dfd2 100644 (file)
@@ -93,6 +93,10 @@ public:
                                                        {
                                                                m_validator.initPrograms(programCollection);
                                                        }
+       virtual void                    checkSupport                            (Context& context) const
+                                                       {
+                                                               checkProtectedQueueSupport(context);
+                                                       }
 private:
        vk::VkClearValue                m_clearValue;
        ValidationData                  m_refData;
index 1568031..9b18eff 100644 (file)
@@ -95,6 +95,10 @@ public:
                                                                {
                                                                        m_validator.initPrograms(programCollection);
                                                                }
+       virtual void                            checkSupport                            (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 private:
        vk::VkClearColorValue           m_clearColorValue;
        ValidationData                          m_refData;
index 823a7b7..c331501 100644 (file)
@@ -95,6 +95,10 @@ public:
                                                                {
                                                                        m_validator.initPrograms(programCollection);
                                                                }
+       virtual void                            checkSupport                            (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 private:
        vk::VkClearColorValue           m_clearColorValue;
        ValidationData                          m_refData;
index c93db6d..495e7f9 100644 (file)
@@ -97,6 +97,10 @@ public:
                                                                {
                                                                        m_validator.initPrograms(programCollection);
                                                                }
+       virtual void                            checkSupport                            (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 private:
        deUint32                                        m_fillValue;
        ValidationData                          m_refData;
index 85b4635..87d3d84 100644 (file)
@@ -95,6 +95,10 @@ public:
                                                                {
                                                                        m_validator.initPrograms(programCollection);
                                                                }
+       virtual void                            checkSupport                    (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 private:
        vk::VkClearColorValue           m_clearColorValue;
        ValidationData                          m_refData;
index 4afde53..1dedf15 100644 (file)
@@ -99,6 +99,10 @@ public:
                                                        {
                                                                m_validator.initPrograms(programCollection);
                                                        }
+       virtual void                    checkSupport                            (Context& context) const
+                                                       {
+                                                               checkProtectedQueueSupport(context);
+                                                       }
 private:
        vk::VkClearColorValue   m_fillValue;
        BufferValidator<T>              m_validator;
index 4616b04..d9211b5 100644 (file)
@@ -117,6 +117,10 @@ public:
                                                        {
                                                                m_validator.initPrograms(programCollection);
                                                        }
+       virtual void                    checkSupport                                    (Context& context) const
+                                                       {
+                                                               checkProtectedQueueSupport(context);
+                                                       }
 private:
        deUint32                                m_fillValue;
        BufferValidator<T>              m_validator;
index e645e5d..ae53934 100644 (file)
@@ -261,6 +261,10 @@ public:
                                                                        return new ImageAccessTestInstance(ctx, m_validator, m_params);
                                                                }
        virtual void                            initPrograms                    (vk::SourceCollections& programCollection) const;
+       virtual void                            checkSupport                    (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 
 private:
        ImageValidator                          m_validator;
index ae944b8..6d1980e 100644 (file)
@@ -216,6 +216,10 @@ public:
                                                                        return new StorageBufferTestInstance<T>(ctx, m_testType, m_shaderType, m_testInput, m_validator);
                                                                }
        virtual void                            initPrograms                    (vk::SourceCollections& programCollection) const;
+       virtual void                            checkSupport                    (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 
        virtual                                         ~StorageBufferTestCase  (void) {}
 
index 8b4339d..4288cc4 100644 (file)
@@ -111,6 +111,30 @@ vk::Move<vk::VkInstance> makeProtectedMemInstance (const vk::PlatformInterface&
        return vk::createDefaultInstance(vkp, context.getUsedApiVersion(), enabledLayers, requiredExtensions);
 }
 
+void checkProtectedQueueSupport (Context& context)
+{
+#ifdef NOT_PROTECTED
+       return;
+#endif
+
+       const vk::InstanceInterface&                            vkd                             = context.getInstanceInterface();
+       vk::VkPhysicalDevice                                            physDevice              = context.getPhysicalDevice();
+       std::vector<vk::VkQueueFamilyProperties>        properties;
+       deUint32                                                                        numFamilies             = 0;
+
+       vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, DE_NULL);
+       DE_ASSERT(numFamilies > 0);
+       properties.resize(numFamilies);
+
+       vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, properties.data());
+
+       for (auto prop: properties)
+               if (prop.queueFlags & vk::VK_QUEUE_PROTECTED_BIT)
+                       return;
+
+       TCU_THROW(NotSupportedError, "No protected queue found.");
+}
+
 deUint32 chooseProtectedMemQueueFamilyIndex    (const vk::InstanceDriver&      vkd,
                                                                                         vk::VkPhysicalDevice           physicalDevice,
                                                                                         vk::VkSurfaceKHR                       surface)
index 22f3590..10039ce 100644 (file)
@@ -55,6 +55,8 @@ enum ProtectionMode {
 typedef std::vector<vk::VkVertexInputBindingDescription>       VertexBindings;
 typedef std::vector<vk::VkVertexInputAttributeDescription>     VertexAttribs;
 
+void                                                           checkProtectedQueueSupport                      (Context& context);
+
 vk::Move<vk::VkInstance>                       makeProtectedMemInstance                        (const vk::PlatformInterface&           vkp,
                                                                                                                                                 const vkt::Context&                            context,
                                                                                                                                                 const std::vector<std::string>&        extraExtensions = std::vector<std::string>());
index 8c9c516..156c626 100644 (file)
@@ -123,6 +123,10 @@ public:
                                                                        return new WorkgroupStorageTestInstance(ctx, m_validator, m_params);
                                                                }
        virtual void                            initPrograms                            (vk::SourceCollections& programCollection) const;
+       virtual void                            checkSupport                            (Context& context) const
+                                                               {
+                                                                       checkProtectedQueueSupport(context);
+                                                               }
 
 private:
        ImageValidator                          m_validator;
index f7d7a05..87ad96e 100644 (file)
@@ -739,13 +739,18 @@ struct GroupParameters
        {}
 };
 
+void checkSupport (Context& context, TestParameters)
+{
+       checkProtectedQueueSupport(context);
+}
+
 void populateSwapchainGroup (tcu::TestCaseGroup* testGroup, GroupParameters params)
 {
        for (int dimensionNdx = 0; dimensionNdx < TEST_DIMENSION_LAST; ++dimensionNdx)
        {
                const TestDimension             testDimension   = (TestDimension)dimensionNdx;
 
-               addFunctionCase(testGroup, getTestDimensionName(testDimension), "", params.function, TestParameters(params.wsiType, testDimension));
+               addFunctionCase(testGroup, getTestDimensionName(testDimension), "", checkSupport, params.function, TestParameters(params.wsiType, testDimension));
        }
 }
 
@@ -1270,9 +1275,14 @@ void getBasicRenderPrograms (vk::SourceCollections& dst, vk::wsi::Type)
        TriangleRenderer::getPrograms(dst);
 }
 
+void checkSupport (Context& context, vk::wsi::Type)
+{
+       checkProtectedQueueSupport(context);
+}
+
 void populateRenderGroup (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
 {
-       addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Test", getBasicRenderPrograms, basicRenderTest, wsiType);
+       addFunctionCaseWithPrograms(testGroup, "basic", "Basic Rendering Test", checkSupport, getBasicRenderPrograms, basicRenderTest, wsiType);
 }
 
 void createSwapchainTests (tcu::TestCaseGroup* testGroup, vk::wsi::Type wsiType)
index d5158f2..c0547e6 100644 (file)
@@ -149,6 +149,10 @@ struct TestConfig
        vk::VkComponentMapping                                  componentMapping;
 };
 
+void checkSupport (Context& context, const TestConfig)
+{
+       checkProtectedQueueSupport(context);
+}
 
 void validateFormatSupport (ProtectedContext& context, TestConfig& config)
 {
@@ -1454,6 +1458,7 @@ tcu::TestCaseGroup*       createYCbCrConversionTests (tcu::TestContext& testCtx)
                                                        addFunctionCaseWithPrograms(colorRangeGroup.get(),
                                                                                                                std::string(tilingName) + "_" + chromaOffsetName + (disjoint ? "_disjoint" : ""),
                                                                                                                "",
+                                                                                                               checkSupport,
                                                                                                                testShaders,
                                                                                                                conversionTest,
                                                                                                                config);
index 7677fd6..84ec9ac 100644 (file)
@@ -949,9 +949,6 @@ BaseLineTestInstance::BaseLineTestInstance (Context& context, VkPrimitiveTopolog
 {
        DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
 
-       if (!context.getDeviceProperties().limits.strictLines)
-               TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
-
        // create line widths
        if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
        {
@@ -959,16 +956,11 @@ BaseLineTestInstance::BaseLineTestInstance (Context& context, VkPrimitiveTopolog
        }
        else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
        {
-               if (!m_context.getDeviceFeatures().wideLines)
-                       TCU_THROW(NotSupportedError , "wide line support required");
-
                const float*    range = context.getDeviceProperties().limits.lineWidthRange;
 
                m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
 
-               // no wide line support
-               if (range[1] <= 1.0f)
-                       TCU_THROW(NotSupportedError, "wide line support required");
+               DE_ASSERT(range[1] > 1.0f);
 
                // set hand picked sizes
                m_lineWidths.push_back(5.0f);
@@ -1076,16 +1068,11 @@ PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness widene
        }
        else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
        {
-               if (!m_context.getDeviceFeatures().largePoints)
-                       TCU_THROW(NotSupportedError , "large point support required");
-
                const float*    range = context.getDeviceProperties().limits.pointSizeRange;
 
                m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
 
-               // no wide line support
-               if (range[1] <= 1.0f)
-                       TCU_THROW(NotSupportedError , "wide point support required");
+               DE_ASSERT(range[1] > 1.0f);
 
                // set hand picked sizes
                m_pointSizes.push_back(10.0f);
@@ -1225,10 +1212,6 @@ public:
        virtual TestInstance*   createInstance          (Context& context) const
                                                        {
                                                                VkPhysicalDeviceProperties      properties      (context.getDeviceProperties());
-                                                               VkPhysicalDeviceFeatures        features        (context.getDeviceFeatures());
-
-                                                               if (!features.largePoints)
-                                                                       TCU_THROW(NotSupportedError , "largePoints feature required");
 
                                                                if (m_renderSize > properties.limits.maxViewportDimensions[0] || m_renderSize > properties.limits.maxViewportDimensions[1])
                                                                        TCU_THROW(NotSupportedError , "Viewport dimensions not supported");
@@ -1238,6 +1221,11 @@ public:
 
                                                                return new ConcreteTestInstance(context, m_renderSize, m_pointSize);
                                                        }
+
+       virtual void                    checkSupport            (Context& context) const
+                                                       {
+                                                               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
+                                                       }
 protected:
        const float                             m_pointSize;
        const deUint32                  m_renderSize;
@@ -1748,17 +1736,36 @@ template <typename ConcreteTestInstance>
 class WidenessTestCase : public BaseRenderingTestCase
 {
 public:
-                                                               WidenessTestCase        (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
+                                                               WidenessTestCase        (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, bool isLineTest, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
                                                                        : BaseRenderingTestCase(context, name, description, sampleCount)
-                                                                       , m_wideness(wideness)
+                                                                       , m_wideness    (wideness)
+                                                                       , m_isLineTest  (isLineTest)
                                                                {}
 
        virtual TestInstance*           createInstance          (Context& context) const
                                                                {
                                                                        return new ConcreteTestInstance(context, m_wideness, m_sampleCount);
                                                                }
+
+       virtual void                            checkSupport            (Context& context) const
+                                                               {
+                                                                       if (m_isLineTest)
+                                                                       {
+                                                                               if (!context.getDeviceProperties().limits.strictLines)
+                                                                                       TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
+
+                                                                               if (m_wideness == PRIMITIVEWIDENESS_WIDE)
+                                                                                       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               if (m_wideness == PRIMITIVEWIDENESS_WIDE)
+                                                                                       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
+                                                                       }
+                                                               }
 protected:
        const PrimitiveWideness         m_wideness;
+       const bool                                      m_isLineTest;
 };
 
 class LinesTestInstance : public BaseLineTestInstance
@@ -2949,12 +2956,15 @@ public:
 
        virtual TestInstance*           createInstance          (Context& context) const
                                                                {
-                                                                       if (m_queryFragmentShaderInvocations && !context.getDeviceFeatures().pipelineStatisticsQuery)
-                                                                               throw tcu::NotSupportedError("Pipeline statistics queries are not supported");
-
                                                                        return new DiscardTestInstance (context, m_primitiveTopology, m_queryFragmentShaderInvocations);
                                                                }
 
+       virtual void                            checkSupport            (Context& context) const
+                                                               {
+                                                                       if (m_queryFragmentShaderInvocations)
+                                                                               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_PIPELINE_STATISTICS_QUERY);
+                                                               }
+
 protected:
        const VkPrimitiveTopology       m_primitiveTopology;
        const deBool                            m_queryFragmentShaderInvocations;
@@ -3234,9 +3244,6 @@ LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context,
 {
        DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
 
-       if (!context.getDeviceProperties().limits.strictLines)
-               TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
-
        // create line widths
        if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
        {
@@ -3244,16 +3251,11 @@ LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context,
        }
        else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
        {
-               if (!m_context.getDeviceFeatures().wideLines)
-                       TCU_THROW(NotSupportedError , "wide line support required");
-
                const float*    range = context.getDeviceProperties().limits.lineWidthRange;
 
                m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
 
-               // no wide line support
-               if (range[1] <= 1.0f)
-                       throw tcu::NotSupportedError("wide line support required");
+               DE_ASSERT(range[1] > 1.0f);
 
                // set hand picked sizes
                m_lineWidths.push_back(5.0f);
@@ -3442,6 +3444,15 @@ public:
                                                                {
                                                                        return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_sampleCount);
                                                                }
+
+       virtual void                            checkSupport            (Context& context) const
+                                                               {
+                                                                       if (!context.getDeviceProperties().limits.strictLines)
+                                                                               TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
+
+                                                                       if (m_wideness == PRIMITIVEWIDENESS_WIDE)
+                                                                               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_WIDE_LINES);
+                                                               }
 protected:
        const VkPrimitiveTopology       m_primitiveTopology;
        const int                                       m_flags;
@@ -3461,11 +3472,11 @@ void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
                primitives->addChild(new BaseTestCase<TrianglesTestInstance>            (testCtx, "triangles",                  "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
                primitives->addChild(new BaseTestCase<TriangleStripTestInstance>        (testCtx, "triangle_strip",             "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
                primitives->addChild(new BaseTestCase<TriangleFanTestInstance>          (testCtx, "triangle_fan",               "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
-               primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines",                              "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",                                            PRIMITIVEWIDENESS_NARROW));
-               primitives->addChild(new WidenessTestCase<LineStripTestInstance>        (testCtx, "line_strip",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",                                           PRIMITIVEWIDENESS_NARROW));
-               primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines_wide",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",            PRIMITIVEWIDENESS_WIDE));
-               primitives->addChild(new WidenessTestCase<LineStripTestInstance>        (testCtx, "line_strip_wide",    "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",           PRIMITIVEWIDENESS_WIDE));
-               primitives->addChild(new WidenessTestCase<PointTestInstance>            (testCtx, "points",                             "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",                                           PRIMITIVEWIDENESS_WIDE));
+               primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines",                              "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",                                            PRIMITIVEWIDENESS_NARROW,       true));
+               primitives->addChild(new WidenessTestCase<LineStripTestInstance>        (testCtx, "line_strip",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",                                           PRIMITIVEWIDENESS_NARROW,       true));
+               primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines_wide",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",            PRIMITIVEWIDENESS_WIDE,         true));
+               primitives->addChild(new WidenessTestCase<LineStripTestInstance>        (testCtx, "line_strip_wide",    "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",           PRIMITIVEWIDENESS_WIDE,         true));
+               primitives->addChild(new WidenessTestCase<PointTestInstance>            (testCtx, "points",                             "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",                                           PRIMITIVEWIDENESS_WIDE,         false));
        }
 
        // .primitive_size
@@ -3699,9 +3710,9 @@ void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
                        rasterizationTests->addChild(primitives);
 
                        primitives->addChild(new BaseTestCase<TrianglesTestInstance>            (testCtx, "triangles",                  "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result",                                        samples[samplesNdx]));
-                       primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines",                              "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",                                            PRIMITIVEWIDENESS_NARROW,       samples[samplesNdx]));
-                       primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines_wide",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",            PRIMITIVEWIDENESS_WIDE,         samples[samplesNdx]));
-                       primitives->addChild(new WidenessTestCase<PointTestInstance>            (testCtx, "points",                             "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",                                           PRIMITIVEWIDENESS_WIDE,         samples[samplesNdx]));
+                       primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines",                              "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",                                            PRIMITIVEWIDENESS_NARROW,       true,   samples[samplesNdx]));
+                       primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines_wide",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",            PRIMITIVEWIDENESS_WIDE,         true,   samples[samplesNdx]));
+                       primitives->addChild(new WidenessTestCase<PointTestInstance>            (testCtx, "points",                             "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",                                           PRIMITIVEWIDENESS_WIDE,         false,  samples[samplesNdx]));
                }
 
                // .fill_rules
index 621297b..24ae508 100755 (executable)
@@ -91,6 +91,7 @@ public:
 
        void                    initPrograms                                    (SourceCollections&             sourceCollections) const;
        TestInstance*   createInstance                                  (Context&                               context) const;
+       virtual void    checkSupport                                    (Context&                               context) const;
 
 private:
        const   deUint32                        m_bufferSizeInBytes;
@@ -111,6 +112,12 @@ BufferSparseMemoryAliasingCase::BufferSparseMemoryAliasingCase (tcu::TestContext
 {
 }
 
+void BufferSparseMemoryAliasingCase::checkSupport (Context& context) const
+{
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
+}
+
 void BufferSparseMemoryAliasingCase::initPrograms (SourceCollections& sourceCollections) const
 {
        // Create compute program
@@ -173,17 +180,10 @@ tcu::TestStatus BufferSparseMemoryAliasingInstance::iterate (void)
 
                createDeviceSupportingQueues(queueRequirements);
        }
-       const vk::VkPhysicalDevice&     physicalDevice          = getPhysicalDevice();
-
-       if (!getPhysicalDeviceFeatures(instance, physicalDevice).sparseBinding)
-               TCU_THROW(NotSupportedError, "Sparse binding not supported");
-
-       if (!getPhysicalDeviceFeatures(instance, physicalDevice).sparseResidencyAliased)
-               TCU_THROW(NotSupportedError, "Sparse memory aliasing not supported");
-
-       const DeviceInterface&  deviceInterface = getDeviceInterface();
-       const Queue&                    sparseQueue             = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
-       const Queue&                    computeQueue    = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
+       const vk::VkPhysicalDevice&     physicalDevice  = getPhysicalDevice();
+       const DeviceInterface&          deviceInterface = getDeviceInterface();
+       const Queue&                            sparseQueue             = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
+       const Queue&                            computeQueue    = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
 
        // Go through all physical devices
        for (deUint32 physDevID = 0; physDevID < m_numPhysicalDevices; physDevID++)
index 1e01d63..d32af1c 100755 (executable)
@@ -64,6 +64,7 @@ public:
                                                                                         const bool                     useDeviceGroups);
 
        TestInstance*   createInstance                  (Context&                       context) const;
+       virtual void    checkSupport                    (Context&                       context) const;
 
 private:
        const deUint32  m_bufferSize;
@@ -81,6 +82,11 @@ BufferSparseBindingCase::BufferSparseBindingCase (tcu::TestContext&          testCtx,
 {
 }
 
+void BufferSparseBindingCase::checkSupport (Context& context) const
+{
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
+}
+
 class BufferSparseBindingInstance : public SparseResourcesBaseInstance
 {
 public:
@@ -118,9 +124,6 @@ tcu::TestStatus BufferSparseBindingInstance::iterate (void)
        }
        const vk::VkPhysicalDevice&     physicalDevice  = getPhysicalDevice();
 
-       if (!getPhysicalDeviceFeatures(instance, physicalDevice).sparseBinding)
-               TCU_THROW(NotSupportedError, "Sparse binding not supported");
-
        const DeviceInterface&  deviceInterface = getDeviceInterface();
        const Queue&                    sparseQueue             = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
        const Queue&                    computeQueue    = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
index 08d7ad9..2a3bcb0 100755 (executable)
@@ -641,21 +641,9 @@ public:
 
                        createDeviceSupportingQueues(requirements);
                }
-               const VkPhysicalDeviceFeatures  features        = getPhysicalDeviceFeatures(m_context.getInstanceInterface(), getPhysicalDevice());
 
-               if (!features.sparseBinding)
-                       TCU_THROW(NotSupportedError, "Missing feature: sparseBinding");
+               const DeviceInterface& vk = getDeviceInterface();
 
-               if (m_residency && !features.sparseResidencyBuffer)
-                       TCU_THROW(NotSupportedError, "Missing feature: sparseResidencyBuffer");
-
-               if (m_aliased && !features.sparseResidencyAliased)
-                       TCU_THROW(NotSupportedError, "Missing feature: sparseResidencyAliased");
-
-               if (m_nonResidentStrict && !m_context.getDeviceProperties().sparseProperties.residencyNonResidentStrict)
-                       TCU_THROW(NotSupportedError, "Missing sparse property: residencyNonResidentStrict");
-
-               const DeviceInterface& vk               = getDeviceInterface();
                m_sparseQueue                                   = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0u);
                m_universalQueue                                = getQueue(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT, 0u);
 
@@ -1457,6 +1445,20 @@ private:
        const Function  m_func;
 };
 
+void checkSupport (Context& context, const TestFlags flags)
+{
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
+
+       if (flags & TEST_FLAG_RESIDENCY)
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_BUFFER);
+
+       if (flags & TEST_FLAG_ALIASED)
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
+
+       if (flags & TEST_FLAG_NON_RESIDENT_STRICT && !context.getDeviceProperties().sparseProperties.residencyNonResidentStrict)
+               TCU_THROW(NotSupportedError, "Missing sparse property: residencyNonResidentStrict");
+}
+
 //! Convenience function to create a TestCase based on a freestanding initPrograms and a TestInstance implementation
 template<typename TestInstanceT, typename Arg0>
 TestCase* createTestInstanceWithPrograms (tcu::TestContext&                                                                    testCtx,
@@ -1465,8 +1467,8 @@ TestCase* createTestInstanceWithPrograms (tcu::TestContext&                                                                       testCtx,
                                                                                  typename FunctionProgramsSimple1<Arg0>::Function      initPrograms,
                                                                                  Arg0                                                                                          arg0)
 {
-       return new InstanceFactory1<TestInstanceT, Arg0, FunctionProgramsSimple1<Arg0> >(
-               testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc, FunctionProgramsSimple1<Arg0>(initPrograms), arg0);
+       return new InstanceFactory1WithSupport<TestInstanceT, Arg0, FunctionSupport1<Arg0>, FunctionProgramsSimple1<Arg0> >(
+               testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc, FunctionProgramsSimple1<Arg0>(initPrograms), arg0, typename FunctionSupport1<Arg0>::Args(checkSupport, arg0));
 }
 
 void populateTestGroup (tcu::TestCaseGroup* parentGroup)
index 29c352a..3767d9f 100644 (file)
@@ -65,6 +65,7 @@ public:
 
        void                    initPrograms                    (SourceCollections&                     sourceCollections) const {DE_UNREF(sourceCollections);};
        TestInstance*   createInstance                  (Context&                                       context) const;
+       virtual void    checkSupport                    (Context&                                       context) const;
 
 private:
        const ImageType                         m_imageType;
@@ -85,6 +86,20 @@ ImageAlignedMipSizeCase::ImageAlignedMipSizeCase (tcu::TestContext&                  testCtx,
 {
 }
 
+void ImageAlignedMipSizeCase::checkSupport (Context& context) const
+{
+       const InstanceInterface&        instance                = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
+
+       // Check the image size does not exceed device limits
+       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
+               TCU_THROW(NotSupportedError, "Image size not supported for device");
+
+       // Check if device supports sparse operations for image type
+       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
+               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
+}
+
 class ImageAlignedMipSizeInstance : public SparseResourcesBaseInstance
 {
 public:
@@ -123,14 +138,6 @@ tcu::TestStatus ImageAlignedMipSizeInstance::iterate (void)
        const VkPhysicalDeviceSparseProperties  sparseProperties = physicalDeviceProperties.sparseProperties;
        VkImageFormatProperties                                 imageFormatProperties;
 
-       // Check the image size does not exceed device limits
-       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-               TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-       // Check if device supports sparse operations for image type
-       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
-               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
-
        imageCreateInfo.sType                                   = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
        imageCreateInfo.pNext                                   = DE_NULL;
        imageCreateInfo.flags                                   = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
index 1deb600..60dc98c 100644 (file)
@@ -64,8 +64,9 @@ public:
                                                                                         const tcu::TextureFormat&      format,
                                                                                         deUint32                                       numSamples);
 
-       void                    initPrograms                            (SourceCollections&                     sourceCollections) const {DE_UNREF(sourceCollections);};
-       TestInstance*   createInstance                          (Context&                                       context) const;
+       void                    initPrograms                    (SourceCollections&                     sourceCollections) const {DE_UNREF(sourceCollections);};
+       TestInstance*   createInstance                  (Context&                                       context) const;
+       virtual void    checkSupport                    (Context&                                       context) const;
 
 private:
        const ImageType                         m_imageType;
@@ -89,6 +90,20 @@ ImageBlockShapesCase::ImageBlockShapesCase (tcu::TestContext&                        testCtx,
 {
 }
 
+void ImageBlockShapesCase::checkSupport (Context& context) const
+{
+       const InstanceInterface&        instance                = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
+
+       // Check the image size does not exceed device limits
+       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
+               TCU_THROW(NotSupportedError, "Image size not supported for device");
+
+       // Check if device supports sparse operations for image type
+       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
+               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
+}
+
 class ImageBlockShapesInstance : public SparseResourcesBaseInstance
 {
 public:
@@ -132,14 +147,6 @@ tcu::TestStatus ImageBlockShapesInstance::iterate (void)
        const deUint32                                                  pixelSize = tcu::getPixelSize(m_format) * 8;
        VkExtent3D                                                              expectedGranularity;
 
-       // Check the image size does not exceed device limits
-       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-               TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-       // Check if device supports sparse operations for image type
-       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
-               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
-
        imageCreateInfo.sType                                   = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
        imageCreateInfo.pNext                                   = DE_NULL;
        imageCreateInfo.flags                                   = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
index 364bb9f..eaa6f51 100755 (executable)
@@ -104,6 +104,7 @@ public:
 
        void                    initPrograms                                    (SourceCollections&                     sourceCollections) const;
        TestInstance*   createInstance                                  (Context&                                       context) const;
+       virtual void    checkSupport                                    (Context&                                       context) const;
 
 
 private:
@@ -131,6 +132,22 @@ ImageSparseMemoryAliasingCase::ImageSparseMemoryAliasingCase (tcu::TestContext&
 {
 }
 
+void ImageSparseMemoryAliasingCase::checkSupport (Context& context) const
+{
+       const InstanceInterface&        instance                = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
+
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_RESIDENCY_ALIASED);
+
+       // Check if image size does not exceed device limits
+       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
+               TCU_THROW(NotSupportedError, "Image size not supported for device");
+
+       // Check if device supports sparse operations for image type
+       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
+               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
+}
+
 class ImageSparseMemoryAliasingInstance : public SparseResourcesBaseInstance
 {
 public:
@@ -183,22 +200,9 @@ tcu::TestStatus ImageSparseMemoryAliasingInstance::iterate (void)
        VkSparseImageMemoryRequirements         aspectRequirements;
        std::vector<DeviceMemorySp>                     deviceMemUniquePtrVec;
 
-       //vsk checking these flags should be after creating m_imageType
-       //getting queues should be outside the loop
+       //vsk getting queues should be outside the loop
        //see these in all image files
 
-       // Check if image size does not exceed device limits
-       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-               TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-       // Check if sparse memory aliasing is supported
-       if (!getPhysicalDeviceFeatures(instance, physicalDevice).sparseResidencyAliased)
-               TCU_THROW(NotSupportedError, "Sparse memory aliasing not supported");
-
-       // Check if device supports sparse operations for image type
-       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
-               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
-
        const DeviceInterface&  deviceInterface = getDeviceInterface();
        const Queue&                    sparseQueue             = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
        const Queue&                    computeQueue    = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
index 22ea849..e3e93d7 100755 (executable)
@@ -66,6 +66,7 @@ public:
                                                                                         const bool                                     useDeviceGroups = false);
 
        TestInstance*   createInstance                  (Context&                                       context) const;
+       virtual void    checkSupport                    (Context&                                       context) const;
 
 private:
        const bool                                      m_useDeviceGroups;
@@ -90,6 +91,14 @@ ImageSparseBindingCase::ImageSparseBindingCase (tcu::TestContext&                    testCtx,
 {
 }
 
+void ImageSparseBindingCase::checkSupport (Context& context) const
+{
+       context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
+
+       if (!isImageSizeSupported(context.getInstanceInterface(), context.getPhysicalDevice(), m_imageType, m_imageSize))
+               TCU_THROW(NotSupportedError, "Image size not supported for device");
+}
+
 class ImageSparseBindingInstance : public SparseResourcesBaseInstance
 {
 public:
@@ -139,14 +148,6 @@ tcu::TestStatus ImageSparseBindingInstance::iterate (void)
        VkImageCreateInfo                       imageSparseInfo;
        std::vector<DeviceMemorySp>     deviceMemUniquePtrVec;
 
-       // Check if image size does not exceed device limits
-       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-               TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-       // Check if device supports sparse binding
-       if (!getPhysicalDeviceFeatures(instance, physicalDevice).sparseBinding)
-               TCU_THROW(NotSupportedError, "Device does not support sparse binding");
-
        const DeviceInterface&  deviceInterface = getDeviceInterface();
        const Queue&                    sparseQueue             = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
        const Queue&                    computeQueue    = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
index e5db408..a7d65df 100755 (executable)
@@ -67,6 +67,7 @@ public:
 
 
        TestInstance*   createInstance                          (Context&                                       context) const;
+       virtual void    checkSupport                            (Context&                                       context) const;
 
 private:
        const bool                                      m_useDeviceGroups;
@@ -90,6 +91,20 @@ MipmapSparseResidencyCase::MipmapSparseResidencyCase (tcu::TestContext&                      testCt
 {
 }
 
+void MipmapSparseResidencyCase::checkSupport (Context& context) const
+{
+       const InstanceInterface&        instance                = context.getInstanceInterface();
+       const VkPhysicalDevice          physicalDevice  = context.getPhysicalDevice();
+
+       // Check if image size does not exceed device limits
+       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
+               TCU_THROW(NotSupportedError, "Image size not supported for device");
+
+       // Check if device supports sparse operations for image type
+       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
+               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
+}
+
 class MipmapSparseResidencyInstance : public SparseResourcesBaseInstance
 {
 public:
@@ -138,14 +153,6 @@ tcu::TestStatus MipmapSparseResidencyInstance::iterate (void)
        VkImageCreateInfo                       imageSparseInfo;
        std::vector<DeviceMemorySp>     deviceMemUniquePtrVec;
 
-       // Check if image size does not exceed device limits
-       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-               TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-       // Check if device supports sparse operations for image type
-       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
-               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
-
        const DeviceInterface&  deviceInterface = getDeviceInterface();
        const Queue&                    sparseQueue             = getQueue(VK_QUEUE_SPARSE_BINDING_BIT, 0);
        const Queue&                    computeQueue    = getQueue(VK_QUEUE_COMPUTE_BIT, 0);
index 5476932..1604e64 100644 (file)
@@ -154,14 +154,9 @@ public:
 
        tcu::TestStatus iterate (void)
        {
-               const InstanceInterface&        vki                             = m_context.getInstanceInterface();
-               const VkPhysicalDevice          physDevice              = m_context.getPhysicalDevice();
                const Queue*                            sparseQueue             = DE_NULL;
                std::vector<const Queue*>       otherQueues;
 
-               if (!getPhysicalDeviceFeatures(vki, physDevice).sparseBinding)
-                       TCU_THROW(NotSupportedError, "Sparse binding not supported");
-
                // Determine required queues and create a device that supports them
                {
                        QueueRequirementsVec requirements;
@@ -313,7 +308,7 @@ private:
 class SparseQueueBindTest : public TestCase
 {
 public:
-       SparseQueueBindTest (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
+                                       SparseQueueBindTest     (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
                : TestCase      (testCtx, name, description)
                , m_params      (params)
        {
@@ -321,11 +316,16 @@ public:
                DE_ASSERT(params.numQueues == 1u || m_params.numWaitSemaphores > 0u || m_params.numSignalSemaphores > 0u);      // without any semaphores, only sparse queue will be used
        }
 
-       TestInstance* createInstance (Context& context) const
+       TestInstance*   createInstance          (Context& context) const
        {
                return new SparseQueueBindTestInstance(context, m_params);
        }
 
+       virtual void    checkSupport            (Context& context) const
+       {
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
+       }
+
 private:
        const TestParams        m_params;
 };
index 7e2f39b..6768b1a 100755 (executable)
@@ -211,17 +211,6 @@ tcu::TestStatus SparseShaderIntrinsicsInstanceBase::iterate (void)
        std::vector <deUint32>                          residencyReferenceData;
        std::vector<DeviceMemorySp>                     deviceMemUniquePtrVec;
 
-       // Check if image size does not exceed device limits
-       if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
-               TCU_THROW(NotSupportedError, "Image size not supported for device");
-
-       // Check if device supports sparse operations for image type
-       if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
-               TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
-
-       if (!getPhysicalDeviceFeatures(instance, physicalDevice).shaderResourceResidency)
-               TCU_THROW(NotSupportedError, "Sparse resource residency information not supported in shader code.");
-
        imageSparseInfo.sType                                   = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
        imageSparseInfo.pNext                                   = DE_NULL;
        imageSparseInfo.flags                                   = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
index f1c1061..9cf4832 100644 (file)
@@ -100,12 +100,12 @@ std::string getOpTypeImageResidency       (const ImageType imageType);
 class SparseShaderIntrinsicsCaseBase : public TestCase
 {
 public:
-       SparseShaderIntrinsicsCaseBase                  (tcu::TestContext&                      testCtx,
-                                                                                        const std::string&                     name,
-                                                                                        const SpirVFunction            function,
-                                                                                        const ImageType                        imageType,
-                                                                                        const tcu::UVec3&                      imageSize,
-                                                                                        const tcu::TextureFormat&      format)
+                                       SparseShaderIntrinsicsCaseBase  (tcu::TestContext&                      testCtx,
+                                                                                                        const std::string&                     name,
+                                                                                                        const SpirVFunction            function,
+                                                                                                        const ImageType                        imageType,
+                                                                                                        const tcu::UVec3&                      imageSize,
+                                                                                                        const tcu::TextureFormat&      format)
                : TestCase(testCtx, name, "")
                , m_function(function)
                , m_imageType(imageType)
@@ -114,6 +114,22 @@ public:
        {
        }
 
+       virtual void    checkSupport                                    (Context&       context) const
+       {
+               const vk::InstanceInterface&    instance                = context.getInstanceInterface();
+               const vk::VkPhysicalDevice              physicalDevice  = context.getPhysicalDevice();
+
+               context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_RESOURCE_RESIDENCY);
+
+               // Check if image size does not exceed device limits
+               if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
+                       TCU_THROW(NotSupportedError, "Image size not supported for device");
+
+               // Check if device supports sparse operations for image type
+               if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
+                       TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
+       }
+
 protected:
        const SpirVFunction                     m_function;
        const ImageType                         m_imageType;
index 96d8fe3..33f726b 100644 (file)
@@ -161,6 +161,11 @@ private:
        const Function  m_func;
 };
 
+struct NoSupport0
+{
+       void                    checkSupport    (Context&) const {};
+};
+
 class FunctionSupport0
 {
 public:
@@ -177,6 +182,12 @@ private:
 };
 
 template<typename Arg0>
+struct NoSupport1
+{
+       void                    checkSupport    (Context&, Arg0) const {};
+};
+
+template<typename Arg0>
 class FunctionSupport1
 {
 public: