Allow sample counting after multisample coverage
authorSÅ‚awomir Cygan <slawomir.cygan@intel.com>
Fri, 17 Jun 2022 13:41:40 +0000 (15:41 +0200)
committerMatthew Netsch <quic_mnetsch@quicinc.com>
Thu, 7 Jul 2022 20:21:46 +0000 (20:21 +0000)
Vulkan specification was modified to allow counting samples
after mutlisample coverage and fragment shading.

The test uses a fragment shader that kills all pixels with
"gl_SampleMask[0] = 0x0" and than verifies the occlusion query results.

This change allows for 0 samples to be counted by a query in case
of `early_fragment_tests` mode being used. The QualityWarning is emitted
in this case.

Components: Vulkan

Vulkan Issue: 3085
VK-GL-CTS Issue: 3778

Affects: dEQP-VK.fragment_operations.early_fragment.sample_*

Change-Id: I86cf17b2d8849a9d543e8447569ac808928c30e6

external/vulkancts/modules/vulkan/fragment_ops/vktFragmentOperationsEarlyFragmentTests.cpp

index a1a4303..26272e6 100644 (file)
@@ -2002,6 +2002,12 @@ tcu::TestStatus EarlyFragmentSampleCountTestInstance::iterate (void)
        const Unique<VkCommandPool>                     cmdPool                                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                                       (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
+       enum QueryIndex
+       {
+               QUERY_INDEX_NO_EARLY_FRAG = 0,
+               QUERY_INDEX_EARLY_FRAG = 1
+       };
+
        {
                const VkRect2D                                  renderArea                                      =
                {
@@ -2043,9 +2049,9 @@ tcu::TestStatus EarlyFragmentSampleCountTestInstance::iterate (void)
                // Run without early fragment test.
                vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineNoEarlyFrag);
 
-               vk.cmdBeginQuery(cmdBuffer.get(), queryPool, 0, VK_QUERY_CONTROL_PRECISE_BIT);
+               vk.cmdBeginQuery(cmdBuffer.get(), queryPool, QUERY_INDEX_NO_EARLY_FRAG, VK_QUERY_CONTROL_PRECISE_BIT);
                vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
-               vk.cmdEndQuery(cmdBuffer.get(), queryPool, 0);
+               vk.cmdEndQuery(cmdBuffer.get(), queryPool, QUERY_INDEX_NO_EARLY_FRAG);
 
                endRenderPass(vk, *cmdBuffer);
 
@@ -2058,9 +2064,9 @@ tcu::TestStatus EarlyFragmentSampleCountTestInstance::iterate (void)
                // Run with early fragment test.
                vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineEarlyFrag);
 
-               vk.cmdBeginQuery(cmdBuffer.get(), queryPool, 1, VK_QUERY_CONTROL_PRECISE_BIT);
+               vk.cmdBeginQuery(cmdBuffer.get(), queryPool, QUERY_INDEX_EARLY_FRAG, VK_QUERY_CONTROL_PRECISE_BIT);
                vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u);
-               vk.cmdEndQuery(cmdBuffer.get(), queryPool, 1);
+               vk.cmdEndQuery(cmdBuffer.get(), queryPool, QUERY_INDEX_EARLY_FRAG);
 
                endRenderPass(vk, *cmdBuffer);
 
@@ -2103,10 +2109,18 @@ tcu::TestStatus EarlyFragmentSampleCountTestInstance::iterate (void)
                vk.destroyQueryPool(device, queryPool, nullptr);
 
                // Check that number of the all passed samples are within an acceptable range.
-               if (sampleCounts[0] >= minValue && sampleCounts[0] <= maxValue && sampleCounts[1] >= minValue && sampleCounts[1] <= maxValue)
+               if (sampleCounts[QUERY_INDEX_NO_EARLY_FRAG] >= minValue && sampleCounts[QUERY_INDEX_NO_EARLY_FRAG] <= maxValue && sampleCounts[QUERY_INDEX_EARLY_FRAG] >= minValue && sampleCounts[QUERY_INDEX_EARLY_FRAG] <= maxValue)
                {
                        return tcu::TestStatus::pass("Success");
                }
+               else if (sampleCounts[QUERY_INDEX_NO_EARLY_FRAG] >= minValue && sampleCounts[QUERY_INDEX_NO_EARLY_FRAG] <= maxValue && sampleCounts[QUERY_INDEX_EARLY_FRAG] == 0)
+               {
+                       // Spec says: "If the fragment shader declares the EarlyFragmentTests execution mode, fragment shading and
+                       // multisample coverage operations should instead be performed after sample counting.
+
+                       // since the specification says 'should', the opposite behavior is allowed, but not preferred
+                       return tcu::TestStatus(QP_TEST_RESULT_QUALITY_WARNING, "Sample count is 0 - sample counting performed after multisample coverage and fragment shading");
+               }
                else
                {
                        // Log no early frag test images