dEQP-VK.pipeline: multisample interpolation tests
authorKantoch <marcin.kantoch@mobica.com>
Thu, 28 Jul 2016 14:39:48 +0000 (16:39 +0200)
committerMaciej Jesionowski <maciej.jesionowski@mobica.com>
Fri, 2 Sep 2016 08:48:09 +0000 (10:48 +0200)
New test:
- dEQP-VK.pipeline.multisample_interpolation.*

Fixes #427

Change-Id: I235dc4781dff92e89ea645778e046d61b3909b32

android/cts/master/com.drawelements.deqp.vk.xml
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt
external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.cpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.hpp [new file with mode: 0644]
external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp
external/vulkancts/mustpass/1.0.1/vk-default.txt

index 4c203f2..fc6fd36 100644 (file)
                                        </TestCase>
                                </TestSuite>
                        </TestSuite>
+                       <TestSuite name="multisample_interpolation">
+                               <TestSuite name="sample_interpolate_at_single_sample_">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_1">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_1">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="sample_interpolate_at_distinct_values">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="sample_interpolate_at_ignores_centroid">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="sample_interpolate_at_consistency">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="sample_qualifier_distinct_values">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="centroid_interpolate_at_consistency">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="centroid_qualifier_inside_primitive">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="offset_interpolate_at_pixel_center">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                               <TestSuite name="offset_interpolate_at_sample_position">
+                                       <TestCase name="128_128_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                                       <TestCase name="137_191_1">
+                                               <Test name="samples_2">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_4">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_8">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_16">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_32">
+                                                       <TestInstance/>
+                                               </Test>
+                                               <Test name="samples_64">
+                                                       <TestInstance/>
+                                               </Test>
+                                       </TestCase>
+                               </TestSuite>
+                       </TestSuite>
                        <TestSuite name="vertex_input">
                                <TestCase name="single_attribute">
                                        <Test name="float_as_r8_unorm_rate_vertex">
index 8c5c0fc..2e7dd75 100644 (file)
@@ -71409,6 +71409,104 @@ dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_32.alpha_invisible
 dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_opaque
 dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_translucent
 dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_invisible
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.128_128_1.samples_1
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.137_191_1.samples_1
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_64
 dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_vertex
 dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_instance
 dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_snorm_rate_vertex
index 383e8b2..e9e7307 100644 (file)
@@ -25,8 +25,12 @@ set(DEQP_VK_PIPELINE_SRCS
        vktPipelineImageUtil.hpp
        vktPipelineImageViewTests.cpp
        vktPipelineImageViewTests.hpp
+       vktPipelineMultisampleTestsUtil.cpp
+       vktPipelineMultisampleTestsUtil.hpp
        vktPipelineMultisampleTests.cpp
        vktPipelineMultisampleTests.hpp
+       vktPipelineMultisampleInterpolationTests.cpp
+       vktPipelineMultisampleInterpolationTests.hpp
        vktPipelineInputAssemblyTests.cpp
        vktPipelineInputAssemblyTests.hpp
        vktPipelineReferenceRenderer.cpp
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.cpp
new file mode 100644 (file)
index 0000000..b7070d6
--- /dev/null
@@ -0,0 +1,1807 @@
+/*------------------------------------------------------------------------
+* Vulkan Conformance Tests
+* ------------------------
+*
+* Copyright (c) 2016 The Khronos Group Inc.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*//*
+* \file vktPipelineMultisampleInterpolationTests.cpp
+* \brief Multisample Interpolation Tests
+*//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleInterpolationTests.hpp"
+#include "vktPipelineMultisampleTestsUtil.hpp"
+#include "vktPipelineMakeUtil.hpp"
+#include "vkQueryUtil.hpp"
+
+#include <set>
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+using namespace vk;
+
+struct ImageMSParams
+{
+       ImageMSParams(const VkSampleCountFlagBits samples, const tcu::UVec3& size) : numSamples(samples), imageSize(size) {}
+
+       VkSampleCountFlagBits   numSamples;
+       tcu::UVec3                              imageSize;
+};
+
+class MSInterpolationCaseBase : public TestCase
+{
+public:
+       MSInterpolationCaseBase (tcu::TestContext&              testCtx,
+                                                        const std::string&             name,
+                                                        const ImageMSParams&   imageMSParams)
+               : TestCase(testCtx, name, "")
+               , m_imageMSParams(imageMSParams)
+       {}
+
+protected:
+       const ImageMSParams m_imageMSParams;
+};
+
+typedef MSInterpolationCaseBase* (*MSInterpolationCaseFuncPtr)(tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams);
+
+class MSInterpolationInstanceBase : public TestInstance
+{
+public:
+                                                               MSInterpolationInstanceBase     (Context&                                                       context,
+                                                                                                                        const ImageMSParams&                           imageMSParams)
+               : TestInstance          (context)
+               , m_imageMSParams       (imageMSParams)
+               , m_imageType           (IMAGE_TYPE_2D)
+               , m_imageFormat         (tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::UNORM_INT8))
+       {}
+
+       tcu::TestStatus                         iterate                                         (void);
+
+protected:
+
+       typedef std::vector<VkVertexInputAttributeDescription> VertexAttribDescVec;
+
+       struct VertexDataDesc
+       {
+               VkPrimitiveTopology     primitiveTopology;
+               deUint32                        verticesCount;
+               deUint32                        dataStride;
+               VkDeviceSize            dataSize;
+               VertexAttribDescVec     vertexAttribDescVec;
+       };
+
+       void                                            validateImageSize                       (const InstanceInterface&                       instance,
+                                                                                                                        const VkPhysicalDevice                         physicalDevice,
+                                                                                                                        const ImageType                                        imageType,
+                                                                                                                        const tcu::UVec3&                                      imageSize) const;
+
+       void                                            validateImageFeatureFlags       (const InstanceInterface&                       instance,
+                                                                                                                        const VkPhysicalDevice                         physicalDevice,
+                                                                                                                        const VkFormat                                         format,
+                                                                                                                        const VkFormatFeatureFlags                     featureFlags) const;
+
+       void                                            validateImageInfo                       (const InstanceInterface&                       instance,
+                                                                                                                        const VkPhysicalDevice                         physicalDevice,
+                                                                                                                        const VkImageCreateInfo&                       imageInfo) const;
+
+       virtual VertexDataDesc          getVertexDataDescripton         (void) const = 0;
+
+       virtual void                            uploadVertexData                        (const Allocation&                                      vertexBufferAllocation,
+                                                                                                                        const VertexDataDesc&                          vertexDataDescripton) const = 0;
+
+       virtual tcu::TestStatus         verifyResolvedImage                     (const tcu::ConstPixelBufferAccess&     imageData) const = 0;
+protected:
+       const ImageMSParams                     m_imageMSParams;
+       const ImageType                         m_imageType;
+       const tcu::TextureFormat        m_imageFormat;
+};
+
+void MSInterpolationInstanceBase::validateImageSize (const InstanceInterface&  instance,
+                                                                                                        const VkPhysicalDevice         physicalDevice,
+                                                                                                        const ImageType                        imageType,
+                                                                                                        const tcu::UVec3&                      imageSize) const
+{
+       const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
+
+       bool isImageSizeValid = true;
+
+       switch (imageType)
+       {
+               case IMAGE_TYPE_1D:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimension1D;
+                       break;
+               case IMAGE_TYPE_1D_ARRAY:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimension1D &&
+                                                               imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
+                       break;
+               case IMAGE_TYPE_2D:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
+                                                               imageSize.y() <= deviceProperties.limits.maxImageDimension2D;
+                       break;
+               case IMAGE_TYPE_2D_ARRAY:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimension2D &&
+                                                               imageSize.y() <= deviceProperties.limits.maxImageDimension2D &&
+                                                               imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
+                       break;
+               case IMAGE_TYPE_CUBE:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
+                                                               imageSize.y() <= deviceProperties.limits.maxImageDimensionCube;
+                       break;
+               case IMAGE_TYPE_CUBE_ARRAY:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimensionCube &&
+                                                               imageSize.y() <= deviceProperties.limits.maxImageDimensionCube &&
+                                                               imageSize.z() <= deviceProperties.limits.maxImageArrayLayers;
+                       break;
+               case IMAGE_TYPE_3D:
+                       isImageSizeValid =      imageSize.x() <= deviceProperties.limits.maxImageDimension3D &&
+                                                               imageSize.y() <= deviceProperties.limits.maxImageDimension3D &&
+                                                               imageSize.z() <= deviceProperties.limits.maxImageDimension3D;
+                       break;
+               default:
+                       DE_FATAL("Unknown image type");
+       }
+
+       if (!isImageSizeValid)
+       {
+               std::ostringstream      notSupportedStream;
+
+               notSupportedStream << "Image type (" << getImageTypeName(imageType) << ") with size (" << imageSize.x() << ", " << imageSize.y() << ", " << imageSize.z() << ") not supported by device" << std::endl;
+
+               const std::string notSupportedString = notSupportedStream.str();
+
+               TCU_THROW(NotSupportedError, notSupportedString.c_str());
+       }
+}
+
+void MSInterpolationInstanceBase::validateImageFeatureFlags    (const InstanceInterface&       instance,
+                                                                                                                        const VkPhysicalDevice         physicalDevice,
+                                                                                                                        const VkFormat                         format,
+                                                                                                                        const VkFormatFeatureFlags     featureFlags) const
+{
+       const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(instance, physicalDevice, format);
+
+       if ((formatProperties.optimalTilingFeatures & featureFlags) != featureFlags)
+       {
+               std::ostringstream      notSupportedStream;
+
+               notSupportedStream << "Device does not support image format " << format << " for feature flags " << featureFlags << std::endl;
+
+               const std::string notSupportedString = notSupportedStream.str();
+
+               TCU_THROW(NotSupportedError, notSupportedString.c_str());
+       }
+}
+
+void MSInterpolationInstanceBase::validateImageInfo    (const InstanceInterface&       instance,
+                                                                                                        const VkPhysicalDevice         physicalDevice,
+                                                                                                        const VkImageCreateInfo&       imageInfo) const
+{
+       VkImageFormatProperties imageFormatProps;
+       instance.getPhysicalDeviceImageFormatProperties(physicalDevice, imageInfo.format, imageInfo.imageType, imageInfo.tiling, imageInfo.usage, imageInfo.flags, &imageFormatProps);
+
+       if (imageFormatProps.maxExtent.width  < imageInfo.extent.width  ||
+               imageFormatProps.maxExtent.height < imageInfo.extent.height ||
+               imageFormatProps.maxExtent.depth  < imageInfo.extent.depth)
+       {
+               std::ostringstream      notSupportedStream;
+
+               notSupportedStream      << "Image extent ("
+                                                       << imageInfo.extent.width  << ", "
+                                                       << imageInfo.extent.height << ", "
+                                                       << imageInfo.extent.depth
+                                                       << ") exceeds allowed maximum ("
+                                                       << imageFormatProps.maxExtent.width <<  ", "
+                                                       << imageFormatProps.maxExtent.height << ", "
+                                                       << imageFormatProps.maxExtent.depth
+                                                       << ")"
+                                                       << std::endl;
+
+               const std::string notSupportedString = notSupportedStream.str();
+
+               TCU_THROW(NotSupportedError, notSupportedString.c_str());
+       }
+
+       if (imageFormatProps.maxArrayLayers < imageInfo.arrayLayers)
+       {
+               std::ostringstream      notSupportedStream;
+
+               notSupportedStream << "Image layers count of " << imageInfo.arrayLayers << " exceeds allowed maximum which is " << imageFormatProps.maxArrayLayers << std::endl;
+
+               const std::string notSupportedString = notSupportedStream.str();
+
+               TCU_THROW(NotSupportedError, notSupportedString.c_str());
+       }
+
+       if (!(imageFormatProps.sampleCounts & imageInfo.samples))
+       {
+               std::ostringstream      notSupportedStream;
+
+               notSupportedStream << "Samples count of " << imageInfo.samples << " not supported for image" << std::endl;
+
+               const std::string notSupportedString = notSupportedStream.str();
+
+               TCU_THROW(NotSupportedError, notSupportedString.c_str());
+       }
+}
+
+tcu::TestStatus MSInterpolationInstanceBase::iterate (void)
+{
+       const InstanceInterface&        instance                        = m_context.getInstanceInterface();
+       const DeviceInterface&          deviceInterface         = m_context.getDeviceInterface();
+       const VkDevice                          device                          = m_context.getDevice();
+       const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
+       Allocator&                                      allocator                       = m_context.getDefaultAllocator();
+       const VkQueue                           queue                           = m_context.getUniversalQueue();
+       const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+
+       VkImageCreateInfo                       imageMSInfo;
+       VkImageCreateInfo                       imageRSInfo;
+
+       // Check if image size does not exceed device limits
+       validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
+
+       // Check if device supports image format as color attachment
+       validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
+
+       imageMSInfo.sType                                       = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+       imageMSInfo.pNext                                       = DE_NULL;
+       imageMSInfo.flags                                       = 0u;
+       imageMSInfo.imageType                           = mapImageType(m_imageType);
+       imageMSInfo.format                                      = mapTextureFormat(m_imageFormat);
+       imageMSInfo.extent                                      = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
+       imageMSInfo.arrayLayers                         = getNumLayers(m_imageType, m_imageMSParams.imageSize);
+       imageMSInfo.mipLevels                           = 1u;
+       imageMSInfo.samples                                     = m_imageMSParams.numSamples;
+       imageMSInfo.tiling                                      = VK_IMAGE_TILING_OPTIMAL;
+       imageMSInfo.initialLayout                       = VK_IMAGE_LAYOUT_UNDEFINED;
+       imageMSInfo.usage                                       = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
+       imageMSInfo.sharingMode                         = VK_SHARING_MODE_EXCLUSIVE;
+       imageMSInfo.queueFamilyIndexCount       = 0u;
+       imageMSInfo.pQueueFamilyIndices         = DE_NULL;
+
+       if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
+       {
+               imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+       }
+
+       validateImageInfo(instance, physicalDevice, imageMSInfo);
+
+       const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
+
+       imageRSInfo                     = imageMSInfo;
+       imageRSInfo.samples     = VK_SAMPLE_COUNT_1_BIT;
+
+       validateImageInfo(instance, physicalDevice, imageRSInfo);
+
+       const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
+
+       // Create render pass
+       const VkAttachmentDescription attachmentMSDesc =
+       {
+               (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
+               imageMSInfo.format,                                                     // VkFormat                                                     format;
+               imageMSInfo.samples,                                            // VkSampleCountFlagBits                        samples;
+               VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
+               VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
+               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
+               VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
+       };
+
+       const VkAttachmentDescription attachmentRSDesc =
+       {
+               (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
+               imageRSInfo.format,                                                     // VkFormat                                                     format;
+               imageRSInfo.samples,                                            // VkSampleCountFlagBits                        samples;
+               VK_ATTACHMENT_LOAD_OP_CLEAR,                    // VkAttachmentLoadOp                           loadOp;
+               VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
+               VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
+               VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
+       };
+
+       const VkAttachmentDescription attachments[] = { attachmentMSDesc, attachmentRSDesc };
+
+       const VkAttachmentReference attachmentMSRef =
+       {
+               0u,                                                                                     // deUint32                     attachment;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
+       };
+
+       const VkAttachmentReference attachmentRSRef =
+       {
+               1u,                                                                                     // deUint32                     attachment;
+               VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
+       };
+
+       const VkAttachmentReference* resolveAttachment = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? DE_NULL : &attachmentRSRef;
+
+       const VkSubpassDescription subpassDescription =
+       {
+               (VkSubpassDescriptionFlags)0u,                                          // VkSubpassDescriptionFlags            flags;
+               VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
+               0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
+               DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
+               1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
+               &attachmentMSRef,                                                                       // const VkAttachmentReference*         pColorAttachments;
+               resolveAttachment,                                                              // const VkAttachmentReference*         pResolveAttachments;
+               DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
+               0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
+               DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
+       };
+
+       const VkRenderPassCreateInfo renderPassInfo =
+       {
+               VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
+               DE_NULL,                                                                                        // const void*                                          pNext;
+               (VkRenderPassCreateFlags)0u,                                            // VkRenderPassCreateFlags                      flags;
+               2u,                                                                                                     // deUint32                                                     attachmentCount;
+               attachments,                                                                            // const VkAttachmentDescription*       pAttachments;
+               1u,                                                                                                     // deUint32                                                     subpassCount;
+               &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
+               0u,                                                                                                     // deUint32                                                     dependencyCount;
+               DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
+       };
+
+       const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
+
+       const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
+
+       // Create color attachments image views
+       const Unique<VkImageView> imageMSView(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
+       const Unique<VkImageView> imageRSView(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
+
+       const VkImageView attachmentsViews[] = { *imageMSView, *imageRSView };
+
+       // Create framebuffer
+       const VkFramebufferCreateInfo framebufferInfo =
+       {
+               VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                             sType;
+               DE_NULL,                                                                        // const void*                                 pNext;
+               (VkFramebufferCreateFlags)0u,                           // VkFramebufferCreateFlags                    flags;
+               *renderPass,                                                            // VkRenderPass                                renderPass;
+               2u,                                                                                     // uint32_t                                    attachmentCount;
+               attachmentsViews,                                                       // const VkImageView*                          pAttachments;
+               imageMSInfo.extent.width,                                       // uint32_t                                    width;
+               imageMSInfo.extent.height,                                      // uint32_t                                    height;
+               imageMSInfo.arrayLayers,                                        // uint32_t                                    layers;
+       };
+
+       const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
+
+       // Create pipeline layout
+       const VkPipelineLayoutCreateInfo pipelineLayoutParams =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
+               DE_NULL,                                                                                        // const void*                                          pNext;
+               (VkPipelineLayoutCreateFlags)0u,                                        // VkPipelineLayoutCreateFlags          flags;
+               0u,                                                                                                     // deUint32                                                     setLayoutCount;
+               DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
+               0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
+               DE_NULL,                                                                                        // const VkPushConstantRange*           pPushConstantRanges;
+       };
+
+       const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, device, &pipelineLayoutParams));
+
+       // Create vertex attributes data
+       const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
+
+       de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
+       const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
+
+       uploadVertexData(vertexBufferAllocation, vertexDataDesc);
+
+       flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), vertexDataDesc.dataSize);
+
+       const VkVertexInputBindingDescription vertexBinding =
+       {
+               0u,                                                     // deUint32                             binding;
+               vertexDataDesc.dataStride,      // deUint32                             stride;
+               VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputRate    inputRate;
+       };
+
+       const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,                      // VkStructureType                             sType;
+               DE_NULL,                                                                                                                        // const void*                                 pNext;
+               (VkPipelineVertexInputStateCreateFlags)0u,                                                      // VkPipelineVertexInputStateCreateFlags       flags;
+               1u,                                                                                                                                     // uint32_t                                    vertexBindingDescriptionCount;
+               &vertexBinding,                                                                                                         // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
+               static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()),       // uint32_t                                    vertexAttributeDescriptionCount;
+               dataPointer(vertexDataDesc.vertexAttribDescVec),                                        // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
+       };
+
+       const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
+               DE_NULL,                                                                                                                // const void*                                 pNext;
+               (VkPipelineInputAssemblyStateCreateFlags)0u,                                    // VkPipelineInputAssemblyStateCreateFlags     flags;
+               vertexDataDesc.primitiveTopology,                                                               // VkPrimitiveTopology                         topology;
+               VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
+       };
+
+       const VkViewport viewport =
+       {
+               0.0f, 0.0f,
+               static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
+               0.0f, 1.0f
+       };
+
+       const VkRect2D scissor =
+       {
+               makeOffset2D(0, 0),
+               makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
+       };
+
+       const VkPipelineViewportStateCreateInfo viewportStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                             sType;
+               DE_NULL,                                                                                                                // const void*                                 pNext;
+               (VkPipelineViewportStateCreateFlags)0u,                                                 // VkPipelineViewportStateCreateFlags          flags;
+               1u,                                                                                                                             // uint32_t                                    viewportCount;
+               &viewport,                                                                                                              // const VkViewport*                           pViewports;
+               1u,                                                                                                                             // uint32_t                                    scissorCount;
+               &scissor,                                                                                                               // const VkRect2D*                             pScissors;
+       };
+
+       const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
+               DE_NULL,                                                                                                                // const void*                              pNext;
+               (VkPipelineRasterizationStateCreateFlags)0u,                                    // VkPipelineRasterizationStateCreateFlags  flags;
+               VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
+               VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
+               VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
+               VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
+               VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
+               0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
+               0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
+               0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
+               1.0f,                                                                                                                   // float                                                                        lineWidth;
+       };
+
+       const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                                // const void*                                                          pNext;
+               (VkPipelineMultisampleStateCreateFlags)0u,                                              // VkPipelineMultisampleStateCreateFlags        flags;
+               imageMSInfo.samples,                                                                                    // VkSampleCountFlagBits                                        rasterizationSamples;
+               VK_TRUE,                                                                                                                // VkBool32                                                                     sampleShadingEnable;
+               1.0f,                                                                                                                   // float                                                                        minSampleShading;
+               DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToOneEnable;
+       };
+
+       const VkStencilOpState stencilOpState = makeStencilOpState
+       (
+               VK_STENCIL_OP_KEEP,             // stencil fail
+               VK_STENCIL_OP_KEEP,             // depth & stencil pass
+               VK_STENCIL_OP_KEEP,             // depth only fail
+               VK_COMPARE_OP_ALWAYS,   // compare op
+               0u,                                             // compare mask
+               0u,                                             // write mask
+               0u                                              // reference
+       );
+
+       const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
+               DE_NULL,                                                                                                                // const void*                                                          pNext;
+               (VkPipelineDepthStencilStateCreateFlags)0u,                                             // VkPipelineDepthStencilStateCreateFlags       flags;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     depthTestEnable;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     depthWriteEnable;
+               VK_COMPARE_OP_LESS,                                                                                             // VkCompareOp                                                          depthCompareOp;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     depthBoundsTestEnable;
+               VK_FALSE,                                                                                                               // VkBool32                                                                     stencilTestEnable;
+               stencilOpState,                                                                                                 // VkStencilOpState                                                     front;
+               stencilOpState,                                                                                                 // VkStencilOpState                                                     back;
+               0.0f,                                                                                                                   // float                                                                        minDepthBounds;
+               1.0f,                                                                                                                   // float                                                                        maxDepthBounds;
+       };
+
+       const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
+
+       const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
+       {
+               VK_FALSE,                                                                                                               // VkBool32                                     blendEnable;
+               VK_BLEND_FACTOR_SRC_ALPHA,                                                                              // VkBlendFactor                        srcColorBlendFactor;
+               VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                                    // VkBlendFactor                        dstColorBlendFactor;
+               VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            colorBlendOp;
+               VK_BLEND_FACTOR_SRC_ALPHA,                                                                              // VkBlendFactor                        srcAlphaBlendFactor;
+               VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                                    // VkBlendFactor                        dstAlphaBlendFactor;
+               VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            alphaBlendOp;
+               colorComponentsAll,                                                                                             // VkColorComponentFlags        colorWriteMask;
+       };
+
+       const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
+               DE_NULL,                                                                                                                // const void*                                                                  pNext;
+               (VkPipelineColorBlendStateCreateFlags)0u,                                               // VkPipelineColorBlendStateCreateFlags                 flags;
+               VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
+               VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
+               1u,                                                                                                                             // deUint32                                                                             attachmentCount;
+               &colorBlendAttachmentState,                                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
+               { 0.0f, 0.0f, 0.0f, 0.0f },                                                                             // float                                                                                blendConstants[4];
+       };
+
+       const Unique<VkShaderModule> vsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0));
+
+       const VkPipelineShaderStageCreateInfo vsShaderStageInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                              sType;
+               DE_NULL,                                                                                                                // const void*                                                  pNext;
+               (VkPipelineShaderStageCreateFlags)0u,                                                   // VkPipelineShaderStageCreateFlags             flags;
+               VK_SHADER_STAGE_VERTEX_BIT,                                                                             // VkShaderStageFlagBits                                stage;
+               *vsModule,                                                                                                              // VkShaderModule                                               module;
+               "main",                                                                                                                 // const char*                                                  pName;
+               DE_NULL,                                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
+       };
+
+       const Unique<VkShaderModule> fsModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0));
+
+       const VkPipelineShaderStageCreateInfo fsShaderStageInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                              sType;
+               DE_NULL,                                                                                                                // const void*                                                  pNext;
+               (VkPipelineShaderStageCreateFlags)0u,                                                   // VkPipelineShaderStageCreateFlags             flags;
+               VK_SHADER_STAGE_FRAGMENT_BIT,                                                                   // VkShaderStageFlagBits                                stage;
+               *fsModule,                                                                                                              // VkShaderModule                                               module;
+               "main",                                                                                                                 // const char*                                                  pName;
+               DE_NULL,                                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
+       };
+
+       const VkPipelineShaderStageCreateInfo shaderStageInfos[] = { vsShaderStageInfo, fsShaderStageInfo };
+
+       const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
+       {
+               VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                // VkStructureType                                                                      sType;
+               DE_NULL,                                                                                                                // const void*                                                                          pNext;
+               (VkPipelineCreateFlags)0,                                                                               // VkPipelineCreateFlags                                                        flags;
+               2u,                                                                                                                             // deUint32                                                                                     stageCount;
+               shaderStageInfos,                                                                                               // const VkPipelineShaderStageCreateInfo*                       pStages;
+               &vertexInputStateInfo,                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
+               &inputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
+               DE_NULL,                                                                                                                // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
+               &viewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
+               &rasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
+               &multisampleStateInfo,                                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
+               &depthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
+               &colorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
+               DE_NULL,                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
+               *pipelineLayout,                                                                                                // VkPipelineLayout                                                                     layout;
+               *renderPass,                                                                                                    // VkRenderPass                                                                         renderPass;
+               0u,                                                                                                                             // deUint32                                                                                     subpass;
+               DE_NULL,                                                                                                                // VkPipeline                                                                           basePipelineHandle;
+               0u,                                                                                                                             // deInt32                                                                                      basePipelineIndex;
+       };
+
+       // Create graphics pipeline
+       const Unique<VkPipeline> graphicsPipeline(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
+
+       // Create command buffer for compute and transfer oparations
+       const Unique<VkCommandPool>       commandPool(makeCommandPool(deviceInterface, device, queueFamilyIndex));
+       const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
+
+       // Start recording commands
+       beginCommandBuffer(deviceInterface, *commandBuffer);
+
+       {
+               VkImageMemoryBarrier imageOutputAttachmentBarriers[2];
+
+               imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
+               (
+                       0u,
+                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                       VK_IMAGE_LAYOUT_UNDEFINED,
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                       **imageMS,
+                       fullImageRange
+               );
+
+               imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
+               (
+                       0u,
+                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                       VK_IMAGE_LAYOUT_UNDEFINED,
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                       **imageRS,
+                       fullImageRange
+               );
+
+               deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputAttachmentBarriers);
+       }
+
+       {
+               const VkDeviceSize vertexStartOffset = 0u;
+
+               std::vector<VkClearValue> clearValues;
+               clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
+               clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
+
+               const vk::VkRect2D renderArea =
+               {
+                       makeOffset2D(0u, 0u),
+                       makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
+               };
+
+               // Begin render pass
+               const VkRenderPassBeginInfo renderPassBeginInfo =
+               {
+                       VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
+                       DE_NULL,                                                                                // const void*             pNext;
+                       *renderPass,                                                                            // VkRenderPass            renderPass;
+                       *framebuffer,                                                                   // VkFramebuffer           framebuffer;
+                       renderArea,                                                                             // VkRect2D                renderArea;
+                       static_cast<deUint32>(clearValues.size()),              // deUint32                clearValueCount;
+                       &clearValues[0],                                                                // const VkClearValue*     pClearValues;
+               };
+
+               deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
+
+               // Bind graphics pipeline
+               deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
+
+               // Bind vertex buffer
+               deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
+
+               // Draw full screen quad
+               deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
+
+               // End render pass
+               deviceInterface.cmdEndRenderPass(*commandBuffer);
+       }
+
+       const VkImage sourceImage = m_imageMSParams.numSamples == VK_SAMPLE_COUNT_1_BIT ? **imageMS : **imageRS;
+
+       {
+               const VkImageMemoryBarrier imageTransferSrcBarrier = makeImageMemoryBarrier
+               (
+                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
+                       VK_ACCESS_TRANSFER_READ_BIT,
+                       VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                       sourceImage,
+                       fullImageRange
+               );
+
+               deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageTransferSrcBarrier);
+       }
+
+       // Copy data from resolve image to buffer
+       const deUint32                          imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels);
+
+       const VkBufferCreateInfo        bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+       const de::UniquePtr<Buffer>     bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
+
+       {
+               const VkBufferImageCopy bufferImageCopy =
+               {
+                       0u,                                                                                                                                                                             //      VkDeviceSize                            bufferOffset;
+                       0u,                                                                                                                                                                             //      deUint32                                        bufferRowLength;
+                       0u,                                                                                                                                                                             //      deUint32                                        bufferImageHeight;
+                       makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), //      VkImageSubresourceLayers        imageSubresource;
+                       makeOffset3D(0, 0, 0),                                                                                                                                  //      VkOffset3D                                      imageOffset;
+                       imageRSInfo.extent,                                                                                                                                             //      VkExtent3D                                      imageExtent;
+               };
+
+               deviceInterface.cmdCopyImageToBuffer(*commandBuffer, sourceImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
+       }
+
+       {
+               const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
+               (
+                       VK_ACCESS_TRANSFER_WRITE_BIT,
+                       VK_ACCESS_HOST_READ_BIT,
+                       bufferRS->get(),
+                       0u,
+                       imageRSSizeInBytes
+               );
+
+               deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
+       }
+
+       // End recording commands
+       VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
+
+       // Submit commands for execution and wait for completion
+       submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
+
+       // Retrieve data from buffer to host memory
+       const Allocation& bufferRSAllocation = bufferRS->getAllocation();
+
+       invalidateMappedMemoryRange(deviceInterface, device, bufferRSAllocation.getMemory(), bufferRSAllocation.getOffset(), imageRSSizeInBytes);
+
+       const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
+                                                                                                       imageRSInfo.extent.width,
+                                                                                                       imageRSInfo.extent.height,
+                                                                                                       imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
+                                                                                                       bufferRSAllocation.getHostPtr());
+
+       std::stringstream imageName;
+       imageName << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
+
+       m_context.getTestContext().getLog()
+               << tcu::TestLog::Section(imageName.str(), imageName.str())
+               << tcu::LogImage("image", "", bufferRSData)
+               << tcu::TestLog::EndSection;
+
+       return verifyResolvedImage(bufferRSData);
+}
+
+class MSInstanceDistinctValues : public MSInterpolationInstanceBase
+{
+public:
+                                       MSInstanceDistinctValues(Context&                               context,
+                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationInstanceBase(context, imageMSParams) {}
+
+       VertexDataDesc  getVertexDataDescripton (void) const;
+       void                    uploadVertexData                (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
+       tcu::TestStatus verifyResolvedImage             (const tcu::ConstPixelBufferAccess&     imageData) const;
+
+protected:
+       struct VertexData
+       {
+               VertexData(const tcu::Vec4& posNdc) : positionNdc(posNdc) {}
+
+               tcu::Vec4 positionNdc;
+       };
+};
+
+MSInterpolationInstanceBase::VertexDataDesc MSInstanceDistinctValues::getVertexDataDescripton (void) const
+{
+       VertexDataDesc vertexDataDesc;
+
+       vertexDataDesc.verticesCount            = 3u;
+       vertexDataDesc.dataStride                       = sizeof(VertexData);
+       vertexDataDesc.dataSize                         = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
+       vertexDataDesc.primitiveTopology        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+       const VkVertexInputAttributeDescription vertexAttribPositionNdc =
+       {
+               0u,                                                                             // deUint32     location;
+               0u,                                                                             // deUint32     binding;
+               VK_FORMAT_R32G32B32A32_SFLOAT,                  // VkFormat     format;
+               DE_OFFSET_OF(VertexData, positionNdc),  // deUint32     offset;
+       };
+
+       vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
+
+       return vertexDataDesc;
+}
+
+void MSInstanceDistinctValues::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+       std::vector<VertexData> vertices;
+
+       vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f)));
+       vertices.push_back(VertexData(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f)));
+       vertices.push_back(VertexData(tcu::Vec4( 4.0f,-1.0f, 0.0f, 1.0f)));
+
+       deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
+}
+
+tcu::TestStatus        MSInstanceDistinctValues::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
+{
+       const deUint32 distinctValuesExpected = static_cast<deUint32>(m_imageMSParams.numSamples) + 1u;
+
+       std::vector<tcu::IVec4> distinctValues;
+
+       for (deInt32 z = 0u; z < imageData.getDepth();  ++z)
+       for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
+       for (deInt32 x = 0u; x < imageData.getWidth();  ++x)
+       {
+               const tcu::IVec4 pixel = imageData.getPixelInt(x, y, z);
+
+               if (std::find(distinctValues.begin(), distinctValues.end(), pixel) == distinctValues.end())
+                       distinctValues.push_back(pixel);
+       }
+
+       if (distinctValues.size() >= distinctValuesExpected)
+               return tcu::TestStatus::pass("Passed");
+       else
+               return tcu::TestStatus::fail("Failed");
+}
+
+class MSCaseSampleQualifierDistinctValues : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseSampleQualifierDistinctValues     (tcu::TestContext&              testCtx,
+                                                                                                                const std::string&             name,
+                                                                                                                const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                            (void);
+       void                    initPrograms                                            (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                          (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseSampleQualifierDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseSampleQualifierDistinctValues(testCtx, name, imageMSParams);
+}
+
+void MSCaseSampleQualifierDistinctValues::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that a sample qualified varying is given different values for different samples.\n"
+               << "    Render full screen traingle with quadratic function defining red/green color pattern division.\n"
+               << "    => Resulting image should contain n+1 different colors, where n = sample count.\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseSampleQualifierDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "\n"
+               << "layout(location = 0) out vec4 vs_out_position_ndc;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                     = vs_in_position_ndc;\n"
+               << "    vs_out_position_ndc = vs_in_position_ndc;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) sample in vec4 fs_in_position_ndc;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    if(fs_in_position_ndc.y < -2.0*pow(0.5*(fs_in_position_ndc.x + 1.0), 2.0) + 1.0)\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseSampleQualifierDistinctValues::createInstance (Context& context) const
+{
+       return new MSInstanceDistinctValues(context, m_imageMSParams);
+}
+
+class MSCaseInterpolateAtSampleDistinctValues : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtSampleDistinctValues (tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseInterpolateAtSampleDistinctValues (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseInterpolateAtSampleDistinctValues(testCtx, name, imageMSParams);
+}
+
+void MSCaseInterpolateAtSampleDistinctValues::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that a interpolateAtSample returns different values for different samples.\n"
+               << "    Render full screen traingle with quadratic function defining red/green color pattern division.\n"
+               << "    => Resulting image should contain n+1 different colors, where n = sample count.\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtSampleDistinctValues::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "\n"
+               << "layout(location = 0) out vec4 vs_out_position_ndc;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                     = vs_in_position_ndc;\n"
+               << "    vs_out_position_ndc = vs_in_position_ndc;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) in vec4 fs_in_position_ndc;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const vec4 position_ndc_at_sample = interpolateAtSample(fs_in_position_ndc, gl_SampleID);\n"
+               << "    if(position_ndc_at_sample.y < -2.0*pow(0.5*(position_ndc_at_sample.x + 1.0), 2.0) + 1.0)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtSampleDistinctValues::createInstance (Context& context) const
+{
+       return new MSInstanceDistinctValues(context, m_imageMSParams);
+}
+
+class MSInstanceInterpolateScreenPosition : public MSInterpolationInstanceBase
+{
+public:
+                                       MSInstanceInterpolateScreenPosition     (Context&                               context,
+                                                                                                                const ImageMSParams&   imageMSParams)
+       : MSInterpolationInstanceBase(context, imageMSParams) {}
+
+       VertexDataDesc  getVertexDataDescripton                         (void) const;
+       void                    uploadVertexData                                        (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
+       tcu::TestStatus verifyResolvedImage                                     (const tcu::ConstPixelBufferAccess&     imageData) const;
+
+protected:
+       struct VertexData
+       {
+               VertexData(const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {}
+
+               tcu::Vec4 positionNdc;
+               tcu::Vec2 positionScreen;
+       };
+};
+
+MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateScreenPosition::getVertexDataDescripton (void) const
+{
+       VertexDataDesc vertexDataDesc;
+
+       vertexDataDesc.verticesCount            = 4u;
+       vertexDataDesc.dataStride                       = sizeof(VertexData);
+       vertexDataDesc.dataSize                         = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
+       vertexDataDesc.primitiveTopology        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
+
+       const VkVertexInputAttributeDescription vertexAttribPositionNdc =
+       {
+               0u,                                                                                     // deUint32     location;
+               0u,                                                                                     // deUint32     binding;
+               VK_FORMAT_R32G32B32A32_SFLOAT,                          // VkFormat     format;
+               DE_OFFSET_OF(VertexData, positionNdc),          // deUint32     offset;
+       };
+
+       vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
+
+       const VkVertexInputAttributeDescription vertexAttribPositionScreen =
+       {
+               1u,                                                                                     // deUint32     location;
+               0u,                                                                                     // deUint32     binding;
+               VK_FORMAT_R32G32_SFLOAT,                                        // VkFormat     format;
+               DE_OFFSET_OF(VertexData, positionScreen),       // deUint32     offset;
+       };
+
+       vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionScreen);
+
+       return vertexDataDesc;
+}
+
+void MSInstanceInterpolateScreenPosition::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+       const tcu::UVec3 layerSize              = getLayerSize(IMAGE_TYPE_2D, m_imageMSParams.imageSize);
+       const float              screenSizeX    = static_cast<float>(layerSize.x());
+       const float              screenSizeY    = static_cast<float>(layerSize.y());
+
+       std::vector<VertexData> vertices;
+
+       vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f,                0.0f)));
+       vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, 0.0f)));
+       vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f,                screenSizeY)));
+       vertices.push_back(VertexData(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, screenSizeY)));
+
+       deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
+}
+
+tcu::TestStatus        MSInstanceInterpolateScreenPosition::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
+{
+       for (deInt32 z = 0u; z < imageData.getDepth();  ++z)
+       for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
+       for (deInt32 x = 0u; x < imageData.getWidth();  ++x)
+       {
+               const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
+
+               if (firstComponent > 0)
+                       return tcu::TestStatus::fail("Failed");
+       }
+       return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseInterpolateAtSampleSingleSample : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtSampleSingleSample   (tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        tcu::UVec3                             imageSize)
+       : MSInterpolationCaseBase(testCtx, name, ImageMSParams(VK_SAMPLE_COUNT_1_BIT, imageSize)) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+void MSCaseInterpolateAtSampleSingleSample::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that using interpolateAtSample with multisample buffers not available returns sample evaluated at the center of the pixel.\n"
+               << "    Interpolate varying containing screen space location.\n"
+               << "    => fract(screen space location) should be (about) (0.5, 0.5)\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtSampleSingleSample::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 vs_out_position_screen;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                             = vs_in_position_ndc;\n"
+               << "    vs_out_position_screen  = vs_in_position_screen;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) in vec2 fs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const float threshold                                   = 0.15625;\n"
+               << "    const vec2  position_screen_at_sample   = interpolateAtSample(fs_in_position_screen, 0);\n"
+               << "    const vec2  position_inside_pixel               = fract(position_screen_at_sample);\n"
+               << "\n"
+               << "    if (abs(position_inside_pixel.x - 0.5) <= threshold && abs(position_inside_pixel.y - 0.5) <= threshold)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtSampleSingleSample::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+}
+
+class MSCaseInterpolateAtSampleIgnoresCentroid : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtSampleIgnoresCentroid(tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseInterpolateAtSampleIgnoresCentroid (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseInterpolateAtSampleIgnoresCentroid(testCtx, name, imageMSParams);
+}
+
+void MSCaseInterpolateAtSampleIgnoresCentroid::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that interpolateAtSample ignores centroid qualifier.\n"
+               << "    Interpolate varying containing screen space location with centroid and sample qualifiers.\n"
+               << "    => interpolateAtSample(screenSample, n) ~= interpolateAtSample(screenCentroid, n)\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtSampleIgnoresCentroid::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n"
+               << "layout(location = 1) out vec2 vs_out_pos_screen_fragment;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                                     = vs_in_position_ndc;\n"
+               << "    vs_out_pos_screen_centroid      = vs_in_position_screen;\n"
+               << "    vs_out_pos_screen_fragment      = vs_in_position_screen;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
+               << "layout(location = 1)                  in vec2 fs_in_pos_screen_fragment;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const float threshold = 0.0005;\n"
+               << "\n"
+               << "    const vec2 position_a  = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n"
+               << "    const vec2 position_b  = interpolateAtSample(fs_in_pos_screen_fragment, gl_SampleID);\n"
+               << "    const bool valuesEqual = all(lessThan(abs(position_a - position_b), vec2(threshold)));\n"
+               << "\n"
+               << "    if (valuesEqual)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtSampleIgnoresCentroid::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+}
+
+class MSCaseInterpolateAtSampleConsistency : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtSampleConsistency    (tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseInterpolateAtSampleConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseInterpolateAtSampleConsistency(testCtx, name, imageMSParams);
+}
+
+void MSCaseInterpolateAtSampleConsistency::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that interpolateAtSample with the sample set to the current sampleID returns consistent values.\n"
+               << "    Interpolate varying containing screen space location with centroid and sample qualifiers.\n"
+               << "    => interpolateAtSample(screenCentroid, sampleID) = screenSample\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtSampleConsistency::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n"
+               << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                                     = vs_in_position_ndc;\n"
+               << "    vs_out_pos_screen_centroid      = vs_in_position_screen;\n"
+               << "    vs_out_pos_screen_sample        = vs_in_position_screen;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n"
+               << "layout(location = 1) sample   in vec2 fs_in_pos_screen_sample;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const float threshold = 0.15625;\n"
+               << "\n"
+               << "    const vec2  pos_interpolated_at_sample = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n"
+               << "    const bool  valuesEqual                            = all(lessThan(abs(pos_interpolated_at_sample - fs_in_pos_screen_sample), vec2(threshold)));\n"
+               << "\n"
+               << "    if (valuesEqual)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtSampleConsistency::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+}
+
+class MSCaseInterpolateAtCentroidConsistency : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtCentroidConsistency  (tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseInterpolateAtCentroidConsistency (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseInterpolateAtCentroidConsistency(testCtx, name, imageMSParams);
+}
+
+void MSCaseInterpolateAtCentroidConsistency::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that interpolateAtCentroid does not return different values than a corresponding centroid qualified varying.\n"
+               << "    Interpolate varying containing screen space location with sample and centroid qualifiers.\n"
+               << "    => interpolateAtCentroid(screenSample) = screenCentroid\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtCentroidConsistency::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 vs_out_pos_screen_sample;\n"
+               << "layout(location = 1) out vec2 vs_out_pos_screen_centroid;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                                     = vs_in_position_ndc;\n"
+               << "    vs_out_pos_screen_sample        = vs_in_position_screen;\n"
+               << "    vs_out_pos_screen_centroid      = vs_in_position_screen;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) sample   in vec2 fs_in_pos_screen_sample;\n"
+               << "layout(location = 1) centroid in vec2 fs_in_pos_screen_centroid;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const float threshold = 0.0005;\n"
+               << "\n"
+               << "    const vec2 pos_interpolated_at_centroid = interpolateAtCentroid(fs_in_pos_screen_sample);\n"
+               << "    const bool valuesEqual                                  = all(lessThan(abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid), vec2(threshold)));\n"
+               << "\n"
+               << "    if (valuesEqual)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtCentroidConsistency::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+}
+
+class MSCaseInterpolateAtOffsetPixelCenter : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtOffsetPixelCenter(tcu::TestContext&          testCtx,
+                                                                                                                const std::string&             name,
+                                                                                                                const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                            (void);
+       void                    initPrograms                                            (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                          (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetPixelCenter (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseInterpolateAtOffsetPixelCenter(testCtx, name, imageMSParams);
+}
+
+void MSCaseInterpolateAtOffsetPixelCenter::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that interpolateAtOffset returns value sampled at an offset from the center of the pixel.\n"
+               << "    Interpolate varying containing screen space location.\n"
+               << "    => interpolateAtOffset(screen, offset) should be \"varying value at the pixel center\" + offset"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtOffsetPixelCenter::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 vs_out_pos_screen;\n"
+               << "layout(location = 1) out vec2 vs_out_offset;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                     = vs_in_position_ndc;\n"
+               << "    vs_out_pos_screen       = vs_in_position_screen;\n"
+               << "    vs_out_offset           = vs_in_position_ndc.xy * 0.5;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) in vec2 fs_in_pos_screen;\n"
+               << "layout(location = 1) in vec2 fs_in_offset;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const float threshold = 0.15625;\n"
+               << "\n"
+               << "    const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen, fs_in_offset);\n"
+               << "    const vec2 pixel_center                           = floor(fs_in_pos_screen) + vec2(0.5, 0.5);\n"
+               << "    const vec2 reference_value                        = pixel_center + fs_in_offset;\n"
+               << "    const bool valuesEqual                            = all(lessThan(abs(pos_interpolated_at_offset - reference_value), vec2(threshold)));\n"
+               << "\n"
+               << "    if (valuesEqual)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtOffsetPixelCenter::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+}
+
+class MSCaseInterpolateAtOffsetSamplePosition : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseInterpolateAtOffsetSamplePosition (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseInterpolateAtOffsetSamplePosition(testCtx, name, imageMSParams);
+}
+
+void MSCaseInterpolateAtOffsetSamplePosition::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that interpolateAtOffset of screen position with the offset of current sample position returns value "
+               << "similar to screen position interpolated at sample.\n"
+               << "    Interpolate varying containing screen space location with and without sample qualifier.\n"
+               << "    => interpolateAtOffset(screenFragment, samplePosition - (0.5,0.5)) = screenSample"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseInterpolateAtOffsetSamplePosition::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec2 vs_in_position_screen;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 vs_out_pos_screen_fragment;\n"
+               << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position                                     = vs_in_position_ndc;\n"
+               << "    vs_out_pos_screen_fragment      = vs_in_position_screen;\n"
+               << "    vs_out_pos_screen_sample        = vs_in_position_screen;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0)                in vec2 fs_in_pos_screen_fragment;\n"
+               << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    const float threshold = 0.15625;\n"
+               << "\n"
+               << "    const vec2 offset                                         = gl_SamplePosition - vec2(0.5, 0.5);\n"
+               << "    const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen_fragment, offset);\n"
+               << "    const bool valuesEqual                            = all(lessThan(abs(pos_interpolated_at_offset - fs_in_pos_screen_sample), vec2(threshold)));\n"
+               << "\n"
+               << "    if (valuesEqual)\n"
+               << "            fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "            fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseInterpolateAtOffsetSamplePosition::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateScreenPosition(context, m_imageMSParams);
+}
+
+class MSInstanceInterpolateBarycentricCoordinates : public MSInterpolationInstanceBase
+{
+public:
+                                       MSInstanceInterpolateBarycentricCoordinates     (Context&                               context,
+                                                                                                                                const ImageMSParams&   imageMSParams)
+       : MSInterpolationInstanceBase(context, imageMSParams) {}
+
+       VertexDataDesc  getVertexDataDescripton                                         (void) const;
+       void                    uploadVertexData                                                        (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const;
+       tcu::TestStatus verifyResolvedImage                                                     (const tcu::ConstPixelBufferAccess&     imageData) const;
+
+protected:
+       struct VertexData
+       {
+               VertexData(const tcu::Vec4& posNdc, const tcu::Vec3& barCoord) : positionNdc(posNdc), barycentricCoord(barCoord) {}
+
+               tcu::Vec4 positionNdc;
+               tcu::Vec3 barycentricCoord;
+       };
+};
+
+MSInterpolationInstanceBase::VertexDataDesc MSInstanceInterpolateBarycentricCoordinates::getVertexDataDescripton (void) const
+{
+       VertexDataDesc vertexDataDesc;
+
+       vertexDataDesc.verticesCount            = 3u;
+       vertexDataDesc.dataStride                       = sizeof(VertexData);
+       vertexDataDesc.dataSize                         = vertexDataDesc.verticesCount * vertexDataDesc.dataStride;
+       vertexDataDesc.primitiveTopology        = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+
+       const VkVertexInputAttributeDescription vertexAttribPositionNdc =
+       {
+               0u,                                                                                     // deUint32     location;
+               0u,                                                                                     // deUint32     binding;
+               VK_FORMAT_R32G32B32A32_SFLOAT,                          // VkFormat     format;
+               DE_OFFSET_OF(VertexData, positionNdc),          // deUint32     offset;
+       };
+
+       vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc);
+
+       const VkVertexInputAttributeDescription vertexAttrBarCoord =
+       {
+               1u,                                                                                     // deUint32     location;
+               0u,                                                                                     // deUint32     binding;
+               VK_FORMAT_R32G32B32_SFLOAT,                                     // VkFormat     format;
+               DE_OFFSET_OF(VertexData, barycentricCoord),     // deUint32     offset;
+       };
+
+       vertexDataDesc.vertexAttribDescVec.push_back(vertexAttrBarCoord);
+
+       return vertexDataDesc;
+}
+
+void MSInstanceInterpolateBarycentricCoordinates::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const
+{
+       // Create buffer storing vertex data
+       std::vector<VertexData> vertices;
+
+       vertices.push_back(VertexData(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 0.0f, 1.0f)));
+       vertices.push_back(VertexData(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec3(1.0f, 0.0f, 0.0f)));
+       vertices.push_back(VertexData(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 1.0f, 0.0f)));
+
+       deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize));
+}
+
+tcu::TestStatus MSInstanceInterpolateBarycentricCoordinates::verifyResolvedImage (const tcu::ConstPixelBufferAccess& imageData) const
+{
+       for (deInt32 z = 0u; z < imageData.getDepth();  ++z)
+       for (deInt32 y = 0u; y < imageData.getHeight(); ++y)
+       for (deInt32 x = 0u; x < imageData.getWidth();  ++x)
+       {
+               const deInt32 firstComponent = imageData.getPixelInt(x, y, z).x();
+
+               if (firstComponent > 0)
+                       return tcu::TestStatus::fail("Failed");
+       }
+
+       return tcu::TestStatus::pass("Passed");
+}
+
+class MSCaseCentroidQualifierInsidePrimitive : public MSInterpolationCaseBase
+{
+public:
+                                       MSCaseCentroidQualifierInsidePrimitive  (tcu::TestContext&              testCtx,
+                                                                                                                        const std::string&             name,
+                                                                                                                        const ImageMSParams&   imageMSParams)
+       : MSInterpolationCaseBase(testCtx, name, imageMSParams) {}
+
+       void                    init                                                                    (void);
+       void                    initPrograms                                                    (vk::SourceCollections& programCollection) const;
+       TestInstance*   createInstance                                                  (Context&                               context) const;
+};
+
+MSInterpolationCaseBase* createMSCaseCentroidQualifierInsidePrimitive (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams)
+{
+       return new MSCaseCentroidQualifierInsidePrimitive(testCtx, name, imageMSParams);
+}
+
+void MSCaseCentroidQualifierInsidePrimitive::init (void)
+{
+       m_testCtx.getLog()
+               << tcu::TestLog::Message
+               << "Verifying that varying qualified with centroid is interpolated at location inside both the pixel and the primitive being processed.\n"
+               << "    Interpolate triangle's barycentric coordinates with centroid qualifier.\n"
+               << "    => After interpolation we expect barycentric.xyz >= 0.0 && barycentric.xyz <= 1.0\n"
+               << tcu::TestLog::EndMessage;
+
+       MSInterpolationCaseBase::init();
+}
+
+void MSCaseCentroidQualifierInsidePrimitive::initPrograms (vk::SourceCollections& programCollection) const
+{
+       // Create vertex shader
+       std::ostringstream vs;
+
+       vs << "#version 440\n"
+               << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
+               << "layout(location = 1) in vec3 vs_in_barCoord;\n"
+               << "\n"
+               << "layout(location = 0) out vec3 vs_out_barCoord;\n"
+               << "\n"
+               << "out gl_PerVertex {\n"
+               << "    vec4  gl_Position;\n"
+               << "};\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    gl_Position             = vs_in_position_ndc;\n"
+               << "    vs_out_barCoord = vs_in_barCoord;\n"
+               << "}\n";
+
+       programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
+
+       // Create fragment shader
+       std::ostringstream fs;
+
+       fs << "#version 440\n"
+               << "layout(location = 0) centroid in vec3 fs_in_barCoord;\n"
+               << "\n"
+               << "layout(location = 0) out vec2 fs_out_color;\n"
+               << "\n"
+               << "void main (void)\n"
+               << "{\n"
+               << "    if( all(greaterThanEqual(fs_in_barCoord, vec3(0.0))) && all(lessThanEqual(fs_in_barCoord, vec3(1.0))) )\n"
+               << "                    fs_out_color = vec2(0.0, 1.0);\n"
+               << "    else\n"
+               << "                    fs_out_color = vec2(1.0, 0.0);\n"
+               << "}\n";
+
+       programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str());
+}
+
+TestInstance* MSCaseCentroidQualifierInsidePrimitive::createInstance (Context& context) const
+{
+       return new MSInstanceInterpolateBarycentricCoordinates(context, m_imageMSParams);
+}
+
+} // multisample
+
+tcu::TestCaseGroup* makeGroup( multisample::MSInterpolationCaseFuncPtr createCaseFuncPtr,
+                                                               tcu::TestContext&                                               testCtx,
+                                                               const std::string                                               groupName,
+                                                               const tcu::UVec3                                                imageSizes[],
+                                                               const deUint32                                                  imageSizesElemCount,
+                                                               const vk::VkSampleCountFlagBits                 imageSamples[],
+                                                               const deUint32                                                  imageSamplesElemCount)
+{
+       de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), ""));
+
+       for (deUint32 imageSizeNdx = 0u; imageSizeNdx < imageSizesElemCount; ++imageSizeNdx)
+       {
+               const tcu::UVec3        imageSize = imageSizes[imageSizeNdx];
+               std::ostringstream      imageSizeStream;
+
+               imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
+
+               de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
+
+               for (deUint32 imageSamplesNdx = 0u; imageSamplesNdx < imageSamplesElemCount; ++imageSamplesNdx)
+               {
+                       const vk::VkSampleCountFlagBits         samples                 = imageSamples[imageSamplesNdx];
+                       const multisample::ImageMSParams        imageMSParams   = multisample::ImageMSParams(samples, imageSize);
+
+                       sizeGroup->addChild(createCaseFuncPtr(testCtx, "samples_" + de::toString(samples), imageMSParams));
+               }
+
+               caseGroup->addChild(sizeGroup.release());
+       }
+       return caseGroup.release();
+}
+
+tcu::TestCaseGroup* createMultisampleInterpolationTests (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "multisample_interpolation", "Multisample Interpolation"));
+
+       const tcu::UVec3 imageSizes[] =
+       {
+               tcu::UVec3(128u, 128u, 1u),
+               tcu::UVec3(137u, 191u, 1u),
+       };
+
+       const deUint32 sizesElemCount = static_cast<deUint32>(sizeof(imageSizes) / sizeof(tcu::UVec3));
+
+       const vk::VkSampleCountFlagBits imageSamples[] =
+       {
+               vk::VK_SAMPLE_COUNT_2_BIT,
+               vk::VK_SAMPLE_COUNT_4_BIT,
+               vk::VK_SAMPLE_COUNT_8_BIT,
+               vk::VK_SAMPLE_COUNT_16_BIT,
+               vk::VK_SAMPLE_COUNT_32_BIT,
+               vk::VK_SAMPLE_COUNT_64_BIT,
+       };
+
+       const deUint32 samplesElemCount = static_cast<deUint32>(sizeof(imageSamples) / sizeof(vk::VkSampleCountFlagBits));
+
+       de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, "sample_interpolate_at_single_sample_", ""));
+
+       for (deUint32 imageSizeNdx = 0u; imageSizeNdx < sizesElemCount; ++imageSizeNdx)
+       {
+               const tcu::UVec3        imageSize = imageSizes[imageSizeNdx];
+               std::ostringstream      imageSizeStream;
+
+               imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z();
+
+               de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str(), ""));
+
+               sizeGroup->addChild(new multisample::MSCaseInterpolateAtSampleSingleSample(testCtx, "samples_" + de::toString(1), imageSize));
+
+               caseGroup->addChild(sizeGroup.release());
+       }
+
+       testGroup->addChild(caseGroup.release());
+
+       testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleDistinctValues,       testCtx, "sample_interpolate_at_distinct_values",       imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleIgnoresCentroid,      testCtx, "sample_interpolate_at_ignores_centroid",      imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtSampleConsistency,          testCtx, "sample_interpolate_at_consistency",           imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseSampleQualifierDistinctValues,           testCtx, "sample_qualifier_distinct_values",            imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtCentroidConsistency,        testCtx, "centroid_interpolate_at_consistency",         imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseCentroidQualifierInsidePrimitive,        testCtx, "centroid_qualifier_inside_primitive",         imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetPixelCenter,          testCtx, "offset_interpolate_at_pixel_center",          imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+       testGroup->addChild(makeGroup(multisample::createMSCaseInterpolateAtOffsetSamplePosition,       testCtx, "offset_interpolate_at_sample_position",       imageSizes, sizesElemCount, imageSamples, samplesElemCount));
+
+       return testGroup.release();
+}
+
+} // pipeline
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleInterpolationTests.hpp
new file mode 100644 (file)
index 0000000..c4052ca
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _VKTPIPELINEMULTISAMPLEINTERPOLATIONTESTS_HPP
+#define _VKTPIPELINEMULTISAMPLEINTERPOLATIONTESTS_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2015 The Khronos Group Inc.
+ * Copyright (c) 2015 Imagination Technologies Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file vktPipelineMultisampleInterpolationTests.hpp
+ * \brief Multisample Interpolation Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "vktTestCase.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+
+tcu::TestCaseGroup* createMultisampleInterpolationTests (tcu::TestContext& testCtx);
+
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLEINTERPOLATIONTESTS_HPP
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.cpp
new file mode 100644 (file)
index 0000000..f1493e2
--- /dev/null
@@ -0,0 +1,417 @@
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file  vktPipelineMultisampleTestsUtil.cpp
+ * \brief Multisample Tests Utility Classes
+ *//*--------------------------------------------------------------------*/
+
+#include "vktPipelineMultisampleTestsUtil.hpp"
+#include "vkQueryUtil.hpp"
+#include "vkTypeUtil.hpp"
+#include "tcuTextureUtil.hpp"
+
+#include <deMath.h>
+
+using namespace vk;
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+tcu::UVec3 getShaderGridSize (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel)
+{
+       const deUint32 mipLevelX = std::max(imageSize.x() >> mipLevel, 1u);
+       const deUint32 mipLevelY = std::max(imageSize.y() >> mipLevel, 1u);
+       const deUint32 mipLevelZ = std::max(imageSize.z() >> mipLevel, 1u);
+
+       switch (imageType)
+       {
+       case IMAGE_TYPE_1D:
+               return tcu::UVec3(mipLevelX, 1u, 1u);
+
+       case IMAGE_TYPE_BUFFER:
+               return tcu::UVec3(imageSize.x(), 1u, 1u);
+
+       case IMAGE_TYPE_1D_ARRAY:
+               return tcu::UVec3(mipLevelX, imageSize.z(), 1u);
+
+       case IMAGE_TYPE_2D:
+               return tcu::UVec3(mipLevelX, mipLevelY, 1u);
+
+       case IMAGE_TYPE_2D_ARRAY:
+               return tcu::UVec3(mipLevelX, mipLevelY, imageSize.z());
+
+       case IMAGE_TYPE_3D:
+               return tcu::UVec3(mipLevelX, mipLevelY, mipLevelZ);
+
+       case IMAGE_TYPE_CUBE:
+               return tcu::UVec3(mipLevelX, mipLevelY, 6u);
+
+       case IMAGE_TYPE_CUBE_ARRAY:
+               return tcu::UVec3(mipLevelX, mipLevelY, 6u * imageSize.z());
+
+       default:
+               DE_FATAL("Unknown image type");
+               return tcu::UVec3(1u, 1u, 1u);
+       }
+}
+
+tcu::UVec3 getLayerSize (const ImageType imageType, const tcu::UVec3& imageSize)
+{
+       switch (imageType)
+       {
+       case IMAGE_TYPE_1D:
+       case IMAGE_TYPE_1D_ARRAY:
+       case IMAGE_TYPE_BUFFER:
+               return tcu::UVec3(imageSize.x(), 1u, 1u);
+
+       case IMAGE_TYPE_2D:
+       case IMAGE_TYPE_2D_ARRAY:
+       case IMAGE_TYPE_CUBE:
+       case IMAGE_TYPE_CUBE_ARRAY:
+               return tcu::UVec3(imageSize.x(), imageSize.y(), 1u);
+
+       case IMAGE_TYPE_3D:
+               return tcu::UVec3(imageSize.x(), imageSize.y(), imageSize.z());
+
+       default:
+               DE_FATAL("Unknown image type");
+               return tcu::UVec3(1u, 1u, 1u);
+       }
+}
+
+deUint32 getNumLayers (const ImageType imageType, const tcu::UVec3& imageSize)
+{
+       switch (imageType)
+       {
+       case IMAGE_TYPE_1D:
+       case IMAGE_TYPE_2D:
+       case IMAGE_TYPE_3D:
+       case IMAGE_TYPE_BUFFER:
+               return 1u;
+
+       case IMAGE_TYPE_1D_ARRAY:
+       case IMAGE_TYPE_2D_ARRAY:
+               return imageSize.z();
+
+       case IMAGE_TYPE_CUBE:
+               return 6u;
+
+       case IMAGE_TYPE_CUBE_ARRAY:
+               return imageSize.z() * 6u;
+
+       default:
+               DE_FATAL("Unknown image type");
+               return 0u;
+       }
+}
+
+deUint32 getNumPixels (const ImageType imageType, const tcu::UVec3& imageSize)
+{
+       const tcu::UVec3 gridSize = getShaderGridSize(imageType, imageSize);
+
+       return gridSize.x() * gridSize.y() * gridSize.z();
+}
+
+deUint32 getDimensions (const ImageType imageType)
+{
+       switch (imageType)
+       {
+       case IMAGE_TYPE_1D:
+       case IMAGE_TYPE_BUFFER:
+               return 1u;
+
+       case IMAGE_TYPE_1D_ARRAY:
+       case IMAGE_TYPE_2D:
+               return 2u;
+
+       case IMAGE_TYPE_2D_ARRAY:
+       case IMAGE_TYPE_CUBE:
+       case IMAGE_TYPE_CUBE_ARRAY:
+       case IMAGE_TYPE_3D:
+               return 3u;
+
+       default:
+               DE_FATAL("Unknown image type");
+               return 0u;
+       }
+}
+
+deUint32 getLayerDimensions (const ImageType imageType)
+{
+       switch (imageType)
+       {
+       case IMAGE_TYPE_1D:
+       case IMAGE_TYPE_BUFFER:
+       case IMAGE_TYPE_1D_ARRAY:
+               return 1u;
+
+       case IMAGE_TYPE_2D:
+       case IMAGE_TYPE_2D_ARRAY:
+       case IMAGE_TYPE_CUBE:
+       case IMAGE_TYPE_CUBE_ARRAY:
+               return 2u;
+
+       case IMAGE_TYPE_3D:
+               return 3u;
+
+       default:
+               DE_FATAL("Unknown image type");
+               return 0u;
+       }
+}
+
+VkImageType    mapImageType (const ImageType imageType)
+{
+       switch (imageType)
+       {
+               case IMAGE_TYPE_1D:
+               case IMAGE_TYPE_1D_ARRAY:
+               case IMAGE_TYPE_BUFFER:
+                       return VK_IMAGE_TYPE_1D;
+
+               case IMAGE_TYPE_2D:
+               case IMAGE_TYPE_2D_ARRAY:
+               case IMAGE_TYPE_CUBE:
+               case IMAGE_TYPE_CUBE_ARRAY:
+                       return VK_IMAGE_TYPE_2D;
+
+               case IMAGE_TYPE_3D:
+                       return VK_IMAGE_TYPE_3D;
+
+               default:
+                       DE_ASSERT(false);
+                       return VK_IMAGE_TYPE_LAST;
+       }
+}
+
+VkImageViewType        mapImageViewType (const ImageType imageType)
+{
+       switch (imageType)
+       {
+               case IMAGE_TYPE_1D:                     return VK_IMAGE_VIEW_TYPE_1D;
+               case IMAGE_TYPE_1D_ARRAY:       return VK_IMAGE_VIEW_TYPE_1D_ARRAY;
+               case IMAGE_TYPE_2D:                     return VK_IMAGE_VIEW_TYPE_2D;
+               case IMAGE_TYPE_2D_ARRAY:       return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
+               case IMAGE_TYPE_3D:                     return VK_IMAGE_VIEW_TYPE_3D;
+               case IMAGE_TYPE_CUBE:           return VK_IMAGE_VIEW_TYPE_CUBE;
+               case IMAGE_TYPE_CUBE_ARRAY:     return VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
+
+               default:
+                       DE_ASSERT(false);
+                       return VK_IMAGE_VIEW_TYPE_LAST;
+       }
+}
+
+std::string getImageTypeName (const ImageType imageType)
+{
+       switch (imageType)
+       {
+               case IMAGE_TYPE_1D:                     return "1d";
+               case IMAGE_TYPE_1D_ARRAY:       return "1d_array";
+               case IMAGE_TYPE_2D:                     return "2d";
+               case IMAGE_TYPE_2D_ARRAY:       return "2d_array";
+               case IMAGE_TYPE_3D:                     return "3d";
+               case IMAGE_TYPE_CUBE:           return "cube";
+               case IMAGE_TYPE_CUBE_ARRAY:     return "cube_array";
+               case IMAGE_TYPE_BUFFER:         return "buffer";
+
+               default:
+                       DE_ASSERT(false);
+                       return "";
+       }
+}
+
+std::string getShaderImageType (const tcu::TextureFormat& format, const ImageType imageType)
+{
+       std::string formatPart = tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ? "u" :
+                                                        tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER   ? "i" : "";
+
+       std::string imageTypePart;
+       switch (imageType)
+       {
+               case IMAGE_TYPE_1D:                     imageTypePart = "1D";                   break;
+               case IMAGE_TYPE_1D_ARRAY:       imageTypePart = "1DArray";              break;
+               case IMAGE_TYPE_2D:                     imageTypePart = "2D";                   break;
+               case IMAGE_TYPE_2D_ARRAY:       imageTypePart = "2DArray";              break;
+               case IMAGE_TYPE_3D:                     imageTypePart = "3D";                   break;
+               case IMAGE_TYPE_CUBE:           imageTypePart = "Cube";                 break;
+               case IMAGE_TYPE_CUBE_ARRAY:     imageTypePart = "CubeArray";    break;
+               case IMAGE_TYPE_BUFFER:         imageTypePart = "Buffer";               break;
+
+               default:
+                       DE_ASSERT(false);
+       }
+
+       return formatPart + "image" + imageTypePart;
+}
+
+
+std::string getShaderImageDataType (const tcu::TextureFormat& format)
+{
+       switch (tcu::getTextureChannelClass(format.type))
+       {
+               case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
+                       return "uvec4";
+               case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
+                       return "ivec4";
+               case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
+                       return "vec4";
+               default:
+                       DE_ASSERT(false);
+                       return "";
+       }
+}
+
+std::string getShaderImageFormatQualifier (const tcu::TextureFormat& format)
+{
+       const char* orderPart;
+       const char* typePart;
+
+       switch (format.order)
+       {
+               case tcu::TextureFormat::R:             orderPart = "r";        break;
+               case tcu::TextureFormat::RG:    orderPart = "rg";       break;
+               case tcu::TextureFormat::RGB:   orderPart = "rgb";      break;
+               case tcu::TextureFormat::RGBA:  orderPart = "rgba";     break;
+
+               default:
+                       DE_ASSERT(false);
+                       orderPart = DE_NULL;
+       }
+
+       switch (format.type)
+       {
+               case tcu::TextureFormat::FLOAT:                         typePart = "32f";               break;
+               case tcu::TextureFormat::HALF_FLOAT:            typePart = "16f";               break;
+
+               case tcu::TextureFormat::UNSIGNED_INT32:        typePart = "32ui";              break;
+               case tcu::TextureFormat::UNSIGNED_INT16:        typePart = "16ui";              break;
+               case tcu::TextureFormat::UNSIGNED_INT8:         typePart = "8ui";               break;
+
+               case tcu::TextureFormat::SIGNED_INT32:          typePart = "32i";               break;
+               case tcu::TextureFormat::SIGNED_INT16:          typePart = "16i";               break;
+               case tcu::TextureFormat::SIGNED_INT8:           typePart = "8i";                break;
+
+               case tcu::TextureFormat::UNORM_INT16:           typePart = "16";                break;
+               case tcu::TextureFormat::UNORM_INT8:            typePart = "8";                 break;
+
+               case tcu::TextureFormat::SNORM_INT16:           typePart = "16_snorm";  break;
+               case tcu::TextureFormat::SNORM_INT8:            typePart = "8_snorm";   break;
+
+               default:
+                       DE_ASSERT(false);
+                       typePart = DE_NULL;
+       }
+
+       return std::string() + orderPart + typePart;
+}
+
+std::string getShaderImageCoordinates  (const ImageType        imageType,
+                                                                                const std::string&     x,
+                                                                                const std::string&     xy,
+                                                                                const std::string&     xyz)
+{
+       switch (imageType)
+       {
+               case IMAGE_TYPE_1D:
+               case IMAGE_TYPE_BUFFER:
+                       return x;
+
+               case IMAGE_TYPE_1D_ARRAY:
+               case IMAGE_TYPE_2D:
+                       return xy;
+
+               case IMAGE_TYPE_2D_ARRAY:
+               case IMAGE_TYPE_3D:
+               case IMAGE_TYPE_CUBE:
+               case IMAGE_TYPE_CUBE_ARRAY:
+                       return xyz;
+
+               default:
+                       DE_ASSERT(0);
+                       return "";
+       }
+}
+
+VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, const deUint32 mipLevel)
+{
+       VkExtent3D result;
+
+       result.width    = std::max(baseExtents.width  >> mipLevel, 1u);
+       result.height   = std::max(baseExtents.height >> mipLevel, 1u);
+       result.depth    = std::max(baseExtents.depth  >> mipLevel, 1u);
+
+       return result;
+}
+
+deUint32 getImageMaxMipLevels (const VkImageFormatProperties& imageFormatProperties, const VkExtent3D& extent)
+{
+       const deUint32 widestEdge = std::max(std::max(extent.width, extent.height), extent.depth);
+
+       return std::min(static_cast<deUint32>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, imageFormatProperties.maxMipLevels);
+}
+
+deUint32 getImageMipLevelSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel)
+{
+       const VkExtent3D extents = mipLevelExtents(baseExtents, mipmapLevel);
+
+       return extents.width * extents.height * extents.depth * layersCount * tcu::getPixelSize(format);
+}
+
+deUint32 getImageSizeInBytes (const VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount)
+{
+       deUint32 imageSizeInBytes = 0;
+       for (deUint32 mipmapLevel = 0; mipmapLevel < mipmapLevelsCount; ++mipmapLevel)
+       {
+               imageSizeInBytes += getImageMipLevelSizeInBytes(baseExtents, layersCount, format, mipmapLevel);
+       }
+
+       return imageSizeInBytes;
+}
+
+void requireFeatures (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const FeatureFlags flags)
+{
+       const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(instanceInterface, physicalDevice);
+
+       if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
+               throw tcu::NotSupportedError("Tessellation shader not supported");
+
+       if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
+               throw tcu::NotSupportedError("Geometry shader not supported");
+
+       if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
+               throw tcu::NotSupportedError("Double-precision floats not supported");
+
+       if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
+               throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
+
+       if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
+               throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
+
+       if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
+               throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
+}
+
+} // multisample
+} // pipeline
+} // vkt
diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineMultisampleTestsUtil.hpp
new file mode 100644 (file)
index 0000000..03e721e
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef _VKTPIPELINEMULTISAMPLETESTSUTIL_HPP
+#define _VKTPIPELINEMULTISAMPLETESTSUTIL_HPP
+/*------------------------------------------------------------------------
+ * Vulkan Conformance Tests
+ * ------------------------
+ *
+ * Copyright (c) 2016 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file  vktPipelineMultisampleTestsUtil.hpp
+ * \brief Multisample Tests Utility Classes
+ *//*--------------------------------------------------------------------*/
+
+#include "vkDefs.hpp"
+#include "vkMemUtil.hpp"
+#include "vkRef.hpp"
+#include "vkRefUtil.hpp"
+#include "vkPrograms.hpp"
+#include "vkTypeUtil.hpp"
+#include "vkImageUtil.hpp"
+#include "deSharedPtr.hpp"
+
+namespace vkt
+{
+namespace pipeline
+{
+namespace multisample
+{
+
+enum ImageType
+{
+       IMAGE_TYPE_1D                   = 0u,
+       IMAGE_TYPE_1D_ARRAY,
+       IMAGE_TYPE_2D,
+       IMAGE_TYPE_2D_ARRAY,
+       IMAGE_TYPE_3D,
+       IMAGE_TYPE_CUBE,
+       IMAGE_TYPE_CUBE_ARRAY,
+       IMAGE_TYPE_BUFFER,
+
+       IMAGE_TYPE_LAST
+};
+
+// Image helper functions
+vk::VkImageType                mapImageType                                    (const ImageType imageType);
+vk::VkImageViewType    mapImageViewType                                (const ImageType imageType);
+std::string                    getImageTypeName                                (const ImageType imageType);
+std::string                    getShaderImageType                              (const tcu::TextureFormat& format, const ImageType imageType);
+std::string                    getShaderImageDataType                  (const tcu::TextureFormat& format);
+std::string                    getShaderImageFormatQualifier   (const tcu::TextureFormat& format);
+std::string                    getShaderImageCoordinates               (const ImageType imageType, const std::string& x, const std::string& xy, const std::string&     xyz);
+//!< Size used for addresing image in a compute shader
+tcu::UVec3                     getShaderGridSize                               (const ImageType imageType, const tcu::UVec3& imageSize, const deUint32 mipLevel = 0);
+//!< Size of a single image layer
+tcu::UVec3                     getLayerSize                                    (const ImageType imageType, const tcu::UVec3& imageSize);
+//!< Number of array layers (for array and cube types)
+deUint32                       getNumLayers                                    (const ImageType imageType, const tcu::UVec3& imageSize);
+//!< Number of texels in an image
+deUint32                       getNumPixels                                    (const ImageType imageType, const tcu::UVec3& imageSize);
+//!< Coordinate dimension used for addressing (e.g. 3 (x,y,z) for 2d array)
+deUint32                       getDimensions                                   (const ImageType imageType);
+//!< Coordinate dimension used for addressing a single layer (e.g. 2 (x,y) for 2d array)
+deUint32                       getLayerDimensions                              (const ImageType imageType);
+vk::VkExtent3D         mipLevelExtents                                 (const vk::VkExtent3D& baseExtents, const deUint32 mipLevel);
+tcu::UVec3                     mipLevelExtents                                 (const tcu::UVec3&         baseExtents, const deUint32 mipLevel);
+deUint32                       getImageMipLevelSizeInBytes             (const vk::VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevel);
+deUint32                       getImageSizeInBytes                             (const vk::VkExtent3D& baseExtents, const deUint32 layersCount, const tcu::TextureFormat& format, const deUint32 mipmapLevelsCount = 1u);
+deUint32                       getImageMaxMipLevels                    (const vk::VkImageFormatProperties& imageFormatProperties, const vk::VkExtent3D& extent);
+
+enum FeatureFlagBits
+{
+       FEATURE_TESSELLATION_SHADER = 1u << 0,
+       FEATURE_GEOMETRY_SHADER = 1u << 1,
+       FEATURE_SHADER_FLOAT_64 = 1u << 2,
+       FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS = 1u << 3,
+       FEATURE_FRAGMENT_STORES_AND_ATOMICS = 1u << 4,
+       FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE = 1u << 5,
+};
+typedef deUint32 FeatureFlags;
+
+void requireFeatures(const vk::InstanceInterface& instanceInterface, const vk::VkPhysicalDevice physicalDevice, const FeatureFlags flags);
+
+template<typename T>
+inline de::SharedPtr<vk::Unique<T> > makeVkSharedPtr(vk::Move<T> vkMove)
+{
+       return de::SharedPtr<vk::Unique<T> >(new vk::Unique<T>(vkMove));
+}
+
+template<typename T>
+inline std::size_t sizeInBytes(const std::vector<T>& vec)
+{
+       return vec.size() * sizeof(vec[0]);
+}
+
+template<typename T>
+inline const T* dataPointer(const std::vector<T>& vec)
+{
+       return (vec.size() != 0 ? &vec[0] : DE_NULL);
+}
+
+} // multisample
+} // pipeline
+} // vkt
+
+#endif // _VKTPIPELINEMULTISAMPLETESTSUTIL_HPP
index 04997bd..f103944 100644 (file)
@@ -33,6 +33,7 @@
 #include "vktPipelinePushConstantTests.hpp"
 #include "vktPipelineSpecConstantTests.hpp"
 #include "vktPipelineMultisampleTests.hpp"
+#include "vktPipelineMultisampleInterpolationTests.hpp"
 #include "vktPipelineVertexInputTests.hpp"
 #include "vktPipelineTimestampTests.hpp"
 #include "vktPipelineEarlyFragmentTests.hpp"
@@ -51,20 +52,21 @@ void createChildren (tcu::TestCaseGroup* pipelineTests)
 {
        tcu::TestContext&       testCtx = pipelineTests->getTestContext();
 
-       pipelineTests->addChild(createStencilTests              (testCtx));
-       pipelineTests->addChild(createBlendTests                (testCtx));
-       pipelineTests->addChild(createDepthTests                (testCtx));
-       pipelineTests->addChild(createImageTests                (testCtx));
-       pipelineTests->addChild(createSamplerTests              (testCtx));
-       pipelineTests->addChild(createImageViewTests    (testCtx));
-       pipelineTests->addChild(createPushConstantTests (testCtx));
-       pipelineTests->addChild(createSpecConstantTests (testCtx));
-       pipelineTests->addChild(createMultisampleTests  (testCtx));
-       pipelineTests->addChild(createVertexInputTests  (testCtx));
-       pipelineTests->addChild(createInputAssemblyTests(testCtx));
-       pipelineTests->addChild(createTimestampTests    (testCtx));
-       pipelineTests->addChild(createEarlyFragmentTests(testCtx));
-       pipelineTests->addChild(createCacheTests                (testCtx));
+       pipelineTests->addChild(createStencilTests                                      (testCtx));
+       pipelineTests->addChild(createBlendTests                                        (testCtx));
+       pipelineTests->addChild(createDepthTests                                        (testCtx));
+       pipelineTests->addChild(createImageTests                                        (testCtx));
+       pipelineTests->addChild(createSamplerTests                                      (testCtx));
+       pipelineTests->addChild(createImageViewTests                            (testCtx));
+       pipelineTests->addChild(createPushConstantTests                         (testCtx));
+       pipelineTests->addChild(createSpecConstantTests                         (testCtx));
+       pipelineTests->addChild(createMultisampleTests                          (testCtx));
+       pipelineTests->addChild(createMultisampleInterpolationTests     (testCtx));
+       pipelineTests->addChild(createVertexInputTests                          (testCtx));
+       pipelineTests->addChild(createInputAssemblyTests                        (testCtx));
+       pipelineTests->addChild(createTimestampTests                            (testCtx));
+       pipelineTests->addChild(createEarlyFragmentTests                        (testCtx));
+       pipelineTests->addChild(createCacheTests                                        (testCtx));
 }
 
 } // anonymous
index b0bb1c6..b5a102d 100644 (file)
@@ -65229,6 +65229,104 @@ dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_32.alpha_invisible
 dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_opaque
 dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_translucent
 dEQP-VK.pipeline.multisample.alpha_to_coverage.samples_64.alpha_invisible
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.128_128_1.samples_1
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_single_sample_.137_191_1.samples_1
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_distinct_values.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_ignores_centroid.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_interpolate_at_consistency.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.sample_qualifier_distinct_values.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_interpolate_at_consistency.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.centroid_qualifier_inside_primitive.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_pixel_center.137_191_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.128_128_1.samples_64
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_2
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_4
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_8
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_16
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_32
+dEQP-VK.pipeline.multisample_interpolation.offset_interpolate_at_sample_position.137_191_1.samples_64
 dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_vertex
 dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_unorm_rate_instance
 dEQP-VK.pipeline.vertex_input.single_attribute.float_as_r8_snorm_rate_vertex