Merge vulkan-cts-1.0.2 into aosp/master am: 55da06144c am: d905a013d0 am: c91ce3f2a2
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / rasterization / vktRasterizationTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Functional rasterization tests.
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktRasterizationTests.hpp"
27 #include "tcuRasterizationVerifier.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuRenderTarget.hpp"
30 #include "tcuVectorUtil.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "tcuTextureUtil.hpp"
33 #include "tcuResultCollector.hpp"
34 #include "vkImageUtil.hpp"
35 #include "deStringUtil.hpp"
36 #include "deRandom.hpp"
37 #include "vktTestCase.hpp"
38 #include "vktTestCaseUtil.hpp"
39 #include "vktTestGroupUtil.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkMemUtil.hpp"
42 #include "vkRefUtil.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkBuilderUtil.hpp"
45 #include "vkTypeUtil.hpp"
46
47 #include <vector>
48
49 using namespace vk;
50
51 namespace vkt
52 {
53 namespace rasterization
54 {
55 namespace
56 {
57
58 using tcu::RasterizationArguments;
59 using tcu::TriangleSceneSpec;
60 using tcu::PointSceneSpec;
61 using tcu::LineSceneSpec;
62 using tcu::LineInterpolationMethod;
63
64 static const char* const s_shaderVertexTemplate =       "#version 310 es\n"
65                                                                                                         "layout(location = 0) in highp vec4 a_position;\n"
66                                                                                                         "layout(location = 1) in highp vec4 a_color;\n"
67                                                                                                         "layout(location = 0) ${INTERPOLATION}out highp vec4 v_color;\n"
68                                                                                                         "layout (set=0, binding=0) uniform PointSize {\n"
69                                                                                                         "       highp float u_pointSize;\n"
70                                                                                                         "};\n"
71                                                                                                         "void main ()\n"
72                                                                                                         "{\n"
73                                                                                                         "       gl_Position = a_position;\n"
74                                                                                                         "       gl_PointSize = u_pointSize;\n"
75                                                                                                         "       v_color = a_color;\n"
76                                                                                                         "}\n";
77
78 static const char* const s_shaderFragmentTemplate =     "#version 310 es\n"
79                                                                                                         "layout(location = 0) out highp vec4 fragColor;\n"
80                                                                                                         "layout(location = 0) ${INTERPOLATION}in highp vec4 v_color;\n"
81                                                                                                         "void main ()\n"
82                                                                                                         "{\n"
83                                                                                                         "       fragColor = v_color;\n"
84                                                                                                         "}\n";
85 enum InterpolationCaseFlags
86 {
87         INTERPOLATIONFLAGS_NONE = 0,
88         INTERPOLATIONFLAGS_PROJECTED = (1 << 1),
89         INTERPOLATIONFLAGS_FLATSHADE = (1 << 2),
90 };
91
92 enum PrimitiveWideness
93 {
94         PRIMITIVEWIDENESS_NARROW = 0,
95         PRIMITIVEWIDENESS_WIDE,
96
97         PRIMITIVEWIDENESS_LAST
98 };
99
100 class BaseRenderingTestCase : public TestCase
101 {
102 public:
103                                                                 BaseRenderingTestCase   (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deBool flatshade = DE_FALSE);
104         virtual                                         ~BaseRenderingTestCase  (void);
105
106         virtual void                            initPrograms                    (vk::SourceCollections& programCollection) const;
107
108 protected:
109         const VkSampleCountFlagBits     m_sampleCount;
110         const deBool                            m_flatshade;
111 };
112
113 BaseRenderingTestCase::BaseRenderingTestCase (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount, deBool flatshade)
114         : TestCase(context, name, description)
115         , m_sampleCount (sampleCount)
116         , m_flatshade   (flatshade)
117 {
118 }
119
120 void BaseRenderingTestCase::initPrograms (vk::SourceCollections& programCollection) const
121 {
122         tcu::StringTemplate                                     vertexSource    (s_shaderVertexTemplate);
123         tcu::StringTemplate                                     fragmentSource  (s_shaderFragmentTemplate);
124         std::map<std::string, std::string>      params;
125
126         params["INTERPOLATION"] = (m_flatshade) ? ("flat ") : ("");
127
128         programCollection.glslSources.add("vertext_shader") << glu::VertexSource(vertexSource.specialize(params));
129         programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fragmentSource.specialize(params));
130 }
131
132 BaseRenderingTestCase::~BaseRenderingTestCase (void)
133 {
134 }
135
136 class BaseRenderingTestInstance : public TestInstance
137 {
138 public:
139         enum {
140                 DEFAULT_RENDER_SIZE = 256
141         };
142
143                                                                                                         BaseRenderingTestInstance               (Context& context, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT, deUint32 renderSize = DEFAULT_RENDER_SIZE);
144                                                                                                         ~BaseRenderingTestInstance              (void);
145
146 protected:
147         void                                                                                    addImageTransitionBarrier               (VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const;
148         void                                                                                    drawPrimitives                                  (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology);
149         void                                                                                    drawPrimitives                                  (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, const std::vector<tcu::Vec4>& coloDrata, VkPrimitiveTopology primitiveTopology);
150         virtual float                                                                   getLineWidth                                    (void) const;
151         virtual float                                                                   getPointSize                                    (void) const;
152
153         virtual
154         const VkPipelineRasterizationStateCreateInfo*   getRasterizationStateCreateInfo (void) const;
155
156         virtual
157         const VkPipelineColorBlendStateCreateInfo*              getColorBlendStateCreateInfo    (void) const;
158
159         const tcu::TextureFormat&                                               getTextureFormat                                (void) const;
160
161         const deUint32                                                                  m_renderSize;
162         const VkSampleCountFlagBits                                             m_sampleCount;
163         const deUint32                                                                  m_subpixelBits;
164         const deBool                                                                    m_multisampling;
165
166         const VkFormat                                                                  m_imageFormat;
167         const tcu::TextureFormat                                                m_textureFormat;
168         Move<VkCommandPool>                                                             m_commandPool;
169
170         Move<VkImage>                                                                   m_image;
171         de::MovePtr<Allocation>                                                 m_imageMemory;
172         Move<VkImageView>                                                               m_imageView;
173
174         Move<VkImage>                                                                   m_resolvedImage;
175         de::MovePtr<Allocation>                                                 m_resolvedImageMemory;
176         Move<VkImageView>                                                               m_resolvedImageView;
177
178         Move<VkRenderPass>                                                              m_renderPass;
179         Move<VkFramebuffer>                                                             m_frameBuffer;
180
181         Move<VkDescriptorPool>                                                  m_descriptorPool;
182         Move<VkDescriptorSet>                                                   m_descriptorSet;
183         Move<VkDescriptorSetLayout>                                             m_descriptorSetLayout;
184
185         Move<VkBuffer>                                                                  m_uniformBuffer;
186         de::MovePtr<Allocation>                                                 m_uniformBufferMemory;
187         const VkDeviceSize                                                              m_uniformBufferSize;
188
189         Move<VkPipelineLayout>                                                  m_pipelineLayout;
190
191         Move<VkShaderModule>                                                    m_vertexShaderModule;
192         Move<VkShaderModule>                                                    m_fragmentShaderModule;
193
194         Move<VkFence>                                                                   m_fence;
195
196         Move<VkBuffer>                                                                  m_resultBuffer;
197         de::MovePtr<Allocation>                                                 m_resultBufferMemory;
198         const VkDeviceSize                                                              m_resultBufferSize;
199 };
200
201 BaseRenderingTestInstance::BaseRenderingTestInstance (Context& context, VkSampleCountFlagBits sampleCount, deUint32 renderSize)
202         : TestInstance                  (context)
203         , m_renderSize                  (renderSize)
204         , m_sampleCount                 (sampleCount)
205         , m_subpixelBits                (context.getDeviceProperties().limits.subPixelPrecisionBits)
206         , m_multisampling               (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
207         , m_imageFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
208         , m_textureFormat               (vk::mapVkFormat(m_imageFormat))
209         , m_uniformBufferSize   (sizeof(float))
210         , m_resultBufferSize    (renderSize * renderSize * m_textureFormat.getPixelSize())
211 {
212         const DeviceInterface&                                          vkd                                             = m_context.getDeviceInterface();
213         const VkDevice                                                          vkDevice                                = m_context.getDevice();
214         const deUint32                                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
215         Allocator&                                                                      allocator                               = m_context.getDefaultAllocator();
216         DescriptorPoolBuilder                                           descriptorPoolBuilder;
217         DescriptorSetLayoutBuilder                                      descriptorSetLayoutBuilder;
218
219         // Command Pool
220         m_commandPool = createCommandPool(vkd, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
221
222         // Image
223         {
224                 const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
225                 VkImageFormatProperties properties;
226
227                 if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
228                                                                                                                                                                          m_imageFormat,
229                                                                                                                                                                          VK_IMAGE_TYPE_2D,
230                                                                                                                                                                          VK_IMAGE_TILING_OPTIMAL,
231                                                                                                                                                                          imageUsage,
232                                                                                                                                                                          0,
233                                                                                                                                                                          &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
234                 {
235                         TCU_THROW(NotSupportedError, "Format not supported");
236                 }
237
238                 if ((properties.sampleCounts & m_sampleCount) != m_sampleCount)
239                 {
240                         TCU_THROW(NotSupportedError, "Format not supported");
241                 }
242
243                 const VkImageCreateInfo                                 imageCreateInfo                 =
244                 {
245                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
246                         DE_NULL,                                                                        // const void*                          pNext;
247                         0u,                                                                                     // VkImageCreateFlags           flags;
248                         VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType;
249                         m_imageFormat,                                                          // VkFormat                                     format;
250                         { m_renderSize, m_renderSize, 1u },                     // VkExtent3D                           extent;
251                         1u,                                                                                     // deUint32                                     mipLevels;
252                         1u,                                                                                     // deUint32                                     arrayLayers;
253                         m_sampleCount,                                                          // VkSampleCountFlagBits        samples;
254                         VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
255                         imageUsage,                                                                     // VkImageUsageFlags            usage;
256                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
257                         1u,                                                                                     // deUint32                                     queueFamilyIndexCount;
258                         &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices;
259                         VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
260                 };
261
262                 m_image = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
263
264                 m_imageMemory   = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_image), MemoryRequirement::Any);
265                 VK_CHECK(vkd.bindImageMemory(vkDevice, *m_image, m_imageMemory->getMemory(), m_imageMemory->getOffset()));
266         }
267
268         // Image View
269         {
270                 const VkImageViewCreateInfo                             imageViewCreateInfo             =
271                 {
272                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
273                         DE_NULL,                                                                        // const void*                                  pNext;
274                         0u,                                                                                     // VkImageViewCreateFlags               flags;
275                         *m_image,                                                                       // VkImage                                              image;
276                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
277                         m_imageFormat,                                                          // VkFormat                                             format;
278                         makeComponentMappingRGBA(),                                     // VkComponentMapping                   components;
279                         {
280                                 VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
281                                 0u,                                                                                     // deUint32                                             baseMipLevel;
282                                 1u,                                                                                     // deUint32                                             mipLevels;
283                                 0u,                                                                                     // deUint32                                             baseArrayLayer;
284                                 1u,                                                                                     // deUint32                                             arraySize;
285                         },                                                                                      // VkImageSubresourceRange              subresourceRange;
286                 };
287
288                 m_imageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
289         }
290
291         if (m_multisampling)
292         {
293                 {
294                         // Resolved Image
295                         const VkImageUsageFlags imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
296                         VkImageFormatProperties properties;
297
298                         if ((m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
299                                                                                                                                                                                  m_imageFormat,
300                                                                                                                                                                                  VK_IMAGE_TYPE_2D,
301                                                                                                                                                                                  VK_IMAGE_TILING_OPTIMAL,
302                                                                                                                                                                                  imageUsage,
303                                                                                                                                                                                  0,
304                                                                                                                                                                                  &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
305                         {
306                                 TCU_THROW(NotSupportedError, "Format not supported");
307                         }
308
309                         const VkImageCreateInfo                                 imageCreateInfo                 =
310                         {
311                                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType;
312                                 DE_NULL,                                                                        // const void*                          pNext;
313                                 0u,                                                                                     // VkImageCreateFlags           flags;
314                                 VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType;
315                                 m_imageFormat,                                                          // VkFormat                                     format;
316                                 { m_renderSize, m_renderSize, 1u },                     // VkExtent3D                           extent;
317                                 1u,                                                                                     // deUint32                                     mipLevels;
318                                 1u,                                                                                     // deUint32                                     arrayLayers;
319                                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits        samples;
320                                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling;
321                                 imageUsage,                                                                     // VkImageUsageFlags            usage;
322                                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode;
323                                 1u,                                                                                     // deUint32                                     queueFamilyIndexCount;
324                                 &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices;
325                                 VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout;
326                         };
327
328                         m_resolvedImage                 = vk::createImage(vkd, vkDevice, &imageCreateInfo, DE_NULL);
329                         m_resolvedImageMemory   = allocator.allocate(getImageMemoryRequirements(vkd, vkDevice, *m_resolvedImage), MemoryRequirement::Any);
330                         VK_CHECK(vkd.bindImageMemory(vkDevice, *m_resolvedImage, m_resolvedImageMemory->getMemory(), m_resolvedImageMemory->getOffset()));
331                 }
332
333                 // Resolved Image View
334                 {
335                         const VkImageViewCreateInfo                             imageViewCreateInfo             =
336                         {
337                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                              sType;
338                                 DE_NULL,                                                                        // const void*                                  pNext;
339                                 0u,                                                                                     // VkImageViewCreateFlags               flags;
340                                 *m_resolvedImage,                                                       // VkImage                                              image;
341                                 VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                              viewType;
342                                 m_imageFormat,                                                          // VkFormat                                             format;
343                                 makeComponentMappingRGBA(),                                     // VkComponentMapping                   components;
344                                 {
345                                         VK_IMAGE_ASPECT_COLOR_BIT,                                      // VkImageAspectFlags                   aspectMask;
346                                         0u,                                                                                     // deUint32                                             baseMipLevel;
347                                         1u,                                                                                     // deUint32                                             mipLevels;
348                                         0u,                                                                                     // deUint32                                             baseArrayLayer;
349                                         1u,                                                                                     // deUint32                                             arraySize;
350                                 },                                                                                      // VkImageSubresourceRange              subresourceRange;
351                         };
352
353                         m_resolvedImageView = vk::createImageView(vkd, vkDevice, &imageViewCreateInfo, DE_NULL);
354                 }
355
356         }
357
358         // Render Pass
359         {
360                 const VkImageLayout                                             imageLayout                             = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
361                 const VkAttachmentDescription                   attachmentDesc[]                =
362                 {
363                         {
364                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
365                                 m_imageFormat,                                                                          // VkFormat                                                     format;
366                                 m_sampleCount,                                                                          // VkSampleCountFlagBits                        samples;
367                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
368                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
369                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
370                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
371                                 imageLayout,                                                                            // VkImageLayout                                        initialLayout;
372                                 imageLayout,                                                                            // VkImageLayout                                        finalLayout;
373                         },
374                         {
375                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
376                                 m_imageFormat,                                                                          // VkFormat                                                     format;
377                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
378                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           loadOp;
379                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
380                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
381                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
382                                 imageLayout,                                                                            // VkImageLayout                                        initialLayout;
383                                 imageLayout,                                                                            // VkImageLayout                                        finalLayout;
384                         }
385                 };
386
387                 const VkAttachmentReference                             attachmentRef                   =
388                 {
389                         0u,                                                                                                     // deUint32                                                     attachment;
390                         imageLayout,                                                                            // VkImageLayout                                        layout;
391                 };
392
393                 const VkAttachmentReference                             resolveAttachmentRef    =
394                 {
395                         1u,                                                                                                     // deUint32                                                     attachment;
396                         imageLayout,                                                                            // VkImageLayout                                        layout;
397                 };
398
399                 const VkSubpassDescription                              subpassDesc                             =
400                 {
401                         0u,                                                                                                     // VkSubpassDescriptionFlags            flags;
402                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
403                         0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
404                         DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
405                         1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
406                         &attachmentRef,                                                                         // const VkAttachmentReference*         pColorAttachments;
407                         m_multisampling ? &resolveAttachmentRef : DE_NULL,      // const VkAttachmentReference*         pResolveAttachments;
408                         DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
409                         0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
410                         DE_NULL,                                                                                        // const VkAttachmentReference*         pPreserveAttachments;
411                 };
412
413                 const VkRenderPassCreateInfo                    renderPassCreateInfo    =
414                 {
415                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
416                         DE_NULL,                                                                                        // const void*                                          pNext;
417                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
418                         m_multisampling ? 2u : 1u,                                                      // deUint32                                                     attachmentCount;
419                         attachmentDesc,                                                                         // const VkAttachmentDescription*       pAttachments;
420                         1u,                                                                                                     // deUint32                                                     subpassCount;
421                         &subpassDesc,                                                                           // const VkSubpassDescription*          pSubpasses;
422                         0u,                                                                                                     // deUint32                                                     dependencyCount;
423                         DE_NULL,                                                                                        // const VkSubpassDependency*           pDependencies;
424                 };
425
426                 m_renderPass =  createRenderPass(vkd, vkDevice, &renderPassCreateInfo, DE_NULL);
427         }
428
429         // FrameBuffer
430         {
431                 const VkImageView                                               attachments[]                   =
432                 {
433                         *m_imageView,
434                         *m_resolvedImageView
435                 };
436
437                 const VkFramebufferCreateInfo                   framebufferCreateInfo   =
438                 {
439                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
440                         DE_NULL,                                                                        // const void*                          pNext;
441                         0u,                                                                                     // VkFramebufferCreateFlags     flags;
442                         *m_renderPass,                                                          // VkRenderPass                         renderPass;
443                         m_multisampling ? 2u : 1u,                                      // deUint32                                     attachmentCount;
444                         attachments,                                                            // const VkImageView*           pAttachments;
445                         m_renderSize,                                                           // deUint32                                     width;
446                         m_renderSize,                                                           // deUint32                                     height;
447                         1u,                                                                                     // deUint32                                     layers;
448                 };
449
450                 m_frameBuffer = createFramebuffer(vkd, vkDevice, &framebufferCreateInfo, DE_NULL);
451         }
452
453         // Uniform Buffer
454         {
455                 const VkBufferCreateInfo                                bufferCreateInfo                =
456                 {
457                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
458                         DE_NULL,                                                                        // const void*                  pNext;
459                         0u,                                                                                     // VkBufferCreateFlags  flags;
460                         m_uniformBufferSize,                                            // VkDeviceSize                 size;
461                         VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,                     // VkBufferUsageFlags   usage;
462                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
463                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
464                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
465                 };
466
467                 m_uniformBuffer                 = createBuffer(vkd, vkDevice, &bufferCreateInfo);
468                 m_uniformBufferMemory   = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_uniformBuffer), MemoryRequirement::HostVisible);
469
470                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_uniformBuffer, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset()));
471         }
472
473         // Descriptors
474         {
475                 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
476                 m_descriptorPool = descriptorPoolBuilder.build(vkd, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
477
478                 descriptorSetLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_ALL);
479                 m_descriptorSetLayout = descriptorSetLayoutBuilder.build(vkd, vkDevice);
480
481                 const VkDescriptorSetAllocateInfo               descriptorSetParams             =
482                 {
483                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
484                         DE_NULL,
485                         *m_descriptorPool,
486                         1u,
487                         &m_descriptorSetLayout.get(),
488                 };
489
490                 m_descriptorSet = allocateDescriptorSet(vkd, vkDevice, &descriptorSetParams);
491
492                 const VkDescriptorBufferInfo                    descriptorBufferInfo    =
493                 {
494                         *m_uniformBuffer,                                                       // VkBuffer             buffer;
495                         0u,                                                                                     // VkDeviceSize offset;
496                         VK_WHOLE_SIZE                                                           // VkDeviceSize range;
497                 };
498
499                 const VkWriteDescriptorSet                              writeDescritporSet              =
500                 {
501                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,         // VkStructureType                                      sType;
502                         DE_NULL,                                                                        // const void*                                          pNext;
503                         *m_descriptorSet,                                                       // VkDescriptorSet                                      destSet;
504                         0,                                                                                      // deUint32                                                     destBinding;
505                         0,                                                                                      // deUint32                                                     destArrayElement;
506                         1u,                                                                                     // deUint32                                                     count;
507                         VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,                      // VkDescriptorType                                     descriptorType;
508                         DE_NULL,                                                                        // const VkDescriptorImageInfo*         pImageInfo;
509                         &descriptorBufferInfo,                                          // const VkDescriptorBufferInfo*        pBufferInfo;
510                         DE_NULL                                                                         // const VkBufferView*                          pTexelBufferView;
511                 };
512
513                 vkd.updateDescriptorSets(vkDevice, 1u, &writeDescritporSet, 0u, DE_NULL);
514         }
515
516         // Pipeline Layout
517         {
518                 const VkPipelineLayoutCreateInfo                pipelineLayoutCreateInfo        =
519                 {
520                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
521                         DE_NULL,                                                                                        // const void*                                  pNext;
522                         0u,                                                                                                     // VkPipelineLayoutCreateFlags  flags;
523                         1u,                                                                                                     // deUint32                                             descriptorSetCount;
524                         &m_descriptorSetLayout.get(),                                           // const VkDescriptorSetLayout* pSetLayouts;
525                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
526                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
527                 };
528
529                 m_pipelineLayout = createPipelineLayout(vkd, vkDevice, &pipelineLayoutCreateInfo);
530         }
531
532         // Shaders
533         {
534                 m_vertexShaderModule    = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("vertext_shader"), 0);
535                 m_fragmentShaderModule  = createShaderModule(vkd, vkDevice, m_context.getBinaryCollection().get("fragment_shader"), 0);
536         }
537
538         // Fence
539         m_fence = createFence(vkd, vkDevice);
540
541         // Result Buffer
542         {
543                 const VkBufferCreateInfo                                bufferCreateInfo                =
544                 {
545                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
546                         DE_NULL,                                                                        // const void*                  pNext;
547                         0u,                                                                                     // VkBufferCreateFlags  flags;
548                         m_resultBufferSize,                                                     // VkDeviceSize                 size;
549                         VK_BUFFER_USAGE_TRANSFER_DST_BIT,                       // VkBufferUsageFlags   usage;
550                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
551                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
552                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
553                 };
554
555                 m_resultBuffer                  = createBuffer(vkd, vkDevice, &bufferCreateInfo);
556                 m_resultBufferMemory    = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *m_resultBuffer), MemoryRequirement::HostVisible);
557
558                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
559         }
560
561         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Sample count = " << getSampleCountFlagsStr(m_sampleCount) << tcu::TestLog::EndMessage;
562         m_context.getTestContext().getLog() << tcu::TestLog::Message << "SUBPIXEL_BITS = " << m_subpixelBits << tcu::TestLog::EndMessage;
563 }
564
565 BaseRenderingTestInstance::~BaseRenderingTestInstance (void)
566 {
567 }
568
569
570 void BaseRenderingTestInstance::addImageTransitionBarrier(VkCommandBuffer commandBuffer, VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout) const
571 {
572
573         const DeviceInterface&                  vkd                                     = m_context.getDeviceInterface();
574
575         const VkImageSubresourceRange   subResourcerange        =
576         {
577                 VK_IMAGE_ASPECT_COLOR_BIT,              // VkImageAspectFlags   aspectMask;
578                 0,                                                              // deUint32                             baseMipLevel;
579                 1,                                                              // deUint32                             levelCount;
580                 0,                                                              // deUint32                             baseArrayLayer;
581                 1                                                               // deUint32                             layerCount;
582         };
583
584         const VkImageMemoryBarrier              imageBarrier            =
585         {
586                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
587                 DE_NULL,                                                                        // const void*                          pNext;
588                 srcAccessMask,                                                          // VkAccessFlags                        srcAccessMask;
589                 dstAccessMask,                                                          // VkAccessFlags                        dstAccessMask;
590                 oldLayout,                                                                      // VkImageLayout                        oldLayout;
591                 newLayout,                                                                      // VkImageLayout                        newLayout;
592                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
593                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     destQueueFamilyIndex;
594                 image,                                                                          // VkImage                                      image;
595                 subResourcerange                                                        // VkImageSubresourceRange      subresourceRange;
596         };
597
598         vkd.cmdPipelineBarrier(commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
599 }
600
601 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& vertexData, VkPrimitiveTopology primitiveTopology)
602 {
603         // default to color white
604         const std::vector<tcu::Vec4> colorData(vertexData.size(), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
605
606         drawPrimitives(result, vertexData, colorData, primitiveTopology);
607 }
608
609 void BaseRenderingTestInstance::drawPrimitives (tcu::Surface& result, const std::vector<tcu::Vec4>& positionData, const std::vector<tcu::Vec4>& colorData, VkPrimitiveTopology primitiveTopology)
610 {
611         const DeviceInterface&                                          vkd                                             = m_context.getDeviceInterface();
612         const VkDevice                                                          vkDevice                                = m_context.getDevice();
613         const VkQueue                                                           queue                                   = m_context.getUniversalQueue();
614         const deUint32                                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
615         Allocator&                                                                      allocator                               = m_context.getDefaultAllocator();
616         const size_t                                                            attributeBatchSize              = positionData.size() * sizeof(tcu::Vec4);
617
618         Move<VkCommandBuffer>                                           commandBuffer;
619         Move<VkPipeline>                                                        graphicsPipeline;
620         Move<VkBuffer>                                                          vertexBuffer;
621         de::MovePtr<Allocation>                                         vertexBufferMemory;
622         const VkPhysicalDeviceProperties                        properties                              = m_context.getDeviceProperties();
623
624         if (attributeBatchSize > properties.limits.maxVertexInputAttributeOffset)
625         {
626                 std::stringstream message;
627                 message << "Larger vertex input attribute offset is needed (" << attributeBatchSize << ") than the available maximum (" << properties.limits.maxVertexInputAttributeOffset << ").";
628                 TCU_THROW(NotSupportedError, message.str().c_str());
629         }
630
631         // Create Graphics Pipeline
632         {
633                 const VkPipelineShaderStageCreateInfo   shaderStageParams[2]    =
634                 {
635                         {
636                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                      sType;
637                                 DE_NULL,                                                                                                        // const void*                                          pNext;
638                                 0,                                                                                                                      // VkPipelineShaderStageCreateFlags flags;
639                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStage                                        stage;
640                                 *m_vertexShaderModule,                                                                          // VkShader                                                     shader;
641                                 "main",                                                                                                         // const char*                                          pName;
642                                 DE_NULL                                                                                                         // const VkSpecializationInfo*          pSpecializationInfo;
643                         },
644                         {
645                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                      sType;
646                                 DE_NULL,                                                                                                        // const void*                                          pNext;
647                                 0,                                                                                                                      // VkPipelineShaderStageCreateFlags flags;
648                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStage                                        stage;
649                                 *m_fragmentShaderModule,                                                                        // VkShader                                                     shader;
650                                 "main",                                                                                                         // const char*                                          pName;
651                                 DE_NULL                                                                                                         // const VkSpecializationInfo*          pSpecializationInfo;
652                         }
653                 };
654
655                 const VkVertexInputBindingDescription   vertexInputBindingDescription =
656                 {
657                         0u,                                                             // deUint32                                     binding;
658                         sizeof(tcu::Vec4),                              // deUint32                                     strideInBytes;
659                         VK_VERTEX_INPUT_RATE_VERTEX             // VkVertexInputStepRate        stepRate;
660                 };
661
662                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
663                 {
664                         {
665                                 0u,                                                                     // deUint32     location;
666                                 0u,                                                                     // deUint32     binding;
667                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
668                                 0u                                                                      // deUint32     offsetInBytes;
669                         },
670                         {
671                                 1u,                                                                     // deUint32     location;
672                                 0u,                                                                     // deUint32     binding;
673                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
674                                 (deUint32)attributeBatchSize            // deUint32     offsetInBytes;
675                         }
676                 };
677
678                 const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams =
679                 {
680                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
681                         DE_NULL,                                                                                                                // const void*                                                          pNext;
682                         0,                                                                                                                              // VkPipelineVertexInputStateCreateFlags        flags;
683                         1u,                                                                                                                             // deUint32                                                                     bindingCount;
684                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
685                         2u,                                                                                                                             // deUint32                                                                     attributeCount;
686                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
687                 };
688
689                 const VkPipelineInputAssemblyStateCreateInfo    inputAssemblyStateParams =
690                 {
691                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
692                         DE_NULL,                                                                                                                // const void*                                                          pNext;
693                         0,                                                                                                                              // VkPipelineInputAssemblyStateCreateFlags      flags;
694                         primitiveTopology,                                                                                              // VkPrimitiveTopology                                          topology;
695                         false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
696                 };
697
698                 const VkViewport                                                viewport =
699                 {
700                         0.0f,                                           // float        originX;
701                         0.0f,                                           // float        originY;
702                         (float)m_renderSize,            // float        width;
703                         (float)m_renderSize,            // float        height;
704                         0.0f,                                           // float        minDepth;
705                         1.0f                                            // float        maxDepth;
706                 };
707
708                 const VkRect2D                                                  scissor =
709                 {
710                         { 0, 0 },                                                                                                               // VkOffset2D  offset;
711                         { m_renderSize, m_renderSize }                                                                  // VkExtent2D  extent;
712                 };
713
714                 const VkPipelineViewportStateCreateInfo viewportStateParams =
715                 {
716                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
717                         DE_NULL,                                                                                                                // const void*                                                  pNext;
718                         0,                                                                                                                              // VkPipelineViewportStateCreateFlags   flags;
719                         1u,                                                                                                                             // deUint32                                                             viewportCount;
720                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
721                         1u,                                                                                                                             // deUint32                                                             scissorCount;
722                         &scissor                                                                                                                // const VkRect2D*                                              pScissors;
723                 };
724
725                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
726                 {
727                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
728                         DE_NULL,                                                                                                                // const void*                                                          pNext;
729                         0u,                                                                                                                             // VkPipelineMultisampleStateCreateFlags        flags;
730                         m_sampleCount,                                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
731                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
732                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
733                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
734                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
735                         VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
736                 };
737
738                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
739                 {
740                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
741                         DE_NULL,                                                                                        // const void*                                                                          pNext;
742                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
743                         2u,                                                                                                     // deUint32                                                                                     stageCount;
744                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
745                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
746                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
747                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
748                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
749                         getRasterizationStateCreateInfo(),                                      // const VkPipelineRasterStateCreateInfo*                       pRasterizationState;
750                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
751                         DE_NULL,                                                                                        // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
752                         getColorBlendStateCreateInfo(),                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
753                         DE_NULL,                                                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
754                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
755                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
756                         0u,                                                                                                     // deUint32                                                                                     subpass;
757                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
758                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
759                 };
760
761                 graphicsPipeline                = createGraphicsPipeline(vkd, vkDevice, DE_NULL, &graphicsPipelineParams);
762         }
763
764         // Create Vertex Buffer
765         {
766                 const VkBufferCreateInfo                        vertexBufferParams              =
767                 {
768                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
769                         DE_NULL,                                                                        // const void*                  pNext;
770                         0u,                                                                                     // VkBufferCreateFlags  flags;
771                         attributeBatchSize * 2,                                         // VkDeviceSize                 size;
772                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
773                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
774                         1u,                                                                                     // deUint32                             queueFamilyCount;
775                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
776                 };
777
778                 vertexBuffer            = createBuffer(vkd, vkDevice, &vertexBufferParams);
779                 vertexBufferMemory      = allocator.allocate(getBufferMemoryRequirements(vkd, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
780
781                 VK_CHECK(vkd.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
782
783                 // Load vertices into vertex buffer
784                 deMemcpy(vertexBufferMemory->getHostPtr(), positionData.data(), attributeBatchSize);
785                 deMemcpy(reinterpret_cast<deUint8*>(vertexBufferMemory->getHostPtr()) +  attributeBatchSize, colorData.data(), attributeBatchSize);
786                 flushMappedMemoryRange(vkd, vkDevice, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset(), vertexBufferParams.size);
787         }
788
789         // Create Command Buffer
790         commandBuffer = allocateCommandBuffer(vkd, vkDevice, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
791
792         // Begin Command Buffer
793         {
794                 const VkCommandBufferBeginInfo          cmdBufferBeginInfo              =
795                 {
796                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                                      sType;
797                         DE_NULL,                                                                                // const void*                                                          pNext;
798                         0u,                                                                                             // VkCmdBufferOptimizeFlags                                     flags;
799                         DE_NULL                                                                                 // const VkCommandBufferInheritanceInfo*        pInheritanceInfo;
800                 };
801
802                 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &cmdBufferBeginInfo));
803         }
804
805         addImageTransitionBarrier(*commandBuffer, *m_image,
806                                                           VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,                            // VkPipelineStageFlags         srcStageMask
807                                                           VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,                           // VkPipelineStageFlags         dstStageMask
808                                                           0,                                                                                            // VkAccessFlags                        srcAccessMask
809                                                           VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                         // VkAccessFlags                        dstAccessMask
810                                                           VK_IMAGE_LAYOUT_UNDEFINED,                                            // VkImageLayout                        oldLayout;
811                                                           VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);            // VkImageLayout                        newLayout;
812
813         if (m_multisampling) {
814                 addImageTransitionBarrier(*commandBuffer, *m_resolvedImage,
815                                                                   VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,                            // VkPipelineStageFlags         srcStageMask
816                                                                   VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,                           // VkPipelineStageFlags         dstStageMask
817                                                                   0,                                                                                            // VkAccessFlags                        srcAccessMask
818                                                                   VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                         // VkAccessFlags                        dstAccessMask
819                                                                   VK_IMAGE_LAYOUT_UNDEFINED,                                            // VkImageLayout                        oldLayout;
820                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);            // VkImageLayout                        newLayout;
821         }
822
823         // Begin Render Pass
824         {
825                 const VkClearValue                                      clearValue                              = makeClearValueColorF32(0.0, 0.0, 0.0, 1.0);
826
827                 const VkRenderPassBeginInfo                     renderPassBeginInfo             =
828                 {
829                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
830                         DE_NULL,                                                                                                // const void*                  pNext;
831                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
832                         *m_frameBuffer,                                                                                 // VkFramebuffer                framebuffer;
833                         {
834                                 { 0, 0 },
835                                 { m_renderSize, m_renderSize }
836                         },                                                                                                              // VkRect2D                             renderArea;
837                         1u,                                                                                                             // deUint32                             clearValueCount;
838                         &clearValue                                                                                             // const VkClearValue*  pClearValues;
839                 };
840
841                 vkd.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
842         }
843
844         const VkDeviceSize                                              vertexBufferOffset              = 0;
845
846         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
847         vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &m_descriptorSet.get(), 0u, DE_NULL);
848         vkd.cmdBindVertexBuffers(*commandBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
849         vkd.cmdDraw(*commandBuffer, (deUint32)positionData.size(), 1, 0, 0);
850         vkd.cmdEndRenderPass(*commandBuffer);
851
852         // Copy Image
853         {
854
855                 const VkBufferMemoryBarrier                     bufferBarrier                   =
856                 {
857                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType              sType;
858                         DE_NULL,                                                                        // const void*                  pNext;
859                         VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkMemoryOutputFlags  outputMask;
860                         VK_ACCESS_HOST_READ_BIT,                                        // VkMemoryInputFlags   inputMask;
861                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                             srcQueueFamilyIndex;
862                         VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                             destQueueFamilyIndex;
863                         *m_resultBuffer,                                                        // VkBuffer                             buffer;
864                         0u,                                                                                     // VkDeviceSize                 offset;
865                         m_resultBufferSize                                                      // VkDeviceSize                 size;
866                 };
867
868                 const VkBufferImageCopy                         copyRegion                              =
869                 {
870                         0u,                                                                                     // VkDeviceSize                         bufferOffset;
871                         m_renderSize,                                                           // deUint32                                     bufferRowLength;
872                         m_renderSize,                                                           // deUint32                                     bufferImageHeight;
873                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u },      // VkImageSubresourceCopy       imageSubresource;
874                         { 0, 0, 0 },                                                            // VkOffset3D                           imageOffset;
875                         { m_renderSize, m_renderSize, 1u }                      // VkExtent3D                           imageExtent;
876                 };
877
878                 addImageTransitionBarrier(*commandBuffer,
879                                                                   m_multisampling ? *m_resolvedImage : *m_image,
880                                                                   VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,                // VkPipelineStageFlags         srcStageMask
881                                                                   VK_PIPELINE_STAGE_TRANSFER_BIT,                                               // VkPipelineStageFlags         dstStageMask
882                                                                   VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                 // VkAccessFlags                        srcAccessMask
883                                                                   VK_ACCESS_TRANSFER_READ_BIT,                                                  // VkAccessFlags                        dstAccessMask
884                                                                   VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                             // VkImageLayout                        oldLayout;
885                                                                   VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);                                // VkImageLayout                        newLayout;)
886
887                 if (m_multisampling)
888                         vkd.cmdCopyImageToBuffer(*commandBuffer, *m_resolvedImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, &copyRegion);
889                 else
890                         vkd.cmdCopyImageToBuffer(*commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_resultBuffer, 1, &copyRegion);
891
892                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
893         }
894
895         VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
896
897         // Set Point Size
898         {
899                 float   pointSize       = getPointSize();
900                 deMemcpy(m_uniformBufferMemory->getHostPtr(), &pointSize, (size_t)m_uniformBufferSize);
901                 flushMappedMemoryRange(vkd, vkDevice, m_uniformBufferMemory->getMemory(), m_uniformBufferMemory->getOffset(), m_uniformBufferSize);
902         }
903
904         // Submit
905         {
906                 const VkSubmitInfo                                      submitInfo                              =
907                 {
908                         VK_STRUCTURE_TYPE_SUBMIT_INFO,                  // VkStructureType                              sType;
909                         DE_NULL,                                                                // const void*                                  pNext;
910                         0u,                                                                             // deUint32                                             waitSemaphoreCount;
911                         DE_NULL,                                                                // const VkSemaphore*                   pWaitSemaphores;
912                         DE_NULL,                                                                // const VkPipelineStageFlags*  pWaitDstStageMask;
913                         1u,                                                                             // deUint32                                             commandBufferCount;
914                         &commandBuffer.get(),                                   // const VkCommandBuffer*               pCommandBuffers;
915                         0u,                                                                             // deUint32                                             signalSemaphoreCount;
916                         DE_NULL,                                                                // const VkSemaphore*                   pSignalSemaphores;
917                 };
918
919                 VK_CHECK(vkd.resetFences(vkDevice, 1, &m_fence.get()));
920                 VK_CHECK(vkd.queueSubmit(queue, 1, &submitInfo, *m_fence));
921                 VK_CHECK(vkd.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
922         }
923
924         invalidateMappedMemoryRange(vkd, vkDevice, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(), m_resultBufferSize);
925         tcu::copy(result.getAccess(), tcu::ConstPixelBufferAccess(m_textureFormat, tcu::IVec3(m_renderSize, m_renderSize, 1), m_resultBufferMemory->getHostPtr()));
926 }
927
928 float BaseRenderingTestInstance::getLineWidth (void) const
929 {
930         return 1.0f;
931 }
932
933 float BaseRenderingTestInstance::getPointSize (void) const
934 {
935         return 1.0f;
936 }
937
938 const VkPipelineRasterizationStateCreateInfo* BaseRenderingTestInstance::getRasterizationStateCreateInfo (void) const
939 {
940         static VkPipelineRasterizationStateCreateInfo   rasterizationStateCreateInfo    =
941         {
942                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
943                 DE_NULL,                                                                                                                // const void*                                                          pNext;
944                 0,                                                                                                                              // VkPipelineRasterizationStateCreateFlags      flags;
945                 false,                                                                                                                  // VkBool32                                                                     depthClipEnable;
946                 false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
947                 VK_POLYGON_MODE_FILL,                                                                                   // VkFillMode                                                           fillMode;
948                 VK_CULL_MODE_NONE,                                                                                              // VkCullMode                                                           cullMode;
949                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
950                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
951                 0.0f,                                                                                                                   // float                                                                        depthBias;
952                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
953                 0.0f,                                                                                                                   // float                                                                        slopeScaledDepthBias;
954                 getLineWidth(),                                                                                                 // float                                                                        lineWidth;
955         };
956
957         rasterizationStateCreateInfo.lineWidth = getLineWidth();
958         return &rasterizationStateCreateInfo;
959 }
960
961 const VkPipelineColorBlendStateCreateInfo* BaseRenderingTestInstance::getColorBlendStateCreateInfo (void) const
962 {
963         static const VkPipelineColorBlendAttachmentState        colorBlendAttachmentState       =
964         {
965                 false,                                                                                                          // VkBool32                     blendEnable;
966                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendColor;
967                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendColor;
968                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpColor;
969                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendAlpha;
970                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlend                      destBlendAlpha;
971                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpAlpha;
972                 (VK_COLOR_COMPONENT_R_BIT |
973                  VK_COLOR_COMPONENT_G_BIT |
974                  VK_COLOR_COMPONENT_B_BIT |
975                  VK_COLOR_COMPONENT_A_BIT)                                                                      // VkChannelFlags       channelWriteMask;
976         };
977
978         static const VkPipelineColorBlendStateCreateInfo        colorBlendStateParams           =
979         {
980                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
981                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
982                 0,                                                                                                                      // VkPipelineColorBlendStateCreateFlags                 flags;
983                 false,                                                                                                          // VkBool32                                                                             logicOpEnable;
984                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
985                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
986                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
987                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
988         };
989
990         return &colorBlendStateParams;
991 }
992
993 const tcu::TextureFormat& BaseRenderingTestInstance::getTextureFormat (void) const
994 {
995         return m_textureFormat;
996 }
997
998 class BaseTriangleTestInstance : public BaseRenderingTestInstance
999 {
1000 public:
1001                                                         BaseTriangleTestInstance        (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount);
1002         virtual tcu::TestStatus iterate                                         (void);
1003
1004 private:
1005         virtual void                    generateTriangles                       (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles) = DE_NULL;
1006
1007         int                                             m_iteration;
1008         const int                               m_iterationCount;
1009         VkPrimitiveTopology             m_primitiveTopology;
1010         bool                                    m_allIterationsPassed;
1011 };
1012
1013 BaseTriangleTestInstance::BaseTriangleTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, VkSampleCountFlagBits sampleCount)
1014         : BaseRenderingTestInstance             (context, sampleCount)
1015         , m_iteration                                   (0)
1016         , m_iterationCount                              (3)
1017         , m_primitiveTopology                   (primitiveTopology)
1018         , m_allIterationsPassed                 (true)
1019 {
1020 }
1021
1022 tcu::TestStatus BaseTriangleTestInstance::iterate (void)
1023 {
1024         const std::string                                                               iterationDescription    = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1025         const tcu::ScopedLogSection                                             section                                 (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1026         tcu::Surface                                                                    resultImage                             (m_renderSize, m_renderSize);
1027         std::vector<tcu::Vec4>                                                  drawBuffer;
1028         std::vector<TriangleSceneSpec::SceneTriangle>   triangles;
1029
1030         generateTriangles(m_iteration, drawBuffer, triangles);
1031
1032         // draw image
1033         drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1034
1035         // compare
1036         {
1037                 bool                                    compareOk;
1038                 RasterizationArguments  args;
1039                 TriangleSceneSpec               scene;
1040
1041                 tcu::IVec4                              colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1042
1043                 args.numSamples         = m_multisampling ? 1 : 0;
1044                 args.subpixelBits       = m_subpixelBits;
1045                 args.redBits            = colorBits[0];
1046                 args.greenBits          = colorBits[1];
1047                 args.blueBits           = colorBits[2];
1048
1049                 scene.triangles.swap(triangles);
1050
1051                 compareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1052
1053                 if (!compareOk)
1054                         m_allIterationsPassed = false;
1055         }
1056
1057         // result
1058         if (++m_iteration == m_iterationCount)
1059         {
1060                 if (m_allIterationsPassed)
1061                         return tcu::TestStatus::pass("Pass");
1062                 else
1063                         return tcu::TestStatus::fail("Incorrect rasterization");
1064         }
1065         else
1066                 return tcu::TestStatus::incomplete();
1067 }
1068
1069 class BaseLineTestInstance : public BaseRenderingTestInstance
1070 {
1071 public:
1072                                                         BaseLineTestInstance    (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
1073         virtual tcu::TestStatus iterate                                 (void);
1074         virtual float                   getLineWidth                    (void) const;
1075
1076 private:
1077         virtual void                    generateLines                   (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines) = DE_NULL;
1078
1079         int                                             m_iteration;
1080         const int                               m_iterationCount;
1081         VkPrimitiveTopology             m_primitiveTopology;
1082         const PrimitiveWideness m_primitiveWideness;
1083         bool                                    m_allIterationsPassed;
1084         float                                   m_maxLineWidth;
1085         std::vector<float>              m_lineWidths;
1086 };
1087
1088 BaseLineTestInstance::BaseLineTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1089         : BaseRenderingTestInstance                     (context, sampleCount)
1090         , m_iteration                                           (0)
1091         , m_iterationCount                                      (3)
1092         , m_primitiveTopology                           (primitiveTopology)
1093         , m_primitiveWideness                           (wideness)
1094         , m_allIterationsPassed                         (true)
1095         , m_maxLineWidth                                        (1.0f)
1096 {
1097         DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
1098
1099         if (!context.getDeviceProperties().limits.strictLines)
1100                 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
1101
1102         // create line widths
1103         if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1104         {
1105                 m_lineWidths.resize(m_iterationCount, 1.0f);
1106         }
1107         else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1108         {
1109                 if (!m_context.getDeviceFeatures().wideLines)
1110                         TCU_THROW(NotSupportedError , "wide line support required");
1111
1112                 const float*    range = context.getDeviceProperties().limits.lineWidthRange;
1113
1114                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1115
1116                 // no wide line support
1117                 if (range[1] <= 1.0f)
1118                         TCU_THROW(NotSupportedError, "wide line support required");
1119
1120                 // set hand picked sizes
1121                 m_lineWidths.push_back(5.0f);
1122                 m_lineWidths.push_back(10.0f);
1123                 m_lineWidths.push_back(range[1]);
1124                 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
1125
1126                 m_maxLineWidth = range[1];
1127         }
1128         else
1129                 DE_ASSERT(false);
1130 }
1131
1132 tcu::TestStatus BaseLineTestInstance::iterate (void)
1133 {
1134         const std::string                                               iterationDescription    = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1135         const tcu::ScopedLogSection                             section                                 (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1136         const float                                                             lineWidth                               = getLineWidth();
1137         tcu::Surface                                                    resultImage                             (m_renderSize, m_renderSize);
1138         std::vector<tcu::Vec4>                                  drawBuffer;
1139         std::vector<LineSceneSpec::SceneLine>   lines;
1140
1141         // supported?
1142         if (lineWidth <= m_maxLineWidth)
1143         {
1144                 // gen data
1145                 generateLines(m_iteration, drawBuffer, lines);
1146
1147                 // draw image
1148                 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
1149
1150                 // compare
1151                 {
1152                         RasterizationArguments  args;
1153                         LineSceneSpec                   scene;
1154
1155
1156                         tcu::IVec4                              colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1157
1158                         args.numSamples         = m_multisampling ? 1 : 0;
1159                         args.subpixelBits       = m_subpixelBits;
1160                         args.redBits            = colorBits[0];
1161                         args.greenBits          = colorBits[1];
1162                         args.blueBits           = colorBits[2];
1163
1164                         scene.lines.swap(lines);
1165                         scene.lineWidth = lineWidth;
1166
1167                         if (!verifyRelaxedLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog()))
1168                                 m_allIterationsPassed = false;
1169                 }
1170         }
1171         else
1172                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1173
1174         // result
1175         if (++m_iteration == m_iterationCount)
1176         {
1177                 if (m_allIterationsPassed)
1178                         return tcu::TestStatus::pass("Pass");
1179                 else
1180                         return tcu::TestStatus::fail("Incorrect rasterization");
1181         }
1182         else
1183                 return tcu::TestStatus::incomplete();
1184 }
1185
1186
1187 float BaseLineTestInstance::getLineWidth (void) const
1188 {
1189         return m_lineWidths[m_iteration];
1190 }
1191
1192
1193 class PointTestInstance : public BaseRenderingTestInstance
1194 {
1195 public:
1196                                                         PointTestInstance               (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
1197         virtual tcu::TestStatus iterate                                 (void);
1198         virtual float                   getPointSize                    (void) const;
1199
1200 private:
1201         virtual void                    generatePoints                  (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints);
1202
1203         int                                             m_iteration;
1204         const int                               m_iterationCount;
1205         const PrimitiveWideness m_primitiveWideness;
1206         bool                                    m_allIterationsPassed;
1207         float                                   m_maxPointSize;
1208         std::vector<float>              m_pointSizes;
1209 };
1210
1211 PointTestInstance::PointTestInstance (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1212         : BaseRenderingTestInstance     (context, sampleCount)
1213         , m_iteration                           (0)
1214         , m_iterationCount                      (3)
1215         , m_primitiveWideness           (wideness)
1216         , m_allIterationsPassed         (true)
1217         , m_maxPointSize                        (1.0f)
1218 {
1219         // create point sizes
1220         if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
1221         {
1222                 m_pointSizes.resize(m_iterationCount, 1.0f);
1223         }
1224         else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
1225         {
1226                 if (!m_context.getDeviceFeatures().largePoints)
1227                         TCU_THROW(NotSupportedError , "large point support required");
1228
1229                 const float*    range = context.getDeviceProperties().limits.pointSizeRange;
1230
1231                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ALIASED_POINT_SIZE_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
1232
1233                 // no wide line support
1234                 if (range[1] <= 1.0f)
1235                         TCU_THROW(NotSupportedError , "wide point support required");
1236
1237                 // set hand picked sizes
1238                 m_pointSizes.push_back(10.0f);
1239                 m_pointSizes.push_back(25.0f);
1240                 m_pointSizes.push_back(range[1]);
1241                 DE_ASSERT((int)m_pointSizes.size() == m_iterationCount);
1242
1243                 m_maxPointSize = range[1];
1244         }
1245         else
1246                 DE_ASSERT(false);
1247 }
1248
1249 tcu::TestStatus PointTestInstance::iterate (void)
1250 {
1251         const std::string                                               iterationDescription    = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1252         const tcu::ScopedLogSection                             section                                 (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1253         const float                                                             pointSize                               = getPointSize();
1254         tcu::Surface                                                    resultImage                             (m_renderSize, m_renderSize);
1255         std::vector<tcu::Vec4>                                  drawBuffer;
1256         std::vector<PointSceneSpec::ScenePoint> points;
1257
1258         // supported?
1259         if (pointSize <= m_maxPointSize)
1260         {
1261                 // gen data
1262                 generatePoints(m_iteration, drawBuffer, points);
1263
1264                 // draw image
1265                 drawPrimitives(resultImage, drawBuffer, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
1266
1267                 // compare
1268                 {
1269                         bool                                    compareOk;
1270                         RasterizationArguments  args;
1271                         PointSceneSpec                  scene;
1272
1273                         tcu::IVec4                              colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
1274
1275                         args.numSamples         = m_multisampling ? 1 : 0;
1276                         args.subpixelBits       = m_subpixelBits;
1277                         args.redBits            = colorBits[0];
1278                         args.greenBits          = colorBits[1];
1279                         args.blueBits           = colorBits[2];
1280
1281                         scene.points.swap(points);
1282
1283                         compareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
1284
1285                         if (!compareOk)
1286                                 m_allIterationsPassed = false;
1287                 }
1288         }
1289         else
1290                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point size " << pointSize << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
1291
1292         // result
1293         if (++m_iteration == m_iterationCount)
1294         {
1295                 if (m_allIterationsPassed)
1296                         return tcu::TestStatus::pass("Pass");
1297                 else
1298                         return tcu::TestStatus::fail("Incorrect rasterization");
1299         }
1300         else
1301                 return tcu::TestStatus::incomplete();
1302 }
1303
1304 float PointTestInstance::getPointSize (void) const
1305 {
1306         return m_pointSizes[m_iteration];
1307 }
1308
1309 void PointTestInstance::generatePoints (int iteration, std::vector<tcu::Vec4>& outData, std::vector<PointSceneSpec::ScenePoint>& outPoints)
1310 {
1311         outData.resize(6);
1312
1313         switch (iteration)
1314         {
1315                 case 0:
1316                         // \note: these values are chosen arbitrarily
1317                         outData[0] = tcu::Vec4( 0.2f,  0.8f, 0.0f, 1.0f);
1318                         outData[1] = tcu::Vec4( 0.5f,  0.2f, 0.0f, 1.0f);
1319                         outData[2] = tcu::Vec4( 0.5f,  0.3f, 0.0f, 1.0f);
1320                         outData[3] = tcu::Vec4(-0.5f,  0.2f, 0.0f, 1.0f);
1321                         outData[4] = tcu::Vec4(-0.2f, -0.4f, 0.0f, 1.0f);
1322                         outData[5] = tcu::Vec4(-0.4f,  0.2f, 0.0f, 1.0f);
1323                         break;
1324
1325                 case 1:
1326                         outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1327                         outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
1328                         outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
1329                         outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
1330                         outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
1331                         outData[5] = tcu::Vec4(   0.4f,   1.2f, 0.0f, 1.0f);
1332                         break;
1333
1334                 case 2:
1335                         outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1336                         outData[1] = tcu::Vec4(  0.3f, -0.9f, 0.0f, 1.0f);
1337                         outData[2] = tcu::Vec4( -0.4f, -0.1f, 0.0f, 1.0f);
1338                         outData[3] = tcu::Vec4(-0.11f,  0.2f, 0.0f, 1.0f);
1339                         outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
1340                         outData[5] = tcu::Vec4( -0.4f,  0.4f, 0.0f, 1.0f);
1341                         break;
1342         }
1343
1344         outPoints.resize(outData.size());
1345         for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1346         {
1347                 outPoints[pointNdx].position = outData[pointNdx];
1348                 outPoints[pointNdx].pointSize = getPointSize();
1349         }
1350
1351         // log
1352         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outPoints.size() << " point(s): (point size = " << getPointSize() << ")" << tcu::TestLog::EndMessage;
1353         for (int pointNdx = 0; pointNdx < (int)outPoints.size(); ++pointNdx)
1354                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Point " << (pointNdx+1) << ":\t" << outPoints[pointNdx].position << tcu::TestLog::EndMessage;
1355 }
1356
1357 template <typename ConcreteTestInstance>
1358 class BaseTestCase : public BaseRenderingTestCase
1359 {
1360 public:
1361                                                         BaseTestCase    (tcu::TestContext& context, const std::string& name, const std::string& description, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1362                                                                 : BaseRenderingTestCase(context, name, description, sampleCount)
1363                                                         {}
1364
1365         virtual TestInstance*   createInstance  (Context& context) const
1366                                                         {
1367                                                                 return new ConcreteTestInstance(context, m_sampleCount);
1368                                                         }
1369 };
1370
1371 class TrianglesTestInstance : public BaseTriangleTestInstance
1372 {
1373 public:
1374                                                         TrianglesTestInstance   (Context& context, VkSampleCountFlagBits sampleCount)
1375                                                                 : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, sampleCount)
1376                                                         {}
1377
1378         void                                    generateTriangles               (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1379 };
1380
1381 void TrianglesTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1382 {
1383         outData.resize(6);
1384
1385         switch (iteration)
1386         {
1387                 case 0:
1388                         // \note: these values are chosen arbitrarily
1389                         outData[0] = tcu::Vec4( 0.2f,  0.8f, 0.0f, 1.0f);
1390                         outData[1] = tcu::Vec4( 0.5f,  0.2f, 0.0f, 1.0f);
1391                         outData[2] = tcu::Vec4( 0.5f,  0.3f, 0.0f, 1.0f);
1392                         outData[3] = tcu::Vec4(-0.5f,  0.2f, 0.0f, 1.0f);
1393                         outData[4] = tcu::Vec4(-1.5f, -0.4f, 0.0f, 1.0f);
1394                         outData[5] = tcu::Vec4(-0.4f,  0.2f, 0.0f, 1.0f);
1395                         break;
1396
1397                 case 1:
1398                         outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1399                         outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
1400                         outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
1401                         outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
1402                         outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
1403                         outData[5] = tcu::Vec4(   0.4f,   1.2f, 0.0f, 1.0f);
1404                         break;
1405
1406                 case 2:
1407                         outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1408                         outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
1409                         outData[2] = tcu::Vec4( -1.1f, -0.1f, 0.0f, 1.0f);
1410                         outData[3] = tcu::Vec4(-0.11f,  0.2f, 0.0f, 1.0f);
1411                         outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
1412                         outData[5] = tcu::Vec4( -0.4f,  0.4f, 0.0f, 1.0f);
1413                         break;
1414         }
1415
1416         outTriangles.resize(2);
1417         outTriangles[0].positions[0] = outData[0];      outTriangles[0].sharedEdge[0] = false;
1418         outTriangles[0].positions[1] = outData[1];      outTriangles[0].sharedEdge[1] = false;
1419         outTriangles[0].positions[2] = outData[2];      outTriangles[0].sharedEdge[2] = false;
1420
1421         outTriangles[1].positions[0] = outData[3];      outTriangles[1].sharedEdge[0] = false;
1422         outTriangles[1].positions[1] = outData[4];      outTriangles[1].sharedEdge[1] = false;
1423         outTriangles[1].positions[2] = outData[5];      outTriangles[1].sharedEdge[2] = false;
1424
1425         // log
1426         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outTriangles.size() << " triangle(s):" << tcu::TestLog::EndMessage;
1427         for (int triangleNdx = 0; triangleNdx < (int)outTriangles.size(); ++triangleNdx)
1428         {
1429                 m_context.getTestContext().getLog()
1430                         << tcu::TestLog::Message
1431                         << "Triangle " << (triangleNdx+1) << ":"
1432                         << "\n\t" << outTriangles[triangleNdx].positions[0]
1433                         << "\n\t" << outTriangles[triangleNdx].positions[1]
1434                         << "\n\t" << outTriangles[triangleNdx].positions[2]
1435                         << tcu::TestLog::EndMessage;
1436         }
1437 }
1438
1439 class TriangleStripTestInstance : public BaseTriangleTestInstance
1440 {
1441 public:
1442                                 TriangleStripTestInstance               (Context& context, VkSampleCountFlagBits sampleCount)
1443                                         : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, sampleCount)
1444                                 {}
1445
1446         void            generateTriangles                               (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1447 };
1448
1449 void TriangleStripTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1450 {
1451         outData.resize(5);
1452
1453         switch (iteration)
1454         {
1455                 case 0:
1456                         // \note: these values are chosen arbitrarily
1457                         outData[0] = tcu::Vec4(-0.504f,  0.8f,   0.0f, 1.0f);
1458                         outData[1] = tcu::Vec4(-0.2f,   -0.2f,   0.0f, 1.0f);
1459                         outData[2] = tcu::Vec4(-0.2f,    0.199f, 0.0f, 1.0f);
1460                         outData[3] = tcu::Vec4( 0.5f,    0.201f, 0.0f, 1.0f);
1461                         outData[4] = tcu::Vec4( 1.5f,    0.4f,   0.0f, 1.0f);
1462                         break;
1463
1464                 case 1:
1465                         outData[0] = tcu::Vec4(-0.499f, 0.129f,  0.0f, 1.0f);
1466                         outData[1] = tcu::Vec4(-0.501f,  -0.3f,  0.0f, 1.0f);
1467                         outData[2] = tcu::Vec4(  0.11f,  -0.2f,  0.0f, 1.0f);
1468                         outData[3] = tcu::Vec4(  0.11f,  -0.31f, 0.0f, 1.0f);
1469                         outData[4] = tcu::Vec4(  0.88f,   0.9f,  0.0f, 1.0f);
1470                         break;
1471
1472                 case 2:
1473                         outData[0] = tcu::Vec4( -0.9f, -0.3f,  0.0f, 1.0f);
1474                         outData[1] = tcu::Vec4(  1.1f, -0.9f,  0.0f, 1.0f);
1475                         outData[2] = tcu::Vec4(-0.87f, -0.1f,  0.0f, 1.0f);
1476                         outData[3] = tcu::Vec4(-0.11f,  0.19f, 0.0f, 1.0f);
1477                         outData[4] = tcu::Vec4( 0.88f,  0.7f,  0.0f, 1.0f);
1478                         break;
1479         }
1480
1481         outTriangles.resize(3);
1482         outTriangles[0].positions[0] = outData[0];      outTriangles[0].sharedEdge[0] = false;
1483         outTriangles[0].positions[1] = outData[1];      outTriangles[0].sharedEdge[1] = true;
1484         outTriangles[0].positions[2] = outData[2];      outTriangles[0].sharedEdge[2] = false;
1485
1486         outTriangles[1].positions[0] = outData[2];      outTriangles[1].sharedEdge[0] = true;
1487         outTriangles[1].positions[1] = outData[1];      outTriangles[1].sharedEdge[1] = false;
1488         outTriangles[1].positions[2] = outData[3];      outTriangles[1].sharedEdge[2] = true;
1489
1490         outTriangles[2].positions[0] = outData[2];      outTriangles[2].sharedEdge[0] = true;
1491         outTriangles[2].positions[1] = outData[3];      outTriangles[2].sharedEdge[1] = false;
1492         outTriangles[2].positions[2] = outData[4];      outTriangles[2].sharedEdge[2] = false;
1493
1494         // log
1495         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle strip, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1496         for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1497         {
1498                 m_context.getTestContext().getLog()
1499                         << tcu::TestLog::Message
1500                         << "\t" << outData[vtxNdx]
1501                         << tcu::TestLog::EndMessage;
1502         }
1503 }
1504
1505 class TriangleFanTestInstance : public BaseTriangleTestInstance
1506 {
1507 public:
1508                                 TriangleFanTestInstance                 (Context& context, VkSampleCountFlagBits sampleCount)
1509                                         : BaseTriangleTestInstance(context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, sampleCount)
1510                                 {}
1511
1512         void            generateTriangles                               (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles);
1513 };
1514
1515 void TriangleFanTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData, std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles)
1516 {
1517         outData.resize(5);
1518
1519         switch (iteration)
1520         {
1521                 case 0:
1522                         // \note: these values are chosen arbitrarily
1523                         outData[0] = tcu::Vec4( 0.01f,  0.0f, 0.0f, 1.0f);
1524                         outData[1] = tcu::Vec4( 0.5f,   0.2f, 0.0f, 1.0f);
1525                         outData[2] = tcu::Vec4( 0.46f,  0.3f, 0.0f, 1.0f);
1526                         outData[3] = tcu::Vec4(-0.5f,   0.2f, 0.0f, 1.0f);
1527                         outData[4] = tcu::Vec4(-1.5f,  -0.4f, 0.0f, 1.0f);
1528                         break;
1529
1530                 case 1:
1531                         outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1532                         outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
1533                         outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
1534                         outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
1535                         outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
1536                         break;
1537
1538                 case 2:
1539                         outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1540                         outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
1541                         outData[2] = tcu::Vec4(  0.7f, -0.1f, 0.0f, 1.0f);
1542                         outData[3] = tcu::Vec4( 0.11f,  0.2f, 0.0f, 1.0f);
1543                         outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
1544                         break;
1545         }
1546
1547         outTriangles.resize(3);
1548         outTriangles[0].positions[0] = outData[0];      outTriangles[0].sharedEdge[0] = false;
1549         outTriangles[0].positions[1] = outData[1];      outTriangles[0].sharedEdge[1] = false;
1550         outTriangles[0].positions[2] = outData[2];      outTriangles[0].sharedEdge[2] = true;
1551
1552         outTriangles[1].positions[0] = outData[0];      outTriangles[1].sharedEdge[0] = true;
1553         outTriangles[1].positions[1] = outData[2];      outTriangles[1].sharedEdge[1] = false;
1554         outTriangles[1].positions[2] = outData[3];      outTriangles[1].sharedEdge[2] = true;
1555
1556         outTriangles[2].positions[0] = outData[0];      outTriangles[2].sharedEdge[0] = true;
1557         outTriangles[2].positions[1] = outData[3];      outTriangles[2].sharedEdge[1] = false;
1558         outTriangles[2].positions[2] = outData[4];      outTriangles[2].sharedEdge[2] = false;
1559
1560         // log
1561         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering triangle fan, " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1562         for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1563         {
1564                 m_context.getTestContext().getLog()
1565                         << tcu::TestLog::Message
1566                         << "\t" << outData[vtxNdx]
1567                         << tcu::TestLog::EndMessage;
1568         }
1569 }
1570
1571 template <typename ConcreteTestInstance>
1572 class WidenessTestCase : public BaseRenderingTestCase
1573 {
1574 public:
1575                                                                 WidenessTestCase        (tcu::TestContext& context, const std::string& name, const std::string& description, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
1576                                                                         : BaseRenderingTestCase(context, name, description, sampleCount)
1577                                                                         , m_wideness(wideness)
1578                                                                 {}
1579
1580         virtual TestInstance*           createInstance          (Context& context) const
1581                                                                 {
1582                                                                         return new ConcreteTestInstance(context, m_wideness, m_sampleCount);
1583                                                                 }
1584 protected:
1585         const PrimitiveWideness         m_wideness;
1586 };
1587
1588 class LinesTestInstance : public BaseLineTestInstance
1589 {
1590 public:
1591                                                                 LinesTestInstance       (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1592                                                                         : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_LIST, wideness, sampleCount)
1593                                                                 {}
1594
1595         virtual void                            generateLines           (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1596 };
1597
1598 void LinesTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1599 {
1600         outData.resize(6);
1601
1602         switch (iteration)
1603         {
1604                 case 0:
1605                         // \note: these values are chosen arbitrarily
1606                         outData[0] = tcu::Vec4( 0.01f,  0.0f, 0.0f, 1.0f);
1607                         outData[1] = tcu::Vec4( 0.5f,   0.2f, 0.0f, 1.0f);
1608                         outData[2] = tcu::Vec4( 0.46f,  0.3f, 0.0f, 1.0f);
1609                         outData[3] = tcu::Vec4(-0.3f,   0.2f, 0.0f, 1.0f);
1610                         outData[4] = tcu::Vec4(-1.5f,  -0.4f, 0.0f, 1.0f);
1611                         outData[5] = tcu::Vec4( 0.1f,   0.5f, 0.0f, 1.0f);
1612                         break;
1613
1614                 case 1:
1615                         outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1616                         outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
1617                         outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
1618                         outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
1619                         outData[4] = tcu::Vec4(  0.88f,   0.9f, 0.0f, 1.0f);
1620                         outData[5] = tcu::Vec4(  0.18f,  -0.2f, 0.0f, 1.0f);
1621                         break;
1622
1623                 case 2:
1624                         outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1625                         outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
1626                         outData[2] = tcu::Vec4(  0.7f, -0.1f, 0.0f, 1.0f);
1627                         outData[3] = tcu::Vec4( 0.11f,  0.2f, 0.0f, 1.0f);
1628                         outData[4] = tcu::Vec4( 0.88f,  0.7f, 0.0f, 1.0f);
1629                         outData[5] = tcu::Vec4(  0.8f, -0.7f, 0.0f, 1.0f);
1630                         break;
1631         }
1632
1633         outLines.resize(3);
1634         outLines[0].positions[0] = outData[0];
1635         outLines[0].positions[1] = outData[1];
1636         outLines[1].positions[0] = outData[2];
1637         outLines[1].positions[1] = outData[3];
1638         outLines[2].positions[0] = outData[4];
1639         outLines[2].positions[1] = outData[5];
1640
1641         // log
1642         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering " << outLines.size() << " lines(s): (width = " << getLineWidth() << ")" << tcu::TestLog::EndMessage;
1643         for (int lineNdx = 0; lineNdx < (int)outLines.size(); ++lineNdx)
1644         {
1645                 m_context.getTestContext().getLog()
1646                         << tcu::TestLog::Message
1647                         << "Line " << (lineNdx+1) << ":"
1648                         << "\n\t" << outLines[lineNdx].positions[0]
1649                         << "\n\t" << outLines[lineNdx].positions[1]
1650                         << tcu::TestLog::EndMessage;
1651         }
1652 }
1653
1654 class LineStripTestInstance : public BaseLineTestInstance
1655 {
1656 public:
1657                                         LineStripTestInstance   (Context& context, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
1658                                                 : BaseLineTestInstance(context, VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, wideness, sampleCount)
1659                                         {}
1660
1661         virtual void    generateLines                   (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines);
1662 };
1663
1664 void LineStripTestInstance::generateLines (int iteration, std::vector<tcu::Vec4>& outData, std::vector<LineSceneSpec::SceneLine>& outLines)
1665 {
1666         outData.resize(4);
1667
1668         switch (iteration)
1669         {
1670                 case 0:
1671                         // \note: these values are chosen arbitrarily
1672                         outData[0] = tcu::Vec4( 0.01f,  0.0f, 0.0f, 1.0f);
1673                         outData[1] = tcu::Vec4( 0.5f,   0.2f, 0.0f, 1.0f);
1674                         outData[2] = tcu::Vec4( 0.46f,  0.3f, 0.0f, 1.0f);
1675                         outData[3] = tcu::Vec4(-0.5f,   0.2f, 0.0f, 1.0f);
1676                         break;
1677
1678                 case 1:
1679                         outData[0] = tcu::Vec4(-0.499f, 0.128f, 0.0f, 1.0f);
1680                         outData[1] = tcu::Vec4(-0.501f,  -0.3f, 0.0f, 1.0f);
1681                         outData[2] = tcu::Vec4(  0.11f,  -0.2f, 0.0f, 1.0f);
1682                         outData[3] = tcu::Vec4(  0.11f,   0.2f, 0.0f, 1.0f);
1683                         break;
1684
1685                 case 2:
1686                         outData[0] = tcu::Vec4( -0.9f, -0.3f, 0.0f, 1.0f);
1687                         outData[1] = tcu::Vec4(  1.1f, -0.9f, 0.0f, 1.0f);
1688                         outData[2] = tcu::Vec4(  0.7f, -0.1f, 0.0f, 1.0f);
1689                         outData[3] = tcu::Vec4( 0.11f,  0.2f, 0.0f, 1.0f);
1690                         break;
1691         }
1692
1693         outLines.resize(3);
1694         outLines[0].positions[0] = outData[0];
1695         outLines[0].positions[1] = outData[1];
1696         outLines[1].positions[0] = outData[1];
1697         outLines[1].positions[1] = outData[2];
1698         outLines[2].positions[0] = outData[2];
1699         outLines[2].positions[1] = outData[3];
1700
1701         // log
1702         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Rendering line strip, width = " << getLineWidth() << ", " << outData.size() << " vertices." << tcu::TestLog::EndMessage;
1703         for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
1704         {
1705                 m_context.getTestContext().getLog()
1706                         << tcu::TestLog::Message
1707                         << "\t" << outData[vtxNdx]
1708                         << tcu::TestLog::EndMessage;
1709         }
1710 }
1711
1712 class FillRuleTestInstance : public BaseRenderingTestInstance
1713 {
1714 public:
1715         enum FillRuleCaseType
1716         {
1717                 FILLRULECASE_BASIC = 0,
1718                 FILLRULECASE_REVERSED,
1719                 FILLRULECASE_CLIPPED_FULL,
1720                 FILLRULECASE_CLIPPED_PARTIAL,
1721                 FILLRULECASE_PROJECTED,
1722
1723                 FILLRULECASE_LAST
1724         };
1725                                                                                                                 FillRuleTestInstance                    (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount);
1726         virtual tcu::TestStatus                                                         iterate                                                 (void);
1727
1728 private:
1729
1730         virtual const VkPipelineColorBlendStateCreateInfo*      getColorBlendStateCreateInfo    (void) const;
1731         int                                                                                                     getRenderSize                                   (FillRuleCaseType type) const;
1732         int                                                                                                     getNumIterations                                (FillRuleCaseType type) const;
1733         void                                                                                            generateTriangles                               (int iteration, std::vector<tcu::Vec4>& outData) const;
1734
1735         const FillRuleCaseType                                                          m_caseType;
1736         int                                                                                                     m_iteration;
1737         const int                                                                                       m_iterationCount;
1738         bool                                                                                            m_allIterationsPassed;
1739
1740 };
1741
1742 FillRuleTestInstance::FillRuleTestInstance (Context& context, FillRuleCaseType type, VkSampleCountFlagBits sampleCount)
1743         : BaseRenderingTestInstance             (context, sampleCount, getRenderSize(type))
1744         , m_caseType                                    (type)
1745         , m_iteration                                   (0)
1746         , m_iterationCount                              (getNumIterations(type))
1747         , m_allIterationsPassed                 (true)
1748 {
1749         DE_ASSERT(type < FILLRULECASE_LAST);
1750 }
1751
1752 tcu::TestStatus FillRuleTestInstance::iterate (void)
1753 {
1754         const std::string                                               iterationDescription    = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
1755         const tcu::ScopedLogSection                             section                                 (m_context.getTestContext().getLog(), iterationDescription, iterationDescription);
1756         tcu::IVec4                                                              colorBits                               = tcu::getTextureFormatBitDepth(getTextureFormat());
1757         const int                                                               thresholdRed                    = 1 << (8 - colorBits[0]);
1758         const int                                                               thresholdGreen                  = 1 << (8 - colorBits[1]);
1759         const int                                                               thresholdBlue                   = 1 << (8 - colorBits[2]);
1760         tcu::Surface                                                    resultImage                             (m_renderSize, m_renderSize);
1761         std::vector<tcu::Vec4>                                  drawBuffer;
1762
1763         generateTriangles(m_iteration, drawBuffer);
1764
1765         // draw image
1766         {
1767                 const std::vector<tcu::Vec4>    colorBuffer             (drawBuffer.size(), tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
1768
1769                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing gray triangles with shared edges.\nEnabling additive blending to detect overlapping fragments." << tcu::TestLog::EndMessage;
1770
1771                 drawPrimitives(resultImage, drawBuffer, colorBuffer, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
1772         }
1773
1774         // verify no overdraw
1775         {
1776                 const tcu::RGBA triangleColor   = tcu::RGBA(127, 127, 127, 255);
1777                 bool                    overdraw                = false;
1778
1779                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Verifying result." << tcu::TestLog::EndMessage;
1780
1781                 for (int y = 0; y < resultImage.getHeight(); ++y)
1782                 for (int x = 0; x < resultImage.getWidth();  ++x)
1783                 {
1784                         const tcu::RGBA color = resultImage.getPixel(x, y);
1785
1786                         // color values are greater than triangle color? Allow lower values for multisampled edges and background.
1787                         if ((color.getRed()   - triangleColor.getRed())   > thresholdRed   ||
1788                                 (color.getGreen() - triangleColor.getGreen()) > thresholdGreen ||
1789                                 (color.getBlue()  - triangleColor.getBlue())  > thresholdBlue)
1790                                 overdraw = true;
1791                 }
1792
1793                 // results
1794                 if (!overdraw)
1795                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "No overlapping fragments detected." << tcu::TestLog::EndMessage;
1796                 else
1797                 {
1798                         m_context.getTestContext().getLog()     << tcu::TestLog::Message << "Overlapping fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1799                         m_allIterationsPassed = false;
1800                 }
1801         }
1802
1803         // verify no missing fragments in the full viewport case
1804         if (m_caseType == FILLRULECASE_CLIPPED_FULL)
1805         {
1806                 bool missingFragments = false;
1807
1808                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Searching missing fragments." << tcu::TestLog::EndMessage;
1809
1810                 for (int y = 0; y < resultImage.getHeight(); ++y)
1811                 for (int x = 0; x < resultImage.getWidth();  ++x)
1812                 {
1813                         const tcu::RGBA color = resultImage.getPixel(x, y);
1814
1815                         // black? (background)
1816                         if (color.getRed()   <= thresholdRed   ||
1817                                 color.getGreen() <= thresholdGreen ||
1818                                 color.getBlue()  <= thresholdBlue)
1819                                 missingFragments = true;
1820                 }
1821
1822                 // results
1823                 if (!missingFragments)
1824                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "No missing fragments detected." << tcu::TestLog::EndMessage;
1825                 else
1826                 {
1827                         m_context.getTestContext().getLog()     << tcu::TestLog::Message << "Missing fragments detected, image is not valid." << tcu::TestLog::EndMessage;
1828
1829                         m_allIterationsPassed = false;
1830                 }
1831         }
1832
1833         m_context.getTestContext().getLog()     << tcu::TestLog::ImageSet("Result of rendering", "Result of rendering")
1834                                                                                 << tcu::TestLog::Image("Result", "Result", resultImage)
1835                                                                                 << tcu::TestLog::EndImageSet;
1836
1837         // result
1838         if (++m_iteration == m_iterationCount)
1839         {
1840                 if (m_allIterationsPassed)
1841                         return tcu::TestStatus::pass("Pass");
1842                 else
1843                         return tcu::TestStatus::fail("Found invalid pixels");
1844         }
1845         else
1846                 return tcu::TestStatus::incomplete();
1847 }
1848
1849 int FillRuleTestInstance::getRenderSize (FillRuleCaseType type) const
1850 {
1851         if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1852                 return DEFAULT_RENDER_SIZE / 4;
1853         else
1854                 return DEFAULT_RENDER_SIZE;
1855 }
1856
1857 int FillRuleTestInstance::getNumIterations (FillRuleCaseType type) const
1858 {
1859         if (type == FILLRULECASE_CLIPPED_FULL || type == FILLRULECASE_CLIPPED_PARTIAL)
1860                 return 15;
1861         else
1862                 return 2;
1863 }
1864
1865 void FillRuleTestInstance::generateTriangles (int iteration, std::vector<tcu::Vec4>& outData) const
1866 {
1867         switch (m_caseType)
1868         {
1869                 case FILLRULECASE_BASIC:
1870                 case FILLRULECASE_REVERSED:
1871                 case FILLRULECASE_PROJECTED:
1872                 {
1873                         const int       numRows         = 4;
1874                         const int       numColumns      = 4;
1875                         const float     quadSide        = 0.15f;
1876                         de::Random      rnd                     (0xabcd);
1877
1878                         outData.resize(6 * numRows * numColumns);
1879
1880                         for (int col = 0; col < numColumns; ++col)
1881                         for (int row = 0; row < numRows;    ++row)
1882                         {
1883                                 const tcu::Vec2 center          = tcu::Vec2(((float)row + 0.5f) / (float)numRows * 2.0f - 1.0f, ((float)col + 0.5f) / (float)numColumns * 2.0f - 1.0f);
1884                                 const float             rotation        = (float)(iteration * numColumns * numRows + col * numRows + row) / (float)(m_iterationCount * numColumns * numRows) * DE_PI / 2.0f;
1885                                 const tcu::Vec2 sideH           = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1886                                 const tcu::Vec2 sideV           = tcu::Vec2(sideH.y(), -sideH.x());
1887                                 const tcu::Vec2 quad[4]         =
1888                                 {
1889                                         center + sideH + sideV,
1890                                         center + sideH - sideV,
1891                                         center - sideH - sideV,
1892                                         center - sideH + sideV,
1893                                 };
1894
1895                                 if (m_caseType == FILLRULECASE_BASIC)
1896                                 {
1897                                         outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1898                                         outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1899                                         outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1900                                         outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1901                                         outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1902                                         outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1903                                 }
1904                                 else if (m_caseType == FILLRULECASE_REVERSED)
1905                                 {
1906                                         outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1907                                         outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1908                                         outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1909                                         outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1910                                         outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1911                                         outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1912                                 }
1913                                 else if (m_caseType == FILLRULECASE_PROJECTED)
1914                                 {
1915                                         const float w0 = rnd.getFloat(0.1f, 4.0f);
1916                                         const float w1 = rnd.getFloat(0.1f, 4.0f);
1917                                         const float w2 = rnd.getFloat(0.1f, 4.0f);
1918                                         const float w3 = rnd.getFloat(0.1f, 4.0f);
1919
1920                                         outData[6 * (col * numRows + row) + 0] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1921                                         outData[6 * (col * numRows + row) + 1] = tcu::Vec4(quad[1].x() * w1, quad[1].y() * w1, 0.0f, w1);
1922                                         outData[6 * (col * numRows + row) + 2] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1923                                         outData[6 * (col * numRows + row) + 3] = tcu::Vec4(quad[2].x() * w2, quad[2].y() * w2, 0.0f, w2);
1924                                         outData[6 * (col * numRows + row) + 4] = tcu::Vec4(quad[0].x() * w0, quad[0].y() * w0, 0.0f, w0);
1925                                         outData[6 * (col * numRows + row) + 5] = tcu::Vec4(quad[3].x() * w3, quad[3].y() * w3, 0.0f, w3);
1926                                 }
1927                                 else
1928                                         DE_ASSERT(DE_FALSE);
1929                         }
1930
1931                         break;
1932                 }
1933
1934                 case FILLRULECASE_CLIPPED_PARTIAL:
1935                 case FILLRULECASE_CLIPPED_FULL:
1936                 {
1937                         const float             quadSide        = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (1.0f) : (2.0f);
1938                         const tcu::Vec2 center          = (m_caseType == FILLRULECASE_CLIPPED_PARTIAL) ? (tcu::Vec2(0.5f, 0.5f)) : (tcu::Vec2(0.0f, 0.0f));
1939                         const float             rotation        = (float)(iteration) / (float)(m_iterationCount - 1) * DE_PI / 2.0f;
1940                         const tcu::Vec2 sideH           = quadSide * tcu::Vec2(deFloatCos(rotation), deFloatSin(rotation));
1941                         const tcu::Vec2 sideV           = tcu::Vec2(sideH.y(), -sideH.x());
1942                         const tcu::Vec2 quad[4]         =
1943                         {
1944                                 center + sideH + sideV,
1945                                 center + sideH - sideV,
1946                                 center - sideH - sideV,
1947                                 center - sideH + sideV,
1948                         };
1949
1950                         outData.resize(6);
1951                         outData[0] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1952                         outData[1] = tcu::Vec4(quad[1].x(), quad[1].y(), 0.0f, 1.0f);
1953                         outData[2] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1954                         outData[3] = tcu::Vec4(quad[2].x(), quad[2].y(), 0.0f, 1.0f);
1955                         outData[4] = tcu::Vec4(quad[0].x(), quad[0].y(), 0.0f, 1.0f);
1956                         outData[5] = tcu::Vec4(quad[3].x(), quad[3].y(), 0.0f, 1.0f);
1957                         break;
1958                 }
1959
1960                 default:
1961                         DE_ASSERT(DE_FALSE);
1962         }
1963 }
1964
1965 const VkPipelineColorBlendStateCreateInfo* FillRuleTestInstance::getColorBlendStateCreateInfo (void) const
1966 {
1967         static const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
1968         {
1969                 true,                                                                                                           // VkBool32                     blendEnable;
1970                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendColor;
1971                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      destBlendColor;
1972                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpColor;
1973                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      srcBlendAlpha;
1974                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlend                      destBlendAlpha;
1975                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp            blendOpAlpha;
1976                 (VK_COLOR_COMPONENT_R_BIT |
1977                  VK_COLOR_COMPONENT_G_BIT |
1978                  VK_COLOR_COMPONENT_B_BIT |
1979                  VK_COLOR_COMPONENT_A_BIT)                                                                      // VkChannelFlags       channelWriteMask;
1980         };
1981
1982         static const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1983         {
1984                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1985                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
1986                 0,                                                                                                                      // VkPipelineColorBlendStateCreateFlags                 flags;
1987                 false,                                                                                                          // VkBool32                                                                             logicOpEnable;
1988                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1989                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1990                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1991                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConst[4];
1992         };
1993
1994         return &colorBlendStateParams;
1995 }
1996
1997
1998 class FillRuleTestCase : public BaseRenderingTestCase
1999 {
2000 public:
2001                                                                 FillRuleTestCase        (tcu::TestContext& context, const std::string& name, const std::string& description, FillRuleTestInstance::FillRuleCaseType type, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2002                                                                         : BaseRenderingTestCase (context, name, description, sampleCount)
2003                                                                         , m_type                                (type)
2004                                                                 {}
2005
2006         virtual TestInstance*           createInstance          (Context& context) const
2007                                                                 {
2008                                                                         return new FillRuleTestInstance(context, m_type, m_sampleCount);
2009                                                                 }
2010 protected:
2011         const FillRuleTestInstance::FillRuleCaseType m_type;
2012 };
2013
2014 class CullingTestInstance : public BaseRenderingTestInstance
2015 {
2016 public:
2017                                                                                                         CullingTestInstance                             (Context& context, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode)
2018                                                                                                                 : BaseRenderingTestInstance             (context, VK_SAMPLE_COUNT_1_BIT, DEFAULT_RENDER_SIZE)
2019                                                                                                                 , m_cullMode                                    (cullMode)
2020                                                                                                                 , m_primitiveTopology                   (primitiveTopology)
2021                                                                                                                 , m_frontFace                                   (frontFace)
2022                                                                                                                 , m_polygonMode                                 (polygonMode)
2023                                                                                                                 , m_multisampling                               (true)
2024                                                                                                         {}
2025         virtual
2026         const VkPipelineRasterizationStateCreateInfo*   getRasterizationStateCreateInfo (void) const;
2027
2028         tcu::TestStatus                                                                 iterate                                                 (void);
2029
2030 private:
2031         void                                                                                    generateVertices                                (std::vector<tcu::Vec4>& outData) const;
2032         void                                                                                    extractTriangles                                (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const;
2033         void                                                                                    extractLines                                    (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<LineSceneSpec::SceneLine>& outLines) const;
2034         void                                                                                    extractPoints                                   (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, std::vector<PointSceneSpec::ScenePoint>& outPoints) const;
2035         bool                                                                                    triangleOrder                                   (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const;
2036
2037         const VkCullModeFlags                                                   m_cullMode;
2038         const VkPrimitiveTopology                                               m_primitiveTopology;
2039         const VkFrontFace                                                               m_frontFace;
2040         const VkPolygonMode                                                             m_polygonMode;
2041         const bool                                                                              m_multisampling;
2042 };
2043
2044
2045 tcu::TestStatus CullingTestInstance::iterate (void)
2046 {
2047         DE_ASSERT(m_polygonMode < VK_POLYGON_MODE_LAST);
2048
2049         tcu::Surface                                                                    resultImage                                             (m_renderSize, m_renderSize);
2050         std::vector<tcu::Vec4>                                                  drawBuffer;
2051         std::vector<TriangleSceneSpec::SceneTriangle>   triangles;
2052         std::vector<PointSceneSpec::ScenePoint>                 points;
2053         std::vector<LineSceneSpec::SceneLine>                   lines;
2054
2055         const InstanceInterface&                                                vk                              = m_context.getInstanceInterface();
2056         const VkPhysicalDevice                                                  physicalDevice  = m_context.getPhysicalDevice();
2057         const VkPhysicalDeviceFeatures                                  deviceFeatures  = getPhysicalDeviceFeatures(vk, physicalDevice);
2058
2059         if (!(deviceFeatures.fillModeNonSolid) && (m_polygonMode == VK_POLYGON_MODE_LINE || m_polygonMode == VK_POLYGON_MODE_POINT))
2060                 TCU_THROW(NotSupportedError, "Wireframe fill modes are not supported");
2061
2062         // generate scene
2063         generateVertices(drawBuffer);
2064         extractTriangles(triangles, drawBuffer);
2065
2066         if (m_polygonMode == VK_POLYGON_MODE_LINE)
2067                 extractLines(triangles ,lines);
2068         else if (m_polygonMode == VK_POLYGON_MODE_POINT)
2069                 extractPoints(triangles, points);
2070
2071         // draw image
2072         {
2073                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting front face to " << m_frontFace << tcu::TestLog::EndMessage;
2074                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Setting cull face to " << m_cullMode << tcu::TestLog::EndMessage;
2075                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Drawing test pattern (" << m_primitiveTopology << ")" << tcu::TestLog::EndMessage;
2076
2077                 drawPrimitives(resultImage, drawBuffer, m_primitiveTopology);
2078         }
2079
2080         // compare
2081         {
2082                 RasterizationArguments  args;
2083                 tcu::IVec4                              colorBits       = tcu::getTextureFormatBitDepth(getTextureFormat());
2084                 bool                                    isCompareOk     = false;
2085
2086                 args.numSamples         = m_multisampling ? 1 : 0;
2087                 args.subpixelBits       = m_subpixelBits;
2088                 args.redBits            = colorBits[0];
2089                 args.greenBits          = colorBits[1];
2090                 args.blueBits           = colorBits[2];
2091
2092                 switch (m_polygonMode)
2093                 {
2094                         case VK_POLYGON_MODE_LINE:
2095                         {
2096                                 LineSceneSpec scene;
2097                                 scene.lineWidth = 0;
2098                                 scene.lines.swap(lines);
2099                                 isCompareOk = verifyLineGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
2100                                 break;
2101                         }
2102                         case VK_POLYGON_MODE_POINT:
2103                         {
2104                                 PointSceneSpec scene;
2105                                 scene.points.swap(points);
2106                                 isCompareOk = verifyPointGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog());
2107                                 break;
2108                         }
2109                         default:
2110                         {
2111                                 TriangleSceneSpec scene;
2112                                 scene.triangles.swap(triangles);
2113                                 isCompareOk = verifyTriangleGroupRasterization(resultImage, scene, args, m_context.getTestContext().getLog(), tcu::VERIFICATIONMODE_WEAK);
2114                                 break;
2115                         }
2116                 }
2117
2118                 if (isCompareOk)
2119                         return tcu::TestStatus::pass("Pass");
2120                 else
2121                         return tcu::TestStatus::fail("Incorrect rendering");
2122         }
2123 }
2124
2125 void CullingTestInstance::generateVertices (std::vector<tcu::Vec4>& outData) const
2126 {
2127         de::Random rnd(543210);
2128
2129         outData.resize(6);
2130         for (int vtxNdx = 0; vtxNdx < (int)outData.size(); ++vtxNdx)
2131         {
2132                 outData[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2133                 outData[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2134                 outData[vtxNdx].z() = 0.0f;
2135                 outData[vtxNdx].w() = 1.0f;
2136         }
2137 }
2138
2139 void CullingTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices) const
2140 {
2141         const bool cullDirection = (m_cullMode == VK_CULL_MODE_FRONT_BIT) ^ (m_frontFace == VK_FRONT_FACE_COUNTER_CLOCKWISE);
2142
2143         // No triangles
2144         if (m_cullMode == VK_CULL_MODE_FRONT_AND_BACK)
2145                 return;
2146
2147         switch (m_primitiveTopology)
2148         {
2149                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2150                 {
2151                         for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2152                         {
2153                                 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2154                                 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2155                                 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2156
2157                                 if (triangleOrder(v0, v1, v2) != cullDirection)
2158                                 {
2159                                         TriangleSceneSpec::SceneTriangle tri;
2160                                         tri.positions[0] = v0;  tri.sharedEdge[0] = false;
2161                                         tri.positions[1] = v1;  tri.sharedEdge[1] = false;
2162                                         tri.positions[2] = v2;  tri.sharedEdge[2] = false;
2163
2164                                         outTriangles.push_back(tri);
2165                                 }
2166                         }
2167                         break;
2168                 }
2169
2170                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2171                 {
2172                         for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2173                         {
2174                                 const tcu::Vec4& v0 = vertices[vtxNdx + 0];
2175                                 const tcu::Vec4& v1 = vertices[vtxNdx + 1];
2176                                 const tcu::Vec4& v2 = vertices[vtxNdx + 2];
2177
2178                                 if (triangleOrder(v0, v1, v2) != (cullDirection ^ (vtxNdx % 2 != 0)))
2179                                 {
2180                                         TriangleSceneSpec::SceneTriangle tri;
2181                                         tri.positions[0] = v0;  tri.sharedEdge[0] = false;
2182                                         tri.positions[1] = v1;  tri.sharedEdge[1] = false;
2183                                         tri.positions[2] = v2;  tri.sharedEdge[2] = false;
2184
2185                                         outTriangles.push_back(tri);
2186                                 }
2187                         }
2188                         break;
2189                 }
2190
2191                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2192                 {
2193                         for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2194                         {
2195                                 const tcu::Vec4& v0 = vertices[0];
2196                                 const tcu::Vec4& v1 = vertices[vtxNdx + 0];
2197                                 const tcu::Vec4& v2 = vertices[vtxNdx + 1];
2198
2199                                 if (triangleOrder(v0, v1, v2) != cullDirection)
2200                                 {
2201                                         TriangleSceneSpec::SceneTriangle tri;
2202                                         tri.positions[0] = v0;  tri.sharedEdge[0] = false;
2203                                         tri.positions[1] = v1;  tri.sharedEdge[1] = false;
2204                                         tri.positions[2] = v2;  tri.sharedEdge[2] = false;
2205
2206                                         outTriangles.push_back(tri);
2207                                 }
2208                         }
2209                         break;
2210                 }
2211
2212                 default:
2213                         DE_ASSERT(false);
2214         }
2215 }
2216
2217 void CullingTestInstance::extractLines (std::vector<TriangleSceneSpec::SceneTriangle>&  outTriangles,
2218                                                                                 std::vector<LineSceneSpec::SceneLine>&                  outLines) const
2219 {
2220         for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2221         {
2222                 for (int vrtxNdx = 0; vrtxNdx < 2; ++vrtxNdx)
2223                 {
2224                         LineSceneSpec::SceneLine line;
2225                         line.positions[0] = outTriangles.at(triNdx).positions[vrtxNdx];
2226                         line.positions[1] = outTriangles.at(triNdx).positions[vrtxNdx + 1];
2227
2228                         outLines.push_back(line);
2229                 }
2230                 LineSceneSpec::SceneLine line;
2231                 line.positions[0] = outTriangles.at(triNdx).positions[2];
2232                 line.positions[1] = outTriangles.at(triNdx).positions[0];
2233                 outLines.push_back(line);
2234         }
2235 }
2236
2237 void CullingTestInstance::extractPoints (std::vector<TriangleSceneSpec::SceneTriangle>  &outTriangles,
2238                                                                                 std::vector<PointSceneSpec::ScenePoint>                 &outPoints) const
2239 {
2240         for (int triNdx = 0; triNdx < (int)outTriangles.size(); ++triNdx)
2241         {
2242                 for (int vrtxNdx = 0; vrtxNdx < 3; ++vrtxNdx)
2243                 {
2244                         PointSceneSpec::ScenePoint point;
2245                         point.position = outTriangles.at(triNdx).positions[vrtxNdx];
2246                         point.pointSize = 1.0f;
2247
2248                         outPoints.push_back(point);
2249                 }
2250         }
2251 }
2252
2253 bool CullingTestInstance::triangleOrder (const tcu::Vec4& v0, const tcu::Vec4& v1, const tcu::Vec4& v2) const
2254 {
2255         const tcu::Vec2 s0 = v0.swizzle(0, 1) / v0.w();
2256         const tcu::Vec2 s1 = v1.swizzle(0, 1) / v1.w();
2257         const tcu::Vec2 s2 = v2.swizzle(0, 1) / v2.w();
2258
2259         // cross
2260         return ((s1.x() - s0.x()) * (s2.y() - s0.y()) - (s2.x() - s0.x()) * (s1.y() - s0.y())) > 0;
2261 }
2262
2263
2264 const VkPipelineRasterizationStateCreateInfo* CullingTestInstance::getRasterizationStateCreateInfo (void) const
2265 {
2266         static VkPipelineRasterizationStateCreateInfo   rasterizationStateCreateInfo    =
2267         {
2268                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
2269                 DE_NULL,                                                                                                                // const void*                                                          pNext;
2270                 0,                                                                                                                              // VkPipelineRasterizationStateCreateFlags      flags;
2271                 false,                                                                                                                  // VkBool32                                                                     depthClipEnable;
2272                 false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
2273                 VK_POLYGON_MODE_FILL,                                                                                   // VkFillMode                                                           fillMode;
2274                 VK_CULL_MODE_NONE,                                                                                              // VkCullMode                                                           cullMode;
2275                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
2276                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
2277                 0.0f,                                                                                                                   // float                                                                        depthBias;
2278                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
2279                 0.0f,                                                                                                                   // float                                                                        slopeScaledDepthBias;
2280                 getLineWidth(),                                                                                                 // float                                                                        lineWidth;
2281         };
2282
2283         rasterizationStateCreateInfo.lineWidth          = getLineWidth();
2284         rasterizationStateCreateInfo.cullMode           = m_cullMode;
2285         rasterizationStateCreateInfo.frontFace          = m_frontFace;
2286         rasterizationStateCreateInfo.polygonMode        = m_polygonMode;
2287
2288         return &rasterizationStateCreateInfo;
2289 }
2290
2291 class CullingTestCase : public BaseRenderingTestCase
2292 {
2293 public:
2294                                                                 CullingTestCase         (tcu::TestContext& context, const std::string& name, const std::string& description, VkCullModeFlags cullMode, VkPrimitiveTopology primitiveTopology, VkFrontFace frontFace, VkPolygonMode polygonMode, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2295                                                                         : BaseRenderingTestCase (context, name, description, sampleCount)
2296                                                                         , m_cullMode                    (cullMode)
2297                                                                         , m_primitiveTopology   (primitiveTopology)
2298                                                                         , m_frontFace                   (frontFace)
2299                                                                         , m_polygonMode                 (polygonMode)
2300                                                                 {}
2301
2302         virtual TestInstance*           createInstance          (Context& context) const
2303                                                                 {
2304                                                                         return new CullingTestInstance(context, m_cullMode, m_primitiveTopology, m_frontFace, m_polygonMode);
2305                                                                 }
2306 protected:
2307         const VkCullModeFlags           m_cullMode;
2308         const VkPrimitiveTopology       m_primitiveTopology;
2309         const VkFrontFace                       m_frontFace;
2310         const VkPolygonMode                     m_polygonMode;
2311 };
2312
2313 class TriangleInterpolationTestInstance : public BaseRenderingTestInstance
2314 {
2315 public:
2316
2317                                                                 TriangleInterpolationTestInstance       (Context& context, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount)
2318                                                                         : BaseRenderingTestInstance     (context, sampleCount, DEFAULT_RENDER_SIZE)
2319                                                                         , m_primitiveTopology           (primitiveTopology)
2320                                                                         , m_projective                          ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2321                                                                         , m_iterationCount                      (3)
2322                                                                         , m_iteration                           (0)
2323                                                                         , m_allIterationsPassed         (true)
2324                                                                         , m_flatshade                           ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2325                                                                 {}
2326
2327         tcu::TestStatus                         iterate                                                         (void);
2328
2329
2330 private:
2331         void                                            generateVertices                                        (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2332         void                                            extractTriangles                                        (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2333
2334
2335         VkPrimitiveTopology                     m_primitiveTopology;
2336         const bool                                      m_projective;
2337         const int                                       m_iterationCount;
2338         int                                                     m_iteration;
2339         bool                                            m_allIterationsPassed;
2340         const deBool                            m_flatshade;
2341 };
2342
2343 tcu::TestStatus TriangleInterpolationTestInstance::iterate (void)
2344 {
2345         const std::string                                                               iterationDescription    = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2346         const tcu::ScopedLogSection                                             section                                 (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2347         tcu::Surface                                                                    resultImage                             (m_renderSize, m_renderSize);
2348         std::vector<tcu::Vec4>                                                  drawBuffer;
2349         std::vector<tcu::Vec4>                                                  colorBuffer;
2350         std::vector<TriangleSceneSpec::SceneTriangle>   triangles;
2351
2352         // generate scene
2353         generateVertices(m_iteration, drawBuffer, colorBuffer);
2354         extractTriangles(triangles, drawBuffer, colorBuffer);
2355
2356         // log
2357         {
2358                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2359                 for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2360                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2361         }
2362
2363         // draw image
2364         drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2365
2366         // compare
2367         {
2368                 RasterizationArguments  args;
2369                 TriangleSceneSpec               scene;
2370                 tcu::IVec4                              colorBits       = tcu::getTextureFormatBitDepth(getTextureFormat());
2371
2372                 args.numSamples         = m_multisampling ? 1 : 0;
2373                 args.subpixelBits       = m_subpixelBits;
2374                 args.redBits            = colorBits[0];
2375                 args.greenBits          = colorBits[1];
2376                 args.blueBits           = colorBits[2];
2377
2378                 scene.triangles.swap(triangles);
2379
2380                 if (!verifyTriangleGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2381                         m_allIterationsPassed = false;
2382         }
2383
2384         // result
2385         if (++m_iteration == m_iterationCount)
2386         {
2387                 if (m_allIterationsPassed)
2388                         return tcu::TestStatus::pass("Pass");
2389                 else
2390                         return tcu::TestStatus::fail("Found invalid pixel values");
2391         }
2392         else
2393                 return tcu::TestStatus::incomplete();
2394 }
2395
2396 void TriangleInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2397 {
2398         // use only red, green and blue
2399         const tcu::Vec4 colors[] =
2400         {
2401                 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2402                 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2403                 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2404         };
2405
2406         de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2407
2408         outVertices.resize(6);
2409         outColors.resize(6);
2410
2411         for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2412         {
2413                 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2414                 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2415                 outVertices[vtxNdx].z() = 0.0f;
2416
2417                 if (!m_projective)
2418                         outVertices[vtxNdx].w() = 1.0f;
2419                 else
2420                 {
2421                         const float w = rnd.getFloat(0.2f, 4.0f);
2422
2423                         outVertices[vtxNdx].x() *= w;
2424                         outVertices[vtxNdx].y() *= w;
2425                         outVertices[vtxNdx].z() *= w;
2426                         outVertices[vtxNdx].w() = w;
2427                 }
2428
2429                 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2430         }
2431 }
2432
2433 void TriangleInterpolationTestInstance::extractTriangles (std::vector<TriangleSceneSpec::SceneTriangle>& outTriangles, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2434 {
2435         switch (m_primitiveTopology)
2436         {
2437                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
2438                 {
2439                         for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; vtxNdx += 3)
2440                         {
2441                                 TriangleSceneSpec::SceneTriangle tri;
2442                                 tri.positions[0]        = vertices[vtxNdx + 0];
2443                                 tri.positions[1]        = vertices[vtxNdx + 1];
2444                                 tri.positions[2]        = vertices[vtxNdx + 2];
2445                                 tri.sharedEdge[0]       = false;
2446                                 tri.sharedEdge[1]       = false;
2447                                 tri.sharedEdge[2]       = false;
2448
2449                                 if (m_flatshade)
2450                                 {
2451                                         tri.colors[0] = colors[vtxNdx];
2452                                         tri.colors[1] = colors[vtxNdx];
2453                                         tri.colors[2] = colors[vtxNdx];
2454                                 }
2455                                 else
2456                                 {
2457                                         tri.colors[0] = colors[vtxNdx + 0];
2458                                         tri.colors[1] = colors[vtxNdx + 1];
2459                                         tri.colors[2] = colors[vtxNdx + 2];
2460                                 }
2461
2462                                 outTriangles.push_back(tri);
2463                         }
2464                         break;
2465                 }
2466
2467                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
2468                 {
2469                         for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 2; ++vtxNdx)
2470                         {
2471                                 TriangleSceneSpec::SceneTriangle tri;
2472                                 tri.positions[0]        = vertices[vtxNdx + 0];
2473                                 tri.positions[1]        = vertices[vtxNdx + 1];
2474                                 tri.positions[2]        = vertices[vtxNdx + 2];
2475                                 tri.sharedEdge[0]       = false;
2476                                 tri.sharedEdge[1]       = false;
2477                                 tri.sharedEdge[2]       = false;
2478
2479                                 if (m_flatshade)
2480                                 {
2481                                         tri.colors[0] = colors[vtxNdx];
2482                                         tri.colors[1] = colors[vtxNdx];
2483                                         tri.colors[2] = colors[vtxNdx];
2484                                 }
2485                                 else
2486                                 {
2487                                         tri.colors[0] = colors[vtxNdx + 0];
2488                                         tri.colors[1] = colors[vtxNdx + 1];
2489                                         tri.colors[2] = colors[vtxNdx + 2];
2490                                 }
2491
2492                                 outTriangles.push_back(tri);
2493                         }
2494                         break;
2495                 }
2496
2497                 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
2498                 {
2499                         for (int vtxNdx = 1; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2500                         {
2501                                 TriangleSceneSpec::SceneTriangle tri;
2502                                 tri.positions[0]        = vertices[0];
2503                                 tri.positions[1]        = vertices[vtxNdx + 0];
2504                                 tri.positions[2]        = vertices[vtxNdx + 1];
2505                                 tri.sharedEdge[0]       = false;
2506                                 tri.sharedEdge[1]       = false;
2507                                 tri.sharedEdge[2]       = false;
2508
2509                                 if (m_flatshade)
2510                                 {
2511                                         tri.colors[0] = colors[vtxNdx];
2512                                         tri.colors[1] = colors[vtxNdx];
2513                                         tri.colors[2] = colors[vtxNdx];
2514                                 }
2515                                 else
2516                                 {
2517                                         tri.colors[0] = colors[0];
2518                                         tri.colors[1] = colors[vtxNdx + 0];
2519                                         tri.colors[2] = colors[vtxNdx + 1];
2520                                 }
2521
2522                                 outTriangles.push_back(tri);
2523                         }
2524                         break;
2525                 }
2526
2527                 default:
2528                         DE_ASSERT(false);
2529         }
2530 }
2531
2532 class TriangleInterpolationTestCase : public BaseRenderingTestCase
2533 {
2534 public:
2535                                                                 TriangleInterpolationTestCase   (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2536                                                                         : BaseRenderingTestCase         (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2537                                                                         , m_primitiveTopology           (primitiveTopology)
2538                                                                         , m_flags                                       (flags)
2539                                                                 {}
2540
2541         virtual TestInstance*           createInstance                                  (Context& context) const
2542                                                                 {
2543                                                                         return new TriangleInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_sampleCount);
2544                                                                 }
2545 protected:
2546         const VkPrimitiveTopology       m_primitiveTopology;
2547         const int                                       m_flags;
2548 };
2549
2550 class LineInterpolationTestInstance : public BaseRenderingTestInstance
2551 {
2552 public:
2553                                                         LineInterpolationTestInstance   (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount);
2554
2555         virtual tcu::TestStatus iterate                                                 (void);
2556
2557 private:
2558         void                                    generateVertices                                (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const;
2559         void                                    extractLines                                    (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const;
2560         virtual float                   getLineWidth                                    (void) const;
2561
2562         VkPrimitiveTopology             m_primitiveTopology;
2563         const bool                              m_projective;
2564         const int                               m_iterationCount;
2565         const PrimitiveWideness m_primitiveWideness;
2566
2567         int                                             m_iteration;
2568         bool                                    m_allIterationsPassed;
2569         float                                   m_maxLineWidth;
2570         std::vector<float>              m_lineWidths;
2571         bool                                    m_flatshade;
2572 };
2573
2574 LineInterpolationTestInstance::LineInterpolationTestInstance (Context& context, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount)
2575         : BaseRenderingTestInstance                     (context, sampleCount)
2576         , m_primitiveTopology                           (primitiveTopology)
2577         , m_projective                                          ((flags & INTERPOLATIONFLAGS_PROJECTED) != 0)
2578         , m_iterationCount                                      (3)
2579         , m_primitiveWideness                           (wideness)
2580         , m_iteration                                           (0)
2581         , m_allIterationsPassed                         (true)
2582         , m_maxLineWidth                                        (1.0f)
2583         , m_flatshade                                           ((flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2584 {
2585         DE_ASSERT(m_primitiveWideness < PRIMITIVEWIDENESS_LAST);
2586
2587         if (!context.getDeviceProperties().limits.strictLines)
2588                 TCU_THROW(NotSupportedError, "Strict rasterization is not supported");
2589
2590         // create line widths
2591         if (m_primitiveWideness == PRIMITIVEWIDENESS_NARROW)
2592         {
2593                 m_lineWidths.resize(m_iterationCount, 1.0f);
2594         }
2595         else if (m_primitiveWideness == PRIMITIVEWIDENESS_WIDE)
2596         {
2597                 if (!m_context.getDeviceFeatures().wideLines)
2598                         TCU_THROW(NotSupportedError , "wide line support required");
2599
2600                 const float*    range = context.getDeviceProperties().limits.lineWidthRange;
2601
2602                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "ALIASED_LINE_WIDTH_RANGE = [" << range[0] << ", " << range[1] << "]" << tcu::TestLog::EndMessage;
2603
2604                 // no wide line support
2605                 if (range[1] <= 1.0f)
2606                         throw tcu::NotSupportedError("wide line support required");
2607
2608                 // set hand picked sizes
2609                 m_lineWidths.push_back(5.0f);
2610                 m_lineWidths.push_back(10.0f);
2611                 m_lineWidths.push_back(range[1]);
2612                 DE_ASSERT((int)m_lineWidths.size() == m_iterationCount);
2613
2614                 m_maxLineWidth = range[1];
2615         }
2616         else
2617                 DE_ASSERT(false);
2618 }
2619
2620 tcu::TestStatus LineInterpolationTestInstance::iterate (void)
2621 {
2622         const std::string                                               iterationDescription    = "Test iteration " + de::toString(m_iteration+1) + " / " + de::toString(m_iterationCount);
2623         const tcu::ScopedLogSection                             section                                 (m_context.getTestContext().getLog(), "Iteration" + de::toString(m_iteration+1), iterationDescription);
2624         const float                                                             lineWidth                               = getLineWidth();
2625         tcu::Surface                                                    resultImage                             (m_renderSize, m_renderSize);
2626         std::vector<tcu::Vec4>                                  drawBuffer;
2627         std::vector<tcu::Vec4>                                  colorBuffer;
2628         std::vector<LineSceneSpec::SceneLine>   lines;
2629
2630         // supported?
2631         if (lineWidth <= m_maxLineWidth)
2632         {
2633                 // generate scene
2634                 generateVertices(m_iteration, drawBuffer, colorBuffer);
2635                 extractLines(lines, drawBuffer, colorBuffer);
2636
2637                 // log
2638                 {
2639                         m_context.getTestContext().getLog() << tcu::TestLog::Message << "Generated vertices:" << tcu::TestLog::EndMessage;
2640                         for (int vtxNdx = 0; vtxNdx < (int)drawBuffer.size(); ++vtxNdx)
2641                                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "\t" << drawBuffer[vtxNdx] << ",\tcolor= " << colorBuffer[vtxNdx] << tcu::TestLog::EndMessage;
2642                 }
2643
2644                 // draw image
2645                 drawPrimitives(resultImage, drawBuffer, colorBuffer, m_primitiveTopology);
2646
2647                 // compare
2648                 {
2649                         RasterizationArguments  args;
2650                         LineSceneSpec                   scene;
2651
2652                         tcu::IVec4                              colorBits = tcu::getTextureFormatBitDepth(getTextureFormat());
2653
2654                         args.numSamples         = m_multisampling ? 1 : 0;
2655                         args.subpixelBits       = m_subpixelBits;
2656                         args.redBits            = colorBits[0];
2657                         args.greenBits          = colorBits[1];
2658                         args.blueBits           = colorBits[2];
2659
2660                         scene.lines.swap(lines);
2661                         scene.lineWidth = getLineWidth();
2662
2663                         if (!verifyTriangulatedLineGroupInterpolation(resultImage, scene, args, m_context.getTestContext().getLog()))
2664                                 m_allIterationsPassed = false;
2665                 }
2666         }
2667         else
2668                 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Line width " << lineWidth << " not supported, skipping iteration." << tcu::TestLog::EndMessage;
2669
2670         // result
2671         if (++m_iteration == m_iterationCount)
2672         {
2673                 if (m_allIterationsPassed)
2674                         return tcu::TestStatus::pass("Pass");
2675                 else
2676                         return tcu::TestStatus::fail("Incorrect rasterization");
2677         }
2678         else
2679                 return tcu::TestStatus::incomplete();
2680 }
2681
2682 void LineInterpolationTestInstance::generateVertices (int iteration, std::vector<tcu::Vec4>& outVertices, std::vector<tcu::Vec4>& outColors) const
2683 {
2684         // use only red, green and blue
2685         const tcu::Vec4 colors[] =
2686         {
2687                 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
2688                 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
2689                 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
2690         };
2691
2692         de::Random rnd(123 + iteration * 1000 + (int)m_primitiveTopology);
2693
2694         outVertices.resize(6);
2695         outColors.resize(6);
2696
2697         for (int vtxNdx = 0; vtxNdx < (int)outVertices.size(); ++vtxNdx)
2698         {
2699                 outVertices[vtxNdx].x() = rnd.getFloat(-0.9f, 0.9f);
2700                 outVertices[vtxNdx].y() = rnd.getFloat(-0.9f, 0.9f);
2701                 outVertices[vtxNdx].z() = 0.0f;
2702
2703                 if (!m_projective)
2704                         outVertices[vtxNdx].w() = 1.0f;
2705                 else
2706                 {
2707                         const float w = rnd.getFloat(0.2f, 4.0f);
2708
2709                         outVertices[vtxNdx].x() *= w;
2710                         outVertices[vtxNdx].y() *= w;
2711                         outVertices[vtxNdx].z() *= w;
2712                         outVertices[vtxNdx].w() = w;
2713                 }
2714
2715                 outColors[vtxNdx] = colors[vtxNdx % DE_LENGTH_OF_ARRAY(colors)];
2716         }
2717 }
2718
2719 void LineInterpolationTestInstance::extractLines (std::vector<LineSceneSpec::SceneLine>& outLines, const std::vector<tcu::Vec4>& vertices, const std::vector<tcu::Vec4>& colors) const
2720 {
2721         switch (m_primitiveTopology)
2722         {
2723                 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
2724                 {
2725                         for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; vtxNdx += 2)
2726                         {
2727                                 LineSceneSpec::SceneLine line;
2728                                 line.positions[0] = vertices[vtxNdx + 0];
2729                                 line.positions[1] = vertices[vtxNdx + 1];
2730
2731                                 if (m_flatshade)
2732                                 {
2733                                         line.colors[0] = colors[vtxNdx];
2734                                         line.colors[1] = colors[vtxNdx];
2735                                 }
2736                                 else
2737                                 {
2738                                         line.colors[0] = colors[vtxNdx + 0];
2739                                         line.colors[1] = colors[vtxNdx + 1];
2740                                 }
2741
2742                                 outLines.push_back(line);
2743                         }
2744                         break;
2745                 }
2746
2747                 case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
2748                 {
2749                         for (int vtxNdx = 0; vtxNdx < (int)vertices.size() - 1; ++vtxNdx)
2750                         {
2751                                 LineSceneSpec::SceneLine line;
2752                                 line.positions[0] = vertices[vtxNdx + 0];
2753                                 line.positions[1] = vertices[vtxNdx + 1];
2754
2755                                 if (m_flatshade)
2756                                 {
2757                                         line.colors[0] = colors[vtxNdx];
2758                                         line.colors[1] = colors[vtxNdx];
2759                                 }
2760                                 else
2761                                 {
2762                                         line.colors[0] = colors[vtxNdx + 0];
2763                                         line.colors[1] = colors[vtxNdx + 1];
2764                                 }
2765
2766                                 outLines.push_back(line);
2767                         }
2768                         break;
2769                 }
2770
2771                 default:
2772                         DE_ASSERT(false);
2773         }
2774 }
2775
2776 float LineInterpolationTestInstance::getLineWidth (void) const
2777 {
2778         return m_lineWidths[m_iteration];
2779 }
2780
2781 class LineInterpolationTestCase : public BaseRenderingTestCase
2782 {
2783 public:
2784                                                                 LineInterpolationTestCase               (tcu::TestContext& context, const std::string& name, const std::string& description, VkPrimitiveTopology primitiveTopology, int flags, PrimitiveWideness wideness, VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT)
2785                                                                         : BaseRenderingTestCase         (context, name, description, sampleCount, (flags & INTERPOLATIONFLAGS_FLATSHADE) != 0)
2786                                                                         , m_primitiveTopology           (primitiveTopology)
2787                                                                         , m_flags                                       (flags)
2788                                                                         , m_wideness                            (wideness)
2789                                                                 {}
2790
2791         virtual TestInstance*           createInstance                                  (Context& context) const
2792                                                                 {
2793                                                                         return new LineInterpolationTestInstance(context, m_primitiveTopology, m_flags, m_wideness, m_sampleCount);
2794                                                                 }
2795 protected:
2796         const VkPrimitiveTopology       m_primitiveTopology;
2797         const int                                       m_flags;
2798         const PrimitiveWideness         m_wideness;
2799 };
2800
2801 void createRasterizationTests (tcu::TestCaseGroup* rasterizationTests)
2802 {
2803         tcu::TestContext&       testCtx         =       rasterizationTests->getTestContext();
2804
2805         // .primitives
2806         {
2807                 tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, "primitives", "Primitive rasterization");
2808
2809                 rasterizationTests->addChild(primitives);
2810
2811                 primitives->addChild(new BaseTestCase<TrianglesTestInstance>            (testCtx, "triangles",                  "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result"));
2812                 primitives->addChild(new BaseTestCase<TriangleStripTestInstance>        (testCtx, "triangle_strip",             "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, verify rasterization result"));
2813                 primitives->addChild(new BaseTestCase<TriangleFanTestInstance>          (testCtx, "triangle_fan",               "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, verify rasterization result"));
2814                 primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines",                              "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",                                            PRIMITIVEWIDENESS_NARROW));
2815                 primitives->addChild(new WidenessTestCase<LineStripTestInstance>        (testCtx, "line_strip",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, verify rasterization result",                                           PRIMITIVEWIDENESS_NARROW));
2816                 primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines_wide",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",            PRIMITIVEWIDENESS_WIDE));
2817                 primitives->addChild(new WidenessTestCase<LineStripTestInstance>        (testCtx, "line_strip_wide",    "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_STRIP with wide lines, verify rasterization result",           PRIMITIVEWIDENESS_WIDE));
2818                 primitives->addChild(new WidenessTestCase<PointTestInstance>            (testCtx, "points",                             "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",                                           PRIMITIVEWIDENESS_WIDE));
2819         }
2820
2821         // .fill_rules
2822         {
2823                 tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, "fill_rules", "Primitive fill rules");
2824
2825                 rasterizationTests->addChild(fillRules);
2826
2827                 fillRules->addChild(new FillRuleTestCase(testCtx,       "basic_quad",                   "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_BASIC));
2828                 fillRules->addChild(new FillRuleTestCase(testCtx,       "basic_quad_reverse",   "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_REVERSED));
2829                 fillRules->addChild(new FillRuleTestCase(testCtx,       "clipped_full",                 "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL));
2830                 fillRules->addChild(new FillRuleTestCase(testCtx,       "clipped_partly",               "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL));
2831                 fillRules->addChild(new FillRuleTestCase(testCtx,       "projected",                    "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_PROJECTED));
2832         }
2833
2834         // .culling
2835         {
2836                 static const struct CullMode
2837                 {
2838                         VkCullModeFlags mode;
2839                         const char*             prefix;
2840                 } cullModes[] =
2841                 {
2842                         { VK_CULL_MODE_FRONT_BIT,                               "front_"        },
2843                         { VK_CULL_MODE_BACK_BIT,                                "back_"         },
2844                         { VK_CULL_MODE_FRONT_AND_BACK,                  "both_"         },
2845                 };
2846                 static const struct PrimitiveType
2847                 {
2848                         VkPrimitiveTopology     type;
2849                         const char*                     name;
2850                 } primitiveTypes[] =
2851                 {
2852                         { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                  "triangles"                     },
2853                         { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,                 "triangle_strip"        },
2854                         { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,                   "triangle_fan"          },
2855                 };
2856                 static const struct FrontFaceOrder
2857                 {
2858                         VkFrontFace     mode;
2859                         const char*     postfix;
2860                 } frontOrders[] =
2861                 {
2862                         { VK_FRONT_FACE_COUNTER_CLOCKWISE,      ""                      },
2863                         { VK_FRONT_FACE_CLOCKWISE,                      "_reverse"      },
2864                 };
2865
2866                 static const struct PolygonMode
2867                 {
2868                         VkPolygonMode   mode;
2869                         const char*             name;
2870                 } polygonModes[] =
2871                 {
2872                         { VK_POLYGON_MODE_FILL,         ""              },
2873                         { VK_POLYGON_MODE_LINE,         "_line"         },
2874                         { VK_POLYGON_MODE_POINT,        "_point"        }
2875                 };
2876
2877                 tcu::TestCaseGroup* const culling = new tcu::TestCaseGroup(testCtx, "culling", "Culling");
2878
2879                 rasterizationTests->addChild(culling);
2880
2881                 for (int cullModeNdx    = 0; cullModeNdx        < DE_LENGTH_OF_ARRAY(cullModes);                ++cullModeNdx)
2882                 for (int primitiveNdx   = 0; primitiveNdx       < DE_LENGTH_OF_ARRAY(primitiveTypes);   ++primitiveNdx)
2883                 for (int frontOrderNdx  = 0; frontOrderNdx      < DE_LENGTH_OF_ARRAY(frontOrders);              ++frontOrderNdx)
2884                 for (int polygonModeNdx = 0; polygonModeNdx     < DE_LENGTH_OF_ARRAY(polygonModes);             ++polygonModeNdx)
2885                 {
2886                         if (!(cullModes[cullModeNdx].mode == VK_CULL_MODE_FRONT_AND_BACK && polygonModes[polygonModeNdx].mode != VK_POLYGON_MODE_FILL))
2887                         {
2888                                 const std::string name = std::string(cullModes[cullModeNdx].prefix) + primitiveTypes[primitiveNdx].name + frontOrders[frontOrderNdx].postfix + polygonModes[polygonModeNdx].name;
2889                                 culling->addChild(new CullingTestCase(testCtx, name, "Test primitive culling.", cullModes[cullModeNdx].mode, primitiveTypes[primitiveNdx].type, frontOrders[frontOrderNdx].mode, polygonModes[polygonModeNdx].mode));
2890                         }
2891                 }
2892         }
2893
2894         // .interpolation
2895         {
2896                 tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, "interpolation", "Test interpolation");
2897
2898                 rasterizationTests->addChild(interpolation);
2899
2900                 // .basic
2901                 {
2902                         tcu::TestCaseGroup* const basic = new tcu::TestCaseGroup(testCtx, "basic", "Non-projective interpolation");
2903
2904                         interpolation->addChild(basic);
2905
2906                         basic->addChild(new TriangleInterpolationTestCase               (testCtx, "triangles",          "Verify triangle interpolation",                VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    INTERPOLATIONFLAGS_NONE));
2907                         basic->addChild(new TriangleInterpolationTestCase               (testCtx, "triangle_strip",     "Verify triangle strip interpolation",  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,   INTERPOLATIONFLAGS_NONE));
2908                         basic->addChild(new TriangleInterpolationTestCase               (testCtx, "triangle_fan",       "Verify triangle fan interpolation",    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,             INTERPOLATIONFLAGS_NONE));
2909                         basic->addChild(new LineInterpolationTestCase                   (testCtx, "lines",                      "Verify line interpolation",                    VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_NONE,        PRIMITIVEWIDENESS_NARROW));
2910                         basic->addChild(new LineInterpolationTestCase                   (testCtx, "line_strip",         "Verify line strip interpolation",              VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,               INTERPOLATIONFLAGS_NONE,        PRIMITIVEWIDENESS_NARROW));
2911                         basic->addChild(new LineInterpolationTestCase                   (testCtx, "lines_wide",         "Verify wide line interpolation",               VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_NONE,        PRIMITIVEWIDENESS_WIDE));
2912                         basic->addChild(new LineInterpolationTestCase                   (testCtx, "line_strip_wide","Verify wide line strip interpolation",     VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,               INTERPOLATIONFLAGS_NONE,        PRIMITIVEWIDENESS_WIDE));
2913                 }
2914
2915                 // .projected
2916                 {
2917                         tcu::TestCaseGroup* const projected = new tcu::TestCaseGroup(testCtx, "projected", "Projective interpolation");
2918
2919                         interpolation->addChild(projected);
2920
2921                         projected->addChild(new TriangleInterpolationTestCase   (testCtx, "triangles",          "Verify triangle interpolation",                VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    INTERPOLATIONFLAGS_PROJECTED));
2922                         projected->addChild(new TriangleInterpolationTestCase   (testCtx, "triangle_strip",     "Verify triangle strip interpolation",  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,   INTERPOLATIONFLAGS_PROJECTED));
2923                         projected->addChild(new TriangleInterpolationTestCase   (testCtx, "triangle_fan",       "Verify triangle fan interpolation",    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,             INTERPOLATIONFLAGS_PROJECTED));
2924                         projected->addChild(new LineInterpolationTestCase               (testCtx, "lines",                      "Verify line interpolation",                    VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_PROJECTED,   PRIMITIVEWIDENESS_NARROW));
2925                         projected->addChild(new LineInterpolationTestCase               (testCtx, "line_strip",         "Verify line strip interpolation",              VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,               INTERPOLATIONFLAGS_PROJECTED,   PRIMITIVEWIDENESS_NARROW));
2926                         projected->addChild(new LineInterpolationTestCase               (testCtx, "lines_wide",         "Verify wide line interpolation",               VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_PROJECTED,   PRIMITIVEWIDENESS_WIDE));
2927                         projected->addChild(new LineInterpolationTestCase               (testCtx, "line_strip_wide","Verify wide line strip interpolation",     VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,               INTERPOLATIONFLAGS_PROJECTED,   PRIMITIVEWIDENESS_WIDE));
2928                 }
2929         }
2930
2931         // .flatshading
2932         {
2933                 tcu::TestCaseGroup* const flatshading = new tcu::TestCaseGroup(testCtx, "flatshading", "Test flatshading");
2934
2935                 rasterizationTests->addChild(flatshading);
2936
2937                 flatshading->addChild(new TriangleInterpolationTestCase         (testCtx, "triangles",          "Verify triangle flatshading",                  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    INTERPOLATIONFLAGS_FLATSHADE));
2938                 flatshading->addChild(new TriangleInterpolationTestCase         (testCtx, "triangle_strip",     "Verify triangle strip flatshading",    VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,   INTERPOLATIONFLAGS_FLATSHADE));
2939                 flatshading->addChild(new TriangleInterpolationTestCase         (testCtx, "triangle_fan",       "Verify triangle fan flatshading",              VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,             INTERPOLATIONFLAGS_FLATSHADE));
2940                 flatshading->addChild(new LineInterpolationTestCase                     (testCtx, "lines",                      "Verify line flatshading",                              VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_FLATSHADE,   PRIMITIVEWIDENESS_NARROW));
2941                 flatshading->addChild(new LineInterpolationTestCase                     (testCtx, "line_strip",         "Verify line strip flatshading",                VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,               INTERPOLATIONFLAGS_FLATSHADE,   PRIMITIVEWIDENESS_NARROW));
2942                 flatshading->addChild(new LineInterpolationTestCase                     (testCtx, "lines_wide",         "Verify wide line flatshading",                 VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_FLATSHADE,   PRIMITIVEWIDENESS_WIDE));
2943                 flatshading->addChild(new LineInterpolationTestCase                     (testCtx, "line_strip_wide","Verify wide line strip flatshading",       VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,               INTERPOLATIONFLAGS_FLATSHADE,   PRIMITIVEWIDENESS_WIDE));
2944         }
2945
2946         const VkSampleCountFlagBits samples[] =
2947         {
2948                 VK_SAMPLE_COUNT_2_BIT,
2949                 VK_SAMPLE_COUNT_4_BIT,
2950                 VK_SAMPLE_COUNT_8_BIT,
2951                 VK_SAMPLE_COUNT_16_BIT,
2952                 VK_SAMPLE_COUNT_32_BIT,
2953                 VK_SAMPLE_COUNT_64_BIT
2954         };
2955
2956         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2957         {
2958                 std::ostringstream caseName;
2959
2960                 caseName << "_multisample_" << (2 << samplesNdx) << "_bit";
2961
2962                 // .primitives
2963                 {
2964                         tcu::TestCaseGroup* const primitives = new tcu::TestCaseGroup(testCtx, ("primitives" + caseName.str()).c_str(), "Primitive rasterization");
2965
2966                         rasterizationTests->addChild(primitives);
2967
2968                         primitives->addChild(new BaseTestCase<TrianglesTestInstance>            (testCtx, "triangles",                  "Render primitives as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, verify rasterization result",                                        samples[samplesNdx]));
2969                         primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines",                              "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST, verify rasterization result",                                            PRIMITIVEWIDENESS_NARROW,       samples[samplesNdx]));
2970                         primitives->addChild(new WidenessTestCase<LinesTestInstance>            (testCtx, "lines_wide",                 "Render primitives as VK_PRIMITIVE_TOPOLOGY_LINE_LIST with wide lines, verify rasterization result",            PRIMITIVEWIDENESS_WIDE,         samples[samplesNdx]));
2971                         primitives->addChild(new WidenessTestCase<PointTestInstance>            (testCtx, "points",                             "Render primitives as VK_PRIMITIVE_TOPOLOGY_POINT_LIST, verify rasterization result",                                           PRIMITIVEWIDENESS_WIDE,         samples[samplesNdx]));
2972                 }
2973
2974                 // .fill_rules
2975                 {
2976                         tcu::TestCaseGroup* const fillRules = new tcu::TestCaseGroup(testCtx, ("fill_rules" + caseName.str()).c_str(), "Primitive fill rules");
2977
2978                         rasterizationTests->addChild(fillRules);
2979
2980                         fillRules->addChild(new FillRuleTestCase(testCtx,       "basic_quad",                   "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_BASIC,                       samples[samplesNdx]));
2981                         fillRules->addChild(new FillRuleTestCase(testCtx,       "basic_quad_reverse",   "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_REVERSED,            samples[samplesNdx]));
2982                         fillRules->addChild(new FillRuleTestCase(testCtx,       "clipped_full",                 "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_CLIPPED_FULL,        samples[samplesNdx]));
2983                         fillRules->addChild(new FillRuleTestCase(testCtx,       "clipped_partly",               "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_CLIPPED_PARTIAL,     samples[samplesNdx]));
2984                         fillRules->addChild(new FillRuleTestCase(testCtx,       "projected",                    "Verify fill rules",    FillRuleTestInstance::FILLRULECASE_PROJECTED,           samples[samplesNdx]));
2985                 }
2986
2987                 // .interpolation
2988                 {
2989                         tcu::TestCaseGroup* const interpolation = new tcu::TestCaseGroup(testCtx, ("interpolation" + caseName.str()).c_str(), "Test interpolation");
2990
2991                         rasterizationTests->addChild(interpolation);
2992
2993                         interpolation->addChild(new TriangleInterpolationTestCase               (testCtx, "triangles",          "Verify triangle interpolation",                VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    INTERPOLATIONFLAGS_NONE,                                                                samples[samplesNdx]));
2994                         interpolation->addChild(new LineInterpolationTestCase                   (testCtx, "lines",                      "Verify line interpolation",                    VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_NONE,        PRIMITIVEWIDENESS_NARROW,       samples[samplesNdx]));
2995                         interpolation->addChild(new LineInterpolationTestCase                   (testCtx, "lines_wide",         "Verify wide line interpolation",               VK_PRIMITIVE_TOPOLOGY_LINE_LIST,                INTERPOLATIONFLAGS_NONE,        PRIMITIVEWIDENESS_WIDE,         samples[samplesNdx]));
2996                 }
2997         }
2998 }
2999
3000 } // anonymous
3001
3002 tcu::TestCaseGroup* createTests (tcu::TestContext& testCtx)
3003 {
3004         return createTestGroup(testCtx, "rasterization", "Rasterization Tests", createRasterizationTests);
3005 }
3006
3007 } // rasterization
3008 } // vkt