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