Merge vk-gl-cts/opengl-es-cts-3.2.5 into vk-gl-cts/opengl-es-cts-3.2.6
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / renderpass / vktRenderPassDepthStencilResolveTests.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief VK_KHR_depth_stencil_resolve tests.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassDepthStencilResolveTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29
30 #include "vkDefs.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42
43 #include "tcuImageCompare.hpp"
44 #include "tcuFormatUtil.hpp"
45 #include "tcuResultCollector.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuTextureUtil.hpp"
48
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
51 #include "deMath.h"
52 #include <limits>
53
54 using namespace vk;
55
56 using tcu::Vec4;
57 using tcu::TestLog;
58
59 typedef de::SharedPtr<vk::Unique<VkImage> >             VkImageSp;
60 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
61 typedef de::SharedPtr<vk::Unique<VkBuffer> >    VkBufferSp;
62 typedef de::SharedPtr<vk::Unique<VkPipeline> >  VkPipelineSp;
63 typedef de::SharedPtr<Allocation>                               AllocationSp;
64
65 namespace vkt
66 {
67 namespace
68 {
69
70 using namespace renderpass;
71
72 template<typename T>
73 de::SharedPtr<T> safeSharedPtr (T* ptr)
74 {
75         try
76         {
77                 return de::SharedPtr<T>(ptr);
78         }
79         catch (...)
80         {
81                 delete ptr;
82                 throw;
83         }
84 }
85
86 enum VerifyBuffer
87 {
88         VB_DEPTH = 0,
89         VB_STENCIL
90 };
91
92 struct TestConfig
93 {
94         VkFormat                                        format;
95         deUint32                                        width;
96         deUint32                                        height;
97         deUint32                                        imageLayers;
98         deUint32                                        viewLayers;
99         deUint32                                        resolveBaseLayer;
100         VkRect2D                                        renderArea;
101         VkImageAspectFlags                      aspectFlag;
102         deUint32                                        sampleCount;
103         VkResolveModeFlagBits           depthResolveMode;
104         VkResolveModeFlagBits           stencilResolveMode;
105         VerifyBuffer                            verifyBuffer;
106         VkClearDepthStencilValue        clearValue;
107         float                                           depthExpectedValue;
108         deUint8                                         stencilExpectedValue;
109         bool                                            separateDepthStencilLayouts;
110         bool                                            unusedResolve;
111 };
112
113 float get16bitDepthComponent(deUint8* pixelPtr)
114 {
115         deUint16* value = reinterpret_cast<deUint16*>(pixelPtr);
116         return static_cast<float>(*value) / 65535.0f;
117 }
118
119 float get24bitDepthComponent(deUint8* pixelPtr)
120 {
121         const bool littleEndian = (DE_ENDIANNESS == DE_LITTLE_ENDIAN);
122         deUint32 value = (((deUint32)pixelPtr[0]) << (!littleEndian * 16u)) |
123                                                 (((deUint32)pixelPtr[1]) <<  8u) |
124                                                 (((deUint32)pixelPtr[2]) << ( littleEndian * 16u));
125         return static_cast<float>(value) / 16777215.0f;
126 }
127
128 float get32bitDepthComponent(deUint8* pixelPtr)
129 {
130         return *(reinterpret_cast<float*>(pixelPtr));
131 }
132
133 class DepthStencilResolveTest : public TestInstance
134 {
135 public:
136                                                                 DepthStencilResolveTest         (Context& context, TestConfig config);
137         virtual                                         ~DepthStencilResolveTest        (void);
138
139         virtual tcu::TestStatus         iterate (void);
140
141 protected:
142         bool                                            isFeaturesSupported                             (void);
143         VkSampleCountFlagBits           sampleCountBitFromSampleCount   (deUint32 count) const;
144
145         VkImageSp                                       createImage                                             (deUint32 sampleCount, VkImageUsageFlags additionalUsage = 0u);
146         AllocationSp                            createImageMemory                               (VkImageSp image);
147         VkImageViewSp                           createImageView                                 (VkImageSp image, deUint32 baseArrayLayer);
148         AllocationSp                            createBufferMemory                              (void);
149         VkBufferSp                                      createBuffer                                    (void);
150
151         Move<VkRenderPass>                      createRenderPass                                (void);
152         Move<VkFramebuffer>                     createFramebuffer                               (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView);
153         Move<VkPipelineLayout>          createRenderPipelineLayout              (void);
154         Move<VkPipeline>                        createRenderPipeline                    (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout);
155
156         void                                            submit                                                  (void);
157         bool                                            verifyDepth                                             (void);
158         bool                                            verifyStencil                                   (void);
159
160 protected:
161         const TestConfig                                m_config;
162         const bool                                              m_featureSupported;
163
164         const InstanceInterface&                m_vki;
165         const DeviceInterface&                  m_vkd;
166         VkDevice                                                m_device;
167         VkPhysicalDevice                                m_physicalDevice;
168
169         const Unique<VkCommandPool>             m_commandPool;
170
171         VkImageSp                                               m_multisampleImage;
172         AllocationSp                                    m_multisampleImageMemory;
173         VkImageViewSp                                   m_multisampleImageView;
174         VkImageSp                                               m_singlesampleImage;
175         AllocationSp                                    m_singlesampleImageMemory;
176         VkImageViewSp                                   m_singlesampleImageView;
177         VkBufferSp                                              m_buffer;
178         AllocationSp                                    m_bufferMemory;
179
180         Unique<VkRenderPass>                    m_renderPass;
181         Unique<VkFramebuffer>                   m_framebuffer;
182         Unique<VkPipelineLayout>                m_renderPipelineLayout;
183         Unique<VkPipeline>                              m_renderPipeline;
184 };
185
186 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
187         : TestInstance                          (context)
188         , m_config                                      (config)
189         , m_featureSupported            (isFeaturesSupported())
190         , m_vki                                         (context.getInstanceInterface())
191         , m_vkd                                         (context.getDeviceInterface())
192         , m_device                                      (context.getDevice())
193         , m_physicalDevice                      (context.getPhysicalDevice())
194
195         , m_commandPool                         (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
196
197         , m_multisampleImage            (createImage(m_config.sampleCount, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
198         , m_multisampleImageMemory      (createImageMemory(m_multisampleImage))
199         , m_multisampleImageView        (createImageView(m_multisampleImage, 0u))
200
201         , m_singlesampleImage           (createImage(1, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | (config.unusedResolve ? static_cast<vk::VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_DST_BIT) : 0u))))
202         , m_singlesampleImageMemory     (createImageMemory(m_singlesampleImage))
203         , m_singlesampleImageView       (createImageView(m_singlesampleImage, m_config.resolveBaseLayer))
204
205         , m_buffer                                      (createBuffer())
206         , m_bufferMemory                        (createBufferMemory())
207
208         , m_renderPass                          (createRenderPass())
209         , m_framebuffer                         (createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView))
210         , m_renderPipelineLayout        (createRenderPipelineLayout())
211         , m_renderPipeline                      (createRenderPipeline(*m_renderPass, *m_renderPipelineLayout))
212 {
213 }
214
215 DepthStencilResolveTest::~DepthStencilResolveTest (void)
216 {
217 }
218
219 bool DepthStencilResolveTest::isFeaturesSupported()
220 {
221         m_context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
222         if (m_config.imageLayers > 1)
223                 m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
224
225         if (m_config.separateDepthStencilLayouts)
226                 m_context.requireDeviceFunctionality("VK_KHR_separate_depth_stencil_layouts");
227
228         VkPhysicalDeviceDepthStencilResolveProperties dsResolveProperties;
229         deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolveProperties));
230         dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
231         dsResolveProperties.pNext = DE_NULL;
232
233         VkPhysicalDeviceProperties2 deviceProperties;
234         deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
235         deviceProperties.pNext = &dsResolveProperties;
236
237         // perform query to get supported float control properties
238         const VkPhysicalDevice                  physicalDevice          = m_context.getPhysicalDevice();
239         const vk::InstanceInterface&    instanceInterface       = m_context.getInstanceInterface();
240         instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
241
242         // check if both modes are supported
243         VkResolveModeFlagBits depthResolveMode          = m_config.depthResolveMode;
244         VkResolveModeFlagBits stencilResolveMode                = m_config.stencilResolveMode;
245         if ((depthResolveMode != VK_RESOLVE_MODE_NONE) &&
246                 !(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
247                 TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
248         if ((stencilResolveMode != VK_RESOLVE_MODE_NONE) &&
249                 !(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
250                 TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");
251
252         // check if the implementation supports setting the depth and stencil resolve
253         // modes to different values when one of those modes is VK_RESOLVE_MODE_NONE
254         if (dsResolveProperties.independentResolveNone)
255         {
256                 if ((!dsResolveProperties.independentResolve) &&
257                         (depthResolveMode != stencilResolveMode) &&
258                         (depthResolveMode != VK_RESOLVE_MODE_NONE) &&
259                         (stencilResolveMode != VK_RESOLVE_MODE_NONE))
260                         TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
261         }
262         else if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
263         {
264                 // when independentResolveNone and independentResolve are VK_FALSE then both modes must be the same
265                 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
266         }
267
268         return true;
269 }
270
271 VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const
272 {
273         switch (count)
274         {
275                 case 1:  return VK_SAMPLE_COUNT_1_BIT;
276                 case 2:  return VK_SAMPLE_COUNT_2_BIT;
277                 case 4:  return VK_SAMPLE_COUNT_4_BIT;
278                 case 8:  return VK_SAMPLE_COUNT_8_BIT;
279                 case 16: return VK_SAMPLE_COUNT_16_BIT;
280                 case 32: return VK_SAMPLE_COUNT_32_BIT;
281                 case 64: return VK_SAMPLE_COUNT_64_BIT;
282
283                 default:
284                         DE_FATAL("Invalid sample count");
285                         return (VkSampleCountFlagBits)0x0;
286         }
287 }
288
289 VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage)
290 {
291         const tcu::TextureFormat        format(mapVkFormat(m_config.format));
292         const VkImageTiling                     imageTiling(VK_IMAGE_TILING_OPTIMAL);
293         VkSampleCountFlagBits           sampleCountBit(sampleCountBitFromSampleCount(sampleCount));
294         VkImageUsageFlags                       usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | additionalUsage;
295
296         VkImageFormatProperties imageFormatProperties;
297         if (m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice, m_config.format, VK_IMAGE_TYPE_2D, imageTiling,
298                                                                                                          usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
299         {
300                 TCU_THROW(NotSupportedError, "Format not supported");
301         }
302         if (imageFormatProperties.sampleCounts < sampleCount)
303         {
304                 TCU_THROW(NotSupportedError, "Sample count not supported");
305         }
306         if (imageFormatProperties.maxArrayLayers < m_config.imageLayers)
307         {
308                 TCU_THROW(NotSupportedError, "Layers count not supported");
309         }
310
311         const VkExtent3D imageExtent =
312         {
313                 m_config.width,
314                 m_config.height,
315                 1u
316         };
317
318         if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order)))
319                 TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment");
320
321         if (imageFormatProperties.maxExtent.width < imageExtent.width
322                 || imageFormatProperties.maxExtent.height < imageExtent.height
323                 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
324                 || imageFormatProperties.maxArrayLayers < m_config.imageLayers)
325         {
326                 TCU_THROW(NotSupportedError, "Image type not supported");
327         }
328
329         const VkImageCreateInfo pCreateInfo =
330         {
331                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
332                 DE_NULL,
333                 0u,
334                 VK_IMAGE_TYPE_2D,
335                 m_config.format,
336                 imageExtent,
337                 1u,
338                 m_config.imageLayers,
339                 sampleCountBit,
340                 imageTiling,
341                 usage,
342                 VK_SHARING_MODE_EXCLUSIVE,
343                 0u,
344                 DE_NULL,
345                 VK_IMAGE_LAYOUT_UNDEFINED
346         };
347
348         return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo)));
349 }
350
351 AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image)
352 {
353         Allocator& allocator = m_context.getDefaultAllocator();
354
355         de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, **image), MemoryRequirement::Any));
356         VK_CHECK(m_vkd.bindImageMemory(m_device, **image, allocation->getMemory(), allocation->getOffset()));
357         return safeSharedPtr(allocation.release());
358 }
359
360 VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer)
361 {
362         const VkImageSubresourceRange range =
363         {
364                 m_config.aspectFlag,
365                 0u,
366                 1u,
367                 baseArrayLayer,
368                 m_config.viewLayers
369         };
370
371         const VkImageViewCreateInfo pCreateInfo =
372         {
373                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
374                 DE_NULL,
375                 0u,
376                 **image,
377                 (m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
378                 m_config.format,
379                 makeComponentMappingRGBA(),
380                 range,
381         };
382         return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo)));
383 }
384
385 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (void)
386 {
387         // When the depth/stencil resolve attachment is unused, it needs to be cleared outside the render pass so it has the expected values.
388         if (m_config.unusedResolve)
389         {
390                 const tcu::TextureFormat                        format                  (mapVkFormat(m_config.format));
391                 const Unique<VkCommandBuffer>           commandBuffer   (allocateCommandBuffer(m_vkd, m_device, *m_commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
392                 const vk::VkImageSubresourceRange       imageRange              =
393                 {
394                         ((tcu::hasDepthComponent(format.order)          ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_DEPTH_BIT)    : 0u) |
395                          (tcu::hasStencilComponent(format.order)        ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_STENCIL_BIT)  : 0u)),
396                         0u,
397                         VK_REMAINING_MIP_LEVELS,
398                         0u,
399                         VK_REMAINING_ARRAY_LAYERS,
400                 };
401                 const vk::VkImageMemoryBarrier          preBarrier              =
402                 {
403                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
404                         nullptr,
405
406                         // src and dst access masks.
407                         0,
408                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,
409
410                         // old and new layouts.
411                         vk::VK_IMAGE_LAYOUT_UNDEFINED,
412                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
413
414                         VK_QUEUE_FAMILY_IGNORED,
415                         VK_QUEUE_FAMILY_IGNORED,
416
417                         **m_singlesampleImage,
418                         imageRange,
419                 };
420                 const vk::VkImageMemoryBarrier          postBarrier             =
421                 {
422                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
423                         nullptr,
424
425                         // src and dst access masks.
426                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,
427                         0,
428
429                         // old and new layouts.
430                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
431                         vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
432
433                         VK_QUEUE_FAMILY_IGNORED,
434                         VK_QUEUE_FAMILY_IGNORED,
435
436                         **m_singlesampleImage,
437                         imageRange,
438                 };
439
440                 vk::beginCommandBuffer(m_vkd, commandBuffer.get());
441                         m_vkd.cmdPipelineBarrier(commandBuffer.get(), vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preBarrier);
442                         m_vkd.cmdClearDepthStencilImage(commandBuffer.get(), **m_singlesampleImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_config.clearValue, 1u, &imageRange);
443                         m_vkd.cmdPipelineBarrier(commandBuffer.get(), vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &postBarrier);
444                 vk::endCommandBuffer(m_vkd, commandBuffer.get());
445
446                 vk::submitCommandsAndWait(m_vkd, m_device, m_context.getUniversalQueue(), commandBuffer.get());
447         }
448
449         const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));
450
451         VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
452         VkAttachmentReferenceStencilLayoutKHR stencilLayout =
453         {
454                 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR,
455                 DE_NULL,
456                 VK_IMAGE_LAYOUT_UNDEFINED,
457         };
458         void * attachmentRefStencil = DE_NULL;
459         VkImageLayout finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
460         VkAttachmentDescriptionStencilLayoutKHR stencilFinalLayout =
461         {
462                 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR,
463                 DE_NULL,
464                 VK_IMAGE_LAYOUT_UNDEFINED,
465                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
466         };
467         void * attachmentDescriptionStencil = DE_NULL;
468
469         if (m_config.separateDepthStencilLayouts)
470         {
471                 if (m_config.verifyBuffer == VB_DEPTH)
472                 {
473                         layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
474                         stencilLayout.stencilLayout = VK_IMAGE_LAYOUT_GENERAL;
475                         finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
476                         stencilFinalLayout.stencilFinalLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; // This aspect should be unused.
477                 }
478                 else
479                 {
480                         layout = VK_IMAGE_LAYOUT_GENERAL;
481                         stencilLayout.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
482                         finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; // This aspect should be unused.
483                         stencilFinalLayout.stencilFinalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
484                 }
485                 attachmentRefStencil = &stencilLayout;
486                 attachmentDescriptionStencil = &stencilFinalLayout;
487         }
488
489         const AttachmentDescription2 multisampleAttachment              // VkAttachmentDescription2
490         (
491                                                                                                                         // VkStructureType                                      sType;
492                 attachmentDescriptionStencil,                                           // const void*                                          pNext;
493                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
494                 m_config.format,                                                                        // VkFormat                                                     format;
495                 samples,                                                                                        // VkSampleCountFlagBits                        samples;
496                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
497                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          storeOp;
498                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           stencilLoadOp;
499                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
500                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                                        initialLayout;
501                 finalLayout                                                                                     // VkImageLayout                                        finalLayout;
502         );
503         const AttachmentReference2 multisampleAttachmentRef             // VkAttachmentReference2
504         (
505                                                                                                                         // VkStructureType                                      sType;
506                 attachmentRefStencil,                                                           // const void*                                          pNext;
507                 0u,                                                                                                     // deUint32                                                     attachment;
508                 layout,                                                                                         // VkImageLayout                                        layout;
509                 0u                                                                                                      // VkImageAspectFlags                           aspectMask;
510         );
511
512         const vk::VkImageLayout         singleSampleInitialLayout = (m_config.unusedResolve ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED);
513
514         const AttachmentDescription2 singlesampleAttachment             // VkAttachmentDescription2
515         (
516                                                                                                                         // VkStructureType                                      sType;
517                 attachmentDescriptionStencil,                                           // const void*                                          pNext;
518                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
519                 m_config.format,                                                                        // VkFormat                                                     format;
520                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
521                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
522                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
523                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           stencilLoadOp;
524                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          stencilStoreOp;
525                 singleSampleInitialLayout,                                                      // VkImageLayout                                        initialLayout;
526                 finalLayout                                                                                     // VkImageLayout                                        finalLayout;
527         );
528         AttachmentReference2 singlesampleAttachmentRef                  // VkAttachmentReference2
529         (
530                                                                                                                                 // VkStructureType                                      sType;
531                 DE_NULL,                                                                                                // const void*                                          pNext;
532                 (m_config.unusedResolve ? VK_ATTACHMENT_UNUSED : 1u),   // deUint32                                                     attachment;
533                 layout,                                                                                                 // VkImageLayout                                        layout;
534                 0u                                                                                                              // VkImageAspectFlags                           aspectMask;
535         );
536
537         std::vector<AttachmentDescription2> attachments;
538         attachments.push_back(multisampleAttachment);
539         attachments.push_back(singlesampleAttachment);
540
541         VkSubpassDescriptionDepthStencilResolve dsResolveDescription =
542         {
543                 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
544                 DE_NULL,                                                                                                                                // const void*                                          pNext;
545                 m_config.depthResolveMode,                                                                                              // VkResolveModeFlagBits                        depthResolveMode;
546                 m_config.stencilResolveMode,                                                                                    // VkResolveModeFlagBits                        stencilResolveMode;
547                 &singlesampleAttachmentRef                                                                                              // VkAttachmentReference2                       pDepthStencilResolveAttachment;
548         };
549
550         const SubpassDescription2 subpass                                       // VkSubpassDescription2
551         (
552                                                                                                                 // VkStructureType                                              sType;
553                 &dsResolveDescription,                                                  // const void*                                                  pNext;
554                 (VkSubpassDescriptionFlags)0,                                   // VkSubpassDescriptionFlags                    flags;
555                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                // VkPipelineBindPoint                                  pipelineBindPoint;
556                 0u,                                                                                             // deUint32                                                             viewMask;
557                 0u,                                                                                             // deUint32                                                             inputAttachmentCount;
558                 DE_NULL,                                                                                // const VkAttachmentReference2*                pInputAttachments;
559                 0u,                                                                                             // deUint32                                                             colorAttachmentCount;
560                 DE_NULL,                                                                                // const VkAttachmentReference2*                pColorAttachments;
561                 DE_NULL,                                                                                // const VkAttachmentReference2*                pResolveAttachments;
562                 &multisampleAttachmentRef,                                              // const VkAttachmentReference2*                pDepthStencilAttachment;
563                 0u,                                                                                             // deUint32                                                             preserveAttachmentCount;
564                 DE_NULL                                                                                 // const deUint32*                                              pPreserveAttachments;
565         );
566
567         const RenderPassCreateInfo2 renderPassCreator           // VkRenderPassCreateInfo2
568         (
569                                                                                                                 // VkStructureType                                              sType;
570                 DE_NULL,                                                                                // const void*                                                  pNext;
571                 (VkRenderPassCreateFlags)0u,                                    // VkRenderPassCreateFlags                              flags;
572                 (deUint32)attachments.size(),                                   // deUint32                                                             attachmentCount;
573                 &attachments[0],                                                                // const VkAttachmentDescription2*              pAttachments;
574                 1u,                                                                                             // deUint32                                                             subpassCount;
575                 &subpass,                                                                               // const VkSubpassDescription2*                 pSubpasses;
576                 0u,                                                                                             // deUint32                                                             dependencyCount;
577                 DE_NULL,                                                                                // const VkSubpassDependency2*                  pDependencies;
578                 0u,                                                                                             // deUint32                                                             correlatedViewMaskCount;
579                 DE_NULL                                                                                 // const deUint32*                                              pCorrelatedViewMasks;
580         );
581
582         return renderPassCreator.createRenderPass(m_vkd, m_device);
583 }
584
585 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
586 {
587         std::vector<VkImageView> attachments;
588         attachments.push_back(**multisampleImageView);
589         attachments.push_back(**singlesampleImageView);
590
591         const VkFramebufferCreateInfo createInfo =
592         {
593                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
594                 DE_NULL,
595                 0u,
596
597                 renderPass,
598                 (deUint32)attachments.size(),
599                 &attachments[0],
600
601                 m_config.width,
602                 m_config.height,
603                 m_config.viewLayers
604         };
605
606         return vk::createFramebuffer(m_vkd, m_device, &createInfo);
607 }
608
609 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
610 {
611         VkPushConstantRange pushConstant =
612         {
613                 VK_SHADER_STAGE_FRAGMENT_BIT,
614                 0u,
615                 4u
616         };
617
618         deUint32                                pushConstantRangeCount  = 0u;
619         VkPushConstantRange*    pPushConstantRanges             = DE_NULL;
620         if (m_config.verifyBuffer == VB_STENCIL)
621         {
622                 pushConstantRangeCount  = 1u;
623                 pPushConstantRanges             = &pushConstant;
624         }
625
626         const VkPipelineLayoutCreateInfo createInfo     =
627         {
628                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
629                 DE_NULL,
630                 (vk::VkPipelineLayoutCreateFlags)0,
631
632                 0u,
633                 DE_NULL,
634
635                 pushConstantRangeCount,
636                 pPushConstantRanges
637         };
638
639         return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
640 }
641
642 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout)
643 {
644         const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
645         const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
646
647         const Unique<VkShaderModule>    vertexShaderModule              (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u));
648         const Unique<VkShaderModule>    fragmentShaderModule    (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u));
649         const Move<VkShaderModule>              geometryShaderModule    (m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u));
650
651         const VkPipelineVertexInputStateCreateInfo vertexInputState =
652         {
653                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
654                 DE_NULL,
655                 (VkPipelineVertexInputStateCreateFlags)0u,
656
657                 0u,
658                 DE_NULL,
659
660                 0u,
661                 DE_NULL
662         };
663         const tcu::UVec2                                view            (m_config.width, m_config.height);
664         const std::vector<VkViewport>   viewports       (1, makeViewport(view));
665         const std::vector<VkRect2D>             scissors        (1, m_config.renderArea);
666
667         const VkPipelineMultisampleStateCreateInfo multisampleState =
668         {
669                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
670                 DE_NULL,
671                 (VkPipelineMultisampleStateCreateFlags)0u,
672
673                 sampleCountBitFromSampleCount(m_config.sampleCount),
674                 VK_FALSE,
675                 0.0f,
676                 DE_NULL,
677                 VK_FALSE,
678                 VK_FALSE,
679         };
680         const VkPipelineDepthStencilStateCreateInfo depthStencilState =
681         {
682                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
683                 DE_NULL,
684                 (VkPipelineDepthStencilStateCreateFlags)0u,
685
686                 VK_TRUE,                                                        // depthTestEnable
687                 VK_TRUE,
688                 VK_COMPARE_OP_ALWAYS,
689                 VK_FALSE,
690                 testingStencil,                                         // stencilTestEnable
691                 {
692                         VK_STENCIL_OP_REPLACE,                  // failOp
693                         VK_STENCIL_OP_REPLACE,                  // passOp
694                         VK_STENCIL_OP_REPLACE,                  // depthFailOp
695                         VK_COMPARE_OP_ALWAYS,                   // compareOp
696                         0xFFu,                                                  // compareMask
697                         0xFFu,                                                  // writeMask
698                         1                                                               // reference
699                 },
700                 {
701                         VK_STENCIL_OP_REPLACE,
702                         VK_STENCIL_OP_REPLACE,
703                         VK_STENCIL_OP_REPLACE,
704                         VK_COMPARE_OP_ALWAYS,
705                         0xFFu,
706                         0xFFu,
707                         1
708                 },
709                 0.0f,
710                 1.0f
711         };
712
713         std::vector<VkDynamicState> dynamicState;
714         dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
715         const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
716         {
717                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,   // VkStructureType                      sType;
718                 DE_NULL,                                                                                                // const void*                          pNext;
719                 (VkPipelineDynamicStateCreateFlags)0u,                                  // VkPipelineDynamicStateCreateFlags    flags;
720                 static_cast<deUint32>(dynamicState.size()),                             // deUint32                             dynamicStateCount;
721                 &dynamicState[0]                                                                                // const VkDynamicState*                pDynamicStates;
722         };
723
724         return makeGraphicsPipeline(m_vkd,                                                                                                                      // const DeviceInterface&                        vk
725                                                                 m_device,                                                                                                               // const VkDevice                                device
726                                                                 renderPipelineLayout,                                                                                   // const VkPipelineLayout                        pipelineLayout
727                                                                 *vertexShaderModule,                                                                                    // const VkShaderModule                          vertexShaderModule
728                                                                 DE_NULL,                                                                                                                // const VkShaderModule                          tessellationControlShaderModule
729                                                                 DE_NULL,                                                                                                                // const VkShaderModule                          tessellationEvalShaderModule
730                                                                 m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule,    // const VkShaderModule                          geometryShaderModule
731                                                                 *fragmentShaderModule,                                                                                  // const VkShaderModule                          fragmentShaderModule
732                                                                 renderPass,                                                                                                             // const VkRenderPass                            renderPass
733                                                                 viewports,                                                                                                              // const std::vector<VkViewport>&                viewports
734                                                                 scissors,                                                                                                               // const std::vector<VkRect2D>&                  scissors
735                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // const VkPrimitiveTopology                     topology
736                                                                 0u,                                                                                                                             // const deUint32                                subpass
737                                                                 0u,                                                                                                                             // const deUint32                                patchControlPoints
738                                                                 &vertexInputState,                                                                                              // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
739                                                                 DE_NULL,                                                                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
740                                                                 &multisampleState,                                                                                              // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
741                                                                 &depthStencilState,                                                                                             // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
742                                                                 DE_NULL,                                                                                                                // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
743                                                                 testingStencil ? &dynamicStateCreateInfo : DE_NULL);                    // const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
744 }
745
746 AllocationSp DepthStencilResolveTest::createBufferMemory (void)
747 {
748         Allocator&                              allocator = m_context.getDefaultAllocator();
749         de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible));
750         VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset()));
751         return safeSharedPtr(allocation.release());
752 }
753
754 VkBufferSp DepthStencilResolveTest::createBuffer (void)
755 {
756         const VkBufferUsageFlags        bufferUsage                     (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
757         const tcu::TextureFormat        textureFormat           (mapVkFormat(m_config.format));
758         const VkDeviceSize                      pixelSize                       (textureFormat.getPixelSize());
759         const VkBufferCreateInfo        createInfo                      =
760         {
761                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
762                 DE_NULL,
763                 0u,
764
765                 m_config.width * m_config.height * m_config.imageLayers * pixelSize,
766                 bufferUsage,
767
768                 VK_SHARING_MODE_EXCLUSIVE,
769                 0u,
770                 DE_NULL
771         };
772         return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
773 }
774
775 void DepthStencilResolveTest::submit (void)
776 {
777         const DeviceInterface&                                          vkd                                     (m_context.getDeviceInterface());
778         const VkDevice                                                          device                          (m_context.getDevice());
779         const Unique<VkCommandBuffer>                           commandBuffer           (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
780         const RenderpassSubpass2::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
781         const RenderpassSubpass2::SubpassEndInfo        subpassEndInfo          (DE_NULL);
782
783         beginCommandBuffer(vkd, *commandBuffer);
784
785         {
786                 VkClearValue clearValues[2];
787                 clearValues[0].depthStencil = m_config.clearValue;
788                 clearValues[1].depthStencil = m_config.clearValue;
789
790                 const VkRenderPassBeginInfo beginInfo =
791                 {
792                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
793                         DE_NULL,
794
795                         *m_renderPass,
796                         *m_framebuffer,
797
798                         {
799                                 { 0u, 0u },
800                                 { m_config.width, m_config.height }
801                         },
802
803                         2u,
804                         clearValues
805                 };
806                 RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
807         }
808
809         // Render
810         bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
811         if (testingDepth)
812         {
813                 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
814                 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
815         }
816         else
817         {
818                 // For stencil we can set reference value for just one sample at a time
819                 // so we need to do as many passes as there are samples, first half
820                 // of samples is initialized with 1 and second half with 255
821                 const deUint32 halfOfSamples = m_config.sampleCount >> 1;
822                 for (deUint32 renderPass = 0 ; renderPass < m_config.sampleCount ; renderPass++)
823                 {
824                         deUint32 stencilReference = 1 + 254 * (renderPass >= halfOfSamples);
825                         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
826                         vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(renderPass), &renderPass);
827                         vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference);
828                         vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
829                 }
830         }
831
832         RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
833
834         // Memory barriers between rendering and copying
835         {
836                 const VkImageMemoryBarrier barrier =
837                 {
838                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
839                         DE_NULL,
840
841                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
842                         VK_ACCESS_TRANSFER_READ_BIT,
843
844                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
845                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
846
847                         VK_QUEUE_FAMILY_IGNORED,
848                         VK_QUEUE_FAMILY_IGNORED,
849
850                         **m_singlesampleImage,
851                         {
852                                 (m_config.separateDepthStencilLayouts) ? VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT) : m_config.aspectFlag,
853                                 0u,
854                                 1u,
855                                 0u,
856                                 m_config.viewLayers
857                         }
858                 };
859
860                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
861         }
862
863         // Copy image memory to buffers
864         const VkBufferImageCopy region =
865         {
866                 0u,
867                 0u,
868                 0u,
869                 {
870                         VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT),
871                         0u,
872                         0u,
873                         m_config.viewLayers,
874                 },
875                 { 0u, 0u, 0u },
876                 { m_config.width, m_config.height, 1u }
877         };
878
879         vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, &region);
880
881         // Memory barriers between copies and host access
882         {
883                 const VkBufferMemoryBarrier barrier =
884                 {
885                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
886                         DE_NULL,
887
888                         VK_ACCESS_TRANSFER_WRITE_BIT,
889                         VK_ACCESS_HOST_READ_BIT,
890
891                         VK_QUEUE_FAMILY_IGNORED,
892                         VK_QUEUE_FAMILY_IGNORED,
893
894                         **m_buffer,
895                         0u,
896                         VK_WHOLE_SIZE
897                 };
898
899                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
900         }
901
902         endCommandBuffer(vkd, *commandBuffer);
903
904         submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
905 }
906
907 bool DepthStencilResolveTest::verifyDepth (void)
908 {
909         // Invalidate allocation before attempting to read buffer memory.
910         invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
911
912         deUint32                        layerSize       = m_config.width * m_config.height;
913         deUint32                        valuesCount     = layerSize * m_config.viewLayers;
914         deUint8*                        pixelPtr        = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
915
916         const DeviceInterface&          vkd             (m_context.getDeviceInterface());
917         invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
918
919         float expectedValue = m_config.depthExpectedValue;
920         if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
921                 expectedValue = m_config.clearValue.depth;
922
923         // depth data in buffer is tightly packed, ConstPixelBufferAccess
924         // coludn't be used for depth value extraction as it cant interpret
925         // formats containing just depth component
926
927         typedef float (*DepthComponentGetterFn)(deUint8*);
928         VkFormat                                format                          = m_config.format;
929         DepthComponentGetterFn  getDepthComponent       = &get16bitDepthComponent;
930         deUint32                                pixelStep                       = 2;
931         float                                   epsilon                         = 0.002f;
932
933         if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
934                 (format == VK_FORMAT_D24_UNORM_S8_UINT))
935         {
936                 getDepthComponent       = &get24bitDepthComponent;
937                 pixelStep                       = 4;
938         }
939         else if ((format == VK_FORMAT_D32_SFLOAT) ||
940                                 (format == VK_FORMAT_D32_SFLOAT_S8_UINT))
941         {
942                 getDepthComponent       = &get32bitDepthComponent;
943                 pixelStep                       = 4;
944         }
945
946         for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
947         {
948                 float depth = (*getDepthComponent)(pixelPtr);
949                 pixelPtr += pixelStep;
950
951                 // check if pixel data is outside of render area
952                 deInt32 layerIndex              = valueIndex / layerSize;
953                 deInt32 inLayerIndex    = valueIndex % layerSize;
954                 deInt32 x                               = inLayerIndex % m_config.width;
955                 deInt32 y                               = (inLayerIndex - x) / m_config.width;
956                 deInt32 x1                              = m_config.renderArea.offset.x;
957                 deInt32 y1                              = m_config.renderArea.offset.y;
958                 deInt32 x2                              = x1 + m_config.renderArea.extent.width;
959                 deInt32 y2                              = y1 + m_config.renderArea.extent.height;
960                 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
961                 {
962                         // verify that outside of render area there are clear values
963                         float error = deFloatAbs(depth - m_config.clearValue.depth);
964                         if (error > epsilon)
965                         {
966                                 m_context.getTestContext().getLog()
967                                 << TestLog::Message << "(" << x << ", " << y
968                                 << ", layer: " << layerIndex << ") is outside of render area but depth value is: "
969                                 << depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage;
970                                 return false;
971                         }
972
973                         // value is correct, go to next one
974                         continue;
975                 }
976
977                 float error = deFloatAbs(depth - expectedValue);
978                 if (error > epsilon)
979                 {
980                         m_context.getTestContext().getLog() << TestLog::Message
981                                 << "At (" << x << ", " << y << ", layer: " << layerIndex
982                                 << ") depth value is: " << depth << " expected: "
983                                 << expectedValue << TestLog::EndMessage;
984                         return false;
985                 }
986         }
987         m_context.getTestContext().getLog() << TestLog::Message
988                 << "Depth value is " << expectedValue
989                 << TestLog::EndMessage;
990
991         return true;
992 }
993
994 bool DepthStencilResolveTest::verifyStencil (void)
995 {
996         // Invalidate allocation before attempting to read buffer memory.
997         invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
998
999         deUint32                        layerSize       = m_config.width * m_config.height;
1000         deUint32                        valuesCount     = layerSize * m_config.viewLayers;
1001         deUint8*                        pixelPtr        = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
1002
1003         const DeviceInterface&          vkd             (m_context.getDeviceInterface());
1004         invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
1005
1006         // when stencil is tested we are discarding invocations and
1007         // because of that depth and stencil need to be tested separately
1008
1009         deUint8 expectedValue = m_config.stencilExpectedValue;
1010         if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
1011                 expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);
1012
1013         for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1014         {
1015                 deUint8 stencil                 = *pixelPtr++;
1016                 deInt32 layerIndex              = valueIndex / layerSize;
1017                 deInt32 inLayerIndex    = valueIndex % layerSize;
1018                 deInt32 x                               = inLayerIndex % m_config.width;
1019                 deInt32 y                               = (inLayerIndex - x) / m_config.width;
1020                 deInt32 x1                              = m_config.renderArea.offset.x;
1021                 deInt32 y1                              = m_config.renderArea.offset.y;
1022                 deInt32 x2                              = x1 + m_config.renderArea.extent.width;
1023                 deInt32 y2                              = y1 + m_config.renderArea.extent.height;
1024                 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
1025                 {
1026                         if (stencil != m_config.clearValue.stencil)
1027                         {
1028                                 m_context.getTestContext().getLog()
1029                                 << TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex
1030                                 << ") is outside of render area but stencil value is: "
1031                                 << stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage;
1032                                 return false;
1033                         }
1034
1035                         // value is correct, go to next one
1036                         continue;
1037                 }
1038
1039                 if (stencil != expectedValue)
1040                 {
1041                         m_context.getTestContext().getLog() << TestLog::Message
1042                                 << "At (" << x << ", " << y << ", layer: " << layerIndex
1043                                 << ") stencil value is: " << static_cast<deUint32>(stencil)
1044                                 << " expected: " << static_cast<deUint32>(expectedValue)
1045                                 << TestLog::EndMessage;
1046                         return false;
1047                 }
1048         }
1049         m_context.getTestContext().getLog() << TestLog::Message
1050                 << "Stencil value is "
1051                 << static_cast<deUint32>(expectedValue)
1052                 << TestLog::EndMessage;
1053
1054         return true;
1055 }
1056
1057 tcu::TestStatus DepthStencilResolveTest::iterate (void)
1058 {
1059         submit();
1060
1061         bool result = false;
1062         if (m_config.verifyBuffer == VB_DEPTH)
1063                 result = verifyDepth();
1064         else
1065                 result = verifyStencil();
1066
1067         if (result)
1068                 return tcu::TestStatus::pass("Pass");
1069         return tcu::TestStatus::fail("Fail");
1070 }
1071
1072 struct Programs
1073 {
1074         void init (vk::SourceCollections& dst, TestConfig config) const
1075         {
1076                 // geometry shader is only needed in multi-layer framebuffer resolve tests
1077                 if (config.imageLayers > 1)
1078                 {
1079                         const deUint32 layerCount = 3;
1080
1081                         std::ostringstream src;
1082                         src << "#version 450\n"
1083                                 << "highp float;\n"
1084                                 << "\n"
1085                                 << "layout(triangles) in;\n"
1086                                 << "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
1087                                 << "\n"
1088                                 << "in gl_PerVertex {\n"
1089                                 << "    vec4 gl_Position;\n"
1090                                 << "} gl_in[];\n"
1091                                 << "\n"
1092                                 << "out gl_PerVertex {\n"
1093                                 << "    vec4 gl_Position;\n"
1094                                 << "};\n"
1095                                 << "\n"
1096                                 << "void main (void) {\n"
1097                                 << "    for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n"
1098                                 << "        for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
1099                                 << "            gl_Position = gl_in[vertexNdx].gl_Position;\n"
1100                                 << "            gl_Layer    = layerNdx;\n"
1101                                 << "            EmitVertex();\n"
1102                                 << "        };\n"
1103                                 << "        EndPrimitive();\n"
1104                                 << "    };\n"
1105                                 << "}\n";
1106
1107                         dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
1108                 }
1109
1110                 dst.glslSources.add("quad-vert") << glu::VertexSource(
1111                         "#version 450\n"
1112                         "out gl_PerVertex {\n"
1113                         "\tvec4 gl_Position;\n"
1114                         "};\n"
1115                         "highp float;\n"
1116                         "void main (void) {\n"
1117                         "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1118                         "\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1119                         "}\n");
1120
1121                 if (config.verifyBuffer == VB_DEPTH)
1122                 {
1123                         dst.glslSources.add("quad-frag") << glu::FragmentSource(
1124                                 "#version 450\n"
1125                                 "precision highp float;\n"
1126                                 "precision highp int;\n"
1127                                 "void main (void)\n"
1128                                 "{\n"
1129                                 "  float sampleIndex = float(gl_SampleID);\n"                           // sampleIndex is integer in range <0, 63>
1130                                 "  float valueIndex = round(mod(sampleIndex, 4.0));\n"          // limit possible depth values - count to 4
1131                                 "  float value = valueIndex + 2.0;\n"                                           // value is one of [2, 3, 4, 5]
1132                                 "  value = round(exp2(value));\n"                                                       // value is one of [4, 8, 16, 32]
1133                                 "  bool condition = (int(value) == 8);\n"                                       // select second sample value (to make it smallest)
1134                                 "  value = round(value - float(condition) * 6.0);\n"            // value is one of [4, 2, 16, 32]
1135                                 "  gl_FragDepth = value / 100.0;\n"                                                     // sample depth is one of [0.04, 0.02, 0.16, 0.32]
1136                                 "}\n");
1137                 }
1138                 else
1139                 {
1140                         dst.glslSources.add("quad-frag") << glu::FragmentSource(
1141                                 "#version 450\n"
1142                                 "precision highp float;\n"
1143                                 "precision highp int;\n"
1144                                 "layout(push_constant) uniform PushConstant {\n"
1145                                 "  highp int sampleID;\n"
1146                                 "} pushConstants;\n"
1147                                 "void main (void)\n"
1148                                 "{\n"
1149                                 "  if(gl_SampleID != pushConstants.sampleID)\n"
1150                                 "    discard;\n"
1151                                 "  gl_FragDepth = 0.5;\n"
1152                                 "}\n");
1153                 }
1154         }
1155 };
1156
1157 class PropertiesTestCase : public vkt::TestCase
1158 {
1159 public:
1160                                                         PropertiesTestCase              (tcu::TestContext& testCtx, const std::string& name, const std::string& description)
1161                                                                 : vkt::TestCase(testCtx, name, description)
1162                                                                 {}
1163         virtual                                 ~PropertiesTestCase             (void) {}
1164
1165         virtual TestInstance*   createInstance                  (Context& context) const;
1166         virtual void                    checkSupport                    (Context& context) const;
1167 };
1168
1169 class PropertiesTestInstance : public vkt::TestInstance
1170 {
1171 public:
1172                                                                 PropertiesTestInstance  (Context& context)
1173                                                                         : vkt::TestInstance(context)
1174                                                                         {}
1175         virtual                                         ~PropertiesTestInstance (void) {}
1176
1177         virtual tcu::TestStatus         iterate                                 (void);
1178
1179 };
1180
1181 TestInstance* PropertiesTestCase::createInstance (Context& context) const
1182 {
1183         return new PropertiesTestInstance(context);
1184 }
1185
1186 void PropertiesTestCase::checkSupport (Context& context) const
1187 {
1188         context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
1189 }
1190
1191 tcu::TestStatus PropertiesTestInstance::iterate (void)
1192 {
1193         vk::VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsrProperties;
1194         dsrProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
1195         dsrProperties.pNext = nullptr;
1196
1197         vk::VkPhysicalDeviceProperties2 properties2;
1198         properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1199         properties2.pNext = &dsrProperties;
1200
1201         m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties2);
1202
1203         if ((dsrProperties.supportedDepthResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
1204                 TCU_FAIL("supportedDepthResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
1205
1206         if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
1207                 TCU_FAIL("supportedStencilResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
1208
1209         if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_AVERAGE_BIT_KHR) != 0)
1210                 TCU_FAIL("supportedStencilResolveModes includes forbidden VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
1211
1212         if (dsrProperties.independentResolve == VK_TRUE && dsrProperties.independentResolveNone != VK_TRUE)
1213                 TCU_FAIL("independentResolve supported but independentResolveNone not supported");
1214
1215         return tcu::TestStatus::pass("Pass");
1216 }
1217
1218
1219 void initTests (tcu::TestCaseGroup* group)
1220 {
1221         typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
1222
1223         struct FormatData
1224         {
1225                 VkFormat                format;
1226                 const char*             name;
1227                 bool                    hasDepth;
1228                 bool                    hasStencil;
1229         };
1230         FormatData formats[] =
1231         {
1232                 { VK_FORMAT_D16_UNORM,                          "d16_unorm",                    true,   false },
1233                 { VK_FORMAT_X8_D24_UNORM_PACK32,        "x8_d24_unorm_pack32",  true,   false },
1234                 { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat",                   true,   false },
1235                 { VK_FORMAT_S8_UINT,                            "s8_uint",                              false,  true },
1236                 { VK_FORMAT_D16_UNORM_S8_UINT,          "d16_unorm_s8_uint",    true,   true },
1237                 { VK_FORMAT_D24_UNORM_S8_UINT,          "d24_unorm_s8_uint",    true,   true },
1238                 { VK_FORMAT_D32_SFLOAT_S8_UINT,         "d32_sfloat_s8_uint",   true,   true },
1239         };
1240
1241         struct ResolveModeData
1242         {
1243                 VkResolveModeFlagBits   flag;
1244                 std::string                             name;
1245         };
1246         ResolveModeData resolveModes[] =
1247         {
1248                 { VK_RESOLVE_MODE_NONE,                         "none" },
1249                 { VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,      "zero" },
1250                 { VK_RESOLVE_MODE_AVERAGE_BIT,          "average" },
1251                 { VK_RESOLVE_MODE_MIN_BIT,                      "min" },
1252                 { VK_RESOLVE_MODE_MAX_BIT,                      "max" },
1253         };
1254
1255         struct ImageTestData
1256         {
1257                 const char*                                     groupName;
1258                 deUint32                                        width;
1259                 deUint32                                        height;
1260                 deUint32                                        imageLayers;
1261                 VkRect2D                                        renderArea;
1262                 VkClearDepthStencilValue        clearValue;
1263         };
1264
1265         // NOTE: tests cant be executed for 1D and 3D images:
1266         // 1D images are not tested because acording to specyfication sampleCounts
1267         // will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D
1268         // 3D images are not tested because VkFramebufferCreateInfo specification
1269         // states that: each element of pAttachments that is a 2D or 2D array image
1270         // view taken from a 3D image must not be a depth/stencil format
1271         ImageTestData imagesTestData[] =
1272         {
1273                 { "image_2d_32_32",     32, 32, 1, {{ 0,  0}, {32, 32}}, {0.000f, 0x00} },
1274                 { "image_2d_8_32",       8, 32, 1, {{ 1,  1}, { 6, 30}}, {0.123f, 0x01} },
1275                 { "image_2d_49_13",     49, 13, 1, {{10,  5}, {20,  8}}, {1.000f, 0x05} },
1276                 { "image_2d_5_1",        5,  1, 1, {{ 0,  0}, { 5,  1}}, {0.500f, 0x00} },
1277                 { "image_2d_17_1",      17,  1, 1, {{ 1,  0}, {15,  1}}, {0.789f, 0xfa} },
1278         };
1279         const deUint32 sampleCounts[] =
1280         {
1281                 2u, 4u, 8u, 16u, 32u, 64u
1282         };
1283         const float depthExpectedValue[][6] =
1284         {
1285                 // 2 samples    4                       8                       16                      32                      64
1286                 { 0.0f,                 0.0f,           0.0f,           0.0f,           0.0f,           0.0f },         // RESOLVE_MODE_NONE - expect clear value
1287                 { 0.04f,                0.04f,          0.04f,          0.04f,          0.04f,          0.04f },        // RESOLVE_MODE_SAMPLE_ZERO_BIT
1288                 { 0.03f,                0.135f,         0.135f,         0.135f,         0.135f,         0.135f },       // RESOLVE_MODE_AVERAGE_BIT
1289                 { 0.02f,                0.02f,          0.02f,          0.02f,          0.02f,          0.02f },        // RESOLVE_MODE_MIN_BIT
1290                 { 0.04f,                0.32f,          0.32f,          0.32f,          0.32f,          0.32f },        // RESOLVE_MODE_MAX_BIT
1291         };
1292         const deUint8 stencilExpectedValue[][6] =
1293         {
1294                 // 2 samples    4               8               16              32              64
1295                 { 0u,                   0u,             0u,             0u,             0u,             0u },   // RESOLVE_MODE_NONE - expect clear value
1296                 { 1u,                   1u,             1u,             1u,             1u,             1u },   // RESOLVE_MODE_SAMPLE_ZERO_BIT
1297                 { 0u,                   0u,             0u,             0u,             0u,             0u },   // RESOLVE_MODE_AVERAGE_BIT - not supported
1298                 { 1u,                   1u,             1u,             1u,             1u,             1u },   // RESOLVE_MODE_MIN_BIT
1299                 { 255u,                 255u,   255u,   255u,   255u,   255u }, // RESOLVE_MODE_MAX_BIT
1300         };
1301
1302         tcu::TestContext& testCtx(group->getTestContext());
1303
1304         // Misc tests.
1305         {
1306                 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", "Miscellaneous depth/stencil resolve tests"));
1307                 miscGroup->addChild(new PropertiesTestCase(testCtx, "properties", "Check reported depth/stencil resolve properties"));
1308                 group->addChild(miscGroup.release());
1309         }
1310
1311         // iterate over image data
1312         for      (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
1313         {
1314                 ImageTestData imageData = imagesTestData[imageDataNdx];
1315
1316                 // create test group for image data
1317                 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));
1318
1319                 // iterate over sampleCounts
1320                 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1321                 {
1322                         const deUint32          sampleCount     (sampleCounts[sampleCountNdx]);
1323                         const std::string       sampleName      ("samples_" + de::toString(sampleCount));
1324
1325                         // create test group for sample count
1326                         de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1327
1328                         // iterate over depth/stencil formats
1329                         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1330                         {
1331                                 const FormatData&                       formatData                                      = formats[formatNdx];
1332                                 VkFormat                                        format                                          = formatData.format;
1333                                 const char*                                     formatName                                      = formatData.name;
1334                                 const bool                                      hasDepth                                        = formatData.hasDepth;
1335                                 const bool                                      hasStencil                                      = formatData.hasStencil;
1336                                 VkImageAspectFlags                      aspectFlags                                     = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1337                                                                                                                                                   (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1338                                 const int                                       separateLayoutsLoopCount        = (hasDepth && hasStencil) ? 2 : 1;
1339
1340                                 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1341                                 {
1342                                         const bool                      useSeparateDepthStencilLayouts  = bool(separateDepthStencilLayouts);
1343                                         const std::string       groupName                                               = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1344
1345                                         // create test group for format
1346                                         de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1347
1348                                         // iterate over depth resolve modes
1349                                         for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
1350                                         {
1351                                                 // iterate over stencil resolve modes
1352                                                 for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
1353                                                 {
1354                                                         for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1355                                                         {
1356                                                                 // there is no average resolve mode for stencil - go to next iteration
1357                                                                 ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
1358                                                                 if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1359                                                                         continue;
1360
1361                                                                 // if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
1362                                                                 // depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
1363                                                                 ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
1364                                                                 if ((dResolve.flag == VK_RESOLVE_MODE_NONE) && (sResolve.flag == VK_RESOLVE_MODE_NONE))
1365                                                                         continue;
1366
1367                                                                 // If there is no depth, the depth resolve mode should be NONE, or
1368                                                                 // match the stencil resolve mode.
1369                                                                 if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE) &&
1370                                                                         (dResolve.flag != sResolve.flag))
1371                                                                         continue;
1372
1373                                                                 // If there is no stencil, the stencil resolve mode should be NONE, or
1374                                                                 // match the depth resolve mode.
1375                                                                 if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE) &&
1376                                                                         (dResolve.flag != sResolve.flag))
1377                                                                         continue;
1378
1379                                                                 const bool unusedResolve = (unusedIdx > 0);
1380
1381                                                                 std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
1382                                                                 if (unusedResolve)
1383                                                                         baseName += "_unused_resolve";
1384
1385                                                                 if (hasDepth)
1386                                                                 {
1387                                                                         std::string     name                    = baseName + "_testing_depth";
1388                                                                         const char*     testName                = name.c_str();
1389                                                                         float           expectedValue   = depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
1390
1391                                                                         const TestConfig testConfig =
1392                                                                         {
1393                                                                                 format,
1394                                                                                 imageData.width,
1395                                                                                 imageData.height,
1396                                                                                 1u,
1397                                                                                 1u,
1398                                                                                 0u,
1399                                                                                 imageData.renderArea,
1400                                                                                 aspectFlags,
1401                                                                                 sampleCount,
1402                                                                                 dResolve.flag,
1403                                                                                 sResolve.flag,
1404                                                                                 VB_DEPTH,
1405                                                                                 imageData.clearValue,
1406                                                                                 expectedValue,
1407                                                                                 0u,
1408                                                                                 useSeparateDepthStencilLayouts,
1409                                                                                 unusedResolve,
1410                                                                         };
1411                                                                         formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1412                                                                 }
1413                                                                 if (hasStencil)
1414                                                                 {
1415                                                                         std::string     name                    = baseName + "_testing_stencil";
1416                                                                         const char*     testName                = name.c_str();
1417                                                                         deUint8         expectedValue   = stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
1418
1419                                                                         const TestConfig testConfig =
1420                                                                         {
1421                                                                                 format,
1422                                                                                 imageData.width,
1423                                                                                 imageData.height,
1424                                                                                 1u,
1425                                                                                 1u,
1426                                                                                 0u,
1427                                                                                 imageData.renderArea,
1428                                                                                 aspectFlags,
1429                                                                                 sampleCount,
1430                                                                                 dResolve.flag,
1431                                                                                 sResolve.flag,
1432                                                                                 VB_STENCIL,
1433                                                                                 imageData.clearValue,
1434                                                                                 0.0f,
1435                                                                                 expectedValue,
1436                                                                                 useSeparateDepthStencilLayouts,
1437                                                                                 unusedResolve,
1438                                                                         };
1439                                                                         formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1440                                                                 }
1441                                                         }
1442                                                 }
1443                                         }
1444                                         sampleGroup->addChild(formatGroup.release());
1445                                 }
1446                         }
1447
1448                         imageGroup->addChild(sampleGroup.release());
1449                 }
1450
1451                 group->addChild(imageGroup.release());
1452         }
1453
1454         {
1455                 // layered texture tests are done for all stencil modes and depth modes - not all combinations
1456                 // Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer
1457                 // which starts at a layer other than zero. Both parts are tested together by rendering to layers
1458                 // 4-6 and resolving to layers 1-3.
1459                 ImageTestData layeredTextureTestData =
1460                 {
1461                         "image_2d_16_64_6", 16, 64, 6, {{ 10,  10}, {6, 54}}, {1.0f, 0x0}
1462                 };
1463
1464                 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));
1465
1466                 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1467                 {
1468                         const deUint32          sampleCount     (sampleCounts[sampleCountNdx]);
1469                         const std::string       sampleName      ("samples_" + de::toString(sampleCount));
1470
1471                         // create test group for sample count
1472                         de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1473
1474                         // iterate over depth/stencil formats
1475                         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1476                         {
1477                                 const FormatData&                       formatData                                      = formats[formatNdx];
1478                                 VkFormat                                        format                                          = formatData.format;
1479                                 const char*                                     formatName                                      = formatData.name;
1480                                 const bool                                      hasDepth                                        = formatData.hasDepth;
1481                                 const bool                                      hasStencil                                      = formatData.hasStencil;
1482                                 VkImageAspectFlags                      aspectFlags                                     = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1483                                                                                                                                                   (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1484                                 const int                                       separateLayoutsLoopCount        = (hasDepth && hasStencil) ? 2 : 1;
1485
1486                                 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1487                                 {
1488                                         const bool                      useSeparateDepthStencilLayouts  = bool(separateDepthStencilLayouts);
1489                                         const std::string       groupName                                               = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1490
1491                                         // create test group for format
1492                                         de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1493
1494                                         for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
1495                                         {
1496                                                 for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1497                                                 {
1498                                                         ResolveModeData& mode = resolveModes[resolveModeNdx];
1499
1500                                                         const bool                      unusedResolve   = (unusedIdx > 0);
1501                                                         const std::string       unusedSuffix    = (unusedResolve ? "_unused_resolve" : "");
1502
1503                                                         if (hasDepth)
1504                                                         {
1505                                                                 std::string     name                    = "depth_" + mode.name + unusedSuffix;
1506                                                                 const char*     testName                = name.c_str();
1507                                                                 float           expectedValue   = depthExpectedValue[resolveModeNdx][sampleCountNdx];
1508                                                                 const TestConfig testConfig =
1509                                                                 {
1510                                                                         format,
1511                                                                         layeredTextureTestData.width,
1512                                                                         layeredTextureTestData.height,
1513                                                                         layeredTextureTestData.imageLayers,
1514                                                                         3u,
1515                                                                         0u,
1516                                                                         layeredTextureTestData.renderArea,
1517                                                                         aspectFlags,
1518                                                                         sampleCount,
1519                                                                         mode.flag,
1520                                                                         VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1521                                                                         VB_DEPTH,
1522                                                                         layeredTextureTestData.clearValue,
1523                                                                         expectedValue,
1524                                                                         0u,
1525                                                                         useSeparateDepthStencilLayouts,
1526                                                                         unusedResolve,
1527                                                                 };
1528                                                                 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1529                                                         }
1530
1531                                                         // there is no average resolve mode for stencil - go to next iteration
1532                                                         if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1533                                                                 continue;
1534
1535                                                         if (hasStencil)
1536                                                         {
1537                                                                 std::string     name                    = "stencil_" + mode.name + unusedSuffix;
1538                                                                 const char*     testName                = name.c_str();
1539                                                                 deUint8         expectedValue   = stencilExpectedValue[resolveModeNdx][sampleCountNdx];
1540                                                                 const TestConfig testConfig =
1541                                                                 {
1542                                                                         format,
1543                                                                         layeredTextureTestData.width,
1544                                                                         layeredTextureTestData.height,
1545                                                                         layeredTextureTestData.imageLayers,
1546                                                                         3u,
1547                                                                         0u,
1548                                                                         layeredTextureTestData.renderArea,
1549                                                                         aspectFlags,
1550                                                                         sampleCount,
1551                                                                         VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1552                                                                         mode.flag,
1553                                                                         VB_STENCIL,
1554                                                                         layeredTextureTestData.clearValue,
1555                                                                         0.0f,
1556                                                                         expectedValue,
1557                                                                         useSeparateDepthStencilLayouts,
1558                                                                         unusedResolve,
1559                                                                 };
1560                                                                 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1561                                                         }
1562                                                 }
1563                                         }
1564                                         sampleGroup->addChild(formatGroup.release());
1565                                 }
1566                         }
1567                         imageGroup->addChild(sampleGroup.release());
1568                 }
1569
1570                 group->addChild(imageGroup.release());
1571         }
1572 }
1573
1574 } // anonymous
1575
1576 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
1577 {
1578         return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);
1579 }
1580
1581 } // vkt