Merge vk-gl-cts/vulkan-cts-1.2.7 into vk-gl-cts/vulkan-cts-1.2.8
[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 stencilFinalLayout =
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         void * attachmentDescriptionStencil = DE_NULL;
458
459         if (m_config.separateDepthStencilLayouts)
460         {
461                 if (m_config.verifyBuffer == VB_DEPTH)
462                 {
463                         layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
464                         stencilLayout.stencilLayout = VK_IMAGE_LAYOUT_GENERAL;
465                         finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
466                         stencilFinalLayout.stencilFinalLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; // This aspect should be unused.
467                 }
468                 else
469                 {
470                         layout = VK_IMAGE_LAYOUT_GENERAL;
471                         stencilLayout.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
472                         finalLayout = VK_IMAGE_LAYOUT_GENERAL;  // This aspect should be unused.
473                         stencilFinalLayout.stencilFinalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
474                 }
475                 attachmentRefStencil = &stencilLayout;
476                 attachmentDescriptionStencil = &stencilFinalLayout;
477         }
478
479         if (renderPassNo != 0)
480         {
481                 stencilFinalLayout.stencilInitialLayout = stencilLayout.stencilLayout;
482         }
483
484         if (renderPassNo != m_numRenderPasses - 1)
485         {
486                 finalLayout = layout;
487                 stencilFinalLayout.stencilFinalLayout = layout;
488         }
489
490         const AttachmentDescription2 multisampleAttachment              // VkAttachmentDescription2
491         (
492                                                                                                                         // VkStructureType                                      sType;
493                 attachmentDescriptionStencil,                                           // const void*                                          pNext;
494                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
495                 m_config.format,                                                                        // VkFormat                                                     format;
496                 samples,                                                                                        // VkSampleCountFlagBits                        samples;
497                 (renderPassNo == 0) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,         // VkAttachmentLoadOp                           loadOp;
498                 VK_ATTACHMENT_STORE_OP_STORE,
499                 (renderPassNo == 0) ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,         // VkAttachmentLoadOp                           stencilLoadOp;
500                 VK_ATTACHMENT_STORE_OP_STORE,
501                 (renderPassNo == 0) ? VK_IMAGE_LAYOUT_UNDEFINED : layout,                                                       // VkImageLayout                                        initialLayout;
502                 finalLayout                                                                                     // VkImageLayout                                        finalLayout;
503         );
504         const AttachmentReference2 multisampleAttachmentRef             // VkAttachmentReference2
505         (
506                                                                                                                         // VkStructureType                                      sType;
507                 attachmentRefStencil,                                                           // const void*                                          pNext;
508                 0u,                                                                                                     // deUint32                                                     attachment;
509                 layout,                                                                                         // VkImageLayout                                        layout;
510                 m_config.aspectFlag                                                                     // VkImageAspectFlags                           aspectMask;
511         );
512
513         vk::VkImageLayout               singleSampleInitialLayout = (m_config.unusedResolve ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED);
514         if (renderPassNo != 0)
515                 singleSampleInitialLayout = layout;
516
517         const tcu::TextureFormat                        format                  (mapVkFormat(vkformat));
518         VkImageAspectFlags aspectFlags =
519                 ((tcu::hasDepthComponent(format.order)          ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_DEPTH_BIT)    : 0u) |
520                  (tcu::hasStencilComponent(format.order)        ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_STENCIL_BIT)  : 0u));
521
522         const AttachmentDescription2 singlesampleAttachment             // VkAttachmentDescription2
523         (
524                                                                                                                         // VkStructureType                                      sType;
525                 attachmentDescriptionStencil,                                           // const void*                                          pNext;
526                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
527                 vkformat,                                                                                       // VkFormat                                                     format;
528                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
529                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
530                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
531                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           stencilLoadOp;
532                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          stencilStoreOp;
533                 singleSampleInitialLayout,                                                      // VkImageLayout                                        initialLayout;
534                 finalLayout                                                                                     // VkImageLayout                                        finalLayout;
535         );
536         AttachmentReference2 singlesampleAttachmentRef                  // VkAttachmentReference2
537         (
538                                                                                                                                 // VkStructureType                                      sType;
539                 attachmentRefStencil,                                                                   // const void*                                          pNext;
540                 ((m_config.unusedResolve || renderPassNo != m_numRenderPasses - 1) ? VK_ATTACHMENT_UNUSED : 1u),        // deUint32                                                     attachment;
541                 layout,                                                                                                 // VkImageLayout                                        layout;
542                 aspectFlags                                                                                             // VkImageAspectFlags                           aspectMask;
543         );
544
545         std::vector<AttachmentDescription2> attachments;
546         attachments.push_back(multisampleAttachment);
547         attachments.push_back(singlesampleAttachment);
548
549         VkSubpassDescriptionDepthStencilResolve dsResolveDescription =
550         {
551                 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
552                 DE_NULL,                                                                                                                                // const void*                                          pNext;
553                 m_config.depthResolveMode,                                                                                              // VkResolveModeFlagBits                        depthResolveMode;
554                 m_config.stencilResolveMode,                                                                                    // VkResolveModeFlagBits                        stencilResolveMode;
555                 &singlesampleAttachmentRef                                                                                              // VkAttachmentReference2                       pDepthStencilResolveAttachment;
556         };
557
558         const SubpassDescription2 subpass                                       // VkSubpassDescription2
559         (
560                                                                                                                 // VkStructureType                                              sType;
561                 renderPassNo == m_numRenderPasses - 1 ? &dsResolveDescription : DE_NULL,        // const void*                                                  pNext;
562                 (VkSubpassDescriptionFlags)0,                                   // VkSubpassDescriptionFlags                    flags;
563                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                // VkPipelineBindPoint                                  pipelineBindPoint;
564                 0u,                                                                                             // deUint32                                                             viewMask;
565                 0u,                                                                                             // deUint32                                                             inputAttachmentCount;
566                 DE_NULL,                                                                                // const VkAttachmentReference2*                pInputAttachments;
567                 0u,                                                                                             // deUint32                                                             colorAttachmentCount;
568                 DE_NULL,                                                                                // const VkAttachmentReference2*                pColorAttachments;
569                 DE_NULL,                                                                                // const VkAttachmentReference2*                pResolveAttachments;
570                 &multisampleAttachmentRef,                                              // const VkAttachmentReference2*                pDepthStencilAttachment;
571                 0u,                                                                                             // deUint32                                                             preserveAttachmentCount;
572                 DE_NULL                                                                                 // const deUint32*                                              pPreserveAttachments;
573         );
574
575         const RenderPassCreateInfo2 renderPassCreator           // VkRenderPassCreateInfo2
576         (
577                                                                                                                 // VkStructureType                                              sType;
578                 DE_NULL,                                                                                // const void*                                                  pNext;
579                 (VkRenderPassCreateFlags)0u,                                    // VkRenderPassCreateFlags                              flags;
580                 (deUint32)attachments.size(),                                   // deUint32                                                             attachmentCount;
581                 &attachments[0],                                                                // const VkAttachmentDescription2*              pAttachments;
582                 1u,                                                                                             // deUint32                                                             subpassCount;
583                 &subpass,                                                                               // const VkSubpassDescription2*                 pSubpasses;
584                 0u,                                                                                             // deUint32                                                             dependencyCount;
585                 DE_NULL,                                                                                // const VkSubpassDependency2*                  pDependencies;
586                 0u,                                                                                             // deUint32                                                             correlatedViewMaskCount;
587                 DE_NULL                                                                                 // const deUint32*                                              pCorrelatedViewMasks;
588         );
589
590         return renderPassCreator.createRenderPass(m_vkd, m_device);
591 }
592
593 // Checks format support.
594 // Note: we need the context because this is called from the constructor only after m_config has been set.
595 bool DepthStencilResolveTest::isSupportedFormat (Context& context, VkFormat format) const
596 {
597         const VkImageUsageFlags usage   = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
598                                                                         | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
599                                                                         | (m_config.unusedResolve ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : static_cast<vk::VkImageUsageFlagBits>(0u));
600         VkImageFormatProperties props;
601
602         const auto&     vki                             = context.getInstanceInterface();
603         const auto      physicalDevice  = context.getPhysicalDevice();
604         const auto      formatCheck             = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0u, &props);
605
606         return (formatCheck == VK_SUCCESS);
607 }
608
609 Move<VkRenderPass> DepthStencilResolveTest::createRenderPassCompatible (void)
610 {
611         // Early exit if we are not testing compatibility.
612         if (! m_config.compatibleFormat)
613                 return {};
614
615         return createRenderPass(m_config.compatibleFormat.get(), 0);
616 }
617
618 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
619 {
620         std::vector<VkImageView> attachments;
621         attachments.push_back(**multisampleImageView);
622         attachments.push_back(**singlesampleImageView);
623
624         const VkFramebufferCreateInfo createInfo =
625         {
626                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
627                 DE_NULL,
628                 0u,
629
630                 renderPass,
631                 (deUint32)attachments.size(),
632                 &attachments[0],
633
634                 m_config.width,
635                 m_config.height,
636                 m_config.viewLayers
637         };
638
639         return vk::createFramebuffer(m_vkd, m_device, &createInfo);
640 }
641
642 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
643 {
644         VkPushConstantRange pushConstant =
645         {
646                 VK_SHADER_STAGE_FRAGMENT_BIT,
647                 0u,
648                 4u
649         };
650
651         deUint32                                pushConstantRangeCount  = 0u;
652         VkPushConstantRange*    pPushConstantRanges             = DE_NULL;
653         if (m_config.verifyBuffer == VB_STENCIL)
654         {
655                 pushConstantRangeCount  = 1u;
656                 pPushConstantRanges             = &pushConstant;
657         }
658
659         const VkPipelineLayoutCreateInfo createInfo     =
660         {
661                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
662                 DE_NULL,
663                 (vk::VkPipelineLayoutCreateFlags)0,
664
665                 0u,
666                 DE_NULL,
667
668                 pushConstantRangeCount,
669                 pPushConstantRanges
670         };
671
672         return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
673 }
674
675 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, deUint32 renderPassNo, VkPipelineLayout renderPipelineLayout)
676 {
677         const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
678         const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
679
680         const Unique<VkShaderModule>    vertexShaderModule              (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u));
681         const Unique<VkShaderModule>    fragmentShaderModule    (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u));
682         const Move<VkShaderModule>              geometryShaderModule    (m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u));
683
684         const VkPipelineVertexInputStateCreateInfo vertexInputState =
685         {
686                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
687                 DE_NULL,
688                 (VkPipelineVertexInputStateCreateFlags)0u,
689
690                 0u,
691                 DE_NULL,
692
693                 0u,
694                 DE_NULL
695         };
696         const tcu::UVec2                                view            (m_config.width, m_config.height);
697         const std::vector<VkViewport>   viewports       (1, makeViewport(view));
698         const std::vector<VkRect2D>             scissors        (1, m_config.renderArea);
699         const VkSampleMask samplemask[2] = {
700                 renderPassNo < 32 ? (1u << renderPassNo) : 0,
701                 renderPassNo < 32 ? 0 : (1u << (renderPassNo - 32)) };
702
703         const VkPipelineMultisampleStateCreateInfo multisampleState =
704         {
705                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
706                 DE_NULL,
707                 (VkPipelineMultisampleStateCreateFlags)0u,
708
709                 sampleCountBitFromSampleCount(m_config.sampleCount),
710                 VK_FALSE,
711                 0.0f,
712                 (m_config.sampleMask) ? &samplemask[0] : DE_NULL,
713                 VK_FALSE,
714                 VK_FALSE,
715         };
716         const VkPipelineDepthStencilStateCreateInfo depthStencilState =
717         {
718                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
719                 DE_NULL,
720                 (VkPipelineDepthStencilStateCreateFlags)0u,
721
722                 VK_TRUE,                                                        // depthTestEnable
723                 VK_TRUE,
724                 VK_COMPARE_OP_ALWAYS,
725                 VK_FALSE,
726                 testingStencil,                                         // stencilTestEnable
727                 {
728                         VK_STENCIL_OP_REPLACE,                  // failOp
729                         VK_STENCIL_OP_REPLACE,                  // passOp
730                         VK_STENCIL_OP_REPLACE,                  // depthFailOp
731                         VK_COMPARE_OP_ALWAYS,                   // compareOp
732                         0xFFu,                                                  // compareMask
733                         0xFFu,                                                  // writeMask
734                         1                                                               // reference
735                 },
736                 {
737                         VK_STENCIL_OP_REPLACE,
738                         VK_STENCIL_OP_REPLACE,
739                         VK_STENCIL_OP_REPLACE,
740                         VK_COMPARE_OP_ALWAYS,
741                         0xFFu,
742                         0xFFu,
743                         1
744                 },
745                 0.0f,
746                 1.0f
747         };
748
749         std::vector<VkDynamicState> dynamicState;
750         dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
751         const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
752         {
753                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,   // VkStructureType                      sType;
754                 DE_NULL,                                                                                                // const void*                          pNext;
755                 (VkPipelineDynamicStateCreateFlags)0u,                                  // VkPipelineDynamicStateCreateFlags    flags;
756                 static_cast<deUint32>(dynamicState.size()),                             // deUint32                             dynamicStateCount;
757                 &dynamicState[0]                                                                                // const VkDynamicState*                pDynamicStates;
758         };
759
760         return makeGraphicsPipeline(m_vkd,                                                                                                                      // const DeviceInterface&                        vk
761                                                                 m_device,                                                                                                               // const VkDevice                                device
762                                                                 renderPipelineLayout,                                                                                   // const VkPipelineLayout                        pipelineLayout
763                                                                 *vertexShaderModule,                                                                                    // const VkShaderModule                          vertexShaderModule
764                                                                 DE_NULL,                                                                                                                // const VkShaderModule                          tessellationControlShaderModule
765                                                                 DE_NULL,                                                                                                                // const VkShaderModule                          tessellationEvalShaderModule
766                                                                 m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule,    // const VkShaderModule                          geometryShaderModule
767                                                                 *fragmentShaderModule,                                                                                  // const VkShaderModule                          fragmentShaderModule
768                                                                 renderPass,                                                                                                             // const VkRenderPass                            renderPass
769                                                                 viewports,                                                                                                              // const std::vector<VkViewport>&                viewports
770                                                                 scissors,                                                                                                               // const std::vector<VkRect2D>&                  scissors
771                                                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,                                                    // const VkPrimitiveTopology                     topology
772                                                                 0u,                                                                                                                             // const deUint32                                subpass
773                                                                 0u,                                                                                                                             // const deUint32                                patchControlPoints
774                                                                 &vertexInputState,                                                                                              // const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
775                                                                 DE_NULL,                                                                                                                // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
776                                                                 &multisampleState,                                                                                              // const VkPipelineMultisampleStateCreateInfo*   multisampleStateCreateInfo
777                                                                 &depthStencilState,                                                                                             // const VkPipelineDepthStencilStateCreateInfo*  depthStencilStateCreateInfo
778                                                                 DE_NULL,                                                                                                                // const VkPipelineColorBlendStateCreateInfo*    colorBlendStateCreateInfo
779                                                                 testingStencil ? &dynamicStateCreateInfo : DE_NULL);                    // const VkPipelineDynamicStateCreateInfo*       dynamicStateCreateInfo
780 }
781
782 AllocationSp DepthStencilResolveTest::createBufferMemory (void)
783 {
784         Allocator&                              allocator = m_context.getDefaultAllocator();
785         de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible));
786         VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset()));
787         return safeSharedPtr(allocation.release());
788 }
789
790 VkBufferSp DepthStencilResolveTest::createBuffer (void)
791 {
792         const VkBufferUsageFlags        bufferUsage                     (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
793         const tcu::TextureFormat        textureFormat           (mapVkFormat(m_config.format));
794         const VkDeviceSize                      pixelSize                       (textureFormat.getPixelSize());
795         const VkBufferCreateInfo        createInfo                      =
796         {
797                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
798                 DE_NULL,
799                 0u,
800
801                 m_config.width * m_config.height * m_config.imageLayers * pixelSize,
802                 bufferUsage,
803
804                 VK_SHARING_MODE_EXCLUSIVE,
805                 0u,
806                 DE_NULL
807         };
808         return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
809 }
810
811 void DepthStencilResolveTest::submit (void)
812 {
813         const DeviceInterface&                                          vkd                                     (m_context.getDeviceInterface());
814         const VkDevice                                                          device                          (m_context.getDevice());
815
816         // When the depth/stencil resolve attachment is unused, it needs to be cleared outside
817         // the render pass so it has the expected values.
818         if (m_config.unusedResolve)
819         {
820                 const tcu::TextureFormat                        format                  (mapVkFormat(m_config.format));
821                 const Unique<VkCommandBuffer>           commandBuffer   (allocateCommandBuffer(m_vkd, m_device, *m_commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
822                 const vk::VkImageSubresourceRange       imageRange              =
823                 {
824                         ((tcu::hasDepthComponent(format.order)          ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_DEPTH_BIT)    : 0u) |
825                          (tcu::hasStencilComponent(format.order)        ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_STENCIL_BIT)  : 0u)),
826                         0u,
827                         VK_REMAINING_MIP_LEVELS,
828                         0u,
829                         VK_REMAINING_ARRAY_LAYERS,
830                 };
831                 const vk::VkImageMemoryBarrier          preBarrier              =
832                 {
833                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
834                         nullptr,
835
836                         // src and dst access masks.
837                         0,
838                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,
839
840                         // old and new layouts.
841                         vk::VK_IMAGE_LAYOUT_UNDEFINED,
842                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
843
844                         VK_QUEUE_FAMILY_IGNORED,
845                         VK_QUEUE_FAMILY_IGNORED,
846
847                         **m_singlesampleImage,
848                         imageRange,
849                 };
850                 const vk::VkImageMemoryBarrier          postBarrier             =
851                 {
852                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
853                         nullptr,
854
855                         // src and dst access masks.
856                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,
857                         0,
858
859                         // old and new layouts.
860                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
861                         vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
862
863                         VK_QUEUE_FAMILY_IGNORED,
864                         VK_QUEUE_FAMILY_IGNORED,
865
866                         **m_singlesampleImage,
867                         imageRange,
868                 };
869
870                 vk::beginCommandBuffer(m_vkd, commandBuffer.get());
871                 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);
872                 m_vkd.cmdClearDepthStencilImage(commandBuffer.get(), **m_singlesampleImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_config.clearValue, 1u, &imageRange);
873                 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);
874                 vk::endCommandBuffer(m_vkd, commandBuffer.get());
875
876                 vk::submitCommandsAndWait(m_vkd, m_device, m_context.getUniversalQueue(), commandBuffer.get());
877         }
878
879         const Unique<VkCommandBuffer>                           commandBuffer(allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
880         const RenderpassSubpass2::SubpassBeginInfo      subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
881         const RenderpassSubpass2::SubpassEndInfo        subpassEndInfo(DE_NULL);
882
883         beginCommandBuffer(vkd, *commandBuffer);
884         bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
885         if (testingDepth)
886         {
887                 {
888                         VkClearValue clearValues[2];
889                         clearValues[0].depthStencil = m_config.clearValue;
890                         clearValues[1].depthStencil = m_config.clearValue;
891
892                         const VkRenderPassBeginInfo beginInfo =
893                         {
894                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
895                                 DE_NULL,
896
897                                         (m_config.compatibleFormat ? *m_renderPassCompatible : *m_renderPass[0]),
898                                 *m_framebuffer,
899
900                                 {
901                                         { 0u, 0u },
902                                         { m_config.width, m_config.height }
903                                 },
904
905                                 2u,
906                                 clearValues
907                         };
908                         RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
909                 }
910
911                 // Render
912                 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline[0]);
913                 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
914                 RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
915         }
916         else
917         {
918                 // Stencil
919                 for (deUint32 i = 0; i < m_config.sampleCount; i++)
920                 {
921                         if (i == 0 || m_config.sampleMask)
922                         {
923                                 VkClearValue clearValues[2];
924                                 clearValues[0].depthStencil = m_config.clearValue;
925                                 clearValues[1].depthStencil = m_config.clearValue;
926
927                                 const VkRenderPassBeginInfo beginInfo =
928                                 {
929                                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
930                                         DE_NULL,
931
932                                         (m_config.compatibleFormat ? *m_renderPassCompatible : *m_renderPass[i]),
933                                         *m_framebuffer,
934
935                                         {
936                                                 { 0u, 0u },
937                                                 { m_config.width, m_config.height }
938                                         },
939
940                                         2u,
941                                         clearValues
942                                 };
943                                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, 0, 0, 0, 0, 0);
944                                 RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
945                         }
946                         // For stencil we can set reference value for just one sample at a time
947                         // so we need to do as many passes as there are samples, first half
948                         // of samples is initialized with 1 and second half with 255
949                         const deUint32 halfOfSamples = m_config.sampleCount >> 1;
950
951                         deUint32 stencilReference = 1 + 254 * (i >= halfOfSamples);
952                         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline[m_config.sampleMask ? i : 0]);
953                         vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(i), &i);
954                         vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference);
955                         vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
956                         if (i == m_config.sampleCount - 1 || m_config.sampleMask)
957                                 RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
958                 }
959         }
960
961         // Memory barriers between rendering and copying
962         {
963                 const VkImageMemoryBarrier barrier =
964                 {
965                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
966                         DE_NULL,
967
968                         // Note: as per the spec, depth/stencil *resolve* operations are synchronized using the color attachment write access.
969                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
970                         VK_ACCESS_TRANSFER_READ_BIT,
971
972                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
973                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
974
975                         VK_QUEUE_FAMILY_IGNORED,
976                         VK_QUEUE_FAMILY_IGNORED,
977
978                         **m_singlesampleImage,
979                         {
980                                 (m_config.separateDepthStencilLayouts) ? VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT) : m_config.aspectFlag,
981                                 0u,
982                                 1u,
983                                 0u,
984                                 m_config.viewLayers
985                         }
986                 };
987
988                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
989         }
990
991         // Copy image memory to buffers
992         const VkBufferImageCopy region =
993         {
994                 0u,
995                 0u,
996                 0u,
997                 {
998                         VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT),
999                         0u,
1000                         0u,
1001                         m_config.viewLayers,
1002                 },
1003                 { 0u, 0u, 0u },
1004                 { m_config.width, m_config.height, 1u }
1005         };
1006
1007         vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, &region);
1008
1009         // Memory barriers between copies and host access
1010         {
1011                 const VkBufferMemoryBarrier barrier =
1012                 {
1013                         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1014                         DE_NULL,
1015
1016                         VK_ACCESS_TRANSFER_WRITE_BIT,
1017                         VK_ACCESS_HOST_READ_BIT,
1018
1019                         VK_QUEUE_FAMILY_IGNORED,
1020                         VK_QUEUE_FAMILY_IGNORED,
1021
1022                         **m_buffer,
1023                         0u,
1024                         VK_WHOLE_SIZE
1025                 };
1026
1027                 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
1028         }
1029
1030         endCommandBuffer(vkd, *commandBuffer);
1031
1032         submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1033 }
1034
1035 bool DepthStencilResolveTest::verifyDepth (void)
1036 {
1037         // Invalidate allocation before attempting to read buffer memory.
1038         invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
1039
1040         deUint32                        layerSize       = m_config.width * m_config.height;
1041         deUint32                        valuesCount     = layerSize * m_config.viewLayers;
1042         deUint8*                        pixelPtr        = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
1043
1044         const DeviceInterface&          vkd             (m_context.getDeviceInterface());
1045         invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
1046
1047         float expectedValue = m_config.depthExpectedValue;
1048         if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
1049                 expectedValue = m_config.clearValue.depth;
1050
1051         // depth data in buffer is tightly packed, ConstPixelBufferAccess
1052         // coludn't be used for depth value extraction as it cant interpret
1053         // formats containing just depth component
1054
1055         typedef float (*DepthComponentGetterFn)(deUint8*);
1056         VkFormat                                format                          = m_config.format;
1057         DepthComponentGetterFn  getDepthComponent       = &get16bitDepthComponent;
1058         deUint32                                pixelStep                       = 2;
1059         float                                   epsilon                         = 0.002f;
1060
1061         if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
1062                 (format == VK_FORMAT_D24_UNORM_S8_UINT))
1063         {
1064                 getDepthComponent       = &get24bitDepthComponent;
1065                 pixelStep                       = 4;
1066         }
1067         else if ((format == VK_FORMAT_D32_SFLOAT) ||
1068                                 (format == VK_FORMAT_D32_SFLOAT_S8_UINT))
1069         {
1070                 getDepthComponent       = &get32bitDepthComponent;
1071                 pixelStep                       = 4;
1072         }
1073
1074         for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1075         {
1076                 float depth = (*getDepthComponent)(pixelPtr);
1077                 pixelPtr += pixelStep;
1078
1079                 // check if pixel data is outside of render area
1080                 deInt32 layerIndex              = valueIndex / layerSize;
1081                 deInt32 inLayerIndex    = valueIndex % layerSize;
1082                 deInt32 x                               = inLayerIndex % m_config.width;
1083                 deInt32 y                               = (inLayerIndex - x) / m_config.width;
1084                 deInt32 x1                              = m_config.renderArea.offset.x;
1085                 deInt32 y1                              = m_config.renderArea.offset.y;
1086                 deInt32 x2                              = x1 + m_config.renderArea.extent.width;
1087                 deInt32 y2                              = y1 + m_config.renderArea.extent.height;
1088                 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
1089                 {
1090                         // verify that outside of render area there are clear values
1091                         float error = deFloatAbs(depth - m_config.clearValue.depth);
1092                         if (error > epsilon)
1093                         {
1094                                 m_context.getTestContext().getLog()
1095                                 << TestLog::Message << "(" << x << ", " << y
1096                                 << ", layer: " << layerIndex << ") is outside of render area but depth value is: "
1097                                 << depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage;
1098                                 return false;
1099                         }
1100
1101                         // value is correct, go to next one
1102                         continue;
1103                 }
1104
1105                 float error = deFloatAbs(depth - expectedValue);
1106                 if (error > epsilon)
1107                 {
1108                         m_context.getTestContext().getLog() << TestLog::Message
1109                                 << "At (" << x << ", " << y << ", layer: " << layerIndex
1110                                 << ") depth value is: " << depth << " expected: "
1111                                 << expectedValue << TestLog::EndMessage;
1112                         return false;
1113                 }
1114         }
1115         m_context.getTestContext().getLog() << TestLog::Message
1116                 << "Depth value is " << expectedValue
1117                 << TestLog::EndMessage;
1118
1119         return true;
1120 }
1121
1122 bool DepthStencilResolveTest::verifyStencil (void)
1123 {
1124         // Invalidate allocation before attempting to read buffer memory.
1125         invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
1126
1127         deUint32                        layerSize       = m_config.width * m_config.height;
1128         deUint32                        valuesCount     = layerSize * m_config.viewLayers;
1129         deUint8*                        pixelPtr        = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
1130
1131         const DeviceInterface&          vkd             (m_context.getDeviceInterface());
1132         invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
1133
1134         // when stencil is tested we are discarding invocations and
1135         // because of that depth and stencil need to be tested separately
1136
1137         deUint8 expectedValue = m_config.stencilExpectedValue;
1138         if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
1139                 expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);
1140
1141         for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1142         {
1143                 deUint8 stencil                 = *pixelPtr++;
1144                 deInt32 layerIndex              = valueIndex / layerSize;
1145                 deInt32 inLayerIndex    = valueIndex % layerSize;
1146                 deInt32 x                               = inLayerIndex % m_config.width;
1147                 deInt32 y                               = (inLayerIndex - x) / m_config.width;
1148                 deInt32 x1                              = m_config.renderArea.offset.x;
1149                 deInt32 y1                              = m_config.renderArea.offset.y;
1150                 deInt32 x2                              = x1 + m_config.renderArea.extent.width;
1151                 deInt32 y2                              = y1 + m_config.renderArea.extent.height;
1152                 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
1153                 {
1154                         if (stencil != m_config.clearValue.stencil)
1155                         {
1156                                 m_context.getTestContext().getLog()
1157                                 << TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex
1158                                 << ") is outside of render area but stencil value is: "
1159                                 << stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage;
1160                                 return false;
1161                         }
1162
1163                         // value is correct, go to next one
1164                         continue;
1165                 }
1166
1167                 if (stencil != expectedValue)
1168                 {
1169                         m_context.getTestContext().getLog() << TestLog::Message
1170                                 << "At (" << x << ", " << y << ", layer: " << layerIndex
1171                                 << ") stencil value is: " << static_cast<deUint32>(stencil)
1172                                 << " expected: " << static_cast<deUint32>(expectedValue)
1173                                 << TestLog::EndMessage;
1174                         return false;
1175                 }
1176         }
1177         m_context.getTestContext().getLog() << TestLog::Message
1178                 << "Stencil value is "
1179                 << static_cast<deUint32>(expectedValue)
1180                 << TestLog::EndMessage;
1181
1182         return true;
1183 }
1184
1185 tcu::TestStatus DepthStencilResolveTest::iterate (void)
1186 {
1187         submit();
1188
1189         bool result = false;
1190         if (m_config.verifyBuffer == VB_DEPTH)
1191                 result = verifyDepth();
1192         else
1193                 result = verifyStencil();
1194
1195         if (result)
1196                 return tcu::TestStatus::pass("Pass");
1197         return tcu::TestStatus::fail("Fail");
1198 }
1199
1200 struct Programs
1201 {
1202         void init (vk::SourceCollections& dst, TestConfig config) const
1203         {
1204                 // geometry shader is only needed in multi-layer framebuffer resolve tests
1205                 if (config.imageLayers > 1)
1206                 {
1207                         const deUint32 layerCount = 3;
1208
1209                         std::ostringstream src;
1210                         src << "#version 450\n"
1211                                 << "highp float;\n"
1212                                 << "\n"
1213                                 << "layout(triangles) in;\n"
1214                                 << "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
1215                                 << "\n"
1216                                 << "in gl_PerVertex {\n"
1217                                 << "    vec4 gl_Position;\n"
1218                                 << "} gl_in[];\n"
1219                                 << "\n"
1220                                 << "out gl_PerVertex {\n"
1221                                 << "    vec4 gl_Position;\n"
1222                                 << "};\n"
1223                                 << "\n"
1224                                 << "void main (void) {\n"
1225                                 << "    for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n"
1226                                 << "        for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
1227                                 << "            gl_Position = gl_in[vertexNdx].gl_Position;\n"
1228                                 << "            gl_Layer    = layerNdx;\n"
1229                                 << "            EmitVertex();\n"
1230                                 << "        };\n"
1231                                 << "        EndPrimitive();\n"
1232                                 << "    };\n"
1233                                 << "}\n";
1234
1235                         dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
1236                 }
1237
1238                 dst.glslSources.add("quad-vert") << glu::VertexSource(
1239                         "#version 450\n"
1240                         "out gl_PerVertex {\n"
1241                         "\tvec4 gl_Position;\n"
1242                         "};\n"
1243                         "highp float;\n"
1244                         "void main (void) {\n"
1245                         "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1246                         "\t                   ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1247                         "}\n");
1248
1249                 if (config.verifyBuffer == VB_DEPTH)
1250                 {
1251                         dst.glslSources.add("quad-frag") << glu::FragmentSource(
1252                                 "#version 450\n"
1253                                 "precision highp float;\n"
1254                                 "precision highp int;\n"
1255                                 "void main (void)\n"
1256                                 "{\n"
1257                                 "  float sampleIndex = float(gl_SampleID);\n"                           // sampleIndex is integer in range <0, 63>
1258                                 "  float valueIndex = round(mod(sampleIndex, 4.0));\n"          // limit possible depth values - count to 4
1259                                 "  float value = valueIndex + 2.0;\n"                                           // value is one of [2, 3, 4, 5]
1260                                 "  value = round(exp2(value));\n"                                                       // value is one of [4, 8, 16, 32]
1261                                 "  bool condition = (int(value) == 8);\n"                                       // select second sample value (to make it smallest)
1262                                 "  value = round(value - float(condition) * 6.0);\n"            // value is one of [4, 2, 16, 32]
1263                                 "  gl_FragDepth = value / 100.0;\n"                                                     // sample depth is one of [0.04, 0.02, 0.16, 0.32]
1264                                 "}\n");
1265                 }
1266                 else
1267                 {
1268                         if (config.sampleMask)
1269                         {
1270                                 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1271                                         "#version 450\n"
1272                                         "precision highp float;\n"
1273                                         "precision highp int;\n"
1274                                         "void main (void)\n"
1275                                         "{\n"
1276                                         "  gl_FragDepth = 0.5;\n"
1277                                         "}\n");
1278                         }
1279                         else
1280                         {
1281                                 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1282                                         "#version 450\n"
1283                                         "precision highp float;\n"
1284                                         "precision highp int;\n"
1285                                         "layout(push_constant) uniform PushConstant {\n"
1286                                         "  highp int sampleID;\n"
1287                                         "} pushConstants;\n"
1288                                         "void main (void)\n"
1289                                         "{\n"
1290                                         "  if(gl_SampleID != pushConstants.sampleID)\n"
1291                                         "    discard;\n"
1292                                         "  gl_FragDepth = 0.5;\n"
1293                                         "}\n");
1294                         }
1295                 }
1296         }
1297 };
1298
1299 class PropertiesTestCase : public vkt::TestCase
1300 {
1301 public:
1302                                                         PropertiesTestCase              (tcu::TestContext& testCtx, const std::string& name, const std::string& description)
1303                                                                 : vkt::TestCase(testCtx, name, description)
1304                                                                 {}
1305         virtual                                 ~PropertiesTestCase             (void) {}
1306
1307         virtual TestInstance*   createInstance                  (Context& context) const;
1308         virtual void                    checkSupport                    (Context& context) const;
1309 };
1310
1311 class PropertiesTestInstance : public vkt::TestInstance
1312 {
1313 public:
1314                                                                 PropertiesTestInstance  (Context& context)
1315                                                                         : vkt::TestInstance(context)
1316                                                                         {}
1317         virtual                                         ~PropertiesTestInstance (void) {}
1318
1319         virtual tcu::TestStatus         iterate                                 (void);
1320
1321 };
1322
1323 TestInstance* PropertiesTestCase::createInstance (Context& context) const
1324 {
1325         return new PropertiesTestInstance(context);
1326 }
1327
1328 void PropertiesTestCase::checkSupport (Context& context) const
1329 {
1330         context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
1331 }
1332
1333 tcu::TestStatus PropertiesTestInstance::iterate (void)
1334 {
1335         vk::VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsrProperties;
1336         dsrProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
1337         dsrProperties.pNext = nullptr;
1338
1339         vk::VkPhysicalDeviceProperties2 properties2;
1340         properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1341         properties2.pNext = &dsrProperties;
1342
1343         m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties2);
1344
1345         if ((dsrProperties.supportedDepthResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
1346                 TCU_FAIL("supportedDepthResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
1347
1348         if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
1349                 TCU_FAIL("supportedStencilResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
1350
1351         if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_AVERAGE_BIT_KHR) != 0)
1352                 TCU_FAIL("supportedStencilResolveModes includes forbidden VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
1353
1354         if (dsrProperties.independentResolve == VK_TRUE && dsrProperties.independentResolveNone != VK_TRUE)
1355                 TCU_FAIL("independentResolve supported but independentResolveNone not supported");
1356
1357         return tcu::TestStatus::pass("Pass");
1358 }
1359
1360
1361 void initTests (tcu::TestCaseGroup* group)
1362 {
1363         typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
1364
1365         struct FormatData
1366         {
1367                 VkFormat                format;
1368                 const char*             name;
1369                 bool                    hasDepth;
1370                 bool                    hasStencil;
1371         };
1372         FormatData formats[] =
1373         {
1374                 { VK_FORMAT_D16_UNORM,                          "d16_unorm",                    true,   false },
1375                 { VK_FORMAT_X8_D24_UNORM_PACK32,        "x8_d24_unorm_pack32",  true,   false },
1376                 { VK_FORMAT_D32_SFLOAT,                         "d32_sfloat",                   true,   false },
1377                 { VK_FORMAT_S8_UINT,                            "s8_uint",                              false,  true },
1378                 { VK_FORMAT_D16_UNORM_S8_UINT,          "d16_unorm_s8_uint",    true,   true },
1379                 { VK_FORMAT_D24_UNORM_S8_UINT,          "d24_unorm_s8_uint",    true,   true },
1380                 { VK_FORMAT_D32_SFLOAT_S8_UINT,         "d32_sfloat_s8_uint",   true,   true },
1381         };
1382
1383         struct ResolveModeData
1384         {
1385                 VkResolveModeFlagBits   flag;
1386                 std::string                             name;
1387         };
1388         ResolveModeData resolveModes[] =
1389         {
1390                 { VK_RESOLVE_MODE_NONE,                         "none" },
1391                 { VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,      "zero" },
1392                 { VK_RESOLVE_MODE_AVERAGE_BIT,          "average" },
1393                 { VK_RESOLVE_MODE_MIN_BIT,                      "min" },
1394                 { VK_RESOLVE_MODE_MAX_BIT,                      "max" },
1395         };
1396
1397         struct ImageTestData
1398         {
1399                 const char*                                     groupName;
1400                 deUint32                                        width;
1401                 deUint32                                        height;
1402                 deUint32                                        imageLayers;
1403                 VkRect2D                                        renderArea;
1404                 VkClearDepthStencilValue        clearValue;
1405         };
1406
1407         // NOTE: tests cant be executed for 1D and 3D images:
1408         // 1D images are not tested because acording to specyfication sampleCounts
1409         // will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D
1410         // 3D images are not tested because VkFramebufferCreateInfo specification
1411         // states that: each element of pAttachments that is a 2D or 2D array image
1412         // view taken from a 3D image must not be a depth/stencil format
1413         ImageTestData imagesTestData[] =
1414         {
1415                 { "image_2d_32_32",     32, 32, 1, {{ 0,  0}, {32, 32}}, {0.000f, 0x00} },
1416                 { "image_2d_8_32",       8, 32, 1, {{ 1,  1}, { 6, 30}}, {0.123f, 0x01} },
1417                 { "image_2d_49_13",     49, 13, 1, {{10,  5}, {20,  8}}, {1.000f, 0x05} },
1418                 { "image_2d_5_1",        5,  1, 1, {{ 0,  0}, { 5,  1}}, {0.500f, 0x00} },
1419                 { "image_2d_17_1",      17,  1, 1, {{ 1,  0}, {15,  1}}, {0.789f, 0xfa} },
1420         };
1421         const deUint32 sampleCounts[] =
1422         {
1423                 2u, 4u, 8u, 16u, 32u, 64u
1424         };
1425         const float depthExpectedValue[][6] =
1426         {
1427                 // 2 samples    4                       8                       16                      32                      64
1428                 { 0.0f,                 0.0f,           0.0f,           0.0f,           0.0f,           0.0f },         // RESOLVE_MODE_NONE - expect clear value
1429                 { 0.04f,                0.04f,          0.04f,          0.04f,          0.04f,          0.04f },        // RESOLVE_MODE_SAMPLE_ZERO_BIT
1430                 { 0.03f,                0.135f,         0.135f,         0.135f,         0.135f,         0.135f },       // RESOLVE_MODE_AVERAGE_BIT
1431                 { 0.02f,                0.02f,          0.02f,          0.02f,          0.02f,          0.02f },        // RESOLVE_MODE_MIN_BIT
1432                 { 0.04f,                0.32f,          0.32f,          0.32f,          0.32f,          0.32f },        // RESOLVE_MODE_MAX_BIT
1433         };
1434         const deUint8 stencilExpectedValue[][6] =
1435         {
1436                 // 2 samples    4               8               16              32              64
1437                 { 0u,                   0u,             0u,             0u,             0u,             0u },   // RESOLVE_MODE_NONE - expect clear value
1438                 { 1u,                   1u,             1u,             1u,             1u,             1u },   // RESOLVE_MODE_SAMPLE_ZERO_BIT
1439                 { 0u,                   0u,             0u,             0u,             0u,             0u },   // RESOLVE_MODE_AVERAGE_BIT - not supported
1440                 { 1u,                   1u,             1u,             1u,             1u,             1u },   // RESOLVE_MODE_MIN_BIT
1441                 { 255u,                 255u,   255u,   255u,   255u,   255u }, // RESOLVE_MODE_MAX_BIT
1442         };
1443
1444         const DepthCompatibilityManager compatManager;
1445
1446         tcu::TestContext& testCtx(group->getTestContext());
1447
1448         // Misc tests.
1449         {
1450                 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", "Miscellaneous depth/stencil resolve tests"));
1451                 miscGroup->addChild(new PropertiesTestCase(testCtx, "properties", "Check reported depth/stencil resolve properties"));
1452                 group->addChild(miscGroup.release());
1453         }
1454
1455         // iterate over image data
1456         for      (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
1457         {
1458                 ImageTestData imageData = imagesTestData[imageDataNdx];
1459
1460                 // create test group for image data
1461                 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));
1462
1463                 // iterate over sampleCounts
1464                 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1465                 {
1466                         const deUint32          sampleCount     (sampleCounts[sampleCountNdx]);
1467                         const std::string       sampleName      ("samples_" + de::toString(sampleCount));
1468
1469                         // create test group for sample count
1470                         de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1471
1472                         // iterate over depth/stencil formats
1473                         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1474                         {
1475                                 const FormatData&                       formatData                                      = formats[formatNdx];
1476                                 VkFormat                                        format                                          = formatData.format;
1477                                 const char*                                     formatName                                      = formatData.name;
1478                                 const bool                                      hasDepth                                        = formatData.hasDepth;
1479                                 const bool                                      hasStencil                                      = formatData.hasStencil;
1480                                 VkImageAspectFlags                      aspectFlags                                     = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1481                                                                                                                                                   (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1482                                 const int                                       separateLayoutsLoopCount        = (hasDepth && hasStencil) ? 2 : 1;
1483
1484                                 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1485                                 {
1486                                         const bool                      useSeparateDepthStencilLayouts  = bool(separateDepthStencilLayouts);
1487                                         const std::string       groupName                                               = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1488
1489                                         // create test group for format
1490                                         de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1491
1492                                         // iterate over depth resolve modes
1493                                         for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
1494                                         {
1495                                                 // iterate over stencil resolve modes
1496                                                 for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
1497                                                 {
1498                                                         for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1499                                                         {
1500                                                                 // there is no average resolve mode for stencil - go to next iteration
1501                                                                 ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
1502                                                                 if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1503                                                                         continue;
1504
1505                                                                 // if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
1506                                                                 // depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
1507                                                                 ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
1508                                                                 if ((dResolve.flag == VK_RESOLVE_MODE_NONE) && (sResolve.flag == VK_RESOLVE_MODE_NONE))
1509                                                                         continue;
1510
1511                                                                 // If there is no depth, the depth resolve mode should be NONE, or
1512                                                                 // match the stencil resolve mode.
1513                                                                 if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE) &&
1514                                                                         (dResolve.flag != sResolve.flag))
1515                                                                         continue;
1516
1517                                                                 // If there is no stencil, the stencil resolve mode should be NONE, or
1518                                                                 // match the depth resolve mode.
1519                                                                 if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE) &&
1520                                                                         (dResolve.flag != sResolve.flag))
1521                                                                         continue;
1522
1523                                                                 const bool unusedResolve = (unusedIdx > 0);
1524
1525                                                                 std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
1526                                                                 if (unusedResolve)
1527                                                                         baseName += "_unused_resolve";
1528
1529                                                                 if (hasDepth)
1530                                                                 {
1531                                                                         std::string     name                    = baseName + "_testing_depth";
1532                                                                         const char*     testName                = name.c_str();
1533                                                                         float           expectedValue   = depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
1534
1535                                                                         const TestConfig testConfig =
1536                                                                         {
1537                                                                                 format,
1538                                                                                 imageData.width,
1539                                                                                 imageData.height,
1540                                                                                 1u,
1541                                                                                 1u,
1542                                                                                 0u,
1543                                                                                 imageData.renderArea,
1544                                                                                 aspectFlags,
1545                                                                                 sampleCount,
1546                                                                                 dResolve.flag,
1547                                                                                 sResolve.flag,
1548                                                                                 VB_DEPTH,
1549                                                                                 imageData.clearValue,
1550                                                                                 expectedValue,
1551                                                                                 0u,
1552                                                                                 useSeparateDepthStencilLayouts,
1553                                                                                 unusedResolve,
1554                                                                                 tcu::nothing<VkFormat>(),
1555                                                                                 false
1556                                                                         };
1557                                                                         formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1558
1559                                                                         if (sampleCountNdx == 0 && imageDataNdx == 0)
1560                                                                         {
1561                                                                                 const auto compatibleFormat = compatManager.getAlternativeFormat(format);
1562
1563                                                                                 if (compatibleFormat != VK_FORMAT_UNDEFINED)
1564                                                                                 {
1565                                                                                         std::string     compatibilityTestName                   = "compatibility_" + name;
1566                                                                                         TestConfig compatibilityTestConfig                      = testConfig;
1567                                                                                         compatibilityTestConfig.compatibleFormat        = tcu::just(compatibleFormat);
1568
1569                                                                                         formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig));
1570                                                                                 }
1571                                                                         }
1572                                                                 }
1573                                                                 if (hasStencil)
1574                                                                 {
1575                                                                         std::string     name                    = baseName + "_testing_stencil";
1576                                                                         const char*     testName                = name.c_str();
1577                                                                         deUint8         expectedValue   = stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
1578
1579                                                                         const TestConfig testConfig =
1580                                                                         {
1581                                                                                 format,
1582                                                                                 imageData.width,
1583                                                                                 imageData.height,
1584                                                                                 1u,
1585                                                                                 1u,
1586                                                                                 0u,
1587                                                                                 imageData.renderArea,
1588                                                                                 aspectFlags,
1589                                                                                 sampleCount,
1590                                                                                 dResolve.flag,
1591                                                                                 sResolve.flag,
1592                                                                                 VB_STENCIL,
1593                                                                                 imageData.clearValue,
1594                                                                                 0.0f,
1595                                                                                 expectedValue,
1596                                                                                 useSeparateDepthStencilLayouts,
1597                                                                                 unusedResolve,
1598                                                                                 tcu::nothing<VkFormat>(),
1599                                                                                 false
1600                                                                         };
1601                                                                         formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1602
1603                                                                         if (dResolve.flag == VK_RESOLVE_MODE_SAMPLE_ZERO_BIT)
1604                                                                         {
1605                                                                                 std::string samplemaskTestName = name + "_samplemask";
1606                                                                                 TestConfig samplemaskTestConfig = testConfig;
1607                                                                                 samplemaskTestConfig.sampleMask = true;
1608                                                                                 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, samplemaskTestName.c_str(), samplemaskTestName.c_str(), samplemaskTestConfig));
1609                                                                         }
1610
1611                                                                         // All formats with stencil and depth aspects have incompatible formats and sizes in the depth
1612                                                                         // aspect, so their only alternative is the VK_FORMAT_S8_UINT format. Finally, that stencil-only
1613                                                                         // format has no compatible formats that can be used.
1614                                                                         if (sampleCountNdx == 0 && imageDataNdx == 0 && hasDepth)
1615                                                                         {
1616                                                                                 std::string     compatibilityTestName                   = "compatibility_" + name;
1617                                                                                 TestConfig compatibilityTestConfig                      = testConfig;
1618                                                                                 compatibilityTestConfig.compatibleFormat        = tcu::just(VK_FORMAT_S8_UINT);
1619
1620                                                                                 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig));
1621                                                                         }
1622                                                                 }
1623                                                         }
1624                                                 }
1625                                         }
1626                                         sampleGroup->addChild(formatGroup.release());
1627                                 }
1628                         }
1629
1630                         imageGroup->addChild(sampleGroup.release());
1631                 }
1632
1633                 group->addChild(imageGroup.release());
1634         }
1635
1636         {
1637                 // layered texture tests are done for all stencil modes and depth modes - not all combinations
1638                 // Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer
1639                 // which starts at a layer other than zero. Both parts are tested together by rendering to layers
1640                 // 4-6 and resolving to layers 1-3.
1641                 ImageTestData layeredTextureTestData =
1642                 {
1643                         "image_2d_16_64_6", 16, 64, 6, {{ 10,  10}, {6, 54}}, {1.0f, 0x0}
1644                 };
1645
1646                 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));
1647
1648                 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1649                 {
1650                         const deUint32          sampleCount     (sampleCounts[sampleCountNdx]);
1651                         const std::string       sampleName      ("samples_" + de::toString(sampleCount));
1652
1653                         // create test group for sample count
1654                         de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1655
1656                         // iterate over depth/stencil formats
1657                         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1658                         {
1659                                 const FormatData&                       formatData                                      = formats[formatNdx];
1660                                 VkFormat                                        format                                          = formatData.format;
1661                                 const char*                                     formatName                                      = formatData.name;
1662                                 const bool                                      hasDepth                                        = formatData.hasDepth;
1663                                 const bool                                      hasStencil                                      = formatData.hasStencil;
1664                                 VkImageAspectFlags                      aspectFlags                                     = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1665                                                                                                                                                   (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1666                                 const int                                       separateLayoutsLoopCount        = (hasDepth && hasStencil) ? 2 : 1;
1667
1668                                 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1669                                 {
1670                                         const bool                      useSeparateDepthStencilLayouts  = bool(separateDepthStencilLayouts);
1671                                         const std::string       groupName                                               = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1672
1673                                         // create test group for format
1674                                         de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1675
1676                                         for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
1677                                         {
1678                                                 for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1679                                                 {
1680                                                         ResolveModeData& mode = resolveModes[resolveModeNdx];
1681
1682                                                         const bool                      unusedResolve   = (unusedIdx > 0);
1683                                                         const std::string       unusedSuffix    = (unusedResolve ? "_unused_resolve" : "");
1684
1685                                                         if (hasDepth)
1686                                                         {
1687                                                                 std::string     name                    = "depth_" + mode.name + unusedSuffix;
1688                                                                 const char*     testName                = name.c_str();
1689                                                                 float           expectedValue   = depthExpectedValue[resolveModeNdx][sampleCountNdx];
1690                                                                 const TestConfig testConfig =
1691                                                                 {
1692                                                                         format,
1693                                                                         layeredTextureTestData.width,
1694                                                                         layeredTextureTestData.height,
1695                                                                         layeredTextureTestData.imageLayers,
1696                                                                         3u,
1697                                                                         0u,
1698                                                                         layeredTextureTestData.renderArea,
1699                                                                         aspectFlags,
1700                                                                         sampleCount,
1701                                                                         mode.flag,
1702                                                                         VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1703                                                                         VB_DEPTH,
1704                                                                         layeredTextureTestData.clearValue,
1705                                                                         expectedValue,
1706                                                                         0u,
1707                                                                         useSeparateDepthStencilLayouts,
1708                                                                         unusedResolve,
1709                                                                         tcu::nothing<VkFormat>(),
1710                                                                         false
1711                                                                 };
1712                                                                 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1713                                                         }
1714
1715                                                         // there is no average resolve mode for stencil - go to next iteration
1716                                                         if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1717                                                                 continue;
1718
1719                                                         if (hasStencil)
1720                                                         {
1721                                                                 std::string     name                    = "stencil_" + mode.name + unusedSuffix;
1722                                                                 const char*     testName                = name.c_str();
1723                                                                 deUint8         expectedValue   = stencilExpectedValue[resolveModeNdx][sampleCountNdx];
1724                                                                 const TestConfig testConfig =
1725                                                                 {
1726                                                                         format,
1727                                                                         layeredTextureTestData.width,
1728                                                                         layeredTextureTestData.height,
1729                                                                         layeredTextureTestData.imageLayers,
1730                                                                         3u,
1731                                                                         0u,
1732                                                                         layeredTextureTestData.renderArea,
1733                                                                         aspectFlags,
1734                                                                         sampleCount,
1735                                                                         VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1736                                                                         mode.flag,
1737                                                                         VB_STENCIL,
1738                                                                         layeredTextureTestData.clearValue,
1739                                                                         0.0f,
1740                                                                         expectedValue,
1741                                                                         useSeparateDepthStencilLayouts,
1742                                                                         unusedResolve,
1743                                                                         tcu::nothing<VkFormat>(),
1744                                                                         false
1745                                                                 };
1746                                                                 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1747                                                         }
1748                                                 }
1749                                         }
1750                                         sampleGroup->addChild(formatGroup.release());
1751                                 }
1752                         }
1753                         imageGroup->addChild(sampleGroup.release());
1754                 }
1755
1756                 group->addChild(imageGroup.release());
1757         }
1758 }
1759
1760 } // anonymous
1761
1762 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
1763 {
1764         return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);
1765 }
1766
1767 } // vkt