VK_KHR_dedicated_allocation: Extend pipeline.image
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineDepthTests.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 Depth Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineDepthTests.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineImageUtil.hpp"
28 #include "vktPipelineVertexUtil.hpp"
29 #include "vktPipelineReferenceRenderer.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.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 "deUniquePtr.hpp"
41 #include "deStringUtil.hpp"
42 #include "deMemory.h"
43
44 #include <sstream>
45 #include <vector>
46
47 namespace vkt
48 {
49 namespace pipeline
50 {
51
52 using namespace vk;
53
54 namespace
55 {
56
57 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
58 {
59         VkFormatProperties formatProps;
60
61         instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
62
63         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0u;
64 }
65
66 tcu::TestStatus testSupportsDepthStencilFormat (Context& context, VkFormat format)
67 {
68         DE_ASSERT(vk::isDepthStencilFormat(format));
69
70         if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
71                 return tcu::TestStatus::pass("Format can be used in depth/stencil attachment");
72         else
73                 return tcu::TestStatus::fail("Unsupported depth/stencil attachment format");
74 }
75
76 tcu::TestStatus testSupportsAtLeastOneDepthStencilFormat (Context& context, const std::vector<VkFormat> formats)
77 {
78         std::ostringstream      supportedFormatsMsg;
79         bool                            pass                                    = false;
80
81         DE_ASSERT(!formats.empty());
82
83         for (size_t formatNdx = 0; formatNdx < formats.size(); formatNdx++)
84         {
85                 const VkFormat format = formats[formatNdx];
86
87                 DE_ASSERT(vk::isDepthStencilFormat(format));
88
89                 if (isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), format))
90                 {
91                         pass = true;
92                         supportedFormatsMsg << vk::getFormatName(format);
93
94                         if (formatNdx < formats.size() - 1)
95                                 supportedFormatsMsg << ", ";
96                 }
97         }
98
99         if (pass)
100                 return tcu::TestStatus::pass(std::string("Supported depth/stencil formats: ") + supportedFormatsMsg.str());
101         else
102                 return tcu::TestStatus::fail("All depth/stencil formats are unsupported");
103 }
104
105 class DepthTest : public vkt::TestCase
106 {
107 public:
108         enum
109         {
110                 QUAD_COUNT = 4
111         };
112
113         static const float                                      quadDepths[QUAD_COUNT];
114
115                                                                                 DepthTest                               (tcu::TestContext&              testContext,
116                                                                                                                                  const std::string&             name,
117                                                                                                                                  const std::string&             description,
118                                                                                                                                  const VkFormat                 depthFormat,
119                                                                                                                                  const VkCompareOp              depthCompareOps[QUAD_COUNT]);
120         virtual                                                         ~DepthTest                              (void);
121         virtual void                                            initPrograms                    (SourceCollections& programCollection) const;
122         virtual TestInstance*                           createInstance                  (Context& context) const;
123
124 private:
125         const VkFormat                                          m_depthFormat;
126         VkCompareOp                                                     m_depthCompareOps[QUAD_COUNT];
127 };
128
129 class DepthTestInstance : public vkt::TestInstance
130 {
131 public:
132                                                                                 DepthTestInstance               (Context& context, const VkFormat depthFormat, const VkCompareOp depthCompareOps[DepthTest::QUAD_COUNT]);
133         virtual                                                         ~DepthTestInstance              (void);
134         virtual tcu::TestStatus                         iterate                                 (void);
135
136 private:
137         tcu::TestStatus                                         verifyImage                             (void);
138
139 private:
140         VkCompareOp                                                     m_depthCompareOps[DepthTest::QUAD_COUNT];
141         const tcu::UVec2                                        m_renderSize;
142         const VkFormat                                          m_colorFormat;
143         const VkFormat                                          m_depthFormat;
144         VkImageSubresourceRange                         m_depthImageSubresourceRange;
145
146         Move<VkImage>                                           m_colorImage;
147         de::MovePtr<Allocation>                         m_colorImageAlloc;
148         Move<VkImage>                                           m_depthImage;
149         de::MovePtr<Allocation>                         m_depthImageAlloc;
150         Move<VkImageView>                                       m_colorAttachmentView;
151         Move<VkImageView>                                       m_depthAttachmentView;
152         Move<VkRenderPass>                                      m_renderPass;
153         Move<VkFramebuffer>                                     m_framebuffer;
154
155         Move<VkShaderModule>                            m_vertexShaderModule;
156         Move<VkShaderModule>                            m_fragmentShaderModule;
157
158         Move<VkBuffer>                                          m_vertexBuffer;
159         std::vector<Vertex4RGBA>                        m_vertices;
160         de::MovePtr<Allocation>                         m_vertexBufferAlloc;
161
162         Move<VkPipelineLayout>                          m_pipelineLayout;
163         Move<VkPipeline>                                        m_graphicsPipelines[DepthTest::QUAD_COUNT];
164
165         Move<VkCommandPool>                                     m_cmdPool;
166         Move<VkCommandBuffer>                           m_cmdBuffer;
167
168         Move<VkFence>                                           m_fence;
169 };
170
171 const float DepthTest::quadDepths[QUAD_COUNT] =
172 {
173         0.1f,
174         0.0f,
175         0.3f,
176         0.2f
177 };
178
179 DepthTest::DepthTest (tcu::TestContext&         testContext,
180                                           const std::string&    name,
181                                           const std::string&    description,
182                                           const VkFormat                depthFormat,
183                                           const VkCompareOp             depthCompareOps[QUAD_COUNT])
184         : vkt::TestCase (testContext, name, description)
185         , m_depthFormat (depthFormat)
186 {
187         deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * QUAD_COUNT);
188 }
189
190 DepthTest::~DepthTest (void)
191 {
192 }
193
194 TestInstance* DepthTest::createInstance (Context& context) const
195 {
196         return new DepthTestInstance(context, m_depthFormat, m_depthCompareOps);
197 }
198
199 void DepthTest::initPrograms (SourceCollections& programCollection) const
200 {
201         programCollection.glslSources.add("color_vert") << glu::VertexSource(
202                 "#version 310 es\n"
203                 "layout(location = 0) in vec4 position;\n"
204                 "layout(location = 1) in vec4 color;\n"
205                 "layout(location = 0) out highp vec4 vtxColor;\n"
206                 "void main (void)\n"
207                 "{\n"
208                 "       gl_Position = position;\n"
209                 "       vtxColor = color;\n"
210                 "}\n");
211
212         programCollection.glslSources.add("color_frag") << glu::FragmentSource(
213                 "#version 310 es\n"
214                 "layout(location = 0) in highp vec4 vtxColor;\n"
215                 "layout(location = 0) out highp vec4 fragColor;\n"
216                 "void main (void)\n"
217                 "{\n"
218                 "       fragColor = vtxColor;\n"
219                 "}\n");
220 }
221
222 DepthTestInstance::DepthTestInstance (Context&                          context,
223                                                                           const VkFormat                depthFormat,
224                                                                           const VkCompareOp             depthCompareOps[DepthTest::QUAD_COUNT])
225         : vkt::TestInstance     (context)
226         , m_renderSize          (32, 32)
227         , m_colorFormat         (VK_FORMAT_R8G8B8A8_UNORM)
228         , m_depthFormat         (depthFormat)
229 {
230         const DeviceInterface&          vk                                              = context.getDeviceInterface();
231         const VkDevice                          vkDevice                                = context.getDevice();
232         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
233         SimpleAllocator                         memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
234         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
235
236         // Copy depth operators
237         deMemcpy(m_depthCompareOps, depthCompareOps, sizeof(VkCompareOp) * DepthTest::QUAD_COUNT);
238
239         // Create color image
240         {
241                 const VkImageCreateInfo colorImageParams =
242                 {
243                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
244                         DE_NULL,                                                                                                                                        // const void*                          pNext;
245                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
246                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
247                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
248                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
249                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
250                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
251                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
252                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
253                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
254                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
255                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
256                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
257                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
258                 };
259
260                 m_colorImage                    = createImage(vk, vkDevice, &colorImageParams);
261
262                 // Allocate and bind color image memory
263                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
264                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
265         }
266
267         // Create depth image
268         {
269                 // Check format support
270                 if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_depthFormat))
271                         throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_depthFormat));
272
273                 const VkImageCreateInfo depthImageParams =
274                 {
275                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                    // VkStructureType                      sType;
276                         DE_NULL,                                                                                // const void*                          pNext;
277                         0u,                                                                                             // VkImageCreateFlags           flags;
278                         VK_IMAGE_TYPE_2D,                                                               // VkImageType                          imageType;
279                         m_depthFormat,                                                                  // VkFormat                                     format;
280                         { m_renderSize.x(), m_renderSize.y(), 1u },             // VkExtent3D                           extent;
281                         1u,                                                                                             // deUint32                                     mipLevels;
282                         1u,                                                                                             // deUint32                                     arrayLayers;
283                         VK_SAMPLE_COUNT_1_BIT,                                                  // VkSampleCountFlagBits        samples;
284                         VK_IMAGE_TILING_OPTIMAL,                                                // VkImageTiling                        tiling;
285                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,    // VkImageUsageFlags            usage;
286                         VK_SHARING_MODE_EXCLUSIVE,                                              // VkSharingMode                        sharingMode;
287                         1u,                                                                                             // deUint32                                     queueFamilyIndexCount;
288                         &queueFamilyIndex,                                                              // const deUint32*                      pQueueFamilyIndices;
289                         VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        initialLayout;
290                 };
291
292                 m_depthImage = createImage(vk, vkDevice, &depthImageParams);
293
294                 // Allocate and bind depth image memory
295                 m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
296                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
297
298                 const VkImageAspectFlags aspect = (mapVkFormat(m_depthFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT
299                                                                                                                                                                                                           : VK_IMAGE_ASPECT_DEPTH_BIT);
300                 m_depthImageSubresourceRange    = makeImageSubresourceRange(aspect, 0u, depthImageParams.mipLevels, 0u, depthImageParams.arrayLayers);
301         }
302
303         // Create color attachment view
304         {
305                 const VkImageViewCreateInfo colorAttachmentViewParams =
306                 {
307                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
308                         DE_NULL,                                                                                // const void*                          pNext;
309                         0u,                                                                                             // VkImageViewCreateFlags       flags;
310                         *m_colorImage,                                                                  // VkImage                                      image;
311                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
312                         m_colorFormat,                                                                  // VkFormat                                     format;
313                         componentMappingRGBA,                                                   // VkComponentMapping           components;
314                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
315                 };
316
317                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
318         }
319
320         // Create depth attachment view
321         {
322                 const VkImageViewCreateInfo depthAttachmentViewParams =
323                 {
324                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
325                         DE_NULL,                                                                                // const void*                          pNext;
326                         0u,                                                                                             // VkImageViewCreateFlags       flags;
327                         *m_depthImage,                                                                  // VkImage                                      image;
328                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
329                         m_depthFormat,                                                                  // VkFormat                                     format;
330                         componentMappingRGBA,                                                   // VkComponentMapping           components;
331                         m_depthImageSubresourceRange,                                   // VkImageSubresourceRange      subresourceRange;
332                 };
333
334                 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
335         }
336
337         // Create render pass
338         {
339                 const VkAttachmentDescription colorAttachmentDescription =
340                 {
341                         0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
342                         m_colorFormat,                                                                          // VkFormat                                                     format;
343                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
344                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
345                         VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
346                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
347                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
348                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
349                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
350                 };
351
352                 const VkAttachmentDescription depthAttachmentDescription =
353                 {
354                         0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
355                         m_depthFormat,                                                                          // VkFormat                                                     format;
356                         VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
357                         VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
358                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          storeOp;
359                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
360                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
361                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
362                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        finalLayout;
363                 };
364
365                 const VkAttachmentDescription attachments[2] =
366                 {
367                         colorAttachmentDescription,
368                         depthAttachmentDescription
369                 };
370
371                 const VkAttachmentReference colorAttachmentReference =
372                 {
373                         0u,                                                                                                     // deUint32                     attachment;
374                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
375                 };
376
377                 const VkAttachmentReference depthAttachmentReference =
378                 {
379                         1u,                                                                                                     // deUint32                     attachment;
380                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
381                 };
382
383                 const VkSubpassDescription subpassDescription =
384                 {
385                         0u,                                                                                                     // VkSubpassDescriptionFlags            flags;
386                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
387                         0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
388                         DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
389                         1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
390                         &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
391                         DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
392                         &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
393                         0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
394                         DE_NULL                                                                                         // const VkAttachmentReference*         pPreserveAttachments;
395                 };
396
397                 const VkRenderPassCreateInfo renderPassParams =
398                 {
399                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
400                         DE_NULL,                                                                                        // const void*                                          pNext;
401                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
402                         2u,                                                                                                     // deUint32                                                     attachmentCount;
403                         attachments,                                                                            // const VkAttachmentDescription*       pAttachments;
404                         1u,                                                                                                     // deUint32                                                     subpassCount;
405                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
406                         0u,                                                                                                     // deUint32                                                     dependencyCount;
407                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
408                 };
409
410                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
411         }
412
413         // Create framebuffer
414         {
415                 const VkImageView attachmentBindInfos[2] =
416                 {
417                         *m_colorAttachmentView,
418                         *m_depthAttachmentView,
419                 };
420
421                 const VkFramebufferCreateInfo framebufferParams =
422                 {
423                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
424                         DE_NULL,                                                                                        // const void*                                  pNext;
425                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
426                         *m_renderPass,                                                                          // VkRenderPass                                 renderPass;
427                         2u,                                                                                                     // deUint32                                             attachmentCount;
428                         attachmentBindInfos,                                                            // const VkImageView*                   pAttachments;
429                         (deUint32)m_renderSize.x(),                                                     // deUint32                                             width;
430                         (deUint32)m_renderSize.y(),                                                     // deUint32                                             height;
431                         1u                                                                                                      // deUint32                                             layers;
432                 };
433
434                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
435         }
436
437         // Create pipeline layout
438         {
439                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
440                 {
441                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
442                         DE_NULL,                                                                                        // const void*                                          pNext;
443                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
444                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
445                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
446                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
447                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
448                 };
449
450                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
451         }
452
453         // Shader modules
454         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
455         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
456
457         // Create pipeline
458         {
459                 const VkPipelineShaderStageCreateInfo shaderStages[2] =
460                 {
461                         {
462                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
463                                 DE_NULL,                                                                                                // const void*                                                  pNext;
464                                 0u,                                                                                                             // VkPipelineShaderStageCreateFlags             flags;
465                                 VK_SHADER_STAGE_VERTEX_BIT,                                                             // VkShaderStageFlagBits                                stage;
466                                 *m_vertexShaderModule,                                                                  // VkShaderModule                                               module;
467                                 "main",                                                                                                 // const char*                                                  pName;
468                                 DE_NULL                                                                                                 // const VkSpecializationInfo*                  pSpecializationInfo;
469                         },
470                         {
471                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
472                                 DE_NULL,                                                                                                // const void*                                                  pNext;
473                                 0u,                                                                                                             // VkPipelineShaderStageCreateFlags             flags;
474                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                   // VkShaderStageFlagBits                                stage;
475                                 *m_fragmentShaderModule,                                                                // VkShaderModule                                               module;
476                                 "main",                                                                                                 // const char*                                                  pName;
477                                 DE_NULL                                                                                                 // const VkSpecializationInfo*                  pSpecializationInfo;
478                         }
479                 };
480
481                 const VkVertexInputBindingDescription vertexInputBindingDescription =
482                 {
483                         0u,                                                                     // deUint32                                     binding;
484                         sizeof(Vertex4RGBA),                            // deUint32                                     strideInBytes;
485                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        inputRate;
486                 };
487
488                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
489                 {
490                         {
491                                 0u,                                                                     // deUint32     location;
492                                 0u,                                                                     // deUint32     binding;
493                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
494                                 0u                                                                      // deUint32     offset;
495                         },
496                         {
497                                 1u,                                                                     // deUint32     location;
498                                 0u,                                                                     // deUint32     binding;
499                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
500                                 DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32     offset;
501                         }
502                 };
503
504                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
505                 {
506                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
507                         DE_NULL,                                                                                                                // const void*                                                          pNext;
508                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
509                         1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
510                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
511                         2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
512                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
513                 };
514
515                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
516                 {
517                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
518                         DE_NULL,                                                                                                                // const void*                                                          pNext;
519                         0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
520                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // VkPrimitiveTopology                                          topology;
521                         false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
522                 };
523
524                 const VkViewport viewport =
525                 {
526                         0.0f,                                           // float        x;
527                         0.0f,                                           // float        y;
528                         (float)m_renderSize.x(),        // float        width;
529                         (float)m_renderSize.y(),        // float        height;
530                         0.0f,                                           // float        minDepth;
531                         1.0f                                            // float        maxDepth;
532                 };
533                 const VkRect2D scissor =
534                 {
535                         { 0, 0 },                                                                                               // VkOffset2D  offset;
536                         { m_renderSize.x(), m_renderSize.y() }                                  // VkExtent2D  extent;
537                 };
538                 const VkPipelineViewportStateCreateInfo viewportStateParams =
539                 {
540                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
541                         DE_NULL,                                                                                                                // const void*                                                  pNext;
542                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
543                         1u,                                                                                                                             // deUint32                                                             viewportCount;
544                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
545                         1u,                                                                                                                             // deUint32                                                             scissorCount;
546                         &scissor                                                                                                                // const VkRect2D*                                              pScissors;
547                 };
548
549                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
550                 {
551                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
552                         DE_NULL,                                                                                                                // const void*                                                          pNext;
553                         0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
554                         false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
555                         false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
556                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
557                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
558                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
559                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
560                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
561                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
562                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
563                         1.0f,                                                                                                                   // float                                                                        lineWidth;
564                 };
565
566                 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
567                 {
568                         false,                                                                                                                                          // VkBool32                                     blendEnable;
569                         VK_BLEND_FACTOR_ONE,                                                                                                            // VkBlendFactor                        srcColorBlendFactor;
570                         VK_BLEND_FACTOR_ZERO,                                                                                                           // VkBlendFactor                        dstColorBlendFactor;
571                         VK_BLEND_OP_ADD,                                                                                                                        // VkBlendOp                            colorBlendOp;
572                         VK_BLEND_FACTOR_ONE,                                                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
573                         VK_BLEND_FACTOR_ZERO,                                                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
574                         VK_BLEND_OP_ADD,                                                                                                                        // VkBlendOp                            alphaBlendOp;
575                         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |                                           // VkColorComponentFlags        colorWriteMask;
576                                 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
577                 };
578
579                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
580                 {
581                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
582                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
583                         0,                                                                                                                      // VkPipelineColorBlendStateCreateFlags                 flags;
584                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
585                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
586                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
587                         &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
588                         { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
589                 };
590
591                 const VkPipelineMultisampleStateCreateInfo      multisampleStateParams  =
592                 {
593                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
594                         DE_NULL,                                                                                                        // const void*                                                          pNext;
595                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
596                         VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
597                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
598                         0.0f,                                                                                                           // float                                                                        minSampleShading;
599                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
600                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
601                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
602                 };
603                 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
604                 {
605                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
606                         DE_NULL,                                                                                                        // const void*                                                          pNext;
607                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
608                         true,                                                                                                           // VkBool32                                                                     depthTestEnable;
609                         true,                                                                                                           // VkBool32                                                                     depthWriteEnable;
610                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
611                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
612                         false,                                                                                                          // VkBool32                                                                     stencilTestEnable;
613                         // VkStencilOpState     front;
614                         {
615                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
616                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
617                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
618                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
619                                 0u,                                             // deUint32             compareMask;
620                                 0u,                                             // deUint32             writeMask;
621                                 0u,                                             // deUint32             reference;
622                         },
623                         // VkStencilOpState     back;
624                         {
625                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp;
626                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  passOp;
627                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp;
628                                 VK_COMPARE_OP_NEVER,    // VkCompareOp  compareOp;
629                                 0u,                                             // deUint32             compareMask;
630                                 0u,                                             // deUint32             writeMask;
631                                 0u,                                             // deUint32             reference;
632                         },
633                         0.0f,                                                                                                           // float                        minDepthBounds;
634                         1.0f,                                                                                                           // float                        maxDepthBounds;
635                 };
636
637                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
638                 {
639                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
640                         DE_NULL,                                                                                        // const void*                                                                          pNext;
641                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
642                         2u,                                                                                                     // deUint32                                                                                     stageCount;
643                         shaderStages,                                                                           // const VkPipelineShaderStageCreateInfo*                       pStages;
644                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
645                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
646                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
647                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
648                         &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
649                         &multisampleStateParams,                                                        // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
650                         &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
651                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
652                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
653                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
654                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
655                         0u,                                                                                                     // deUint32                                                                                     subpass;
656                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
657                         0u,                                                                                                     // deInt32                                                                                      basePipelineIndex;
658                 };
659
660                 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
661                 {
662                         depthStencilStateParams.depthCompareOp  = depthCompareOps[quadNdx];
663                         m_graphicsPipelines[quadNdx]                    = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
664                 }
665         }
666
667         // Create vertex buffer
668         {
669                 const VkBufferCreateInfo vertexBufferParams =
670                 {
671                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
672                         DE_NULL,                                                                        // const void*                  pNext;
673                         0u,                                                                                     // VkBufferCreateFlags  flags;
674                         1024u,                                                                          // VkDeviceSize                 size;
675                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
676                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
677                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
678                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
679                 };
680
681                 m_vertices                      = createOverlappingQuads();
682                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
683                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
684
685                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
686
687                 // Adjust depths
688                 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
689                         for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++)
690                                 m_vertices[quadNdx * 6 + vertexNdx].position.z() = DepthTest::quadDepths[quadNdx];
691
692                 // Load vertices into vertex buffer
693                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
694                 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
695         }
696
697         // Create command pool
698         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
699
700         // Create command buffer
701         {
702                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
703                 {
704                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
705                         DE_NULL,                                                                                // const void*                                          pNext;
706                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
707                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
708                 };
709
710                 const VkClearValue attachmentClearValues[2] =
711                 {
712                         defaultClearValue(m_colorFormat),
713                         defaultClearValue(m_depthFormat),
714                 };
715
716                 const VkRenderPassBeginInfo renderPassBeginInfo =
717                 {
718                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
719                         DE_NULL,                                                                                                // const void*                  pNext;
720                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
721                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
722                         { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
723                         2,                                                                                                              // deUint32                             clearValueCount;
724                         attachmentClearValues                                                                   // const VkClearValue*  pClearValues;
725                 };
726
727                 const VkImageMemoryBarrier imageLayoutBarriers[] =
728                 {
729                         // color image layout transition
730                         {
731                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType            sType;
732                                 DE_NULL,                                                                                                                                // const void*                pNext;
733                                 (VkAccessFlags)0,                                                                                                               // VkAccessFlags              srcAccessMask;
734                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                                   // VkAccessFlags              dstAccessMask;
735                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout              oldLayout;
736                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                               // VkImageLayout              newLayout;
737                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   srcQueueFamilyIndex;
738                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   dstQueueFamilyIndex;
739                                 *m_colorImage,                                                                                                                  // VkImage                    image;
740                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }                                                   // VkImageSubresourceRange    subresourceRange;
741                         },
742                         // depth image layout transition
743                         {
744                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType            sType;
745                                 DE_NULL,                                                                                                                                // const void*                pNext;
746                                 (VkAccessFlags)0,                                                                                                               // VkAccessFlags              srcAccessMask;
747                                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,                                                   // VkAccessFlags              dstAccessMask;
748                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout              oldLayout;
749                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,                                               // VkImageLayout              newLayout;
750                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   srcQueueFamilyIndex;
751                                 VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   dstQueueFamilyIndex;
752                                 *m_depthImage,                                                                                                                  // VkImage                    image;
753                                 m_depthImageSubresourceRange,                                                                                   // VkImageSubresourceRange    subresourceRange;
754                         },
755                 };
756
757                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
758
759                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
760
761                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
762                         0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageLayoutBarriers), imageLayoutBarriers);
763
764                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
765
766                 const VkDeviceSize              quadOffset              = (m_vertices.size() / DepthTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
767
768                 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
769                 {
770                         VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
771
772                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
773                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
774                         vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / DepthTest::QUAD_COUNT), 1, 0, 0);
775                 }
776
777                 vk.cmdEndRenderPass(*m_cmdBuffer);
778                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
779         }
780
781         // Create fence
782         m_fence = createFence(vk, vkDevice);
783 }
784
785 DepthTestInstance::~DepthTestInstance (void)
786 {
787 }
788
789 tcu::TestStatus DepthTestInstance::iterate (void)
790 {
791         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
792         const VkDevice                          vkDevice        = m_context.getDevice();
793         const VkQueue                           queue           = m_context.getUniversalQueue();
794         const VkSubmitInfo                      submitInfo      =
795         {
796                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
797                 DE_NULL,                                                // const void*                          pNext;
798                 0u,                                                             // deUint32                                     waitSemaphoreCount;
799                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
800                 (const VkPipelineStageFlags*)DE_NULL,
801                 1u,                                                             // deUint32                                     commandBufferCount;
802                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
803                 0u,                                                             // deUint32                                     signalSemaphoreCount;
804                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
805         };
806
807         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
808         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
809         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
810
811         return verifyImage();
812 }
813
814 tcu::TestStatus DepthTestInstance::verifyImage (void)
815 {
816         const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
817         const tcu::TextureFormat        tcuDepthFormat  = mapVkFormat(m_depthFormat);
818         const ColorVertexShader         vertexShader;
819         const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
820         const rr::Program                       program                 (&vertexShader, &fragmentShader);
821         ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
822         bool                                            compareOk               = false;
823
824         // Render reference image
825         {
826                 for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
827                 {
828                         // Set depth state
829                         rr::RenderState renderState(refRenderer.getViewportState());
830                         renderState.fragOps.depthTestEnabled = true;
831                         renderState.fragOps.depthFunc = mapVkCompareOp(m_depthCompareOps[quadNdx]);
832
833                         refRenderer.draw(renderState,
834                                                          rr::PRIMITIVETYPE_TRIANGLES,
835                                                          std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
836                                                                                                           m_vertices.begin() + (quadNdx + 1) * 6));
837                 }
838         }
839
840         // Compare result with reference image
841         {
842                 const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
843                 const VkDevice                                  vkDevice                        = m_context.getDevice();
844                 const VkQueue                                   queue                           = m_context.getUniversalQueue();
845                 const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
846                 SimpleAllocator                                 allocator                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
847                 de::MovePtr<tcu::TextureLevel>  result                          = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize);
848
849                 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
850                                                                                                                           "IntImageCompare",
851                                                                                                                           "Image comparison",
852                                                                                                                           refRenderer.getAccess(),
853                                                                                                                           result->getAccess(),
854                                                                                                                           tcu::UVec4(2, 2, 2, 2),
855                                                                                                                           tcu::IVec3(1, 1, 0),
856                                                                                                                           true,
857                                                                                                                           tcu::COMPARE_LOG_RESULT);
858         }
859
860         if (compareOk)
861                 return tcu::TestStatus::pass("Result image matches reference");
862         else
863                 return tcu::TestStatus::fail("Image mismatch");
864 }
865
866 std::string getFormatCaseName (const VkFormat format)
867 {
868         const std::string       fullName        = getFormatName(format);
869
870         DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
871
872         return de::toLower(fullName.substr(10));
873 }
874
875 std::string     getCompareOpsName (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
876 {
877         std::ostringstream name;
878
879         for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
880         {
881                 const std::string       fullOpName      = getCompareOpName(quadDepthOps[quadNdx]);
882
883                 DE_ASSERT(de::beginsWith(fullOpName, "VK_COMPARE_OP_"));
884
885                 name << de::toLower(fullOpName.substr(14));
886
887                 if (quadNdx < DepthTest::QUAD_COUNT - 1)
888                         name << "_";
889         }
890
891         return name.str();
892 }
893
894 std::string     getCompareOpsDescription (const VkCompareOp quadDepthOps[DepthTest::QUAD_COUNT])
895 {
896         std::ostringstream desc;
897         desc << "Draws " << DepthTest::QUAD_COUNT << " quads with depth compare ops: ";
898
899         for (int quadNdx = 0; quadNdx < DepthTest::QUAD_COUNT; quadNdx++)
900         {
901                 desc << getCompareOpName(quadDepthOps[quadNdx]) << " at depth " << DepthTest::quadDepths[quadNdx];
902
903                 if (quadNdx < DepthTest::QUAD_COUNT - 1)
904                         desc << ", ";
905         }
906         return desc.str();
907 }
908
909
910 } // anonymous
911
912 tcu::TestCaseGroup* createDepthTests (tcu::TestContext& testCtx)
913 {
914         const VkFormat depthFormats[] =
915         {
916                 VK_FORMAT_D16_UNORM,
917                 VK_FORMAT_X8_D24_UNORM_PACK32,
918                 VK_FORMAT_D32_SFLOAT,
919                 VK_FORMAT_D16_UNORM_S8_UINT,
920                 VK_FORMAT_D24_UNORM_S8_UINT,
921                 VK_FORMAT_D32_SFLOAT_S8_UINT
922         };
923
924         // Each entry configures the depth compare operators of QUAD_COUNT quads.
925         // All entries cover pair-wise combinations of compare operators.
926         const VkCompareOp depthOps[][DepthTest::QUAD_COUNT] =
927         {
928                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_NOT_EQUAL },
929                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_GREATER },
930                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_LESS_OR_EQUAL },
931                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL },
932                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_ALWAYS },
933                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_LESS },
934                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_NEVER },
935                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_EQUAL },
936                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_LESS },
937                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL },
938                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_GREATER },
939                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_LESS_OR_EQUAL },
940                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_EQUAL },
941                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_ALWAYS },
942                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_GREATER_OR_EQUAL },
943                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_LESS },
944                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS },
945                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_GREATER },
946                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_NOT_EQUAL },
947                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_GREATER_OR_EQUAL },
948                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_NEVER },
949                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER },
950                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_LESS_OR_EQUAL },
951                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_NOT_EQUAL },
952                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_GREATER_OR_EQUAL },
953                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_LESS_OR_EQUAL },
954                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_LESS },
955                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_EQUAL },
956                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_NEVER },
957                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_LESS_OR_EQUAL },
958                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_EQUAL },
959                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_LESS },
960                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_ALWAYS },
961                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_GREATER_OR_EQUAL },
962                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER },
963                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_GREATER_OR_EQUAL },
964                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_LESS_OR_EQUAL },
965                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_NEVER },
966                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_EQUAL },
967                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_NOT_EQUAL },
968                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_ALWAYS },
969                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_ALWAYS },
970                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS },
971                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_EQUAL },
972                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_GREATER },
973                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_NOT_EQUAL },
974                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
975                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_GREATER_OR_EQUAL },
976                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_NEVER },
977                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_LESS },
978                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_ALWAYS },
979                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_GREATER },
980                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_EQUAL },
981                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_NOT_EQUAL },
982                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_LESS },
983                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_NEVER },
984                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_NOT_EQUAL },
985                 { VK_COMPARE_OP_GREATER,                        VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_EQUAL },
986                 { VK_COMPARE_OP_EQUAL,                          VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_LESS_OR_EQUAL },
987                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_GREATER },
988                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_NEVER },
989                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_GREATER },
990                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_NOT_EQUAL },
991                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_ALWAYS },
992                 { VK_COMPARE_OP_LESS_OR_EQUAL,          VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_GREATER },
993                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS,                             VK_COMPARE_OP_GREATER },
994                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_GREATER_OR_EQUAL },
995                 { VK_COMPARE_OP_ALWAYS,                         VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_LESS_OR_EQUAL },
996                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_GREATER_OR_EQUAL, VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_LESS },
997                 { VK_COMPARE_OP_GREATER_OR_EQUAL,       VK_COMPARE_OP_NEVER,                    VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_NEVER },
998                 { VK_COMPARE_OP_LESS,                           VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_EQUAL,                    VK_COMPARE_OP_EQUAL },
999                 { VK_COMPARE_OP_NEVER,                          VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_ALWAYS,                   VK_COMPARE_OP_GREATER_OR_EQUAL },
1000                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_GREATER,                  VK_COMPARE_OP_ALWAYS },
1001                 { VK_COMPARE_OP_NOT_EQUAL,                      VK_COMPARE_OP_LESS_OR_EQUAL,    VK_COMPARE_OP_NOT_EQUAL,                VK_COMPARE_OP_GREATER }
1002         };
1003
1004         de::MovePtr<tcu::TestCaseGroup> depthTests (new tcu::TestCaseGroup(testCtx, "depth", "Depth tests"));
1005
1006         // Tests for format features
1007         {
1008                 de::MovePtr<tcu::TestCaseGroup> formatFeaturesTests (new tcu::TestCaseGroup(testCtx, "format_features", "Checks depth format features"));
1009
1010                 // Formats that must be supported in all implementations
1011                 addFunctionCase(formatFeaturesTests.get(),
1012                                                 "support_d16_unorm",
1013                                                 "Tests if VK_FORMAT_D16_UNORM is supported as depth/stencil attachment format",
1014                                                 testSupportsDepthStencilFormat,
1015                                                 VK_FORMAT_D16_UNORM);
1016
1017                 // Sets where at least one of the formats must be supported
1018                 const VkFormat  depthOnlyFormats[]              = { VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT };
1019                 const VkFormat  depthStencilFormats[]   = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
1020
1021                 addFunctionCase(formatFeaturesTests.get(),
1022                                                 "support_d24_unorm_or_d32_sfloat",
1023                                                 "Tests if any of VK_FORMAT_D24_UNORM_X8 or VK_FORMAT_D32_SFLOAT are supported as depth/stencil attachment format",
1024                                                 testSupportsAtLeastOneDepthStencilFormat,
1025                                                 std::vector<VkFormat>(depthOnlyFormats, depthOnlyFormats + DE_LENGTH_OF_ARRAY(depthOnlyFormats)));
1026
1027                 addFunctionCase(formatFeaturesTests.get(),
1028                                                 "support_d24_unorm_s8_uint_or_d32_sfloat_s8_uint",
1029                                                 "Tests if any of VK_FORMAT_D24_UNORM_S8_UINT or VK_FORMAT_D32_SFLOAT_S8_UINT are supported as depth/stencil attachment format",
1030                                                 testSupportsAtLeastOneDepthStencilFormat,
1031                                                 std::vector<VkFormat>(depthStencilFormats, depthStencilFormats + DE_LENGTH_OF_ARRAY(depthStencilFormats)));
1032
1033                 depthTests->addChild(formatFeaturesTests.release());
1034         }
1035
1036         // Tests for format and compare operators
1037         {
1038                 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different depth formats"));
1039
1040                 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthFormats); formatNdx++)
1041                 {
1042                         de::MovePtr<tcu::TestCaseGroup> formatTest              (new tcu::TestCaseGroup(testCtx,
1043                                                                                                                                                                         getFormatCaseName(depthFormats[formatNdx]).c_str(),
1044                                                                                                                                                                         (std::string("Uses format ") + getFormatName(depthFormats[formatNdx])).c_str()));
1045                         de::MovePtr<tcu::TestCaseGroup> compareOpsTests (new tcu::TestCaseGroup(testCtx, "compare_ops", "Combines depth compare operators"));
1046
1047                         for (size_t opsNdx = 0; opsNdx < DE_LENGTH_OF_ARRAY(depthOps); opsNdx++)
1048                         {
1049                                 compareOpsTests->addChild(new DepthTest(testCtx,
1050                                                                                                                 getCompareOpsName(depthOps[opsNdx]),
1051                                                                                                                 getCompareOpsDescription(depthOps[opsNdx]),
1052                                                                                                                 depthFormats[formatNdx],
1053                                                                                                                 depthOps[opsNdx]));
1054                         }
1055                         formatTest->addChild(compareOpsTests.release());
1056                         formatTests->addChild(formatTest.release());
1057                 }
1058                 depthTests->addChild(formatTests.release());
1059         }
1060
1061         return depthTests.release();
1062 }
1063
1064 } // pipeline
1065 } // vkt