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