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