dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineStencilTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Imagination Technologies Ltd.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and/or associated documentation files (the
10  * "Materials"), to deal in the Materials without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sublicense, and/or sell copies of the Materials, and to
13  * permit persons to whom the Materials are furnished to do so, subject to
14  * the following conditions:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
19  * The Materials are Confidential Information as defined by the
20  * Khronos Membership Agreement until designated non-confidential by Khronos,
21  * at which point this condition clause shall be removed.
22  *
23  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29  * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
30  *
31  *//*!
32  * \file
33  * \brief Stencil Tests
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktPipelineStencilTests.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktPipelineReferenceRenderer.hpp"
41 #include "vktPipelineUniqueRandomIterator.hpp"
42 #include "vktTestCase.hpp"
43 #include "vkImageUtil.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkPrograms.hpp"
46 #include "vkQueryUtil.hpp"
47 #include "vkRef.hpp"
48 #include "vkRefUtil.hpp"
49 #include "tcuImageCompare.hpp"
50 #include "deMemory.h"
51 #include "deRandom.hpp"
52 #include "deStringUtil.hpp"
53 #include "deUniquePtr.hpp"
54
55 #include <algorithm>
56 #include <sstream>
57 #include <vector>
58
59 namespace vkt
60 {
61 namespace pipeline
62 {
63
64 using namespace vk;
65
66 namespace
67 {
68
69 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
70 {
71         VkFormatProperties formatProps;
72
73         instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
74
75         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
76 }
77
78 class StencilOpStateUniqueRandomIterator : public UniqueRandomIterator<VkStencilOpState>
79 {
80 public:
81                                                                 StencilOpStateUniqueRandomIterator      (int seed);
82         virtual                                         ~StencilOpStateUniqueRandomIterator     (void) {}
83         virtual VkStencilOpState        getIndexedValue (deUint32 index);
84
85 private:
86         const static VkStencilOp        m_stencilOps[];
87         const static VkCompareOp        m_compareOps[];
88
89         // Pre-calculated constants
90         const static deUint32           m_stencilOpsLength;
91         const static deUint32           m_stencilOpsLength2;
92         const static deUint32           m_stencilOpsLength3;
93         const static deUint32           m_compareOpsLength;
94
95         // Total number of cross-combinations of (stencilFailOp x stencilPassOp x stencilDepthFailOp x stencilCompareOp)
96         const static deUint32           m_totalStencilOpStates;
97 };
98
99
100 class StencilTest : public vkt::TestCase
101 {
102 public:
103         enum
104         {
105                 QUAD_COUNT = 4
106         };
107
108         struct StencilStateConfig
109         {
110                 deUint32        frontReadMask;
111                 deUint32        frontWriteMask;
112                 deUint32        frontRef;
113
114                 deUint32        backReadMask;
115                 deUint32        backWriteMask;
116                 deUint32        backRef;
117         };
118
119         const static StencilStateConfig                 s_stencilStateConfigs[QUAD_COUNT];
120         const static float                                              s_quadDepths[QUAD_COUNT];
121
122
123                                                                                         StencilTest                             (tcu::TestContext&                      testContext,
124                                                                                                                                          const std::string&                     name,
125                                                                                                                                          const std::string&                     description,
126                                                                                                                                          VkFormat                                       stencilFormat,
127                                                                                                                                          const VkStencilOpState&        stencilOpStateFront,
128                                                                                                                                          const VkStencilOpState&        stencilOpStateBack);
129         virtual                                                                 ~StencilTest                    (void);
130         virtual void                                                    initPrograms                    (SourceCollections& sourceCollections) const;
131         virtual TestInstance*                                   createInstance                  (Context& context) const;
132
133 private:
134         VkFormat                                                                m_stencilFormat;
135         const VkStencilOpState                                  m_stencilOpStateFront;
136         const VkStencilOpState                                  m_stencilOpStateBack;
137 };
138
139 class StencilTestInstance : public vkt::TestInstance
140 {
141 public:
142                                                                                 StencilTestInstance             (Context&                                       context,
143                                                                                                                                  VkFormat                                       stencilFormat,
144                                                                                                                                  const VkStencilOpState&        stencilOpStatesFront,
145                                                                                                                                  const VkStencilOpState&        stencilOpStatesBack);
146         virtual                                                         ~StencilTestInstance    (void);
147         virtual tcu::TestStatus                         iterate                                 (void);
148
149 private:
150         tcu::TestStatus                                         verifyImage                             (void);
151
152         VkStencilOpState                                        m_stencilOpStateFront;
153         VkStencilOpState                                        m_stencilOpStateBack;
154         const tcu::IVec2                                        m_renderSize;
155         const VkFormat                                          m_colorFormat;
156         const VkFormat                                          m_stencilFormat;
157
158         VkImageCreateInfo                                       m_colorImageCreateInfo;
159         Move<VkImage>                                           m_colorImage;
160         de::MovePtr<Allocation>                         m_colorImageAlloc;
161         Move<VkImage>                                           m_stencilImage;
162         de::MovePtr<Allocation>                         m_stencilImageAlloc;
163         Move<VkImageView>                                       m_colorAttachmentView;
164         Move<VkImageView>                                       m_stencilAttachmentView;
165         Move<VkRenderPass>                                      m_renderPass;
166         Move<VkFramebuffer>                                     m_framebuffer;
167
168         Move<VkShaderModule>                            m_vertexShaderModule;
169         Move<VkShaderModule>                            m_fragmentShaderModule;
170
171         Move<VkBuffer>                                          m_vertexBuffer;
172         std::vector<Vertex4RGBA>                        m_vertices;
173         de::MovePtr<Allocation>                         m_vertexBufferAlloc;
174
175         Move<VkPipelineLayout>                          m_pipelineLayout;
176         Move<VkPipeline>                                        m_graphicsPipelines[StencilTest::QUAD_COUNT];
177
178         Move<VkCommandPool>                                     m_cmdPool;
179         Move<VkCommandBuffer>                           m_cmdBuffer;
180
181         Move<VkFence>                                           m_fence;
182 };
183
184
185 // StencilOpStateUniqueRandomIterator
186
187 const VkStencilOp StencilOpStateUniqueRandomIterator::m_stencilOps[] =
188 {
189         VK_STENCIL_OP_KEEP,
190         VK_STENCIL_OP_ZERO,
191         VK_STENCIL_OP_REPLACE,
192         VK_STENCIL_OP_INCREMENT_AND_CLAMP,
193         VK_STENCIL_OP_DECREMENT_AND_CLAMP,
194         VK_STENCIL_OP_INVERT,
195         VK_STENCIL_OP_INCREMENT_AND_WRAP,
196         VK_STENCIL_OP_DECREMENT_AND_WRAP
197 };
198
199 const VkCompareOp StencilOpStateUniqueRandomIterator::m_compareOps[] =
200 {
201         VK_COMPARE_OP_NEVER,
202         VK_COMPARE_OP_LESS,
203         VK_COMPARE_OP_EQUAL,
204         VK_COMPARE_OP_LESS_OR_EQUAL,
205         VK_COMPARE_OP_GREATER,
206         VK_COMPARE_OP_NOT_EQUAL,
207         VK_COMPARE_OP_GREATER_OR_EQUAL,
208         VK_COMPARE_OP_ALWAYS
209 };
210
211 const deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength           = DE_LENGTH_OF_ARRAY(m_stencilOps);
212 const deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength2          = m_stencilOpsLength * m_stencilOpsLength;
213 const deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength3          = m_stencilOpsLength2 * m_stencilOpsLength;
214 const deUint32 StencilOpStateUniqueRandomIterator::m_compareOpsLength           = DE_LENGTH_OF_ARRAY(m_compareOps);
215 const deUint32 StencilOpStateUniqueRandomIterator::m_totalStencilOpStates       = m_stencilOpsLength3 * m_compareOpsLength;
216
217 StencilOpStateUniqueRandomIterator::StencilOpStateUniqueRandomIterator (int seed)
218         : UniqueRandomIterator<VkStencilOpState>(m_totalStencilOpStates, m_totalStencilOpStates, seed)
219 {
220 }
221
222 VkStencilOpState StencilOpStateUniqueRandomIterator::getIndexedValue (deUint32 index)
223 {
224         const deUint32 stencilCompareOpIndex = index / m_stencilOpsLength3;
225         const deUint32 stencilCompareOpSeqIndex = stencilCompareOpIndex * m_stencilOpsLength3;
226
227         const deUint32 stencilDepthFailOpIndex = (index - stencilCompareOpSeqIndex) / m_stencilOpsLength2;
228         const deUint32 stencilDepthFailOpSeqIndex = stencilDepthFailOpIndex * m_stencilOpsLength2;
229
230         const deUint32 stencilPassOpIndex = (index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex) / m_stencilOpsLength;
231         const deUint32 stencilPassOpSeqIndex = stencilPassOpIndex * m_stencilOpsLength;
232
233         const deUint32 stencilFailOpIndex = index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex - stencilPassOpSeqIndex;
234
235         const VkStencilOpState stencilOpState =
236         {
237                 m_stencilOps[stencilFailOpIndex],               // VkStencilOp  failOp;
238                 m_stencilOps[stencilPassOpIndex],               // VkStencilOp  passOp;
239                 m_stencilOps[stencilDepthFailOpIndex],  // VkStencilOp  depthFailOp;
240                 m_compareOps[stencilCompareOpIndex],    // VkCompareOp  compareOp;
241                 0x0,                                                                    // deUint32             compareMask;
242                 0x0,                                                                    // deUint32             writeMask;
243                 0x0                                                                             // deUint32             reference;
244         };
245
246         return stencilOpState;
247 }
248
249
250 // StencilTest
251
252 const StencilTest::StencilStateConfig StencilTest::s_stencilStateConfigs[QUAD_COUNT] =
253 {
254         //      frontReadMask   frontWriteMask          frontRef                backReadMask    backWriteMask   backRef
255         {       0xFF,                   0xFF,                           0xAB,                   0xF0,                   0xFF,                   0xFF    },
256         {       0xFF,                   0xF0,                           0xCD,                   0xF0,                   0xF0,                   0xEF    },
257         {       0xF0,                   0x0F,                           0xEF,                   0xFF,                   0x0F,                   0xCD    },
258         {       0xF0,                   0x01,                           0xFF,                   0xFF,                   0x01,                   0xAB    }
259 };
260
261 const float StencilTest::s_quadDepths[QUAD_COUNT] =
262 {
263         0.1f,
264         0.0f,
265         0.3f,
266         0.2f
267 };
268
269 StencilTest::StencilTest (tcu::TestContext&                     testContext,
270                                                   const std::string&            name,
271                                                   const std::string&            description,
272                                                   VkFormat                                      stencilFormat,
273                                                   const VkStencilOpState&       stencilOpStateFront,
274                                                   const VkStencilOpState&       stencilOpStateBack)
275         : vkt::TestCase                 (testContext, name, description)
276         , m_stencilFormat               (stencilFormat)
277         , m_stencilOpStateFront (stencilOpStateFront)
278         , m_stencilOpStateBack  (stencilOpStateBack)
279 {
280 }
281
282 StencilTest::~StencilTest (void)
283 {
284 }
285
286 TestInstance* StencilTest::createInstance (Context& context) const
287 {
288         return new StencilTestInstance(context, m_stencilFormat, m_stencilOpStateFront, m_stencilOpStateBack);
289 }
290
291 void StencilTest::initPrograms (SourceCollections& sourceCollections) const
292 {
293         sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
294                 "#version 310 es\n"
295                 "layout(location = 0) in vec4 position;\n"
296                 "layout(location = 1) in vec4 color;\n"
297                 "layout(location = 0) out highp vec4 vtxColor;\n"
298                 "void main (void)\n"
299                 "{\n"
300                 "       gl_Position = position;\n"
301                 "       vtxColor = color;\n"
302                 "}\n");
303
304         sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
305                 "#version 310 es\n"
306                 "layout(location = 0) in highp vec4 vtxColor;\n"
307                 "layout(location = 0) out highp vec4 fragColor;\n"
308                 "void main (void)\n"
309                 "{\n"
310                 "       fragColor = vtxColor;\n"
311                 "}\n");
312 }
313
314
315 // StencilTestInstance
316
317 StencilTestInstance::StencilTestInstance (Context&                                      context,
318                                                                                   VkFormat                                      stencilFormat,
319                                                                                   const VkStencilOpState&       stencilOpStateFront,
320                                                                                   const VkStencilOpState&       stencilOpStateBack)
321         : vkt::TestInstance             (context)
322         , m_stencilOpStateFront (stencilOpStateFront)
323         , m_stencilOpStateBack  (stencilOpStateBack)
324         , m_renderSize                  (32, 32)
325         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
326         , m_stencilFormat               (stencilFormat)
327 {
328         const DeviceInterface&          vk                                              = context.getDeviceInterface();
329         const VkDevice                          vkDevice                                = context.getDevice();
330         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
331         SimpleAllocator                         memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
332         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
333
334         // Create color image
335         {
336                 const VkImageCreateInfo colorImageParams =
337                 {
338                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
339                         DE_NULL,                                                                                                                                        // const void*                          pNext;
340                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
341                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
342                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
343                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
344                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
345                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
346                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
347                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
348                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
349                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
350                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
351                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
352                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
353                 };
354
355                 m_colorImageCreateInfo  = colorImageParams;
356                 m_colorImage                    = createImage(vk, vkDevice, &m_colorImageCreateInfo);
357
358                 // Allocate and bind color image memory
359                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
360                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
361         }
362
363         // Create stencil image
364         {
365                 // Check format support
366                 if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_stencilFormat))
367                         throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_stencilFormat));
368
369                 const VkImageCreateInfo stencilImageParams =
370                 {
371                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
372                         DE_NULL,                                                                                // const void*                          pNext;
373                         0u,                                                                                             // VkImageCreateFlags           flags;
374                         VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
375                         m_stencilFormat,                                                                // VkFormat                                     format;
376                         { m_renderSize.x(), m_renderSize.y(), 1u },             // VkExtent3D                           extent;
377                         1u,                                                                                             // deUint32                                     mipLevels;
378                         1u,                                                                                             // deUint32                                     arrayLayers;
379                         VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
380                         VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
381                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,    // VkImageUsageFlags            usage;
382                         VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
383                         1u,                                                                                             // deUint32                                     queueFamilyIndexCount;
384                         &queueFamilyIndex,                                                              // const deUint32*                      pQueueFamilyIndices;
385                         VK_IMAGE_LAYOUT_UNDEFINED                                               // VkImageLayout                        initialLayout;
386                 };
387
388                 m_stencilImage = createImage(vk, vkDevice, &stencilImageParams);
389
390                 // Allocate and bind stencil image memory
391                 m_stencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_stencilImage), MemoryRequirement::Any);
392                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_stencilImage, m_stencilImageAlloc->getMemory(), m_stencilImageAlloc->getOffset()));
393         }
394
395         // Create color attachment view
396         {
397                 const VkImageViewCreateInfo colorAttachmentViewParams =
398                 {
399                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
400                         DE_NULL,                                                                                        // const void*                          pNext;
401                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
402                         *m_colorImage,                                                                          // VkImage                                      image;
403                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
404                         m_colorFormat,                                                                          // VkFormat                                     format;
405                         componentMappingRGBA,                                                           // VkComponentMapping           components;
406                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }           // VkImageSubresourceRange      subresourceRange;
407                 };
408
409                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
410         }
411
412         // Create stencil attachment view
413         {
414                 const VkImageViewCreateInfo stencilAttachmentViewParams =
415                 {
416                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
417                         DE_NULL,                                                                                        // const void*                          pNext;
418                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
419                         *m_stencilImage,                                                                        // VkImage                                      image;
420                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
421                         m_stencilFormat,                                                                        // VkFormat                                     format;
422                         componentMappingRGBA,                                                           // VkComponentMapping           components;
423                         { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u },        // VkImageSubresourceRange      subresourceRange;
424                 };
425
426                 m_stencilAttachmentView = createImageView(vk, vkDevice, &stencilAttachmentViewParams);
427         }
428
429         // Create render pass
430         {
431                 const VkAttachmentDescription colorAttachmentDescription =
432                 {
433                         0u,                                                                                                     // VkAttachmentDescriptionFlags flags;
434                         m_colorFormat,                                                                          // VkFormat                                             format;
435                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                samples;
436                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   loadOp;
437                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                  storeOp;
438                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                   stencilLoadOp;
439                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  stencilStoreOp;
440                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                initialLayout;
441                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                finalLayout;
442                 };
443
444                 const VkAttachmentDescription stencilAttachmentDescription =
445                 {
446                         0u,                                                                                                     // VkAttachmentDescriptionFlags flags;
447                         m_stencilFormat,                                                                        // VkFormat                                             format;
448                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                samples;
449                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   loadOp;
450                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  storeOp;
451                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                   stencilLoadOp;
452                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                  stencilStoreOp;
453                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                initialLayout;
454                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                finalLayout;
455                 };
456
457                 const VkAttachmentDescription attachments[2] =
458                 {
459                         colorAttachmentDescription,
460                         stencilAttachmentDescription
461                 };
462
463                 const VkAttachmentReference colorAttachmentReference =
464                 {
465                         0u,                                                                                                     // deUint32                     attachment;
466                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
467                 };
468
469                 const VkAttachmentReference stencilAttachmentReference =
470                 {
471                         1u,                                                                                                     // deUint32                     attachment;
472                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
473                 };
474
475                 const VkSubpassDescription subpassDescription =
476                 {
477                         0u,                                                                                                     // VkSubpassDescriptionFlags    flags;
478                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                  pipelineBindPoint;
479                         0u,                                                                                                     // deUint32                                             inputAttachmentCount;
480                         DE_NULL,                                                                                        // const VkAttachmentReference* pInputAttachments;
481                         1u,                                                                                                     // deUint32                                             colorAttachmentCount;
482                         &colorAttachmentReference,                                                      // const VkAttachmentReference* pColorAttachments;
483                         DE_NULL,                                                                                        // const VkAttachmentReference* pResolveAttachments;
484                         &stencilAttachmentReference,                                            // const VkAttachmentReference* pDepthStencilAttachment;
485                         0u,                                                                                                     // deUint32                                             preserveAttachmentCount;
486                         DE_NULL                                                                                         // const VkAttachmentReference* pPreserveAttachments;
487                 };
488
489                 const VkRenderPassCreateInfo renderPassParams =
490                 {
491                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
492                         DE_NULL,                                                                                        // const void*                                          pNext;
493                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
494                         2u,                                                                                                     // deUint32                                                     attachmentCount;
495                         attachments,                                                                            // const VkAttachmentDescription*       pAttachments;
496                         1u,                                                                                                     // deUint32                                                     subpassCount;
497                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
498                         0u,                                                                                                     // deUint32                                                     dependencyCount;
499                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
500                 };
501
502                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
503         }
504
505         // Create framebuffer
506         {
507                 const VkImageView attachmentBindInfos[2] = { *m_colorAttachmentView, *m_stencilAttachmentView };
508
509                 const VkFramebufferCreateInfo framebufferParams =
510                 {
511                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                      sType;
512                         DE_NULL,                                                                                        // const void*                          pNext;
513                         0u,                                                                                                     // VkFramebufferCreateFlags     flags;
514                         *m_renderPass,                                                                          // VkRenderPass                         renderPass;
515                         2u,                                                                                                     // deUint32                                     attachmentCount;
516                         attachmentBindInfos,                                                            // const VkImageView*           pAttachments;
517                         (deUint32)m_renderSize.x(),                                                     // deUint32                                     width;
518                         (deUint32)m_renderSize.y(),                                                     // deUint32                                     height;
519                         1u                                                                                                      // deUint32                                     layers;
520                 };
521
522                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
523         }
524
525         // Create pipeline layout
526         {
527                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
528                 {
529                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
530                         DE_NULL,                                                                                        // const void*                                  pNext;
531                         0u,                                                                                                     // VkPipelineLayoutCreateFlags  flags;
532                         0u,                                                                                                     // deUint32                                             setLayoutCount;
533                         DE_NULL,                                                                                        // const VkDescriptorSetLayout* pSetLayouts;
534                         0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
535                         DE_NULL                                                                                         // const VkPushConstantRange*   pPushConstantRanges;
536                 };
537
538                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
539         }
540
541         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
542         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
543
544         // Create pipeline
545         {
546                 const VkPipelineShaderStageCreateInfo shaderStages[2] =
547                 {
548                         {
549                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
550                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
551                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
552                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
553                                 *m_vertexShaderModule,                                                                          // VkShaderModule                                               module;
554                                 "main",                                                                                                         // const char*                                                  pName;
555                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
556                         },
557                         {
558                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
559                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
560                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
561                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
562                                 *m_fragmentShaderModule,                                                                        // VkShaderModule                                               module;
563                                 "main",                                                                                                         // const char*                                                  pName;
564                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
565                         }
566                 };
567
568                 const VkVertexInputBindingDescription vertexInputBindingDescription =
569                 {
570                         0u,                                                                             // deUint32                                     binding;
571                         sizeof(Vertex4RGBA),                                    // deUint32                                     strideInBytes;
572                         VK_VERTEX_INPUT_RATE_VERTEX                             // VkVertexInputStepRate        inputRate;
573                 };
574
575                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
576                 {
577                         {
578                                 0u,                                                                     // deUint32     location;
579                                 0u,                                                                     // deUint32     binding;
580                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
581                                 0u                                                                      // deUint32     offsetInBytes;
582                         },
583                         {
584                                 1u,                                                                     // deUint32     location;
585                                 0u,                                                                     // deUint32     binding;
586                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
587                                 DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32     offsetInBytes;
588                         }
589                 };
590
591                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
592                 {
593                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
594                         DE_NULL,                                                                                                                // const void*                                                          pNext;
595                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
596                         1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
597                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
598                         2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
599                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
600                 };
601
602                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
603                 {
604                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
605                         DE_NULL,                                                                                                                // const void*                                                          pNext;
606                         0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
607                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
608                         false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
609                 };
610
611                 const VkViewport viewport =
612                 {
613                         0.0f,                                           // float        x;
614                         0.0f,                                           // float        y;
615                         (float)m_renderSize.x(),        // float        width;
616                         (float)m_renderSize.y(),        // float        height;
617                         0.0f,                                           // float        minDepth;
618                         1.0f                                            // float        maxDepth;
619                 };
620
621                 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
622
623                 const VkPipelineViewportStateCreateInfo viewportStateParams =
624                 {
625                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
626                         DE_NULL,                                                                                                                // const void*                                                  pNext;
627                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
628                         1u,                                                                                                                             // deUint32                                                             viewportCount;
629                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
630                         1u,                                                                                                                             // deUint32                                                             scissorCount;
631                         &scissor,                                                                                                               // const VkRect2D*                                              pScissors;
632                 };
633
634                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
635                 {
636                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
637                         DE_NULL,                                                                                                                // const void*                                                          pNext;
638                         0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
639                         false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
640                         false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
641                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
642                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
643                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
644                         false,                                                                                                                  // VkBool32                                                                     depthBiasEnable;
645                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
646                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
647                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
648                         1.0f                                                                                                                    // float                                                                        lineWidth;
649                 };
650
651                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
652                 {
653                         false,                                                                                                                  // VkBool32                                     blendEnable;
654                         VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor                        srcColorBlendFactor;
655                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor                        dstColorBlendFactor;
656                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            colorBlendOp;
657                         VK_BLEND_FACTOR_ONE,                                                                                    // VKBLENDFACTOR                        SRCALPHABLENDFACTOR;
658                         VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor                        dstAlphaBlendFactor;
659                         VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            alphaBlendOp;
660                         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |                   // VkColorComponentFlags        colorWriteMask;
661                                 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
662                 };
663
664                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
665                 {
666                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
667                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
668                         0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
669                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
670                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
671                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
672                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
673                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
674                 };
675
676                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
677                 {
678                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
679                         DE_NULL,                                                                                                        // const void*                                                          pNext;
680                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
681                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
682                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
683                         0.0f,                                                                                                           // float                                                                        minSampleShading;
684                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
685                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
686                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
687                 };
688
689                 const bool isDepthEnabled = (vk::mapVkFormat(m_stencilFormat).order != tcu::TextureFormat::S);
690
691                 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
692                 {
693                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
694                         DE_NULL,                                                                                                        // const void*                                                          pNext;
695                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
696                         isDepthEnabled,                                                                                         // VkBool32                                                                     depthTestEnable;
697                         isDepthEnabled,                                                                                         // VkBool32                                                                     depthWriteEnable;
698                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
699                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
700                         true,                                                                                                           // VkBool32                                                                     stencilTestEnable;
701                         m_stencilOpStateFront,                                                                          // VkStencilOpState                                                     front;
702                         m_stencilOpStateBack,                                                                           // VkStencilOpState                                                     back;
703                         -1.0f,                                                                                                          // float                                                                        minDepthBounds;
704                         +1.0f                                                                                                           // float                                                                        maxDepthBounds;
705                 };
706
707                 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
708                 {
709                         VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,           // VkStructureType                                              sType;
710                         DE_NULL,                                                                                                        // const void*                                                  pNext;
711                         0u,                                                                                                                     // VkPipelineDynamicStateCreateFlags    flags;
712                         0u,                                                                                                                     // deUint32                                                             dynamicStateCount;
713                         DE_NULL                                                                                                         // const VkDynamicState*                                pDynamicStates;
714                 };
715
716                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
717                 {
718                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
719                         DE_NULL,                                                                                        // const void*                                                                          pNext;
720                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
721                         2u,                                                                                                     // deUint32                                                                                     stageCount;
722                         shaderStages,                                                                           // const VkPipelineShaderStageCreateInfo*                       pStages;
723                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
724                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
725                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
726                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
727                         &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
728                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
729                         &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
730                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
731                         &dynamicStateParams,                                                            // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
732                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
733                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
734                         0u,                                                                                                     // deUint32                                                                                     subpass;
735                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
736                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
737                 };
738
739                 // Setup different stencil masks and refs in each quad
740                 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
741                 {
742                         const StencilTest::StencilStateConfig&  config  = StencilTest::s_stencilStateConfigs[quadNdx];
743                         VkStencilOpState&                                               front   = depthStencilStateParams.front;
744                         VkStencilOpState&                                               back    = depthStencilStateParams.back;
745
746                         front.compareMask       = config.frontReadMask;
747                         front.writeMask         = config.frontWriteMask;
748                         front.reference         = config.frontRef;
749
750                         back.compareMask        = config.backReadMask;
751                         back.writeMask          = config.backWriteMask;
752                         back.reference          = config.backRef;
753
754                         m_graphicsPipelines[quadNdx] = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
755                 }
756         }
757
758
759         // Create vertex buffer
760         {
761                 const VkBufferCreateInfo vertexBufferParams =
762                 {
763                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
764                         DE_NULL,                                                                        // const void*                  pNext;
765                         0u,                                                                                     // VkBufferCreateFlags  flags;
766                         1024u,                                                                          // VkDeviceSize                 size;
767                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
768                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
769                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
770                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
771                 };
772
773                 m_vertices                      = createOverlappingQuads();
774                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
775                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
776
777                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
778
779                 // Adjust depths
780                 for (int quadNdx = 0; quadNdx < 4; quadNdx++)
781                         for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
782                                 m_vertices[quadNdx * 6 + vertexNdx].position.z() = StencilTest::s_quadDepths[quadNdx];
783
784                 // Load vertices into vertex buffer
785                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
786
787                 const VkMappedMemoryRange flushRange =
788                 {
789                                 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,  // VkStructureType      sType;
790                                 DE_NULL,                                                                // const void*          pNext;
791                                 m_vertexBufferAlloc->getMemory(),               // VkDeviceMemory       memory;
792                                 m_vertexBufferAlloc->getOffset(),               // VkDeviceSize         offset;
793                                 vertexBufferParams.size                                 // VkDeviceSize         size;
794                 };
795
796                 vk.flushMappedMemoryRanges(vkDevice, 1, &flushRange);
797         }
798
799         // Create command pool
800         {
801                 const VkCommandPoolCreateInfo cmdPoolParams =
802                 {
803                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                      sType;
804                         DE_NULL,                                                                                // const void*                          pNext;
805                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
806                         queueFamilyIndex,                                                               // deUint32                                     queueFamilyIndex;
807                 };
808
809                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
810         }
811
812         // Create command buffer
813         {
814                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
815                 {
816                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType              sType;
817                         DE_NULL,                                                                                // const void*                  pNext;
818                         *m_cmdPool,                                                                             // VkCommandPool                commandPool;
819                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel level;
820                         1u                                                                                              // deUint32                             bufferCount;
821                 };
822
823                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
824                 {
825                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
826                         DE_NULL,                                                                                // const void*                                          pNext;
827                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
828                         DE_NULL,                                                                                // VkRenderPass                                         renderPass;
829                         0u,                                                                                             // deUint32                                                     subpass;
830                         DE_NULL,                                                                                // VkFramebuffer                                        framebuffer;
831                         false,                                                                                  // VkBool32                                                     occlusionQueryEnable;
832                         0u,                                                                                             // VkQueryControlFlags                          queryFlags;
833                         0u                                                                                              // VkQueryPipelineStatisticFlags        pipelineStatistics;
834                 };
835
836                 const VkClearValue attachmentClearValues[2] =
837                 {
838                         defaultClearValue(m_colorFormat),
839                         defaultClearValue(m_stencilFormat)
840                 };
841
842                 const VkRenderPassBeginInfo renderPassBeginInfo =
843                 {
844                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
845                         DE_NULL,                                                                                                // const void*                  pNext;
846                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
847                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
848                         { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } },  // VkRect2D                             renderArea;
849                         2,                                                                                                              // deUint32                             clearValueCount;
850                         attachmentClearValues                                                                   // const VkClearValue*  pClearValues;
851                 };
852
853                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
854
855                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
856                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
857
858                 const VkDeviceSize              quadOffset              = (m_vertices.size() / StencilTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
859
860                 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
861                 {
862                         VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
863
864                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
865                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
866                         vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / StencilTest::QUAD_COUNT), 1, 0, 0);
867                 }
868
869                 vk.cmdEndRenderPass(*m_cmdBuffer);
870                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
871         }
872
873         // Create fence
874         {
875                 const VkFenceCreateInfo fenceParams =
876                 {
877                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
878                         DE_NULL,                                                                // const void*                  pNext;
879                         0u                                                                              // VkFenceCreateFlags   flags;
880                 };
881
882                 m_fence = createFence(vk, vkDevice, &fenceParams);
883         }
884 }
885
886 StencilTestInstance::~StencilTestInstance (void)
887 {
888 }
889
890 tcu::TestStatus StencilTestInstance::iterate (void)
891 {
892         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
893         const VkDevice                          vkDevice        = m_context.getDevice();
894         const VkQueue                           queue           = m_context.getUniversalQueue();
895         const VkSubmitInfo                      submitInfo      =
896         {
897                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
898                 DE_NULL,                                                // const void*                          pNext;
899                 0u,                                                             // deUint32                                     waitSemaphoreCount;
900                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
901                 1u,                                                             // deUint32                                     commandBufferCount;
902                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
903                 0u,                                                             // deUint32                                     signalSemaphoreCount;
904                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
905         };
906
907         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
908         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
909         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
910
911         return verifyImage();
912 }
913
914 tcu::TestStatus StencilTestInstance::verifyImage (void)
915 {
916         const tcu::TextureFormat        tcuColorFormat          = mapVkFormat(m_colorFormat);
917         const tcu::TextureFormat        tcuStencilFormat        = mapVkFormat(m_stencilFormat);
918         const ColorVertexShader         vertexShader;
919         const ColorFragmentShader       fragmentShader          (tcuColorFormat, tcuStencilFormat);
920         const rr::Program                       program                         (&vertexShader, &fragmentShader);
921         ReferenceRenderer                       refRenderer                     (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program);
922         bool                                            compareOk                       = false;
923
924         // Render reference image
925         {
926                 // Set depth state
927                 rr::RenderState renderState(refRenderer.getViewportState());
928
929                 renderState.fragOps.depthTestEnabled    = true;
930                 renderState.fragOps.depthFunc                   = mapVkCompareOp(VK_COMPARE_OP_LESS);
931                 renderState.fragOps.stencilTestEnabled  = true;
932
933                 rr::StencilState& refStencilFront       = renderState.fragOps.stencilStates[rr::FACETYPE_FRONT];
934                 rr::StencilState& refStencilBack        = renderState.fragOps.stencilStates[rr::FACETYPE_BACK];
935
936                 refStencilFront.sFail           = mapVkStencilOp(m_stencilOpStateFront.failOp);
937                 refStencilFront.dpFail          = mapVkStencilOp(m_stencilOpStateFront.depthFailOp);
938                 refStencilFront.dpPass          = mapVkStencilOp(m_stencilOpStateFront.passOp);
939                 refStencilFront.func            = mapVkCompareOp(m_stencilOpStateFront.compareOp);
940
941                 refStencilBack.sFail            = mapVkStencilOp(m_stencilOpStateBack.failOp);
942                 refStencilBack.dpFail           = mapVkStencilOp(m_stencilOpStateBack.depthFailOp);
943                 refStencilBack.dpPass           = mapVkStencilOp(m_stencilOpStateBack.passOp);
944                 refStencilBack.func                     = mapVkCompareOp(m_stencilOpStateBack.compareOp);
945
946                 // Reverse winding of vertices, as Vulkan screen coordinates start at upper left
947                 std::vector<Vertex4RGBA> cwVertices(m_vertices);
948                 for (size_t vertexNdx = 0; vertexNdx < cwVertices.size() - 2; vertexNdx += 3)
949                 {
950                         const Vertex4RGBA cwVertex1     = cwVertices[vertexNdx + 1];
951
952                         cwVertices[vertexNdx + 1]       = cwVertices[vertexNdx + 2];
953                         cwVertices[vertexNdx + 2]       = cwVertex1;
954                 }
955
956                 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
957                 {
958                         refStencilFront.ref                     = (int)StencilTest::s_stencilStateConfigs[quadNdx].frontRef;
959                         refStencilFront.compMask        = StencilTest::s_stencilStateConfigs[quadNdx].frontReadMask;
960                         refStencilFront.writeMask       = StencilTest::s_stencilStateConfigs[quadNdx].frontWriteMask;
961
962                         refStencilBack.ref                      = (int)StencilTest::s_stencilStateConfigs[quadNdx].backRef;
963                         refStencilBack.compMask         = StencilTest::s_stencilStateConfigs[quadNdx].backReadMask;
964                         refStencilBack.writeMask        = StencilTest::s_stencilStateConfigs[quadNdx].backWriteMask;
965
966                         refRenderer.draw(renderState,
967                                                          rr::PRIMITIVETYPE_TRIANGLES,
968                                                          std::vector<Vertex4RGBA>(cwVertices.begin() + quadNdx * 6,
969                                                                                                           cwVertices.begin() + (quadNdx + 1) * 6));
970                 }
971         }
972
973         // Compare result with reference image
974         {
975                 const DeviceInterface&                          vk                                      = m_context.getDeviceInterface();
976                 const VkDevice                                          vkDevice                        = m_context.getDevice();
977                 const VkQueue                                           queue                           = m_context.getUniversalQueue();
978                 const deUint32                                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
979                 SimpleAllocator                                         allocator                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
980                 de::UniquePtr<tcu::TextureLevel>        result                          (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
981
982                 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
983                                                                                                                           "IntImageCompare",
984                                                                                                                           "Image comparison",
985                                                                                                                           refRenderer.getAccess(),
986                                                                                                                           result->getAccess(),
987                                                                                                                           tcu::UVec4(2, 2, 2, 2),
988                                                                                                                           tcu::IVec3(1, 1, 0),
989                                                                                                                           true,
990                                                                                                                           tcu::COMPARE_LOG_RESULT);
991         }
992
993         if (compareOk)
994                 return tcu::TestStatus::pass("Result image matches reference");
995         else
996                 return tcu::TestStatus::fail("Image mismatch");
997 }
998
999
1000 // Utilities for test names
1001
1002 std::string getShortName (VkCompareOp compareOp)
1003 {
1004         const std::string  fullName = getCompareOpName(compareOp);
1005
1006         DE_ASSERT(de::beginsWith(fullName, "VK_COMPARE_OP_"));
1007
1008         return de::toLower(fullName.substr(14));
1009 }
1010
1011 const char* getShortName (VkStencilOp stencilOp)
1012 {
1013         switch (stencilOp)
1014         {
1015                 case VK_STENCIL_OP_KEEP:                                        return "keep";
1016                 case VK_STENCIL_OP_ZERO:                                        return "zero";
1017                 case VK_STENCIL_OP_REPLACE:                                     return "repl";
1018                 case VK_STENCIL_OP_INCREMENT_AND_CLAMP:         return "incc";
1019                 case VK_STENCIL_OP_DECREMENT_AND_CLAMP:         return "decc";
1020                 case VK_STENCIL_OP_INVERT:                                      return "inv";
1021                 case VK_STENCIL_OP_INCREMENT_AND_WRAP:          return "wrap";
1022                 case VK_STENCIL_OP_DECREMENT_AND_WRAP:          return "decw";
1023
1024                 default:
1025                         DE_FATAL("Invalid VkStencilOpState value");
1026         }
1027         return DE_NULL;
1028 }
1029
1030 std::string getStencilName(const VkStencilOpState& stencilOpState)
1031 {
1032         std::ostringstream name;
1033
1034         name << "fail_" << getShortName(stencilOpState.failOp)
1035                  << "_pass_" << getShortName(stencilOpState.passOp)
1036                  << "_dfail_" << getShortName(stencilOpState.depthFailOp)
1037                  << "_comp_" << getShortName(stencilOpState.compareOp);
1038
1039         return name.str();
1040 }
1041
1042 std::string getStencilStateSetName(const VkStencilOpState& stencilOpStateFront,
1043                                                                    const VkStencilOpState& stencilOpStateBack)
1044 {
1045         std::ostringstream name;
1046
1047         name << "front_" << getStencilName(stencilOpStateFront)
1048                  << "_back_" << getStencilName(stencilOpStateBack);
1049
1050         return name.str();
1051 }
1052
1053 std::string getStencilStateSetDescription(const VkStencilOpState& stencilOpStateFront,
1054                                                                                   const VkStencilOpState& stencilOpStateBack)
1055 {
1056         std::ostringstream desc;
1057
1058         desc << "\nFront faces:\n" << stencilOpStateFront;
1059         desc << "Back faces:\n" << stencilOpStateBack;
1060
1061         return desc.str();
1062 }
1063
1064 std::string getFormatCaseName (VkFormat format)
1065 {
1066         const std::string fullName = getFormatName(format);
1067
1068         DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1069
1070         return de::toLower(fullName.substr(10));
1071 }
1072
1073 } // anonymous
1074
1075 tcu::TestCaseGroup* createStencilTests (tcu::TestContext& testCtx)
1076 {
1077         const VkFormat stencilFormats[] =
1078         {
1079                 VK_FORMAT_S8_UINT,
1080                 VK_FORMAT_D16_UNORM_S8_UINT,
1081                 VK_FORMAT_D24_UNORM_S8_UINT,
1082                 VK_FORMAT_D32_SFLOAT_S8_UINT
1083         };
1084
1085         de::MovePtr<tcu::TestCaseGroup>         stencilTests    (new tcu::TestCaseGroup(testCtx, "stencil", "Stencil tests"));
1086         de::MovePtr<tcu::TestCaseGroup>         formatTests             (new tcu::TestCaseGroup(testCtx, "format", "Uses different stencil formats"));
1087         StencilOpStateUniqueRandomIterator      stencilOpItr    (123);
1088
1089         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(stencilFormats); formatNdx++)
1090         {
1091                 const VkFormat                                  stencilFormat   = stencilFormats[formatNdx];
1092                 de::MovePtr<tcu::TestCaseGroup> formatTest              (new tcu::TestCaseGroup(testCtx,
1093                                                                                                                                                                 getFormatCaseName(stencilFormat).c_str(),
1094                                                                                                                                                                 (std::string("Uses format ") + getFormatName(stencilFormat)).c_str()));
1095
1096                 de::MovePtr<tcu::TestCaseGroup> stencilStateTests;
1097                 {
1098                         std::ostringstream desc;
1099                         desc << "Draws 4 quads with the following depths and dynamic stencil states: ";
1100                         for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++)
1101                         {
1102                                 const StencilTest::StencilStateConfig& stencilConfig = StencilTest::s_stencilStateConfigs[quadNdx];
1103
1104                                 desc << "(" << quadNdx << ") "
1105                                          << "z = " << StencilTest::s_quadDepths[quadNdx] << ", "
1106                                          << "frontReadMask = " << stencilConfig.frontReadMask << ", "
1107                                          << "frontWriteMask = " << stencilConfig.frontWriteMask << ", "
1108                                          << "frontRef = " << stencilConfig.frontRef << ", "
1109                                          << "backReadMask = " << stencilConfig.backReadMask << ", "
1110                                          << "backWriteMask = " << stencilConfig.backWriteMask << ", "
1111                                          << "backRef = " << stencilConfig.backRef;
1112                         }
1113
1114                         stencilStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", desc.str().c_str()));
1115                 }
1116
1117                 stencilOpItr.reset();
1118
1119                 VkStencilOpState                prevStencilState        = stencilOpItr.next();
1120                 const VkStencilOpState  firstStencilState       = prevStencilState;
1121
1122                 while (stencilOpItr.hasNext())
1123                 {
1124                         const VkStencilOpState stencilState = stencilOpItr.next();
1125
1126                         // Use current stencil state in front fraces and previous state in back faces
1127                         stencilStateTests->addChild(new StencilTest(testCtx,
1128                                                                                                                 getStencilStateSetName(stencilState, prevStencilState),
1129                                                                                                                 getStencilStateSetDescription(stencilState, prevStencilState),
1130                                                                                                                 stencilFormat,
1131                                                                                                                 stencilState,
1132                                                                                                                 prevStencilState));
1133
1134                         prevStencilState = stencilState;
1135                 }
1136
1137                 // Use first stencil state with last stencil state. This would make the test suite cover all states in front and back faces.
1138                 stencilStateTests->addChild(new StencilTest(testCtx,
1139                                                                                                         getStencilStateSetName(firstStencilState, prevStencilState),
1140                                                                                                         getStencilStateSetDescription(firstStencilState, prevStencilState),
1141                                                                                                         stencilFormat,
1142                                                                                                         firstStencilState,
1143                                                                                                         prevStencilState));
1144
1145                 formatTest->addChild(stencilStateTests.release());
1146                 formatTests->addChild(formatTest.release());
1147         }
1148         stencilTests->addChild(formatTests.release());
1149
1150         return stencilTests.release();
1151 }
1152
1153 } // pipeline
1154 } // vkt