1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 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 Vulkan Imageless Framebuffer Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktImagelessFramebufferTests.hpp"
25 #include "vktTestGroupUtil.hpp"
26 #include "vktTestCase.hpp"
27 
28 #include "deUniquePtr.hpp"
29 #include "deRandom.hpp"
30 
31 #include "tcuTextureUtil.hpp"
32 #include "tcuVectorUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuRGBA.hpp"
35 
36 #include "vkCmdUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "vkBuilderUtil.hpp"
43 
44 #include <iostream>
45 
46 namespace vkt
47 {
48 namespace imageless
49 {
50 
51 namespace
52 {
53 using namespace vk;
54 using de::MovePtr;
55 using de::SharedPtr;
56 using de::UniquePtr;
57 
58 typedef SharedPtr<Unique<VkPipeline>> SharedPtrVkPipeline;
59 
60 enum TestType
61 {
62     TEST_TYPE_COLOR = 0,
63     TEST_TYPE_DEPTH_STENCIL,
64     TEST_TYPE_COLOR_RESOLVE,
65     TEST_TYPE_DEPTH_STENCIL_RESOLVE,
66     TEST_TYPE_MULTISUBPASS,
67     TEST_TYPE_DIFFERENT_ATTACHMENTS,
68     TEST_TYPE_LAST
69 };
70 
71 enum AspectFlagBits
72 {
73     ASPECT_NONE          = 0,
74     ASPECT_COLOR         = (1 << 0),
75     ASPECT_DEPTH         = (1 << 1),
76     ASPECT_STENCIL       = (1 << 2),
77     ASPECT_DEPTH_STENCIL = ASPECT_DEPTH | ASPECT_STENCIL,
78 };
79 typedef uint32_t AspectFlags;
80 
81 const uint32_t NO_SAMPLE  = static_cast<uint32_t>(-1);
82 const uint32_t NO_SUBPASS = static_cast<uint32_t>(-1);
83 
84 struct TestParameters
85 {
86     TestType testType;
87     VkFormat colorFormat;
88     VkFormat dsFormat;
89 };
90 
91 template <typename T>
makeSharedPtr(Move<T> move)92 inline SharedPtr<Unique<T>> makeSharedPtr(Move<T> move)
93 {
94     return SharedPtr<Unique<T>>(new Unique<T>(move));
95 }
96 
sampleCountBitFromSampleCount(uint32_t count)97 VkSampleCountFlagBits sampleCountBitFromSampleCount(uint32_t count)
98 {
99     switch (count)
100     {
101     case 1:
102         return VK_SAMPLE_COUNT_1_BIT;
103     case 2:
104         return VK_SAMPLE_COUNT_2_BIT;
105     case 4:
106         return VK_SAMPLE_COUNT_4_BIT;
107     case 8:
108         return VK_SAMPLE_COUNT_8_BIT;
109     case 16:
110         return VK_SAMPLE_COUNT_16_BIT;
111     case 32:
112         return VK_SAMPLE_COUNT_32_BIT;
113     case 64:
114         return VK_SAMPLE_COUNT_64_BIT;
115 
116     default:
117         DE_FATAL("Invalid sample count");
118         return (VkSampleCountFlagBits)0x0;
119     }
120 }
121 
convertAttachmentReference(const VkAttachmentReference & attachmentReference,const VkImageAspectFlags aspectMask)122 VkAttachmentReference2 convertAttachmentReference(const VkAttachmentReference &attachmentReference,
123                                                   const VkImageAspectFlags aspectMask)
124 {
125     const VkAttachmentReference2 attachmentReference2 = {
126         VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, //  VkStructureType sType;
127         DE_NULL,                                  //  const void* pNext;
128         attachmentReference.attachment,           //  uint32_t attachment;
129         attachmentReference.layout,               //  VkImageLayout layout;
130         aspectMask                                //  VkImageAspectFlags aspectMask;
131     };
132 
133     return attachmentReference2;
134 }
135 
convertAttachmentDescriptions(const std::vector<VkAttachmentDescription> & attachmentDescriptions)136 std::vector<VkAttachmentDescription2> convertAttachmentDescriptions(
137     const std::vector<VkAttachmentDescription> &attachmentDescriptions)
138 {
139     std::vector<VkAttachmentDescription2> attachmentDescriptions2;
140 
141     attachmentDescriptions2.reserve(attachmentDescriptions.size());
142 
143     for (size_t adNdx = 0; adNdx < attachmentDescriptions.size(); ++adNdx)
144     {
145         const VkAttachmentDescription &attachmentDescription  = attachmentDescriptions[adNdx];
146         const VkAttachmentDescription2 attachmentDescription2 = {
147             VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, //  VkStructureType sType;
148             DE_NULL,                                    //  const void* pNext;
149             attachmentDescription.flags,                //  VkAttachmentDescriptionFlags flags;
150             attachmentDescription.format,               //  VkFormat format;
151             attachmentDescription.samples,              //  VkSampleCountFlagBits samples;
152             attachmentDescription.loadOp,               //  VkAttachmentLoadOp loadOp;
153             attachmentDescription.storeOp,              //  VkAttachmentStoreOp storeOp;
154             attachmentDescription.stencilLoadOp,        //  VkAttachmentLoadOp stencilLoadOp;
155             attachmentDescription.stencilStoreOp,       //  VkAttachmentStoreOp stencilStoreOp;
156             attachmentDescription.initialLayout,        //  VkImageLayout initialLayout;
157             attachmentDescription.finalLayout,          //  VkImageLayout finalLayout;
158         };
159 
160         attachmentDescriptions2.push_back(attachmentDescription2);
161     }
162 
163     return attachmentDescriptions2;
164 }
165 
makeGraphicsPipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,const VkShaderModule vertexModule,const VkShaderModule fragmendModule,const VkExtent2D renderSize,const AspectFlags depthStencilAspects=ASPECT_NONE,const VkSampleCountFlagBits sampleCountBits=VK_SAMPLE_COUNT_1_BIT,const uint32_t subpass=0)166 Move<VkPipeline> makeGraphicsPipeline(const DeviceInterface &vk, const VkDevice device,
167                                       const VkPipelineLayout pipelineLayout, const VkRenderPass renderPass,
168                                       const VkShaderModule vertexModule, const VkShaderModule fragmendModule,
169                                       const VkExtent2D renderSize, const AspectFlags depthStencilAspects = ASPECT_NONE,
170                                       const VkSampleCountFlagBits sampleCountBits = VK_SAMPLE_COUNT_1_BIT,
171                                       const uint32_t subpass                      = 0)
172 {
173     const bool useDepth   = (depthStencilAspects & ASPECT_DEPTH) != 0;
174     const bool useStencil = (depthStencilAspects & ASPECT_STENCIL) != 0;
175     const std::vector<VkViewport> viewports(1, makeViewport(renderSize));
176     const std::vector<VkRect2D> scissors(1, makeRect2D(renderSize));
177     const VkStencilOpState stencilOpState = {
178         VK_STENCIL_OP_KEEP,                //  VkStencilOp failOp;
179         VK_STENCIL_OP_INCREMENT_AND_CLAMP, //  VkStencilOp passOp;
180         VK_STENCIL_OP_KEEP,                //  VkStencilOp depthFailOp;
181         VK_COMPARE_OP_ALWAYS,              //  VkCompareOp compareOp;
182         ~0u,                               //  uint32_t compareMask;
183         ~0u,                               //  uint32_t writeMask;
184         0u                                 //  uint32_t reference;
185     };
186     const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = {
187         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, //  VkStructureType sType;
188         DE_NULL,                                                    //  const void* pNext;
189         (VkPipelineDepthStencilStateCreateFlags)0,                  //  VkPipelineDepthStencilStateCreateFlags flags;
190         useDepth ? VK_TRUE : VK_FALSE,                              //  VkBool32 depthTestEnable;
191         useDepth ? VK_TRUE : VK_FALSE,                              //  VkBool32 depthWriteEnable;
192         VK_COMPARE_OP_LESS,                                         //  VkCompareOp depthCompareOp;
193         VK_FALSE,                                                   //  VkBool32 depthBoundsTestEnable;
194         useStencil ? VK_TRUE : VK_FALSE,                            //  VkBool32 stencilTestEnable;
195         stencilOpState,                                             //  VkStencilOpState front;
196         stencilOpState,                                             //  VkStencilOpState back;
197         0.0f,                                                       //  float minDepthBounds;
198         1.0f                                                        //  float maxDepthBounds;
199     };
200     const VkPipelineMultisampleStateCreateInfo multisampleState = {
201         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, //  VkStructureType sType;
202         DE_NULL,                                                  //  const void* pNext;
203         (VkPipelineMultisampleStateCreateFlags)0u,                //  VkPipelineMultisampleStateCreateFlags flags;
204         sampleCountBits,                                          //  VkSampleCountFlagBits rasterizationSamples;
205         VK_FALSE,                                                 //  VkBool32 sampleShadingEnable;
206         0.0f,                                                     //  float minSampleShading;
207         DE_NULL,                                                  //  const VkSampleMask* pSampleMask;
208         VK_FALSE,                                                 //  VkBool32 alphaToCoverageEnable;
209         VK_FALSE,                                                 //  VkBool32 alphaToOneEnable;
210     };
211 
212     return makeGraphicsPipeline(
213         vk,             //  const DeviceInterface&                            vk
214         device,         //  const VkDevice                                    device
215         pipelineLayout, //  const VkPipelineLayout                            pipelineLayout
216         vertexModule,   //  const VkShaderModule                            vertexShaderModule
217         DE_NULL,        //  const VkShaderModule                            tessellationControlModule
218         DE_NULL,        //  const VkShaderModule                            tessellationEvalModule
219         DE_NULL,        //  const VkShaderModule                            geometryShaderModule
220         fragmendModule, //  const VkShaderModule                            fragmentShaderModule
221         renderPass,     //  const VkRenderPass                                renderPass
222         viewports,      //  const std::vector<VkViewport>&                    viewports
223         scissors,       //  const std::vector<VkRect2D>&                    scissors
224         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, //  const VkPrimitiveTopology                        topology
225         subpass,                             //  const uint32_t                                    subpass
226         0u,                                  //  const uint32_t                                    patchControlPoints
227         DE_NULL,           //  const VkPipelineVertexInputStateCreateInfo*        vertexInputStateCreateInfo
228         DE_NULL,           //  const VkPipelineRasterizationStateCreateInfo*    rasterizationStateCreateInfo
229         &multisampleState, //  const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
230         &pipelineDepthStencilStateInfo); //  const VkPipelineDepthStencilStateCreateInfo*    depthStencilStateCreateInfo
231 }
232 
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const VkFormat depthStencilFormat,const VkSampleCountFlagBits colorSamples,const VkSampleCountFlagBits depthStencilSamples=VK_SAMPLE_COUNT_1_BIT,const VkAttachmentLoadOp loadOperation=VK_ATTACHMENT_LOAD_OP_CLEAR,const VkImageLayout finalLayoutColor=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,const VkImageLayout finalLayoutDepthStencil=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,const VkImageLayout subpassLayoutColor=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,const VkImageLayout subpassLayoutDepthStencil=VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,const VkAllocationCallbacks * const allocationCallbacks=DE_NULL)233 Move<VkRenderPass> makeRenderPass(
234     const DeviceInterface &vk, const VkDevice device, const VkFormat colorFormat, const VkFormat depthStencilFormat,
235     const VkSampleCountFlagBits colorSamples, const VkSampleCountFlagBits depthStencilSamples = VK_SAMPLE_COUNT_1_BIT,
236     const VkAttachmentLoadOp loadOperation                 = VK_ATTACHMENT_LOAD_OP_CLEAR,
237     const VkImageLayout finalLayoutColor                   = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
238     const VkImageLayout finalLayoutDepthStencil            = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
239     const VkImageLayout subpassLayoutColor                 = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
240     const VkImageLayout subpassLayoutDepthStencil          = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
241     const VkAllocationCallbacks *const allocationCallbacks = DE_NULL)
242 {
243     const bool hasColor                           = colorFormat != VK_FORMAT_UNDEFINED;
244     const bool hasDepthStencil                    = depthStencilFormat != VK_FORMAT_UNDEFINED;
245     const bool hasColorResolve                    = hasColor && (colorSamples != VK_SAMPLE_COUNT_1_BIT);
246     const bool hasDepthStencilResolve             = hasDepthStencil && (depthStencilSamples != VK_SAMPLE_COUNT_1_BIT);
247     const VkImageLayout initialLayoutColor        = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ?
248                                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
249                                                         VK_IMAGE_LAYOUT_UNDEFINED;
250     const VkImageLayout initialLayoutDepthStencil = loadOperation == VK_ATTACHMENT_LOAD_OP_LOAD ?
251                                                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
252                                                         VK_IMAGE_LAYOUT_UNDEFINED;
253     const VkAttachmentDescription colorAttachmentDescription = {
254         (VkAttachmentDescriptionFlags)0,  //  VkAttachmentDescriptionFlags flags;
255         colorFormat,                      //  VkFormat format;
256         colorSamples,                     //  VkSampleCountFlagBits samples;
257         loadOperation,                    //  VkAttachmentLoadOp loadOp;
258         VK_ATTACHMENT_STORE_OP_STORE,     //  VkAttachmentStoreOp storeOp;
259         VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp stencilLoadOp;
260         VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp;
261         initialLayoutColor,               //  VkImageLayout initialLayout;
262         finalLayoutColor                  //  VkImageLayout finalLayout;
263     };
264     const VkAttachmentDescription depthStencilAttachmentDescription = {
265         (VkAttachmentDescriptionFlags)0, //  VkAttachmentDescriptionFlags flags;
266         depthStencilFormat,              //  VkFormat format;
267         depthStencilSamples,             //  VkSampleCountFlagBits samples;
268         loadOperation,                   //  VkAttachmentLoadOp loadOp;
269         VK_ATTACHMENT_STORE_OP_STORE,    //  VkAttachmentStoreOp storeOp;
270         loadOperation,                   //  VkAttachmentLoadOp stencilLoadOp;
271         VK_ATTACHMENT_STORE_OP_STORE,    //  VkAttachmentStoreOp stencilStoreOp;
272         initialLayoutDepthStencil,       //  VkImageLayout initialLayout;
273         finalLayoutDepthStencil          //  VkImageLayout finalLayout;
274     };
275     const VkAttachmentDescription colorResolveAttachmentDescription = {
276         (VkAttachmentDescriptionFlags)0,  //  VkAttachmentDescriptionFlags flags;
277         colorFormat,                      //  VkFormat format;
278         VK_SAMPLE_COUNT_1_BIT,            //  VkSampleCountFlagBits samples;
279         VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp loadOp;
280         VK_ATTACHMENT_STORE_OP_STORE,     //  VkAttachmentStoreOp storeOp;
281         VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp stencilLoadOp;
282         VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp;
283         initialLayoutColor,               //  VkImageLayout initialLayout;
284         finalLayoutColor                  //  VkImageLayout finalLayout;
285     };
286     const VkAttachmentDescription depthStencilResolveAttachmentDescription = {
287         (VkAttachmentDescriptionFlags)0, //  VkAttachmentDescriptionFlags flags;
288         depthStencilFormat,              //  VkFormat format;
289         VK_SAMPLE_COUNT_1_BIT,           //  VkSampleCountFlagBits samples;
290         VK_ATTACHMENT_LOAD_OP_DONT_CARE, //  VkAttachmentLoadOp loadOp;
291         VK_ATTACHMENT_STORE_OP_STORE,    //  VkAttachmentStoreOp storeOp;
292         VK_ATTACHMENT_LOAD_OP_DONT_CARE, //  VkAttachmentLoadOp stencilLoadOp;
293         VK_ATTACHMENT_STORE_OP_STORE,    //  VkAttachmentStoreOp stencilStoreOp;
294         initialLayoutDepthStencil,       //  VkImageLayout initialLayout;
295         finalLayoutDepthStencil          //  VkImageLayout finalLayout;
296     };
297     std::vector<VkAttachmentDescription> attachmentDescriptions;
298 
299     if (hasColor)
300         attachmentDescriptions.push_back(colorAttachmentDescription);
301     if (hasDepthStencil)
302         attachmentDescriptions.push_back(depthStencilAttachmentDescription);
303     if (hasColorResolve)
304         attachmentDescriptions.push_back(colorResolveAttachmentDescription);
305     if (hasDepthStencilResolve)
306         attachmentDescriptions.push_back(depthStencilResolveAttachmentDescription);
307 
308     uint32_t attachmentCounter                     = 0;
309     const VkAttachmentReference colorAttachmentRef = {
310         hasColor ? attachmentCounter++ : 0u, //  uint32_t attachment;
311         subpassLayoutColor                   //  VkImageLayout layout;
312     };
313     const VkAttachmentReference depthStencilAttachmentRef = {
314         hasDepthStencil ? attachmentCounter++ : 0u, //  uint32_t attachment;
315         subpassLayoutDepthStencil                   //  VkImageLayout layout;
316     };
317     const VkAttachmentReference colorResolveAttachmentRef = {
318         hasColorResolve ? attachmentCounter++ : 0u, //  uint32_t attachment;
319         subpassLayoutColor                          //  VkImageLayout layout;
320     };
321 
322     if (hasDepthStencilResolve)
323     {
324         const VkImageAspectFlags colorAspectMask        = VK_IMAGE_ASPECT_COLOR_BIT;
325         const VkImageAspectFlags depthStencilAspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
326         const VkAttachmentReference2 colorAttachmentRef2 =
327             convertAttachmentReference(colorAttachmentRef, colorAspectMask);
328         const VkAttachmentReference2 depthStencilAttachmentRef2 =
329             convertAttachmentReference(depthStencilAttachmentRef, depthStencilAspectMask);
330         const VkAttachmentReference2 colorResolveAttachmentRef2 =
331             convertAttachmentReference(colorResolveAttachmentRef, colorAspectMask);
332         const VkAttachmentReference2 depthStencilResolveAttachmentRef2 = {
333             VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,          //  VkStructureType sType;
334             DE_NULL,                                           //  const void* pNext;
335             hasDepthStencilResolve ? attachmentCounter++ : 0u, //  uint32_t attachment;
336             subpassLayoutDepthStencil,                         //  VkImageLayout layout;
337             depthStencilAspectMask                             //  VkImageAspectFlags aspectMask;
338         };
339         const VkSubpassDescriptionDepthStencilResolve subpassDescriptionDepthStencilResolve = {
340             VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE, //  VkStructureType sType;
341             DE_NULL,                                                     //  const void* pNext;
342             VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,                             //  VkResolveModeFlagBitsKHR depthResolveMode;
343             VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,   //  VkResolveModeFlagBitsKHR stencilResolveMode;
344             &depthStencilResolveAttachmentRef2 //  const VkAttachmentReference2KHR* pDepthStencilResolveAttachment;
345         };
346         const VkSubpassDescription2 subpassDescription2 = {
347             VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,   //  VkStructureType sType;
348             &subpassDescriptionDepthStencilResolve,    //  const void* pNext;
349             (VkSubpassDescriptionFlags)0,              //  VkSubpassDescriptionFlags flags;
350             VK_PIPELINE_BIND_POINT_GRAPHICS,           //  VkPipelineBindPoint pipelineBindPoint;
351             0u,                                        //  uint32_t viewMask;
352             0u,                                        //  uint32_t inputAttachmentCount;
353             DE_NULL,                                   //  const VkAttachmentReference2* pInputAttachments;
354             hasColor ? 1u : 0u,                        //  uint32_t colorAttachmentCount;
355             hasColor ? &colorAttachmentRef2 : DE_NULL, //  const VkAttachmentReference2* pColorAttachments;
356             hasColorResolve ? &colorResolveAttachmentRef2 :
357                               DE_NULL, //  const VkAttachmentReference2* pResolveAttachments;
358             hasDepthStencil ? &depthStencilAttachmentRef2 :
359                               DE_NULL, //  const VkAttachmentReference2* pDepthStencilAttachment;
360             0u,                        //  uint32_t preserveAttachmentCount;
361             DE_NULL                    //  const uint32_t* pPreserveAttachments;
362         };
363         const std::vector<VkAttachmentDescription2> attachmentDescriptions2 =
364             convertAttachmentDescriptions(attachmentDescriptions);
365         const VkRenderPassCreateInfo2 renderPassInfo = {
366             VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, //  VkStructureType sType;
367             DE_NULL,                                     //  const void* pNext;
368             (VkRenderPassCreateFlags)0,                  //  VkRenderPassCreateFlags flags;
369             (uint32_t)attachmentDescriptions2.size(),    //  uint32_t attachmentCount;
370             &attachmentDescriptions2[0],                 //  const VkAttachmentDescription2* pAttachments;
371             1u,                                          //  uint32_t subpassCount;
372             &subpassDescription2,                        //  const VkSubpassDescription2* pSubpasses;
373             0u,                                          //  uint32_t dependencyCount;
374             DE_NULL,                                     //  const VkSubpassDependency2* pDependencies;
375             0u,                                          //  uint32_t correlatedViewMaskCount;
376             DE_NULL                                      //  const uint32_t* pCorrelatedViewMasks;
377         };
378 
379         return createRenderPass2(vk, device, &renderPassInfo, allocationCallbacks);
380     }
381     else
382     {
383         const VkSubpassDescription subpassDescription = {
384             (VkSubpassDescriptionFlags)0,             //  VkSubpassDescriptionFlags flags;
385             VK_PIPELINE_BIND_POINT_GRAPHICS,          //  VkPipelineBindPoint pipelineBindPoint;
386             0u,                                       //  uint32_t inputAttachmentCount;
387             DE_NULL,                                  //  const VkAttachmentReference* pInputAttachments;
388             hasColor ? 1u : 0u,                       //  uint32_t colorAttachmentCount;
389             hasColor ? &colorAttachmentRef : DE_NULL, //  const VkAttachmentReference* pColorAttachments;
390             hasColorResolve ? &colorResolveAttachmentRef :
391                               DE_NULL, //  const VkAttachmentReference* pResolveAttachments;
392             hasDepthStencil ? &depthStencilAttachmentRef :
393                               DE_NULL, //  const VkAttachmentReference* pDepthStencilAttachment;
394             0u,                        //  uint32_t preserveAttachmentCount;
395             DE_NULL                    //  const uint32_t* pPreserveAttachments;
396         };
397         const VkRenderPassCreateInfo renderPassInfo = {
398             VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, //  VkStructureType sType;
399             DE_NULL,                                   //  const void* pNext;
400             (VkRenderPassCreateFlags)0,                //  VkRenderPassCreateFlags flags;
401             (uint32_t)attachmentDescriptions.size(),   //  uint32_t attachmentCount;
402             &attachmentDescriptions[0],                //  const VkAttachmentDescription* pAttachments;
403             1u,                                        //  uint32_t subpassCount;
404             &subpassDescription,                       //  const VkSubpassDescription* pSubpasses;
405             0u,                                        //  uint32_t dependencyCount;
406             DE_NULL                                    //  const VkSubpassDependency* pDependencies;
407         };
408 
409         return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
410     }
411 }
412 
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const VkAllocationCallbacks * const allocationCallbacks)413 Move<VkRenderPass> makeRenderPass(const DeviceInterface &vk, const VkDevice device, const VkFormat colorFormat,
414                                   const VkAllocationCallbacks *const allocationCallbacks)
415 {
416     const VkAttachmentDescription attachmentDescriptions[] = {
417         {
418             (VkAttachmentDescriptionFlags)0,  //  VkAttachmentDescriptionFlags flags;
419             colorFormat,                      //  VkFormat format;
420             VK_SAMPLE_COUNT_1_BIT,            //  VkSampleCountFlagBits samples;
421             VK_ATTACHMENT_LOAD_OP_CLEAR,      //  VkAttachmentLoadOp loadOp;
422             VK_ATTACHMENT_STORE_OP_STORE,     //  VkAttachmentStoreOp storeOp;
423             VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp stencilLoadOp;
424             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp;
425             VK_IMAGE_LAYOUT_UNDEFINED,        //  VkImageLayout initialLayout;
426             VK_IMAGE_LAYOUT_GENERAL           //  VkImageLayout finalLayout;
427         },
428         {
429             (VkAttachmentDescriptionFlags)0,  //  VkAttachmentDescriptionFlags flags;
430             colorFormat,                      //  VkFormat format;
431             VK_SAMPLE_COUNT_1_BIT,            //  VkSampleCountFlagBits samples;
432             VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp loadOp;
433             VK_ATTACHMENT_STORE_OP_STORE,     //  VkAttachmentStoreOp storeOp;
434             VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp stencilLoadOp;
435             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp;
436             VK_IMAGE_LAYOUT_UNDEFINED,        //  VkImageLayout initialLayout;
437             VK_IMAGE_LAYOUT_GENERAL           //  VkImageLayout finalLayout;
438         },
439     };
440     const VkAttachmentReference colorAttachmentRef0 = {
441         0u,                     //  uint32_t attachment;
442         VK_IMAGE_LAYOUT_GENERAL //  VkImageLayout layout;
443     };
444     const uint32_t preserveAttachment               = 1u;
445     const VkAttachmentReference inputAttachmentRef1 = {
446         0u,                     //  uint32_t attachment;
447         VK_IMAGE_LAYOUT_GENERAL //  VkImageLayout layout;
448     };
449     const VkAttachmentReference colorAttachmentRef1 = {
450         1u,                     //  uint32_t attachment;
451         VK_IMAGE_LAYOUT_GENERAL //  VkImageLayout layout;
452     };
453     const VkSubpassDescription subpassDescriptions[] = {
454         {
455             (VkSubpassDescriptionFlags)0,    //  VkSubpassDescriptionFlags flags;
456             VK_PIPELINE_BIND_POINT_GRAPHICS, //  VkPipelineBindPoint pipelineBindPoint;
457             0u,                              //  uint32_t inputAttachmentCount;
458             DE_NULL,                         //  const VkAttachmentReference* pInputAttachments;
459             1u,                              //  uint32_t colorAttachmentCount;
460             &colorAttachmentRef0,            //  const VkAttachmentReference* pColorAttachments;
461             DE_NULL,                         //  const VkAttachmentReference* pResolveAttachments;
462             DE_NULL,                         //  const VkAttachmentReference* pDepthStencilAttachment;
463             1u,                              //  uint32_t preserveAttachmentCount;
464             &preserveAttachment              //  const uint32_t* pPreserveAttachments;
465         },
466         {
467             (VkSubpassDescriptionFlags)0,    //  VkSubpassDescriptionFlags flags;
468             VK_PIPELINE_BIND_POINT_GRAPHICS, //  VkPipelineBindPoint pipelineBindPoint;
469             1u,                              //  uint32_t inputAttachmentCount;
470             &inputAttachmentRef1,            //  const VkAttachmentReference* pInputAttachments;
471             1u,                              //  uint32_t colorAttachmentCount;
472             &colorAttachmentRef1,            //  const VkAttachmentReference* pColorAttachments;
473             DE_NULL,                         //  const VkAttachmentReference* pResolveAttachments;
474             DE_NULL,                         //  const VkAttachmentReference* pDepthStencilAttachment;
475             0u,                              //  uint32_t preserveAttachmentCount;
476             DE_NULL                          //  const uint32_t* pPreserveAttachments;
477         },
478     };
479     const VkSubpassDependency subpassDependency = {
480         0,                                             //  uint32_t srcSubpass;
481         1u,                                            //  uint32_t dstSubpass;
482         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //  VkPipelineStageFlags srcStageMask;
483         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,         //  VkPipelineStageFlags dstStageMask;
484         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          //  VkAccessFlags srcAccessMask;
485         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,           //  VkAccessFlags dstAccessMask;
486         VK_DEPENDENCY_VIEW_LOCAL_BIT,                  //  VkDependencyFlags dependencyFlags;
487     };
488     const VkRenderPassCreateInfo renderPassInfo = {
489         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,  //  VkStructureType sType;
490         DE_NULL,                                    //  const void* pNext;
491         (VkRenderPassCreateFlags)0,                 //  VkRenderPassCreateFlags flags;
492         DE_LENGTH_OF_ARRAY(attachmentDescriptions), //  uint32_t attachmentCount;
493         &attachmentDescriptions[0],                 //  const VkAttachmentDescription* pAttachments;
494         DE_LENGTH_OF_ARRAY(subpassDescriptions),    //  uint32_t subpassCount;
495         &subpassDescriptions[0],                    //  const VkSubpassDescription* pSubpasses;
496         1u,                                         //  uint32_t dependencyCount;
497         &subpassDependency                          //  const VkSubpassDependency* pDependencies;
498     };
499 
500     return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
501 }
502 
makeSingleAttachmentRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const VkAllocationCallbacks * const allocationCallbacks)503 Move<VkRenderPass> makeSingleAttachmentRenderPass(const DeviceInterface &vk, const VkDevice device,
504                                                   const VkFormat colorFormat,
505                                                   const VkAllocationCallbacks *const allocationCallbacks)
506 {
507     const VkAttachmentDescription attachmentDescriptions[] = {
508         {
509             (VkAttachmentDescriptionFlags)0,  //  VkAttachmentDescriptionFlags flags;
510             colorFormat,                      //  VkFormat format;
511             VK_SAMPLE_COUNT_1_BIT,            //  VkSampleCountFlagBits samples;
512             VK_ATTACHMENT_LOAD_OP_CLEAR,      //  VkAttachmentLoadOp loadOp;
513             VK_ATTACHMENT_STORE_OP_STORE,     //  VkAttachmentStoreOp storeOp;
514             VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp stencilLoadOp;
515             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp;
516             VK_IMAGE_LAYOUT_UNDEFINED,        //  VkImageLayout initialLayout;
517             VK_IMAGE_LAYOUT_GENERAL           //  VkImageLayout finalLayout;
518         },
519     };
520     const VkAttachmentReference colorAttachmentRef0 = {
521         0u,                     //  uint32_t attachment;
522         VK_IMAGE_LAYOUT_GENERAL //  VkImageLayout layout;
523     };
524     const VkSubpassDescription subpassDescriptions[] = {{
525         (VkSubpassDescriptionFlags)0,    //  VkSubpassDescriptionFlags flags;
526         VK_PIPELINE_BIND_POINT_GRAPHICS, //  VkPipelineBindPoint pipelineBindPoint;
527         0u,                              //  uint32_t inputAttachmentCount;
528         DE_NULL,                         //  const VkAttachmentReference* pInputAttachments;
529         1u,                              //  uint32_t colorAttachmentCount;
530         &colorAttachmentRef0,            //  const VkAttachmentReference* pColorAttachments;
531         DE_NULL,                         //  const VkAttachmentReference* pResolveAttachments;
532         DE_NULL,                         //  const VkAttachmentReference* pDepthStencilAttachment;
533         0u,                              //  uint32_t preserveAttachmentCount;
534         DE_NULL                          //  const uint32_t* pPreserveAttachments;
535     }};
536     const VkRenderPassCreateInfo renderPassInfo      = {
537         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,  //  VkStructureType sType;
538         DE_NULL,                                    //  const void* pNext;
539         (VkRenderPassCreateFlags)0,                 //  VkRenderPassCreateFlags flags;
540         DE_LENGTH_OF_ARRAY(attachmentDescriptions), //  uint32_t attachmentCount;
541         &attachmentDescriptions[0],                 //  const VkAttachmentDescription* pAttachments;
542         DE_LENGTH_OF_ARRAY(subpassDescriptions),    //  uint32_t subpassCount;
543         &subpassDescriptions[0],                    //  const VkSubpassDescription* pSubpasses;
544         0u,                                         //  uint32_t dependencyCount;
545         DE_NULL                                     //  const VkSubpassDependency* pDependencies;
546     };
547 
548     return createRenderPass(vk, device, &renderPassInfo, allocationCallbacks);
549 }
550 
makeImageCreateInfo(const VkFormat format,const VkExtent2D size,const VkImageUsageFlags usage,VkSampleCountFlagBits samples=VK_SAMPLE_COUNT_1_BIT)551 VkImageCreateInfo makeImageCreateInfo(const VkFormat format, const VkExtent2D size, const VkImageUsageFlags usage,
552                                       VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT)
553 {
554     const VkExtent3D extent             = {size.width, size.height, 1u};
555     const VkImageCreateInfo imageParams = {
556         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
557         DE_NULL,                             // const void* pNext;
558         0u,                                  // VkImageCreateFlags flags;
559         VK_IMAGE_TYPE_2D,                    // VkImageType imageType;
560         format,                              // VkFormat format;
561         extent,                              // VkExtent3D extent;
562         1u,                                  // uint32_t mipLevels;
563         1u,                                  // uint32_t arrayLayers;
564         samples,                             // VkSampleCountFlagBits samples;
565         VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling tiling;
566         usage,                               // VkImageUsageFlags usage;
567         VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode sharingMode;
568         0u,                                  // uint32_t queueFamilyIndexCount;
569         DE_NULL,                             // const uint32_t* pQueueFamilyIndices;
570         VK_IMAGE_LAYOUT_UNDEFINED,           // VkImageLayout initialLayout;
571     };
572     return imageParams;
573 }
574 
makeFramebufferAttachmentImageInfos(const VkExtent2D & renderSize,const VkFormat * colorFormat,const VkImageUsageFlags colorUsage,const VkFormat * dsFormat,const VkImageUsageFlags dsUsage,const AspectFlags resolveAspects,const uint32_t inputAttachmentCount)575 std::vector<VkFramebufferAttachmentImageInfo> makeFramebufferAttachmentImageInfos(
576     const VkExtent2D &renderSize, const VkFormat *colorFormat, const VkImageUsageFlags colorUsage,
577     const VkFormat *dsFormat, const VkImageUsageFlags dsUsage, const AspectFlags resolveAspects,
578     const uint32_t inputAttachmentCount)
579 {
580     const bool colorResolve        = (resolveAspects & ASPECT_COLOR) != 0;
581     const bool depthStencilResolve = (resolveAspects & ASPECT_DEPTH_STENCIL) != 0;
582     std::vector<VkFramebufferAttachmentImageInfo> framebufferAttachmentImageInfos;
583 
584     DE_ASSERT(colorFormat != DE_NULL);
585     DE_ASSERT(dsFormat != DE_NULL);
586 
587     if (*colorFormat != VK_FORMAT_UNDEFINED)
588     {
589         const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo = {
590             VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, //  VkStructureType sType;
591             DE_NULL,                                             //  const void* pNext;
592             (VkImageCreateFlags)0u,                              //  VkImageCreateFlags flags;
593             colorUsage,                                          //  VkImageUsageFlags usage;
594             renderSize.width,                                    //  uint32_t width;
595             renderSize.height,                                   //  uint32_t height;
596             1u,                                                  //  uint32_t layerCount;
597             1u,                                                  //  uint32_t viewFormatCount;
598             colorFormat                                          //  const VkFormat* pViewFormats;
599         };
600 
601         framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
602     }
603 
604     if (*dsFormat != VK_FORMAT_UNDEFINED)
605     {
606         const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo = {
607             VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, //  VkStructureType sType;
608             DE_NULL,                                             //  const void* pNext;
609             (VkImageCreateFlags)0u,                              //  VkImageCreateFlags flags;
610             dsUsage,                                             //  VkImageUsageFlags usage;
611             renderSize.width,                                    //  uint32_t width;
612             renderSize.height,                                   //  uint32_t height;
613             1u,                                                  //  uint32_t layerCount;
614             1u,                                                  //  uint32_t viewFormatCount;
615             dsFormat                                             //  const VkFormat* pViewFormats;
616         };
617 
618         framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
619     }
620 
621     if (colorResolve)
622     {
623         const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo = {
624             VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, //  VkStructureType sType;
625             DE_NULL,                                             //  const void* pNext;
626             (VkImageCreateFlags)0u,                              //  VkImageCreateFlags flags;
627             colorUsage,                                          //  VkImageUsageFlags usage;
628             renderSize.width,                                    //  uint32_t width;
629             renderSize.height,                                   //  uint32_t height;
630             1u,                                                  //  uint32_t layerCount;
631             1u,                                                  //  uint32_t viewFormatCount;
632             colorFormat                                          //  const VkFormat* pViewFormats;
633         };
634 
635         DE_ASSERT(*colorFormat != VK_FORMAT_UNDEFINED);
636 
637         framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
638     }
639 
640     if (depthStencilResolve)
641     {
642         const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo = {
643             VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, //  VkStructureType sType;
644             DE_NULL,                                             //  const void* pNext;
645             (VkImageCreateFlags)0u,                              //  VkImageCreateFlags flags;
646             dsUsage,                                             //  VkImageUsageFlags usage;
647             renderSize.width,                                    //  uint32_t width;
648             renderSize.height,                                   //  uint32_t height;
649             1u,                                                  //  uint32_t layerCount;
650             1u,                                                  //  uint32_t viewFormatCount;
651             dsFormat                                             //  const VkFormat* pViewFormats;
652         };
653 
654         DE_ASSERT(*dsFormat != VK_FORMAT_UNDEFINED);
655 
656         framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
657     }
658 
659     for (uint32_t inputAttachmentNdx = 0; inputAttachmentNdx < inputAttachmentCount; ++inputAttachmentNdx)
660     {
661         const VkFramebufferAttachmentImageInfo framebufferAttachmentImageInfo = {
662             VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENT_IMAGE_INFO, //  VkStructureType sType;
663             DE_NULL,                                             //  const void* pNext;
664             (VkImageCreateFlags)0u,                              //  VkImageCreateFlags flags;
665             colorUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,    //  VkImageUsageFlags usage;
666             renderSize.width,                                    //  uint32_t width;
667             renderSize.height,                                   //  uint32_t height;
668             1u,                                                  //  uint32_t layerCount;
669             1u,                                                  //  uint32_t viewFormatCount;
670             colorFormat                                          //  const VkFormat* pViewFormats;
671         };
672 
673         framebufferAttachmentImageInfos.push_back(framebufferAttachmentImageInfo);
674     }
675 
676     return framebufferAttachmentImageInfos;
677 }
678 
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const VkExtent2D & renderSize,const VkFormat * colorFormat,const VkImageUsageFlags colorUsage,const VkFormat * dsFormat,const VkImageUsageFlags dsUsage=static_cast<VkImageUsageFlags> (0),const AspectFlags resolveAspects=ASPECT_NONE,const uint32_t inputAttachmentCount=0)679 Move<VkFramebuffer> makeFramebuffer(const DeviceInterface &vk, const VkDevice device, const VkRenderPass renderPass,
680                                     const VkExtent2D &renderSize, const VkFormat *colorFormat,
681                                     const VkImageUsageFlags colorUsage, const VkFormat *dsFormat,
682                                     const VkImageUsageFlags dsUsage     = static_cast<VkImageUsageFlags>(0),
683                                     const AspectFlags resolveAspects    = ASPECT_NONE,
684                                     const uint32_t inputAttachmentCount = 0)
685 {
686     const std::vector<VkFramebufferAttachmentImageInfo> framebufferAttachmentImageInfos =
687         makeFramebufferAttachmentImageInfos(renderSize, colorFormat, colorUsage, dsFormat, dsUsage, resolveAspects,
688                                             inputAttachmentCount);
689     const uint32_t attachmentCount = static_cast<uint32_t>(framebufferAttachmentImageInfos.size());
690     const VkFramebufferAttachmentsCreateInfo framebufferAttachmentsCreateInfo = {
691         VK_STRUCTURE_TYPE_FRAMEBUFFER_ATTACHMENTS_CREATE_INFO, //  VkStructureType sType;
692         DE_NULL,                                               //  const void* pNext;
693         attachmentCount,                                       //  uint32_t attachmentImageInfoCount;
694         &framebufferAttachmentImageInfos[0] //  const VkFramebufferAttachmentImageInfo* pAttachmentImageInfos;
695     };
696     const VkFramebufferCreateInfo framebufferInfo = {
697         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, //  VkStructureType sType;
698         &framebufferAttachmentsCreateInfo,         //  const void* pNext;
699         VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT,       //  VkFramebufferCreateFlags flags;
700         renderPass,                                //  VkRenderPass renderPass;
701         attachmentCount,                           //  uint32_t attachmentCount;
702         DE_NULL,                                   //  const VkImageView* pAttachments;
703         renderSize.width,                          //  uint32_t width;
704         renderSize.height,                         //  uint32_t height;
705         1u,                                        //  uint32_t layers;
706     };
707 
708     return createFramebuffer(vk, device, &framebufferInfo);
709 }
710 
makeVerifyFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const VkImageView colorAttachment,const VkExtent2D & renderSize,const uint32_t layers=1u)711 Move<VkFramebuffer> makeVerifyFramebuffer(const DeviceInterface &vk, const VkDevice device,
712                                           const VkRenderPass renderPass, const VkImageView colorAttachment,
713                                           const VkExtent2D &renderSize, const uint32_t layers = 1u)
714 {
715     const VkFramebufferCreateInfo framebufferInfo = {
716         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, //  VkStructureType sType;
717         DE_NULL,                                   //  const void* pNext;
718         (VkFramebufferCreateFlags)0,               //  VkFramebufferCreateFlags flags;
719         renderPass,                                //  VkRenderPass renderPass;
720         1u,                                        //  uint32_t attachmentCount;
721         &colorAttachment,                          //  const VkImageView* pAttachments;
722         renderSize.width,                          //  uint32_t width;
723         renderSize.height,                         //  uint32_t height;
724         layers,                                    //  uint32_t layers;
725     };
726 
727     return createFramebuffer(vk, device, &framebufferInfo);
728 }
729 
makeVerifyPipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)730 Move<VkPipelineLayout> makeVerifyPipelineLayout(const DeviceInterface &vk, const VkDevice device,
731                                                 const VkDescriptorSetLayout descriptorSetLayout)
732 {
733     const VkPushConstantRange pushConstantRanges = {
734         VK_SHADER_STAGE_FRAGMENT_BIT, //  VkShaderStageFlags stageFlags;
735         0u,                           //  uint32_t offset;
736         sizeof(uint32_t)              //  uint32_t size;
737     };
738     const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
739         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, //  VkStructureType sType;
740         DE_NULL,                                       //  const void* pNext;
741         (VkPipelineLayoutCreateFlags)0,                //  VkPipelineLayoutCreateFlags flags;
742         1u,                                            //  uint32_t setLayoutCount;
743         &descriptorSetLayout,                          //  const VkDescriptorSetLayout* pSetLayouts;
744         1u,                                            //  uint32_t pushConstantRangeCount;
745         &pushConstantRanges,                           //  const VkPushConstantRange* pPushConstantRanges;
746     };
747     return createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
748 }
749 
makeVerifyRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat)750 Move<VkRenderPass> makeVerifyRenderPass(const DeviceInterface &vk, const VkDevice device, const VkFormat colorFormat)
751 {
752     return makeRenderPass(vk, device, colorFormat);
753 }
754 
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)755 VkImageMemoryBarrier makeImageMemoryBarrier(const VkAccessFlags srcAccessMask, const VkAccessFlags dstAccessMask,
756                                             const VkImageLayout oldLayout, const VkImageLayout newLayout,
757                                             const VkImage image, const VkImageSubresourceRange subresourceRange)
758 {
759     const VkImageMemoryBarrier barrier = {
760         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
761         DE_NULL,                                // const void* pNext;
762         srcAccessMask,                          // VkAccessFlags outputMask;
763         dstAccessMask,                          // VkAccessFlags inputMask;
764         oldLayout,                              // VkImageLayout oldLayout;
765         newLayout,                              // VkImageLayout newLayout;
766         VK_QUEUE_FAMILY_IGNORED,                // uint32_t srcQueueFamilyIndex;
767         VK_QUEUE_FAMILY_IGNORED,                // uint32_t destQueueFamilyIndex;
768         image,                                  // VkImage image;
769         subresourceRange,                       // VkImageSubresourceRange subresourceRange;
770     };
771     return barrier;
772 }
773 
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)774 VkBufferMemoryBarrier makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask, const VkAccessFlags dstAccessMask,
775                                               const VkBuffer buffer, const VkDeviceSize offset,
776                                               const VkDeviceSize bufferSizeBytes)
777 {
778     const VkBufferMemoryBarrier barrier = {
779         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //  VkStructureType sType;
780         DE_NULL,                                 //  const void* pNext;
781         srcAccessMask,                           //  VkAccessFlags srcAccessMask;
782         dstAccessMask,                           //  VkAccessFlags dstAccessMask;
783         VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t srcQueueFamilyIndex;
784         VK_QUEUE_FAMILY_IGNORED,                 //  uint32_t destQueueFamilyIndex;
785         buffer,                                  //  VkBuffer buffer;
786         offset,                                  //  VkDeviceSize offset;
787         bufferSizeBytes,                         //  VkDeviceSize size;
788     };
789     return barrier;
790 }
791 
makeSampler(const DeviceInterface & vk,const VkDevice & device)792 Move<VkSampler> makeSampler(const DeviceInterface &vk, const VkDevice &device)
793 {
794     const VkSamplerCreateInfo createInfo = {
795         VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,   //  VkStructureType sType;
796         DE_NULL,                                 //  const void* pNext;
797         0u,                                      //  VkSamplerCreateFlags flags;
798         VK_FILTER_NEAREST,                       //  VkFilter magFilter;
799         VK_FILTER_NEAREST,                       //  VkFilter minFilter;
800         VK_SAMPLER_MIPMAP_MODE_LINEAR,           //  VkSamplerMipmapMode mipmapMode;
801         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   //  VkSamplerAddressMode addressModeU;
802         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   //  VkSamplerAddressMode addressModeV;
803         VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   //  VkSamplerAddressMode addressModeW;
804         0.0f,                                    //  float mipLodBias;
805         VK_FALSE,                                //  VkBool32 anisotropyEnable;
806         1.0f,                                    //  float maxAnisotropy;
807         VK_FALSE,                                //  VkBool32 compareEnable;
808         VK_COMPARE_OP_ALWAYS,                    //  VkCompareOp compareOp;
809         0.0f,                                    //  float minLod;
810         0.0f,                                    //  float maxLod;
811         VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, //  VkBorderColor borderColor;
812         VK_FALSE                                 //  VkBool32 unnormalizedCoordinates;
813     };
814 
815     return createSampler(vk, device, &createInfo);
816 }
817 
fillBuffer(const DeviceInterface & vk,const VkDevice device,Allocation & bufferAlloc,const void * data,const VkDeviceSize dataSize)818 void fillBuffer(const DeviceInterface &vk, const VkDevice device, Allocation &bufferAlloc, const void *data,
819                 const VkDeviceSize dataSize)
820 {
821     const VkMappedMemoryRange memRange = {
822         VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, //  VkStructureType sType;
823         DE_NULL,                               //  const void* pNext;
824         bufferAlloc.getMemory(),               //  VkDeviceMemory memory;
825         bufferAlloc.getOffset(),               //  VkDeviceSize offset;
826         VK_WHOLE_SIZE                          //  VkDeviceSize size;
827     };
828     const uint32_t dataSize32 = static_cast<uint32_t>(dataSize);
829 
830     deMemcpy(bufferAlloc.getHostPtr(), data, dataSize32);
831     VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &memRange));
832 }
833 
getFullQuadVertices(void)834 std::vector<float> getFullQuadVertices(void)
835 {
836     const float verticesData[] = {
837         -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, -1.0f, 0.0f, 1.0f,
838         -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, -1.0f, 0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f,
839     };
840     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
841 
842     return vertices;
843 }
844 
checkImageFormatProperties(const InstanceInterface & vki,const VkPhysicalDevice & physDevice,const VkFormat format,const VkImageUsageFlags imageUsageFlags,const VkExtent2D & requiredSize2D)845 void checkImageFormatProperties(const InstanceInterface &vki, const VkPhysicalDevice &physDevice, const VkFormat format,
846                                 const VkImageUsageFlags imageUsageFlags, const VkExtent2D &requiredSize2D)
847 {
848     const VkImageType imageType               = VK_IMAGE_TYPE_2D;
849     const VkImageTiling imageTiling           = VK_IMAGE_TILING_OPTIMAL;
850     const VkImageCreateFlags imageCreateFlags = static_cast<VkImageCreateFlags>(0u);
851     const uint32_t requiredLayers             = 1u;
852     const VkExtent3D requiredSize             = makeExtent3D(requiredSize2D.height, requiredSize2D.width, 1u);
853 
854     VkImageFormatProperties imageFormatProperties;
855     VkResult result;
856 
857     deMemset(&imageFormatProperties, 0, sizeof(imageFormatProperties));
858 
859     result = vki.getPhysicalDeviceImageFormatProperties(physDevice, format, imageType, imageTiling, imageUsageFlags,
860                                                         imageCreateFlags, &imageFormatProperties);
861 
862     if (result != VK_SUCCESS || imageFormatProperties.maxArrayLayers < requiredLayers ||
863         imageFormatProperties.maxExtent.height < requiredSize.height ||
864         imageFormatProperties.maxExtent.width < requiredSize.width ||
865         imageFormatProperties.maxExtent.depth < requiredSize.depth)
866     {
867         TCU_THROW(NotSupportedError, "Depth/stencil format is not supported");
868     }
869 }
870 
getStencilBufferFormat(VkFormat depthStencilImageFormat)871 VkFormat getStencilBufferFormat(VkFormat depthStencilImageFormat)
872 {
873     const tcu::TextureFormat tcuFormat = mapVkFormat(depthStencilImageFormat);
874     const VkFormat result = (tcuFormat.order == tcu::TextureFormat::S || tcuFormat.order == tcu::TextureFormat::DS) ?
875                                 VK_FORMAT_S8_UINT :
876                                 VK_FORMAT_UNDEFINED;
877 
878     DE_ASSERT(result != VK_FORMAT_UNDEFINED);
879 
880     return result;
881 }
882 
convertDepthToColor(const tcu::TextureFormat & dataFormat,const int width,const int height,const void * data,const tcu::TextureFormat & targetFormat)883 static MovePtr<tcu::TextureLevel> convertDepthToColor(const tcu::TextureFormat &dataFormat, const int width,
884                                                       const int height, const void *data,
885                                                       const tcu::TextureFormat &targetFormat)
886 {
887     const tcu::ConstPixelBufferAccess srcImage(dataFormat, width, height, 1u, data);
888     MovePtr<tcu::TextureLevel> dstImage(new tcu::TextureLevel(targetFormat, width, height, 1u));
889     tcu::PixelBufferAccess dstAccess(dstImage->getAccess());
890 
891     for (int y = 0; y < height; y++)
892         for (int x = 0; x < width; x++)
893         {
894             const float depth     = srcImage.getPixDepth(x, y);
895             const tcu::Vec4 color = tcu::Vec4(depth, depth, depth, 1.0f);
896 
897             dstAccess.setPixel(color, x, y);
898         }
899 
900     return dstImage;
901 }
902 
convertStencilToColor(const tcu::TextureFormat & dataFormat,const int width,const int height,const void * data,const tcu::TextureFormat & targetFormat)903 static MovePtr<tcu::TextureLevel> convertStencilToColor(const tcu::TextureFormat &dataFormat, const int width,
904                                                         const int height, const void *data,
905                                                         const tcu::TextureFormat &targetFormat)
906 {
907     const int maxValue(4);
908     const tcu::ConstPixelBufferAccess srcImage(dataFormat, width, height, 1u, data);
909     MovePtr<tcu::TextureLevel> dstImage(new tcu::TextureLevel(targetFormat, width, height, 1u));
910     tcu::PixelBufferAccess dstAccess(dstImage->getAccess());
911 
912     for (int y = 0; y < height; y++)
913         for (int x = 0; x < width; x++)
914         {
915             const int stencilInt  = srcImage.getPixStencil(x, y);
916             const float stencil   = (stencilInt < maxValue) ? float(stencilInt) / float(maxValue) : 1.0f;
917             const tcu::Vec4 color = tcu::Vec4(stencil, stencil, stencil, 1.0f);
918 
919             dstAccess.setPixel(color, x, y);
920         }
921 
922     return dstImage;
923 }
924 
925 class ColorImagelessTestInstance : public TestInstance
926 {
927 public:
928     ColorImagelessTestInstance(Context &context, const TestParameters &parameters);
929 
930 protected:
931     virtual tcu::TestStatus iterate(void);
932 
933     virtual std::vector<float> getVertices(void);
934     void readOneSampleFromMultisampleImage(const VkFormat srcFormat, const Unique<VkImage> &srcImage,
935                                            const uint32_t sampleID, const VkFormat dstFormat,
936                                            const Unique<VkImage> &dstImage, const Unique<VkBuffer> &dstBuffer,
937                                            const AspectFlags aspect);
938     virtual MovePtr<tcu::TextureLevel> generateReferenceImage(const tcu::TextureFormat &textureFormat,
939                                                               const AspectFlags aspectFlags, const uint32_t sample,
940                                                               const uint32_t subpass);
941     virtual bool verifyBuffer(const UniquePtr<Allocation> &bufAlloc, const VkFormat bufferFormat,
942                               const std::string &name, const AspectFlags aspectFlags, const uint32_t sample = NO_SAMPLE,
943                               const uint32_t subpass = NO_SUBPASS);
944     virtual bool verifyBufferInternal(const void *resultData, const tcu::TextureFormat &textureFormat,
945                                       const tcu::TextureLevel &referenceImage, const std::string &name);
946 
947     const bool m_extensions;
948     const VkExtent2D m_imageExtent2D;
949     const TestParameters m_parameters;
950     VkImageUsageFlags m_colorImageUsage;
951 };
952 
ColorImagelessTestInstance(Context & context,const TestParameters & parameters)953 ColorImagelessTestInstance::ColorImagelessTestInstance(Context &context, const TestParameters &parameters)
954     : TestInstance(context)
955     , m_extensions(context.requireDeviceFunctionality("VK_KHR_imageless_framebuffer"))
956     , m_imageExtent2D(makeExtent2D(32u, 32u))
957     , m_parameters(parameters)
958     , m_colorImageUsage(VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
959                         VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
960 {
961     const InstanceInterface &vki      = m_context.getInstanceInterface();
962     const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
963     const VkPhysicalDeviceImagelessFramebufferFeatures &imagelessFramebufferFeatures(
964         context.getImagelessFramebufferFeatures());
965 
966     if (imagelessFramebufferFeatures.imagelessFramebuffer == false)
967         TCU_THROW(NotSupportedError, "Imageless framebuffer is not supported");
968 
969     checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
970 }
971 
readOneSampleFromMultisampleImage(const VkFormat srcFormat,const Unique<VkImage> & srcImage,const uint32_t sampleID,const VkFormat dstFormat,const Unique<VkImage> & dstImage,const Unique<VkBuffer> & dstBuffer,const AspectFlags aspect)972 void ColorImagelessTestInstance::readOneSampleFromMultisampleImage(
973     const VkFormat srcFormat, const Unique<VkImage> &srcImage, const uint32_t sampleID, const VkFormat dstFormat,
974     const Unique<VkImage> &dstImage, const Unique<VkBuffer> &dstBuffer, const AspectFlags aspect)
975 {
976     const DeviceInterface &vk       = m_context.getDeviceInterface();
977     const VkDevice device           = m_context.getDevice();
978     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
979     const VkQueue queue             = m_context.getUniversalQueue();
980     Allocator &allocator            = m_context.getDefaultAllocator();
981 
982     const tcu::Vec4 clearColor                   = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
983     const bool color                             = ((aspect & ASPECT_COLOR) != 0);
984     const bool depth                             = ((aspect & ASPECT_DEPTH) != 0);
985     const bool stencil                           = ((aspect & ASPECT_STENCIL) != 0);
986     const VkImageAspectFlags srcAspect           = color ? VK_IMAGE_ASPECT_COLOR_BIT :
987                                                    depth ? VK_IMAGE_ASPECT_DEPTH_BIT :
988                                                            VK_IMAGE_ASPECT_STENCIL_BIT;
989     const VkImageSubresourceRange srcSubresRange = makeImageSubresourceRange(srcAspect, 0u, 1u, 0u, 1u);
990     const Unique<VkImageView> srcImageView(
991         makeImageView(vk, device, *srcImage, VK_IMAGE_VIEW_TYPE_2D, srcFormat, srcSubresRange));
992 
993     const VkImageAspectFlags dstAspect           = VK_IMAGE_ASPECT_COLOR_BIT;
994     const VkImageSubresourceRange dstSubresRange = makeImageSubresourceRange(dstAspect, 0u, 1u, 0u, 1u);
995     const Unique<VkImageView> dstAttachment(
996         makeImageView(vk, device, *dstImage, VK_IMAGE_VIEW_TYPE_2D, dstFormat, dstSubresRange));
997 
998     const std::string fragModuleInfix = color ? "-color" : depth ? "-depth" : stencil ? "-stencil" : "";
999     const Unique<VkShaderModule> vertModule(
1000         createShaderModule(vk, device, m_context.getBinaryCollection().get("demultisample-vert"), 0u));
1001     const Unique<VkShaderModule> fragModule(createShaderModule(
1002         vk, device, m_context.getBinaryCollection().get("demultisample" + fragModuleInfix + "-frag"), 0u));
1003     const Unique<VkRenderPass> renderPass(makeVerifyRenderPass(vk, device, dstFormat));
1004     const Unique<VkFramebuffer> framebuffer(
1005         makeVerifyFramebuffer(vk, device, *renderPass, *dstAttachment, m_imageExtent2D));
1006 
1007     const VkDescriptorType samplerDescType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
1008     const Unique<VkSampler> sampler(makeSampler(vk, device));
1009     const Unique<VkDescriptorSetLayout> descriptorSetLayout(
1010         DescriptorSetLayoutBuilder()
1011             .addSingleSamplerBinding(samplerDescType, VK_SHADER_STAGE_FRAGMENT_BIT, &sampler.get())
1012             .build(vk, device));
1013     const Unique<VkDescriptorPool> descriptorPool(
1014         DescriptorPoolBuilder()
1015             .addType(samplerDescType)
1016             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1017     const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
1018     const VkDescriptorImageInfo imageDescriptorInfo(
1019         makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
1020 
1021     DescriptorSetUpdateBuilder()
1022         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), samplerDescType,
1023                      &imageDescriptorInfo)
1024         .update(vk, device);
1025 
1026     const Unique<VkPipelineLayout> pipelineLayout(makeVerifyPipelineLayout(vk, device, *descriptorSetLayout));
1027     const Unique<VkPipeline> pipeline(
1028         makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
1029     const Unique<VkCommandPool> cmdPool(
1030         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1031     const Unique<VkCommandBuffer> cmdBuffer(
1032         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1033 
1034     const std::vector<float> vertexArray(getFullQuadVertices());
1035     const uint32_t vertexCount(static_cast<uint32_t>(vertexArray.size() / 4u));
1036     const VkDeviceSize vertexArraySize(vertexArray.size() * sizeof(vertexArray[0]));
1037     const Unique<VkBuffer> vertexBuffer(makeBuffer(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1038     const UniquePtr<Allocation> vertexBufferAlloc(
1039         bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1040     const VkDeviceSize vertexBufferOffset(0u);
1041 
1042     fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
1043 
1044     beginCommandBuffer(vk, *cmdBuffer);
1045     {
1046         if (sampleID == 0)
1047         {
1048             if (color)
1049             {
1050                 const VkImageMemoryBarrier preCopyBarrier =
1051                     makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1052                                            VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1053                                            VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, *srcImage, srcSubresRange);
1054 
1055                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1056                                       VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u,
1057                                       &preCopyBarrier);
1058             }
1059             else if (depth)
1060             {
1061                 const VkImageSubresourceRange preCopySubresRange =
1062                     makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u);
1063                 const VkImageMemoryBarrier preCopyBarrier =
1064                     makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1065                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1066                                            VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, *srcImage, preCopySubresRange);
1067 
1068                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1069                                       VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u,
1070                                       &preCopyBarrier);
1071             }
1072         }
1073 
1074         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor);
1075         {
1076             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1077 
1078             vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u,
1079                                      &descriptorSet.get(), 0u, DE_NULL);
1080 
1081             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
1082 
1083             vk.cmdPushConstants(*cmdBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleID),
1084                                 &sampleID);
1085 
1086             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
1087         }
1088         endRenderPass(vk, *cmdBuffer);
1089 
1090         // Image copy
1091         {
1092             const VkImageMemoryBarrier preCopyBarrier =
1093                 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1094                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1095                                        *dstImage, dstSubresRange);
1096             const VkBufferImageCopy region =
1097                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1098                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1099             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
1100                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *dstBuffer, 0ull, VK_WHOLE_SIZE);
1101 
1102             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1103                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1104             vk.cmdCopyImageToBuffer(*cmdBuffer, *dstImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dstBuffer, 1u,
1105                                     &region);
1106             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1107                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1108         }
1109     }
1110     endCommandBuffer(vk, *cmdBuffer);
1111     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1112 }
1113 
verifyBufferInternal(const void * resultData,const tcu::TextureFormat & textureFormat,const tcu::TextureLevel & referenceImage,const std::string & name)1114 bool ColorImagelessTestInstance::verifyBufferInternal(const void *resultData, const tcu::TextureFormat &textureFormat,
1115                                                       const tcu::TextureLevel &referenceImage, const std::string &name)
1116 {
1117     const int dataSize(m_imageExtent2D.width * m_imageExtent2D.height * textureFormat.getPixelSize());
1118     const tcu::ConstPixelBufferAccess referenceAccess(referenceImage.getAccess());
1119 
1120     if (deMemCmp(resultData, referenceAccess.getDataPtr(), dataSize) != 0)
1121     {
1122         const tcu::ConstPixelBufferAccess resultImage(textureFormat, m_imageExtent2D.width, m_imageExtent2D.height, 1u,
1123                                                       resultData);
1124         bool ok;
1125 
1126         ok = tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), "", referenceAccess,
1127                                       resultImage, tcu::UVec4(1), tcu::COMPARE_LOG_RESULT);
1128 
1129         return ok;
1130     }
1131 
1132     return true;
1133 }
1134 
verifyBuffer(const UniquePtr<Allocation> & bufAlloc,const VkFormat bufferFormat,const std::string & name,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t subpass)1135 bool ColorImagelessTestInstance::verifyBuffer(const UniquePtr<Allocation> &bufAlloc, const VkFormat bufferFormat,
1136                                               const std::string &name, const AspectFlags aspectFlags,
1137                                               const uint32_t sample, const uint32_t subpass)
1138 {
1139     invalidateMappedMemoryRange(m_context.getDeviceInterface(), m_context.getDevice(), bufAlloc->getMemory(),
1140                                 bufAlloc->getOffset(), VK_WHOLE_SIZE);
1141 
1142     const tcu::TextureFormat bufferTextureFormat(mapVkFormat(bufferFormat));
1143     const bool multisampled(sample != NO_SAMPLE);
1144     const bool depth((aspectFlags & ASPECT_DEPTH) != 0);
1145     const bool stencil((aspectFlags & ASPECT_STENCIL) != 0);
1146     const bool convertRequired((depth || stencil) && !multisampled);
1147     const tcu::TextureFormat convertTextureFormat(
1148         tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::UNORM_INT8));
1149     const tcu::TextureFormat referenceTextureFormat(convertRequired ? convertTextureFormat : bufferTextureFormat);
1150     const MovePtr<tcu::TextureLevel> referenceImage(
1151         generateReferenceImage(referenceTextureFormat, aspectFlags, sample, subpass));
1152 
1153     if (!multisampled && depth)
1154     {
1155         MovePtr<tcu::TextureLevel> convertedImage(convertDepthToColor(bufferTextureFormat, m_imageExtent2D.width,
1156                                                                       m_imageExtent2D.height, bufAlloc->getHostPtr(),
1157                                                                       convertTextureFormat));
1158         tcu::ConstPixelBufferAccess convertedAccess(convertedImage->getAccess());
1159 
1160         return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
1161     }
1162     else if (!multisampled && stencil)
1163     {
1164         MovePtr<tcu::TextureLevel> convertedImage(convertStencilToColor(bufferTextureFormat, m_imageExtent2D.width,
1165                                                                         m_imageExtent2D.height, bufAlloc->getHostPtr(),
1166                                                                         convertTextureFormat));
1167         tcu::ConstPixelBufferAccess convertedAccess(convertedImage->getAccess());
1168 
1169         return verifyBufferInternal(convertedAccess.getDataPtr(), convertTextureFormat, *referenceImage, name);
1170     }
1171     else
1172     {
1173         const void *resultData(bufAlloc->getHostPtr());
1174 
1175         return verifyBufferInternal(resultData, bufferTextureFormat, *referenceImage, name);
1176     }
1177 }
1178 
generateReferenceImage(const tcu::TextureFormat & textureFormat,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t subpass)1179 MovePtr<tcu::TextureLevel> ColorImagelessTestInstance::generateReferenceImage(const tcu::TextureFormat &textureFormat,
1180                                                                               const AspectFlags aspectFlags,
1181                                                                               const uint32_t sample,
1182                                                                               const uint32_t subpass)
1183 {
1184     const int width  = m_imageExtent2D.width;
1185     const int height = m_imageExtent2D.height;
1186     const int componentValue(static_cast<int>(0.75f * 0x100));
1187     const tcu::RGBA colorDrawRGBA(tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
1188     const tcu::Vec4 colorDraw(colorDrawRGBA.toVec());
1189     const tcu::Vec4 colorFill(tcu::RGBA::black().toVec());
1190     MovePtr<tcu::TextureLevel> image(new tcu::TextureLevel(textureFormat, width, height));
1191     tcu::PixelBufferAccess access(image->getAccess());
1192 
1193     DE_UNREF(aspectFlags);
1194     DE_ASSERT(aspectFlags == ASPECT_COLOR);
1195     DE_UNREF(sample);
1196     DE_ASSERT(sample == NO_SAMPLE);
1197     DE_UNREF(subpass);
1198     DE_ASSERT(subpass == NO_SUBPASS);
1199 
1200     for (int y = 0; y < height; ++y)
1201     {
1202         const tcu::Vec4 &validColor = (y < height / 2) ? colorFill : colorDraw;
1203 
1204         for (int x = 0; x < width; ++x)
1205             access.setPixel(validColor, x, y);
1206     }
1207 
1208     return image;
1209 }
1210 
getVertices(void)1211 std::vector<float> ColorImagelessTestInstance::getVertices(void)
1212 {
1213     const float verticesData[] = {
1214         -1.0f, 0.0f,  0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, 0.0f,  0.0f, 1.0f,
1215         -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, 0.0f,  0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f,
1216     };
1217     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
1218 
1219     return vertices;
1220 }
1221 
iterate(void)1222 tcu::TestStatus ColorImagelessTestInstance::iterate(void)
1223 {
1224     const DeviceInterface &vk       = m_context.getDeviceInterface();
1225     const VkDevice device           = m_context.getDevice();
1226     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1227     const VkQueue queue             = m_context.getUniversalQueue();
1228     Allocator &allocator            = m_context.getDefaultAllocator();
1229 
1230     const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1231     const VkFormat colorFormat = m_parameters.colorFormat;
1232     const VkDeviceSize colorBufferSize =
1233         m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
1234     const VkImageSubresourceRange colorSubresRange =
1235         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1236 
1237     const Unique<VkImage> colorImage(
1238         makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
1239     const UniquePtr<Allocation> colorImageAlloc(bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
1240     const Unique<VkImageView> colorAttachment(
1241         makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1242     const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1243     const UniquePtr<Allocation> colorBufferAlloc(
1244         bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1245 
1246     const Unique<VkShaderModule> vertModule(
1247         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1248     const Unique<VkShaderModule> fragModule(
1249         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1250     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, device, colorFormat, m_parameters.dsFormat));
1251     const Unique<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, m_imageExtent2D, &colorFormat,
1252                                                             m_colorImageUsage, &m_parameters.dsFormat));
1253     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device));
1254     const Unique<VkPipeline> pipeline(
1255         makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
1256     const Unique<VkCommandPool> cmdPool(
1257         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1258     const Unique<VkCommandBuffer> cmdBuffer(
1259         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1260 
1261     const std::vector<float> vertexArray(getVertices());
1262     const uint32_t vertexCount(static_cast<uint32_t>(vertexArray.size() / 4u));
1263     const VkDeviceSize vertexArraySize(vertexArray.size() * sizeof(vertexArray[0]));
1264     const Unique<VkBuffer> vertexBuffer(makeBuffer(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1265     const UniquePtr<Allocation> vertexBufferAlloc(
1266         bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1267     const VkDeviceSize vertexBufferOffset(0u);
1268 
1269     fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
1270 
1271     beginCommandBuffer(vk, *cmdBuffer);
1272     {
1273         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo = {
1274             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
1275             DE_NULL,                                             //  const void* pNext;
1276             1u,                                                  //  uint32_t attachmentCount;
1277             &*colorAttachment                                    //  const VkImageView* pAttachments;
1278         };
1279 
1280         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor,
1281                         &renderPassAttachmentBeginInfo);
1282         {
1283             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1284 
1285             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
1286 
1287             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
1288         }
1289         endRenderPass(vk, *cmdBuffer);
1290 
1291         // Color image copy
1292         {
1293             const VkImageMemoryBarrier preCopyBarrier =
1294                 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1295                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1296                                        *colorImage, colorSubresRange);
1297             const VkBufferImageCopy region =
1298                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1299                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1300             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
1301                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1302 
1303             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1304                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1305             vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u,
1306                                     &region);
1307             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1308                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1309         }
1310     }
1311     endCommandBuffer(vk, *cmdBuffer);
1312     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1313 
1314     if (verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
1315         return tcu::TestStatus::pass("Pass");
1316     else
1317         return tcu::TestStatus::fail("Fail");
1318 }
1319 
1320 class DepthImagelessTestInstance : public ColorImagelessTestInstance
1321 {
1322 public:
1323     DepthImagelessTestInstance(Context &context, const TestParameters &parameters);
1324 
1325 protected:
1326     virtual tcu::TestStatus iterate(void);
1327 
1328     virtual std::vector<float> getVertices(void);
1329 
1330     virtual MovePtr<tcu::TextureLevel> generateReferenceImage(const tcu::TextureFormat &textureFormat,
1331                                                               const AspectFlags aspectFlags, const uint32_t sample,
1332                                                               const uint32_t subpass);
1333 
1334     VkImageUsageFlags m_dsImageUsage;
1335 };
1336 
DepthImagelessTestInstance(Context & context,const TestParameters & parameters)1337 DepthImagelessTestInstance::DepthImagelessTestInstance(Context &context, const TestParameters &parameters)
1338     : ColorImagelessTestInstance(context, parameters)
1339     , m_dsImageUsage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)
1340 {
1341     const InstanceInterface &vki      = m_context.getInstanceInterface();
1342     const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1343 
1344     checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
1345 }
1346 
generateReferenceImage(const tcu::TextureFormat & textureFormat,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t subpass)1347 MovePtr<tcu::TextureLevel> DepthImagelessTestInstance::generateReferenceImage(const tcu::TextureFormat &textureFormat,
1348                                                                               const AspectFlags aspectFlags,
1349                                                                               const uint32_t sample,
1350                                                                               const uint32_t subpass)
1351 {
1352     const bool color   = ((aspectFlags & ASPECT_COLOR) != 0);
1353     const bool depth   = ((aspectFlags & ASPECT_DEPTH) != 0);
1354     const bool stencil = ((aspectFlags & ASPECT_STENCIL) != 0);
1355     const int width    = m_imageExtent2D.width;
1356     const int height   = m_imageExtent2D.height;
1357     MovePtr<tcu::TextureLevel> image(new tcu::TextureLevel(textureFormat, width, height));
1358     tcu::PixelBufferAccess access(image->getAccess());
1359 
1360     DE_ASSERT(dePop32(aspectFlags) == 1);
1361     DE_UNREF(sample);
1362     DE_ASSERT(sample == NO_SAMPLE);
1363     DE_UNREF(subpass);
1364     DE_ASSERT(subpass == NO_SUBPASS);
1365 
1366     if (color)
1367     {
1368         const int componentValue(static_cast<int>(0.75f * 0x100));
1369         const tcu::RGBA colorDrawRGBA(tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
1370         const tcu::Vec4 colorDraw(colorDrawRGBA.toVec());
1371         const tcu::Vec4 colorDrawTop(tcu::RGBA::white().toVec());
1372         const tcu::Vec4 colorFill(tcu::RGBA::black().toVec());
1373 
1374         for (int y = 0; y < height; ++y)
1375             for (int x = 0; x < width; ++x)
1376             {
1377                 const tcu::Vec4 &validColor = (y < height / 2) ? colorFill : (x < width / 2) ? colorDraw : colorDrawTop;
1378 
1379                 access.setPixel(validColor, x, y);
1380             }
1381     }
1382 
1383     if (depth)
1384     {
1385         const int colorFillValue(static_cast<int>(1.00f * 0x100));
1386         const int colorDrawValue(static_cast<int>(0.50f * 0x100));
1387         const int colorTopValue(static_cast<int>(0.25f * 0x100));
1388         const tcu::IVec4 colorFill(colorFillValue, 0, 0, 0xFF);
1389         const tcu::IVec4 colorDraw(colorDrawValue, 0, 0, 0xFF);
1390         const tcu::IVec4 colorTop(colorTopValue, 0, 0, 0xFF);
1391 
1392         for (int y = 0; y < height; ++y)
1393             for (int x = 0; x < width; ++x)
1394             {
1395                 const tcu::IVec4 &validColor = (y < height / 2) ? colorFill : (x < width / 2) ? colorDraw : colorTop;
1396 
1397                 access.setPixel(validColor, x, y);
1398             }
1399     }
1400 
1401     if (stencil)
1402     {
1403         const int colorFillValue(static_cast<int>(0.00f * 0x100));
1404         const int colorDrawValue(static_cast<int>(0.25f * 0x100));
1405         const int colorTopValue(static_cast<int>(0.50f * 0x100));
1406         const tcu::IVec4 colorFill(colorFillValue, 0, 0, 0xFF);
1407         const tcu::IVec4 colorDraw(colorDrawValue, 0, 0, 0xFF);
1408         const tcu::IVec4 colorTop(colorTopValue, 0, 0, 0xFF);
1409 
1410         for (int y = 0; y < height; ++y)
1411             for (int x = 0; x < width; ++x)
1412             {
1413                 const tcu::IVec4 &validColor = (y < height / 2) ? colorFill : (x < width / 2) ? colorDraw : colorTop;
1414 
1415                 access.setPixel(validColor, x, y);
1416             }
1417     }
1418 
1419     return image;
1420 }
1421 
getVertices(void)1422 std::vector<float> DepthImagelessTestInstance::getVertices(void)
1423 {
1424     const float verticesData[] = {
1425         -1.0f, 0.0f,  0.50f, 1.0f, -1.0f, +1.0f, 0.50f, 1.0f, +1.0f, 0.0f,  0.50f, 1.0f,
1426         -1.0f, +1.0f, 0.50f, 1.0f, +1.0f, 0.0f,  0.50f, 1.0f, +1.0f, +1.0f, 0.50f, 1.0f,
1427 
1428         0.0f,  0.0f,  0.25f, 1.0f, 0.0f,  +1.0f, 0.25f, 1.0f, +1.0f, 0.0f,  0.25f, 1.0f,
1429         0.0f,  +1.0f, 0.25f, 1.0f, +1.0f, 0.0f,  0.25f, 1.0f, +1.0f, +1.0f, 0.25f, 1.0f,
1430     };
1431     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
1432 
1433     return vertices;
1434 }
1435 
iterate(void)1436 tcu::TestStatus DepthImagelessTestInstance::iterate(void)
1437 {
1438     const DeviceInterface &vk       = m_context.getDeviceInterface();
1439     const VkDevice device           = m_context.getDevice();
1440     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1441     const VkQueue queue             = m_context.getUniversalQueue();
1442     Allocator &allocator            = m_context.getDefaultAllocator();
1443 
1444     const uint32_t sampleCount                  = 1u;
1445     const VkSampleCountFlagBits sampleCountFlag = sampleCountBitFromSampleCount(sampleCount);
1446     const tcu::Vec4 clearColor                  = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1447     const VkFormat colorFormat                  = m_parameters.colorFormat;
1448     const VkDeviceSize colorBufferSize =
1449         m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
1450     const VkImageSubresourceRange colorSubresRange =
1451         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1452 
1453     const Unique<VkImage> colorImage(
1454         makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
1455     const UniquePtr<Allocation> colorImageAlloc(bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
1456     const Unique<VkImageView> colorAttachment(
1457         makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1458     const Unique<VkBuffer> colorBuffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1459     const UniquePtr<Allocation> colorBufferAlloc(
1460         bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible));
1461 
1462     const float clearDepth                      = 1.0f;
1463     const uint32_t clearStencil                 = 0u;
1464     const VkFormat dsFormat                     = m_parameters.dsFormat;
1465     const uint32_t dsImagePixelSize             = static_cast<uint32_t>(tcu::getPixelSize(mapVkFormat(dsFormat)));
1466     const VkImageAspectFlags dsAspectFlags      = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1467     const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);
1468 
1469     const VkDeviceSize depthBufferSize   = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
1470     const VkFormat stencilBufferFormat   = getStencilBufferFormat(dsFormat);
1471     const uint32_t stencilPixelSize      = static_cast<uint32_t>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
1472     const VkDeviceSize stencilBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;
1473 
1474     const Unique<VkImage> dsImage(
1475         makeImage(vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
1476     const UniquePtr<Allocation> dsImageAlloc(bindImage(vk, device, allocator, *dsImage, MemoryRequirement::Any));
1477     const Unique<VkImageView> dsAttachment(
1478         makeImageView(vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
1479     const Unique<VkBuffer> depthBuffer(
1480         makeBuffer(vk, device, depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1481     const UniquePtr<Allocation> depthBufferAlloc(
1482         bindBuffer(vk, device, allocator, *depthBuffer, MemoryRequirement::HostVisible));
1483     const Unique<VkBuffer> stencilBuffer(
1484         makeBuffer(vk, device, stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1485     const UniquePtr<Allocation> stencilBufferAlloc(
1486         bindBuffer(vk, device, allocator, *stencilBuffer, MemoryRequirement::HostVisible));
1487 
1488     const Unique<VkShaderModule> vertModule(
1489         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1490     const Unique<VkShaderModule> fragModule(
1491         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1492     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, device, colorFormat, dsFormat, sampleCountFlag));
1493     const Unique<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, m_imageExtent2D, &colorFormat,
1494                                                             m_colorImageUsage, &dsFormat, m_dsImageUsage));
1495     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device));
1496     const Unique<VkPipeline> pipeline(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertModule,
1497                                                            *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL));
1498     const Unique<VkCommandPool> cmdPool(
1499         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1500     const Unique<VkCommandBuffer> cmdBuffer(
1501         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1502 
1503     const std::vector<float> vertexArray(getVertices());
1504     const uint32_t vertexCount(static_cast<uint32_t>(vertexArray.size() / 4u));
1505     const VkDeviceSize vertexArraySize(vertexArray.size() * sizeof(vertexArray[0]));
1506     const Unique<VkBuffer> vertexBuffer(makeBuffer(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1507     const UniquePtr<Allocation> vertexBufferAlloc(
1508         bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1509     const VkDeviceSize vertexBufferOffset(0u);
1510 
1511     fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
1512 
1513     beginCommandBuffer(vk, *cmdBuffer);
1514     {
1515         const VkImageView attachments[]                                     = {*colorAttachment, *dsAttachment};
1516         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo = {
1517             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
1518             DE_NULL,                                             //  const void* pNext;
1519             DE_LENGTH_OF_ARRAY(attachments),                     //  uint32_t attachmentCount;
1520             attachments                                          //  const VkImageView* pAttachments;
1521         };
1522 
1523         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth,
1524                         clearStencil, &renderPassAttachmentBeginInfo);
1525         {
1526             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1527 
1528             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
1529 
1530             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
1531         }
1532         endRenderPass(vk, *cmdBuffer);
1533 
1534         // Color image copy
1535         {
1536             const VkImageMemoryBarrier preCopyBarrier =
1537                 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1538                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1539                                        *colorImage, colorSubresRange);
1540             const VkBufferImageCopy region =
1541                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1542                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1543             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
1544                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, VK_WHOLE_SIZE);
1545 
1546             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1547                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1548             vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u,
1549                                     &region);
1550             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1551                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1552         }
1553 
1554         // Depth/Stencil image copy
1555         {
1556             const VkImageMemoryBarrier preCopyBarrier =
1557                 makeImageMemoryBarrier(VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1558                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1559                                        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsImage, dsSubresRange);
1560             const VkBufferImageCopy depthCopyRegion =
1561                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1562                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
1563             const VkBufferImageCopy stencilCopyRegion =
1564                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1565                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
1566             const VkBufferMemoryBarrier postCopyBarriers[] = {
1567                 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthBuffer, 0ull,
1568                                         VK_WHOLE_SIZE),
1569                 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilBuffer, 0ull,
1570                                         VK_WHOLE_SIZE),
1571             };
1572 
1573             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1574                                   0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1575             vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *depthBuffer, 1u,
1576                                     &depthCopyRegion);
1577             vk.cmdCopyImageToBuffer(*cmdBuffer, *dsImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *stencilBuffer, 1u,
1578                                     &stencilCopyRegion);
1579             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1580                                   DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
1581         }
1582     }
1583     endCommandBuffer(vk, *cmdBuffer);
1584     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1585 
1586     {
1587         std::string result;
1588 
1589         if (!verifyBuffer(colorBufferAlloc, colorFormat, "Color", ASPECT_COLOR))
1590             result += " Color";
1591 
1592         if (!verifyBuffer(depthBufferAlloc, dsFormat, "Depth", ASPECT_DEPTH))
1593             result += " Depth";
1594 
1595         if (!verifyBuffer(stencilBufferAlloc, stencilBufferFormat, "Stencil", ASPECT_STENCIL))
1596             result += " Stencil";
1597 
1598         if (result.empty())
1599             return tcu::TestStatus::pass("Pass");
1600         else
1601             return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
1602     }
1603 }
1604 
1605 class ColorResolveImagelessTestInstance : public ColorImagelessTestInstance
1606 {
1607 public:
1608     ColorResolveImagelessTestInstance(Context &context, const TestParameters &parameters);
1609 
1610 protected:
1611     virtual tcu::TestStatus iterate(void);
1612 
1613     virtual MovePtr<tcu::TextureLevel> generateReferenceImage(const tcu::TextureFormat &textureFormat,
1614                                                               const AspectFlags aspectFlags, const uint32_t sample,
1615                                                               const uint32_t subpass);
1616 
1617     virtual std::vector<float> getVertices(void);
1618 };
1619 
ColorResolveImagelessTestInstance(Context & context,const TestParameters & parameters)1620 ColorResolveImagelessTestInstance::ColorResolveImagelessTestInstance(Context &context, const TestParameters &parameters)
1621     : ColorImagelessTestInstance(context, parameters)
1622 {
1623     const InstanceInterface &vki      = m_context.getInstanceInterface();
1624     const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1625 
1626     // To validate per-sample image image must also be sampled
1627     m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1628 
1629     checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
1630 }
1631 
generateReferenceImage(const tcu::TextureFormat & textureFormat,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t subpass)1632 MovePtr<tcu::TextureLevel> ColorResolveImagelessTestInstance::generateReferenceImage(
1633     const tcu::TextureFormat &textureFormat, const AspectFlags aspectFlags, const uint32_t sample,
1634     const uint32_t subpass)
1635 {
1636     const int width  = m_imageExtent2D.width;
1637     const int height = m_imageExtent2D.height;
1638     MovePtr<tcu::TextureLevel> image(new tcu::TextureLevel(textureFormat, width, height));
1639     tcu::PixelBufferAccess access(image->getAccess());
1640     const int componentValue(static_cast<int>(0.75f * 0x100));
1641     const tcu::RGBA colorDrawRGBA(tcu::RGBA(componentValue, componentValue, componentValue, 0xFF));
1642     const tcu::Vec4 colorDraw(colorDrawRGBA.toVec());
1643     const tcu::Vec4 colorFill(tcu::RGBA::black().toVec());
1644     const tcu::Vec4 colorEdge0(colorDraw);
1645     const tcu::Vec4 colorEdge1(colorFill);
1646     const tcu::Vec4 colorEdge2(colorDraw);
1647     const tcu::Vec4 colorEdge3(colorFill);
1648     const tcu::Vec4 colorEdgeR((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2,
1649                                (colorDraw.z() + colorFill.z()) / 2, colorDraw.w()); // AVERAGE
1650     const tcu::Vec4 &colorEdge = sample == 0 ? colorEdge0 :
1651                                  sample == 1 ? colorEdge1 :
1652                                  sample == 2 ? colorEdge2 :
1653                                  sample == 3 ? colorEdge3 :
1654                                                colorEdgeR;
1655 
1656     DE_UNREF(aspectFlags);
1657     DE_ASSERT(dePop32(aspectFlags) == 1);
1658     DE_ASSERT(aspectFlags == ASPECT_COLOR);
1659     DE_UNREF(subpass);
1660     DE_ASSERT(subpass == NO_SUBPASS);
1661 
1662     for (int y = 0; y < height; ++y)
1663         for (int x = 0; x < width; ++x)
1664         {
1665             const int mx                = width - 1 - x;
1666             const tcu::Vec4 &validColor = (y == mx) ? colorEdge : (y > mx) ? colorFill : colorDraw;
1667 
1668             access.setPixel(validColor, x, y);
1669         }
1670 
1671     return image;
1672 }
1673 
getVertices(void)1674 std::vector<float> ColorResolveImagelessTestInstance::getVertices(void)
1675 {
1676     const float verticesData[] = {
1677         -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, -1.0f, 0.0f, 1.0f,
1678     };
1679     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
1680 
1681     return vertices;
1682 }
1683 
iterate(void)1684 tcu::TestStatus ColorResolveImagelessTestInstance::iterate(void)
1685 {
1686     const DeviceInterface &vk       = m_context.getDeviceInterface();
1687     const VkDevice device           = m_context.getDevice();
1688     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1689     const VkQueue queue             = m_context.getUniversalQueue();
1690     Allocator &allocator            = m_context.getDefaultAllocator();
1691 
1692     const VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
1693     const tcu::Vec4 clearColor              = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1694     const VkFormat colorFormat              = m_parameters.colorFormat;
1695     const VkDeviceSize colorBufferSize =
1696         m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
1697     const VkImageSubresourceRange colorSubresRange =
1698         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1699 
1700     const Unique<VkImage> colorImage(
1701         makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCount)));
1702     const UniquePtr<Allocation> colorImageAlloc(bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
1703     const Unique<VkImageView> colorAttachment(
1704         makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1705 
1706     const Unique<VkImage> colorResolveImage(
1707         makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
1708     const UniquePtr<Allocation> colorResolveImageAlloc(
1709         bindImage(vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
1710     const Unique<VkImageView> colorResolveAttachment(
1711         makeImageView(vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1712     const Unique<VkBuffer> colorResolveBuffer(
1713         makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1714     const UniquePtr<Allocation> colorResolveBufferAlloc(
1715         bindBuffer(vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));
1716 
1717     const Unique<VkShaderModule> vertModule(
1718         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
1719     const Unique<VkShaderModule> fragModule(
1720         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
1721     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, device, colorFormat, m_parameters.dsFormat, sampleCount));
1722     const Unique<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, m_imageExtent2D, &colorFormat,
1723                                                             m_colorImageUsage, &m_parameters.dsFormat, 0u,
1724                                                             ASPECT_COLOR));
1725     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device));
1726     const Unique<VkPipeline> pipeline(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertModule,
1727                                                            *fragModule, m_imageExtent2D, ASPECT_NONE, sampleCount));
1728     const Unique<VkCommandPool> cmdPool(
1729         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1730     const Unique<VkCommandBuffer> cmdBuffer(
1731         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1732 
1733     const std::vector<float> vertexArray(getVertices());
1734     const uint32_t vertexCount(static_cast<uint32_t>(vertexArray.size() / 4u));
1735     const VkDeviceSize vertexArraySize(vertexArray.size() * sizeof(vertexArray[0]));
1736     const Unique<VkBuffer> vertexBuffer(makeBuffer(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
1737     const UniquePtr<Allocation> vertexBufferAlloc(
1738         bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
1739     const VkDeviceSize vertexBufferOffset(0u);
1740 
1741     fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
1742 
1743     beginCommandBuffer(vk, *cmdBuffer);
1744     {
1745         const VkImageView attachments[] = {*colorAttachment, *colorResolveAttachment};
1746         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo = {
1747             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
1748             DE_NULL,                                             //  const void* pNext;
1749             DE_LENGTH_OF_ARRAY(attachments),                     //  uint32_t attachmentCount;
1750             attachments                                          //  const VkImageView* pAttachments;
1751         };
1752 
1753         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor,
1754                         &renderPassAttachmentBeginInfo);
1755         {
1756             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1757 
1758             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
1759 
1760             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
1761         }
1762         endRenderPass(vk, *cmdBuffer);
1763 
1764         // Color image copy
1765         {
1766             const VkImageMemoryBarrier preCopyBarrier =
1767                 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1768                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1769                                        *colorResolveImage, colorSubresRange);
1770             const VkBufferImageCopy region =
1771                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
1772                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
1773             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
1774                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);
1775 
1776             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1777                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
1778             vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1779                                     *colorResolveBuffer, 1u, &region);
1780             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1781                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
1782         }
1783     }
1784     endCommandBuffer(vk, *cmdBuffer);
1785     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1786 
1787     {
1788         std::string result;
1789 
1790         if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
1791             result += " ResolveColor";
1792 
1793         // Parse color aspect of separate samples of multisample image
1794         for (uint32_t sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
1795         {
1796             const std::string name("Color" + de::toString(sampleNdx));
1797             const Unique<VkImage> imageSample(
1798                 makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
1799             const UniquePtr<Allocation> imageSampleAlloc(
1800                 bindImage(vk, device, allocator, *imageSample, MemoryRequirement::Any));
1801             const Unique<VkBuffer> imageBuffer(
1802                 makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
1803             const UniquePtr<Allocation> imageBufferAlloc(
1804                 bindBuffer(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
1805 
1806             readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer,
1807                                               ASPECT_COLOR);
1808 
1809             if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
1810                 result += " " + name;
1811         }
1812 
1813         if (result.empty())
1814             return tcu::TestStatus::pass("Pass");
1815         else
1816             return tcu::TestStatus::fail("Fail");
1817     }
1818 }
1819 
1820 class DepthResolveImagelessTestInstance : public DepthImagelessTestInstance
1821 {
1822 public:
1823     DepthResolveImagelessTestInstance(Context &context, const TestParameters &parameters);
1824 
1825 protected:
1826     virtual tcu::TestStatus iterate(void);
1827 
1828     virtual MovePtr<tcu::TextureLevel> generateReferenceImage(const tcu::TextureFormat &textureFormat,
1829                                                               const AspectFlags aspectFlags, const uint32_t sample,
1830                                                               const uint32_t subpass);
1831 
1832     virtual std::vector<float> getVertices(void);
1833 };
1834 
DepthResolveImagelessTestInstance(Context & context,const TestParameters & parameters)1835 DepthResolveImagelessTestInstance::DepthResolveImagelessTestInstance(Context &context, const TestParameters &parameters)
1836     : DepthImagelessTestInstance(context, parameters)
1837 {
1838     context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
1839 
1840     const InstanceInterface &vki      = m_context.getInstanceInterface();
1841     const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
1842     VkPhysicalDeviceProperties2 deviceProperties;
1843     VkPhysicalDeviceDepthStencilResolveProperties dsResolveProperties;
1844 
1845     deMemset(&deviceProperties, 0, sizeof(deviceProperties));
1846     deMemset(&dsResolveProperties, 0, sizeof(dsResolveProperties));
1847 
1848     deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1849     deviceProperties.pNext = &dsResolveProperties;
1850 
1851     dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
1852     dsResolveProperties.pNext = DE_NULL;
1853 
1854     vki.getPhysicalDeviceProperties2(physDevice, &deviceProperties);
1855 
1856     m_colorImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1857 
1858     checkImageFormatProperties(vki, physDevice, m_parameters.colorFormat, m_colorImageUsage, m_imageExtent2D);
1859 
1860     m_dsImageUsage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1861 
1862     checkImageFormatProperties(vki, physDevice, m_parameters.dsFormat, m_dsImageUsage, m_imageExtent2D);
1863 }
1864 
generateReferenceImage(const tcu::TextureFormat & textureFormat,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t subpass)1865 MovePtr<tcu::TextureLevel> DepthResolveImagelessTestInstance::generateReferenceImage(
1866     const tcu::TextureFormat &textureFormat, const AspectFlags aspectFlags, const uint32_t sample,
1867     const uint32_t subpass)
1868 {
1869     const bool color   = ((aspectFlags & ASPECT_COLOR) != 0);
1870     const bool depth   = ((aspectFlags & ASPECT_DEPTH) != 0);
1871     const bool stencil = ((aspectFlags & ASPECT_STENCIL) != 0);
1872     const int width    = m_imageExtent2D.width;
1873     const int height   = m_imageExtent2D.height;
1874     MovePtr<tcu::TextureLevel> image(new tcu::TextureLevel(textureFormat, width, height));
1875     tcu::PixelBufferAccess access(image->getAccess());
1876 
1877     DE_ASSERT(dePop32(aspectFlags) == 1);
1878     DE_UNREF(subpass);
1879 
1880     if (color)
1881     {
1882         const tcu::Vec4 colorDraw(tcu::RGBA::blue().toVec());
1883         const tcu::Vec4 colorFill(tcu::RGBA::black().toVec());
1884         const tcu::Vec4 colorEdge0(colorDraw);
1885         const tcu::Vec4 colorEdge1(colorFill);
1886         const tcu::Vec4 colorEdge2(colorDraw);
1887         const tcu::Vec4 colorEdge3(colorFill);
1888         const tcu::Vec4 colorEdgeR((colorDraw.x() + colorFill.x()) / 2, (colorDraw.y() + colorFill.y()) / 2,
1889                                    (colorDraw.z() + colorFill.z()) / 2, colorDraw.w()); // AVERAGE
1890         const tcu::Vec4 &colorEdge = sample == 0 ? colorEdge0 :
1891                                      sample == 1 ? colorEdge1 :
1892                                      sample == 2 ? colorEdge2 :
1893                                      sample == 3 ? colorEdge3 :
1894                                                    colorEdgeR;
1895 
1896         for (int y = 0; y < height; ++y)
1897             for (int x = 0; x < width; ++x)
1898             {
1899                 const int mx                = width - 1 - x;
1900                 const tcu::Vec4 &validColor = (y == mx) ? colorEdge : (y > mx) ? colorFill : colorDraw;
1901 
1902                 access.setPixel(validColor, x, y);
1903             }
1904     }
1905 
1906     if (depth)
1907     {
1908         const int colorFillValue(static_cast<int>(1.00f * 0x100));
1909         const int colorDrawValue(static_cast<int>(0.00f * 0x100));
1910         const tcu::IVec4 colorFill(colorFillValue, colorFillValue, colorFillValue, 0xFF);
1911         const tcu::IVec4 colorDraw(colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
1912         const tcu::IVec4 colorEdge0(colorDraw);
1913         const tcu::IVec4 colorEdge1(colorFill);
1914         const tcu::IVec4 colorEdge2(colorDraw);
1915         const tcu::IVec4 colorEdge3(colorFill);
1916         const tcu::IVec4 colorEdgeR(colorEdge0); // SAMPLE_ZERO
1917         const tcu::IVec4 &colorEdge = sample == 0 ? colorEdge0 :
1918                                       sample == 1 ? colorEdge1 :
1919                                       sample == 2 ? colorEdge2 :
1920                                       sample == 3 ? colorEdge3 :
1921                                                     colorEdgeR;
1922 
1923         for (int y = 0; y < height; ++y)
1924             for (int x = 0; x < width; ++x)
1925             {
1926                 const int mx                 = width - 1 - x;
1927                 const tcu::IVec4 &validColor = (y == mx) ? colorEdge : (y > mx) ? colorFill : colorDraw;
1928 
1929                 access.setPixel(validColor, x, y);
1930             }
1931     }
1932 
1933     if (stencil)
1934     {
1935         const int colorFillValue((0 * 0x100) / 4);
1936         const int colorDrawValue((1 * 0x100) / 4);
1937         const tcu::IVec4 colorFill(colorFillValue, colorFillValue, colorFillValue, 0xFF);
1938         const tcu::IVec4 colorDraw(colorDrawValue, colorDrawValue, colorDrawValue, 0xFF);
1939         const tcu::IVec4 colorEdge0(colorDraw);
1940         const tcu::IVec4 colorEdge1(colorFill);
1941         const tcu::IVec4 colorEdge2(colorDraw);
1942         const tcu::IVec4 colorEdge3(colorFill);
1943         const tcu::IVec4 colorEdgeR(colorEdge0); // SAMPLE_ZERO
1944         const tcu::IVec4 &colorEdge = sample == 0 ? colorEdge0 :
1945                                       sample == 1 ? colorEdge1 :
1946                                       sample == 2 ? colorEdge2 :
1947                                       sample == 3 ? colorEdge3 :
1948                                                     colorEdgeR;
1949 
1950         for (int y = 0; y < height; ++y)
1951             for (int x = 0; x < width; ++x)
1952             {
1953                 const int mx                 = width - 1 - x;
1954                 const tcu::IVec4 &validColor = (y == mx) ? colorEdge : (y > mx) ? colorFill : colorDraw;
1955 
1956                 access.setPixel(validColor, x, y);
1957             }
1958     }
1959 
1960     return image;
1961 }
1962 
getVertices(void)1963 std::vector<float> DepthResolveImagelessTestInstance::getVertices(void)
1964 {
1965     const float verticesData[] = {
1966         -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, -1.0f, 0.0f, 1.0f,
1967         -1.0f, -1.0f, 0.5f, 1.0f, -1.0f, +1.0f, 0.5f, 1.0f, +1.0f, -1.0f, 0.5f, 1.0f,
1968     };
1969     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
1970 
1971     return vertices;
1972 }
1973 
iterate(void)1974 tcu::TestStatus DepthResolveImagelessTestInstance::iterate(void)
1975 {
1976     const DeviceInterface &vk       = m_context.getDeviceInterface();
1977     const VkDevice device           = m_context.getDevice();
1978     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1979     const VkQueue queue             = m_context.getUniversalQueue();
1980     Allocator &allocator            = m_context.getDefaultAllocator();
1981 
1982     const uint32_t sampleCount                  = 4u;
1983     const VkSampleCountFlagBits sampleCountFlag = sampleCountBitFromSampleCount(sampleCount);
1984     const tcu::Vec4 clearColor                  = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1985     const VkFormat colorFormat                  = m_parameters.colorFormat;
1986     const VkDeviceSize colorBufferSize =
1987         m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
1988     const VkImageSubresourceRange colorSubresRange =
1989         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1990 
1991     const Unique<VkImage> colorImage(
1992         makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage, sampleCountFlag)));
1993     const UniquePtr<Allocation> colorImageAlloc(bindImage(vk, device, allocator, *colorImage, MemoryRequirement::Any));
1994     const Unique<VkImageView> colorAttachment(
1995         makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
1996 
1997     const Unique<VkImage> colorResolveImage(
1998         makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
1999     const UniquePtr<Allocation> colorResolveImageAlloc(
2000         bindImage(vk, device, allocator, *colorResolveImage, MemoryRequirement::Any));
2001     const Unique<VkImageView> colorResolveAttachment(
2002         makeImageView(vk, device, *colorResolveImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
2003     const Unique<VkBuffer> colorResolveBuffer(
2004         makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2005     const UniquePtr<Allocation> colorResolveBufferAlloc(
2006         bindBuffer(vk, device, allocator, *colorResolveBuffer, MemoryRequirement::HostVisible));
2007 
2008     const float clearDepth                      = 1.0f;
2009     const uint32_t clearStencil                 = 0u;
2010     const VkFormat dsFormat                     = m_parameters.dsFormat;
2011     const uint32_t dsImagePixelSize             = static_cast<uint32_t>(tcu::getPixelSize(mapVkFormat(dsFormat)));
2012     const VkImageAspectFlags dsAspectFlags      = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
2013     const VkImageSubresourceRange dsSubresRange = makeImageSubresourceRange(dsAspectFlags, 0u, 1u, 0u, 1u);
2014 
2015     const VkDeviceSize depthBufferSize   = m_imageExtent2D.width * m_imageExtent2D.height * dsImagePixelSize;
2016     const VkFormat stencilBufferFormat   = getStencilBufferFormat(dsFormat);
2017     const uint32_t stencilPixelSize      = static_cast<uint32_t>(tcu::getPixelSize(mapVkFormat(stencilBufferFormat)));
2018     const VkDeviceSize stencilBufferSize = m_imageExtent2D.width * m_imageExtent2D.height * stencilPixelSize;
2019 
2020     const Unique<VkImage> dsImage(
2021         makeImage(vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage, sampleCountFlag)));
2022     const UniquePtr<Allocation> dsImageAlloc(bindImage(vk, device, allocator, *dsImage, MemoryRequirement::Any));
2023     const Unique<VkImageView> dsAttachment(
2024         makeImageView(vk, device, *dsImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
2025 
2026     const Unique<VkImage> dsResolveImage(
2027         makeImage(vk, device, makeImageCreateInfo(dsFormat, m_imageExtent2D, m_dsImageUsage)));
2028     const UniquePtr<Allocation> dsResolveImageAlloc(
2029         bindImage(vk, device, allocator, *dsResolveImage, MemoryRequirement::Any));
2030     const Unique<VkImageView> dsResolveAttachment(
2031         makeImageView(vk, device, *dsResolveImage, VK_IMAGE_VIEW_TYPE_2D, dsFormat, dsSubresRange));
2032     const Unique<VkBuffer> depthResolveBuffer(
2033         makeBuffer(vk, device, depthBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2034     const UniquePtr<Allocation> depthResolveBufferAlloc(
2035         bindBuffer(vk, device, allocator, *depthResolveBuffer, MemoryRequirement::HostVisible));
2036     const Unique<VkBuffer> stencilResolveBuffer(
2037         makeBuffer(vk, device, stencilBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2038     const UniquePtr<Allocation> stencilResolveBufferAlloc(
2039         bindBuffer(vk, device, allocator, *stencilResolveBuffer, MemoryRequirement::HostVisible));
2040 
2041     const Unique<VkShaderModule> vertModule(
2042         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
2043     const Unique<VkShaderModule> fragModule(
2044         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
2045     const Unique<VkRenderPass> renderPass(
2046         makeRenderPass(vk, device, colorFormat, m_parameters.dsFormat, sampleCountFlag, sampleCountFlag));
2047     const Unique<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, m_imageExtent2D, &colorFormat,
2048                                                             m_colorImageUsage, &m_parameters.dsFormat, m_dsImageUsage,
2049                                                             ASPECT_COLOR | ASPECT_DEPTH_STENCIL));
2050     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device));
2051     const Unique<VkPipeline> pipeline(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertModule,
2052                                                            *fragModule, m_imageExtent2D, ASPECT_DEPTH_STENCIL,
2053                                                            sampleCountFlag));
2054     const Unique<VkCommandPool> cmdPool(
2055         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2056     const Unique<VkCommandBuffer> cmdBuffer(
2057         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2058 
2059     const std::vector<float> vertexArray(getVertices());
2060     const uint32_t vertexCount(static_cast<uint32_t>(vertexArray.size() / 4u));
2061     const VkDeviceSize vertexArraySize(vertexArray.size() * sizeof(vertexArray[0]));
2062     const Unique<VkBuffer> vertexBuffer(makeBuffer(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
2063     const UniquePtr<Allocation> vertexBufferAlloc(
2064         bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
2065     const VkDeviceSize vertexBufferOffset(0u);
2066 
2067     fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
2068 
2069     beginCommandBuffer(vk, *cmdBuffer);
2070     {
2071         const VkImageView attachments[] = {*colorAttachment, *dsAttachment, *colorResolveAttachment,
2072                                            *dsResolveAttachment};
2073         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo = {
2074             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
2075             DE_NULL,                                             //  const void* pNext;
2076             DE_LENGTH_OF_ARRAY(attachments),                     //  uint32_t attachmentCount;
2077             attachments                                          //  const VkImageView* pAttachments;
2078         };
2079 
2080         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor, clearDepth,
2081                         clearStencil, &renderPassAttachmentBeginInfo);
2082         {
2083             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
2084 
2085             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
2086 
2087             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
2088         }
2089         endRenderPass(vk, *cmdBuffer);
2090 
2091         // Color resolve image copy
2092         {
2093             const VkImageMemoryBarrier preCopyBarrier =
2094                 makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2095                                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2096                                        *colorResolveImage, colorSubresRange);
2097             const VkBufferImageCopy region =
2098                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2099                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2100             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
2101                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorResolveBuffer, 0ull, VK_WHOLE_SIZE);
2102 
2103             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2104                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
2105             vk.cmdCopyImageToBuffer(*cmdBuffer, *colorResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2106                                     *colorResolveBuffer, 1u, &region);
2107             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
2108                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
2109         }
2110 
2111         // Depth/Stencil resolve image copy
2112         {
2113             const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(
2114                 0u, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2115                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *dsResolveImage, dsSubresRange);
2116             const VkBufferImageCopy depthCopyRegion =
2117                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2118                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u));
2119             const VkBufferImageCopy stencilCopyRegion =
2120                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2121                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u));
2122             const VkBufferMemoryBarrier postCopyBarriers[] = {
2123                 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *depthResolveBuffer,
2124                                         0ull, VK_WHOLE_SIZE),
2125                 makeBufferMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *stencilResolveBuffer,
2126                                         0ull, VK_WHOLE_SIZE),
2127             };
2128 
2129             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
2130                                   0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
2131             vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2132                                     *depthResolveBuffer, 1u, &depthCopyRegion);
2133             vk.cmdCopyImageToBuffer(*cmdBuffer, *dsResolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2134                                     *stencilResolveBuffer, 1u, &stencilCopyRegion);
2135             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
2136                                   DE_NULL, DE_LENGTH_OF_ARRAY(postCopyBarriers), postCopyBarriers, DE_NULL, 0u);
2137         }
2138     }
2139     endCommandBuffer(vk, *cmdBuffer);
2140     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2141 
2142     {
2143         std::string result;
2144 
2145         if (!verifyBuffer(colorResolveBufferAlloc, colorFormat, "ResolveColor", ASPECT_COLOR))
2146             result += " ResolveColor";
2147 
2148         if (!verifyBuffer(depthResolveBufferAlloc, dsFormat, "ResolveDepth", ASPECT_DEPTH))
2149             result += " ResolveDepth";
2150 
2151         if (!verifyBuffer(stencilResolveBufferAlloc, stencilBufferFormat, "ResolveStencil", ASPECT_STENCIL))
2152             result += " ResolveStencil";
2153 
2154         // Parse color aspect of separate samples of multisample image
2155         for (uint32_t sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
2156         {
2157             const std::string name("Color" + de::toString(sampleNdx));
2158             const Unique<VkImage> imageSample(
2159                 makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
2160             const UniquePtr<Allocation> imageSampleAlloc(
2161                 bindImage(vk, device, allocator, *imageSample, MemoryRequirement::Any));
2162             const Unique<VkBuffer> imageBuffer(
2163                 makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2164             const UniquePtr<Allocation> imageBufferAlloc(
2165                 bindBuffer(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
2166 
2167             readOneSampleFromMultisampleImage(colorFormat, colorImage, sampleNdx, colorFormat, imageSample, imageBuffer,
2168                                               ASPECT_COLOR);
2169 
2170             if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_COLOR, sampleNdx))
2171                 result += " " + name;
2172         }
2173 
2174         // Parse depth aspect of separate samples of multisample image
2175         for (uint32_t sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
2176         {
2177             const std::string name("Depth" + de::toString(sampleNdx));
2178             const Unique<VkImage> imageSample(
2179                 makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
2180             const UniquePtr<Allocation> imageSampleAlloc(
2181                 bindImage(vk, device, allocator, *imageSample, MemoryRequirement::Any));
2182             const Unique<VkBuffer> imageBuffer(
2183                 makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2184             const UniquePtr<Allocation> imageBufferAlloc(
2185                 bindBuffer(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
2186 
2187             readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer,
2188                                               ASPECT_DEPTH);
2189 
2190             if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_DEPTH, sampleNdx))
2191                 result += " " + name;
2192         }
2193 
2194         // Parse stencil aspect of separate samples of multisample image
2195         for (uint32_t sampleNdx = 0; sampleNdx < sampleCount; ++sampleNdx)
2196         {
2197             const std::string name("Stencil" + de::toString(sampleNdx));
2198             const Unique<VkImage> imageSample(
2199                 makeImage(vk, device, makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage)));
2200             const UniquePtr<Allocation> imageSampleAlloc(
2201                 bindImage(vk, device, allocator, *imageSample, MemoryRequirement::Any));
2202             const Unique<VkBuffer> imageBuffer(
2203                 makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2204             const UniquePtr<Allocation> imageBufferAlloc(
2205                 bindBuffer(vk, device, allocator, *imageBuffer, MemoryRequirement::HostVisible));
2206 
2207             readOneSampleFromMultisampleImage(dsFormat, dsImage, sampleNdx, colorFormat, imageSample, imageBuffer,
2208                                               ASPECT_STENCIL);
2209 
2210             if (!verifyBuffer(imageBufferAlloc, colorFormat, name, ASPECT_STENCIL, sampleNdx))
2211                 result += " " + name;
2212         }
2213 
2214         if (result.empty())
2215             return tcu::TestStatus::pass("Pass");
2216         else
2217             return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
2218     }
2219 }
2220 
2221 class MultisubpassTestInstance : public ColorImagelessTestInstance
2222 {
2223 public:
2224     MultisubpassTestInstance(Context &context, const TestParameters &parameters);
2225 
2226 protected:
2227     virtual tcu::TestStatus iterate(void);
2228 
2229     virtual std::vector<float> getVertices(void);
2230 
2231     virtual MovePtr<tcu::TextureLevel> generateReferenceImage(const tcu::TextureFormat &textureFormat,
2232                                                               const AspectFlags aspectFlags, const uint32_t sample,
2233                                                               const uint32_t subpass);
2234 };
2235 
MultisubpassTestInstance(Context & context,const TestParameters & parameters)2236 MultisubpassTestInstance::MultisubpassTestInstance(Context &context, const TestParameters &parameters)
2237     : ColorImagelessTestInstance(context, parameters)
2238 {
2239 }
2240 
getVertices(void)2241 std::vector<float> MultisubpassTestInstance::getVertices(void)
2242 {
2243     const float verticesData[] = {
2244         -1.0f, 0.0f,  0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, 0.0f,  0.0f, 1.0f,
2245         -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, 0.0f,  0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f,
2246     };
2247     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
2248 
2249     return vertices;
2250 }
2251 
generateReferenceImage(const tcu::TextureFormat & textureFormat,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t subpass)2252 MovePtr<tcu::TextureLevel> MultisubpassTestInstance::generateReferenceImage(const tcu::TextureFormat &textureFormat,
2253                                                                             const AspectFlags aspectFlags,
2254                                                                             const uint32_t sample,
2255                                                                             const uint32_t subpass)
2256 {
2257     const int width  = m_imageExtent2D.width;
2258     const int height = m_imageExtent2D.height;
2259     const tcu::Vec4 colorDraw0(0.0f, 0.0f, 1.0f, 1.0f);
2260     const tcu::Vec4 colorFill0(tcu::RGBA::black().toVec());
2261     const tcu::Vec4 colorDraw1(colorDraw0.x(), 1.0f, colorDraw0.z(), 1.0f);
2262     const tcu::Vec4 colorFill1(colorFill0.x(), 1.0f, colorFill0.z(), 1.0f);
2263     const tcu::Vec4 &colorDraw((subpass == 0) ? colorDraw0 : colorDraw1);
2264     const tcu::Vec4 &colorFill((subpass == 0) ? colorFill0 : colorFill1);
2265     MovePtr<tcu::TextureLevel> image(new tcu::TextureLevel(textureFormat, width, height));
2266     tcu::PixelBufferAccess access(image->getAccess());
2267 
2268     DE_UNREF(aspectFlags);
2269     DE_ASSERT(aspectFlags == ASPECT_COLOR);
2270     DE_UNREF(sample);
2271     DE_ASSERT(sample == NO_SAMPLE);
2272     DE_ASSERT(subpass != NO_SUBPASS);
2273 
2274     for (int y = 0; y < height; ++y)
2275     {
2276         const tcu::Vec4 &validColor = (y < height / 2) ? colorFill : colorDraw;
2277 
2278         for (int x = 0; x < width; ++x)
2279             access.setPixel(validColor, x, y);
2280     }
2281 
2282     return image;
2283 }
2284 
iterate(void)2285 tcu::TestStatus MultisubpassTestInstance::iterate(void)
2286 {
2287     const DeviceInterface &vk       = m_context.getDeviceInterface();
2288     const VkDevice device           = m_context.getDevice();
2289     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2290     const VkQueue queue             = m_context.getUniversalQueue();
2291     Allocator &allocator            = m_context.getDefaultAllocator();
2292 
2293     const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2294     const VkFormat colorFormat = m_parameters.colorFormat;
2295     const VkDeviceSize colorBufferSize =
2296         m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
2297     const VkImageSubresourceRange colorSubresRange =
2298         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2299 
2300     const Unique<VkImage> color0Image(makeImage(
2301         vk, device,
2302         makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
2303     const UniquePtr<Allocation> color0ImageAlloc(
2304         bindImage(vk, device, allocator, *color0Image, MemoryRequirement::Any));
2305     const Unique<VkImageView> color0Attachment(
2306         makeImageView(vk, device, *color0Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
2307     const Unique<VkBuffer> color0Buffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2308     const UniquePtr<Allocation> color0BufferAlloc(
2309         bindBuffer(vk, device, allocator, *color0Buffer, MemoryRequirement::HostVisible));
2310 
2311     const Unique<VkImage> color1Image(makeImage(
2312         vk, device,
2313         makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
2314     const UniquePtr<Allocation> color1ImageAlloc(
2315         bindImage(vk, device, allocator, *color1Image, MemoryRequirement::Any));
2316     const Unique<VkImageView> color1Attachment(
2317         makeImageView(vk, device, *color1Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
2318     const Unique<VkBuffer> color1Buffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2319     const UniquePtr<Allocation> color1BufferAlloc(
2320         bindBuffer(vk, device, allocator, *color1Buffer, MemoryRequirement::HostVisible));
2321 
2322     const VkDescriptorType descriptorType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
2323     const Unique<VkDescriptorSetLayout> descriptorSetLayout(
2324         DescriptorSetLayoutBuilder().addSingleBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT).build(vk, device));
2325     const Unique<VkDescriptorPool> descriptorPool(
2326         DescriptorPoolBuilder()
2327             .addType(descriptorType)
2328             .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
2329     const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
2330     const VkDescriptorImageInfo imageDescriptorInfo(
2331         makeDescriptorImageInfo(DE_NULL, *color0Attachment, VK_IMAGE_LAYOUT_GENERAL));
2332 
2333     DescriptorSetUpdateBuilder()
2334         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType,
2335                      &imageDescriptorInfo)
2336         .update(vk, device);
2337 
2338     const Unique<VkRenderPass> renderPass(makeRenderPass(vk, device, colorFormat, DE_NULL));
2339     const Unique<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, m_imageExtent2D, &colorFormat,
2340                                                             m_colorImageUsage, &m_parameters.dsFormat, 0u, ASPECT_NONE,
2341                                                             1u));
2342     const Unique<VkCommandPool> cmdPool(
2343         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2344     const Unique<VkCommandBuffer> cmdBuffer(
2345         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2346 
2347     const Unique<VkShaderModule> vertModule0(
2348         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
2349     const Unique<VkShaderModule> fragModule0(
2350         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
2351     const Unique<VkPipelineLayout> pipelineLayout0(makePipelineLayout(vk, device));
2352     const Unique<VkPipeline> pipeline0(
2353         makeGraphicsPipeline(vk, device, *pipelineLayout0, *renderPass, *vertModule0, *fragModule0, m_imageExtent2D));
2354 
2355     const Unique<VkShaderModule> vertModule1(
2356         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert1"), 0u));
2357     const Unique<VkShaderModule> fragModule1(
2358         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag1"), 0u));
2359     const Unique<VkPipelineLayout> pipelineLayout1(makePipelineLayout(vk, device, 1u, &*descriptorSetLayout));
2360     const Unique<VkPipeline> pipeline1(makeGraphicsPipeline(vk, device, *pipelineLayout1, *renderPass, *vertModule1,
2361                                                             *fragModule1, m_imageExtent2D, 0u, VK_SAMPLE_COUNT_1_BIT,
2362                                                             1u));
2363 
2364     const std::vector<float> vertex0Array(getVertices());
2365     const uint32_t vertex0Count(static_cast<uint32_t>(vertex0Array.size() / 4u));
2366     const VkDeviceSize vertex0ArraySize(vertex0Array.size() * sizeof(vertex0Array[0]));
2367     const Unique<VkBuffer> vertex0Buffer(makeBuffer(vk, device, vertex0ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
2368     const UniquePtr<Allocation> vertex0BufferAlloc(
2369         bindBuffer(vk, device, allocator, *vertex0Buffer, MemoryRequirement::HostVisible));
2370     const VkDeviceSize vertex0BufferOffset(0u);
2371 
2372     const std::vector<float> vertex1Array(getFullQuadVertices());
2373     const uint32_t vertex1Count(static_cast<uint32_t>(vertex1Array.size() / 4u));
2374     const VkDeviceSize vertex1ArraySize(vertex1Array.size() * sizeof(vertex1Array[0]));
2375     const Unique<VkBuffer> vertex1Buffer(makeBuffer(vk, device, vertex1ArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
2376     const UniquePtr<Allocation> vertex1BufferAlloc(
2377         bindBuffer(vk, device, allocator, *vertex1Buffer, MemoryRequirement::HostVisible));
2378     const VkDeviceSize vertex1BufferOffset(0u);
2379 
2380     fillBuffer(vk, device, *vertex0BufferAlloc, &vertex0Array[0], vertex0ArraySize);
2381     fillBuffer(vk, device, *vertex1BufferAlloc, &vertex1Array[0], vertex1ArraySize);
2382 
2383     beginCommandBuffer(vk, *cmdBuffer);
2384     {
2385         const VkImageView attachments[]                                     = {*color0Attachment, *color1Attachment};
2386         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo = {
2387             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
2388             DE_NULL,                                             //  const void* pNext;
2389             DE_LENGTH_OF_ARRAY(attachments),                     //  uint32_t attachmentCount;
2390             &attachments[0]                                      //  const VkImageView* pAttachments;
2391         };
2392 
2393         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor,
2394                         &renderPassAttachmentBeginInfo);
2395         {
2396             {
2397                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline0);
2398 
2399                 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex0Buffer, &vertex0BufferOffset);
2400 
2401                 vk.cmdDraw(*cmdBuffer, vertex0Count, 1u, 0u, 0u);
2402             }
2403 
2404             vk.cmdNextSubpass(*cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
2405 
2406             {
2407                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline1);
2408 
2409                 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertex1Buffer, &vertex1BufferOffset);
2410 
2411                 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout1, 0u, 1u,
2412                                          &descriptorSet.get(), 0u, DE_NULL);
2413 
2414                 vk.cmdDraw(*cmdBuffer, vertex1Count, 1u, 0u, 0u);
2415             }
2416         }
2417         endRenderPass(vk, *cmdBuffer);
2418 
2419         // Subpass0 color image copy
2420         {
2421             const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(
2422                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
2423                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Image, colorSubresRange);
2424             const VkBufferImageCopy region =
2425                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2426                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2427             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
2428                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color0Buffer, 0ull, VK_WHOLE_SIZE);
2429 
2430             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2431                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
2432             vk.cmdCopyImageToBuffer(*cmdBuffer, *color0Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Buffer, 1u,
2433                                     &region);
2434             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
2435                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
2436         }
2437 
2438         // Subpass1 color image copy
2439         {
2440             const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(
2441                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
2442                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Image, colorSubresRange);
2443             const VkBufferImageCopy region =
2444                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2445                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2446             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
2447                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color1Buffer, 0ull, VK_WHOLE_SIZE);
2448 
2449             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2450                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
2451             vk.cmdCopyImageToBuffer(*cmdBuffer, *color1Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Buffer, 1u,
2452                                     &region);
2453             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
2454                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
2455         }
2456     }
2457     endCommandBuffer(vk, *cmdBuffer);
2458     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2459 
2460     {
2461         std::string result;
2462 
2463         if (!verifyBuffer(color0BufferAlloc, colorFormat, "ColorSubpass0", ASPECT_COLOR, NO_SAMPLE, 0u))
2464             result += " ColorSubpass0";
2465 
2466         if (!verifyBuffer(color1BufferAlloc, colorFormat, "ColorSubpass1", ASPECT_COLOR, NO_SAMPLE, 1u))
2467             result += " ColorSubpass1";
2468 
2469         if (result.empty())
2470             return tcu::TestStatus::pass("Pass");
2471         else
2472             return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
2473     }
2474 }
2475 
2476 class DifferentAttachmentsTestInstance : public ColorImagelessTestInstance
2477 {
2478 public:
2479     DifferentAttachmentsTestInstance(Context &context, const TestParameters &parameters);
2480 
2481 protected:
2482     virtual tcu::TestStatus iterate(void);
2483 
2484     virtual std::vector<float> getVertices(void);
2485 
2486     virtual MovePtr<tcu::TextureLevel> generateReferenceImage(const tcu::TextureFormat &textureFormat,
2487                                                               const AspectFlags aspectFlags, const uint32_t sample,
2488                                                               const uint32_t subpass);
2489 };
2490 
DifferentAttachmentsTestInstance(Context & context,const TestParameters & parameters)2491 DifferentAttachmentsTestInstance::DifferentAttachmentsTestInstance(Context &context, const TestParameters &parameters)
2492     : ColorImagelessTestInstance(context, parameters)
2493 {
2494 }
2495 
getVertices(void)2496 std::vector<float> DifferentAttachmentsTestInstance::getVertices(void)
2497 {
2498     const float verticesData[] = {
2499         -1.0f, 0.0f,  0.0f, 1.0f, -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, 0.0f,  0.0f, 1.0f,
2500         -1.0f, +1.0f, 0.0f, 1.0f, +1.0f, 0.0f,  0.0f, 1.0f, +1.0f, +1.0f, 0.0f, 1.0f,
2501     };
2502     const std::vector<float> vertices(verticesData, verticesData + DE_LENGTH_OF_ARRAY(verticesData));
2503 
2504     return vertices;
2505 }
2506 
generateReferenceImage(const tcu::TextureFormat & textureFormat,const AspectFlags aspectFlags,const uint32_t sample,const uint32_t)2507 MovePtr<tcu::TextureLevel> DifferentAttachmentsTestInstance::generateReferenceImage(
2508     const tcu::TextureFormat &textureFormat, const AspectFlags aspectFlags, const uint32_t sample, const uint32_t)
2509 {
2510     const int width  = m_imageExtent2D.width;
2511     const int height = m_imageExtent2D.height;
2512     const tcu::Vec4 colorDraw(0.0f, 0.0f, 1.0f, 1.0f);
2513     const tcu::Vec4 colorFill(tcu::RGBA::black().toVec());
2514     MovePtr<tcu::TextureLevel> image(new tcu::TextureLevel(textureFormat, width, height));
2515     tcu::PixelBufferAccess access(image->getAccess());
2516 
2517     DE_UNREF(aspectFlags);
2518     DE_ASSERT(aspectFlags == ASPECT_COLOR);
2519     DE_UNREF(sample);
2520     DE_ASSERT(sample == NO_SAMPLE);
2521 
2522     for (int y = 0; y < height; ++y)
2523     {
2524         const tcu::Vec4 &validColor = (y < height / 2) ? colorFill : colorDraw;
2525 
2526         for (int x = 0; x < width; ++x)
2527             access.setPixel(validColor, x, y);
2528     }
2529 
2530     return image;
2531 }
2532 
iterate(void)2533 tcu::TestStatus DifferentAttachmentsTestInstance::iterate(void)
2534 {
2535     const DeviceInterface &vk       = m_context.getDeviceInterface();
2536     const VkDevice device           = m_context.getDevice();
2537     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2538     const VkQueue queue             = m_context.getUniversalQueue();
2539     Allocator &allocator            = m_context.getDefaultAllocator();
2540 
2541     const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2542     const VkFormat colorFormat = m_parameters.colorFormat;
2543     const VkDeviceSize colorBufferSize =
2544         m_imageExtent2D.width * m_imageExtent2D.height * tcu::getPixelSize(mapVkFormat(colorFormat));
2545     const VkImageSubresourceRange colorSubresRange =
2546         makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
2547 
2548     const Unique<VkImage> color0Image(makeImage(
2549         vk, device,
2550         makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
2551     const UniquePtr<Allocation> color0ImageAlloc(
2552         bindImage(vk, device, allocator, *color0Image, MemoryRequirement::Any));
2553     const Unique<VkImageView> color0Attachment(
2554         makeImageView(vk, device, *color0Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
2555     const Unique<VkBuffer> color0Buffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2556     const UniquePtr<Allocation> color0BufferAlloc(
2557         bindBuffer(vk, device, allocator, *color0Buffer, MemoryRequirement::HostVisible));
2558 
2559     const Unique<VkImage> color1Image(makeImage(
2560         vk, device,
2561         makeImageCreateInfo(colorFormat, m_imageExtent2D, m_colorImageUsage | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)));
2562     const UniquePtr<Allocation> color1ImageAlloc(
2563         bindImage(vk, device, allocator, *color1Image, MemoryRequirement::Any));
2564     const Unique<VkImageView> color1Attachment(
2565         makeImageView(vk, device, *color1Image, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresRange));
2566     const Unique<VkBuffer> color1Buffer(makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
2567     const UniquePtr<Allocation> color1BufferAlloc(
2568         bindBuffer(vk, device, allocator, *color1Buffer, MemoryRequirement::HostVisible));
2569 
2570     const Unique<VkRenderPass> renderPass(makeSingleAttachmentRenderPass(vk, device, colorFormat, DE_NULL));
2571     const Unique<VkFramebuffer> framebuffer(makeFramebuffer(vk, device, *renderPass, m_imageExtent2D, &colorFormat,
2572                                                             m_colorImageUsage, &m_parameters.dsFormat));
2573     const Unique<VkCommandPool> cmdPool(
2574         createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2575     const Unique<VkCommandBuffer> cmdBuffer(
2576         allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2577 
2578     const Unique<VkShaderModule> vertModule(
2579         createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
2580     const Unique<VkShaderModule> fragModule(
2581         createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u));
2582     const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device));
2583     const Unique<VkPipeline> pipeline(
2584         makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertModule, *fragModule, m_imageExtent2D));
2585 
2586     const std::vector<float> vertexArray(getVertices());
2587     const uint32_t vertexCount(static_cast<uint32_t>(vertexArray.size() / 4u));
2588     const VkDeviceSize vertexArraySize(vertexArray.size() * sizeof(vertexArray[0]));
2589     const Unique<VkBuffer> vertexBuffer(makeBuffer(vk, device, vertexArraySize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT));
2590     const UniquePtr<Allocation> vertexBufferAlloc(
2591         bindBuffer(vk, device, allocator, *vertexBuffer, MemoryRequirement::HostVisible));
2592     const VkDeviceSize vertexBufferOffset(0u);
2593 
2594     fillBuffer(vk, device, *vertexBufferAlloc, &vertexArray[0], vertexArraySize);
2595 
2596     beginCommandBuffer(vk, *cmdBuffer);
2597     {
2598         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo0 = {
2599             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
2600             DE_NULL,                                             //  const void* pNext;
2601             1u,                                                  //  uint32_t attachmentCount;
2602             &*color0Attachment                                   //  const VkImageView* pAttachments;
2603         };
2604 
2605         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor,
2606                         &renderPassAttachmentBeginInfo0);
2607         {
2608             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
2609 
2610             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
2611 
2612             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
2613         }
2614         endRenderPass(vk, *cmdBuffer);
2615 
2616         const VkRenderPassAttachmentBeginInfo renderPassAttachmentBeginInfo1 = {
2617             VK_STRUCTURE_TYPE_RENDER_PASS_ATTACHMENT_BEGIN_INFO, //  VkStructureType sType;
2618             DE_NULL,                                             //  const void* pNext;
2619             1u,                                                  //  uint32_t attachmentCount;
2620             &*color1Attachment                                   //  const VkImageView* pAttachments;
2621         };
2622 
2623         beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, makeRect2D(m_imageExtent2D), clearColor,
2624                         &renderPassAttachmentBeginInfo1);
2625         {
2626             vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
2627 
2628             vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &*vertexBuffer, &vertexBufferOffset);
2629 
2630             vk.cmdDraw(*cmdBuffer, vertexCount, 1u, 0u, 0u);
2631         }
2632         endRenderPass(vk, *cmdBuffer);
2633 
2634         // Subpass0 color image copy
2635         {
2636             const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(
2637                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
2638                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Image, colorSubresRange);
2639             const VkBufferImageCopy region =
2640                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2641                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2642             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
2643                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color0Buffer, 0ull, VK_WHOLE_SIZE);
2644 
2645             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2646                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
2647             vk.cmdCopyImageToBuffer(*cmdBuffer, *color0Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color0Buffer, 1u,
2648                                     &region);
2649             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
2650                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
2651         }
2652 
2653         // Subpass1 color image copy
2654         {
2655             const VkImageMemoryBarrier preCopyBarrier = makeImageMemoryBarrier(
2656                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
2657                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Image, colorSubresRange);
2658             const VkBufferImageCopy region =
2659                 makeBufferImageCopy(makeExtent3D(m_imageExtent2D.width, m_imageExtent2D.height, 1u),
2660                                     makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u));
2661             const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier(
2662                 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *color1Buffer, 0ull, VK_WHOLE_SIZE);
2663 
2664             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2665                                   VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyBarrier);
2666             vk.cmdCopyImageToBuffer(*cmdBuffer, *color1Image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *color1Buffer, 1u,
2667                                     &region);
2668             vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
2669                                   DE_NULL, 1u, &postCopyBarrier, DE_NULL, 0u);
2670         }
2671     }
2672     endCommandBuffer(vk, *cmdBuffer);
2673     submitCommandsAndWait(vk, device, queue, *cmdBuffer);
2674 
2675     {
2676         std::string result;
2677 
2678         if (!verifyBuffer(color0BufferAlloc, colorFormat, "ColorSubpass0", ASPECT_COLOR, NO_SAMPLE, 0u))
2679             result += " ColorSubpass0";
2680 
2681         if (!verifyBuffer(color1BufferAlloc, colorFormat, "ColorSubpass1", ASPECT_COLOR, NO_SAMPLE, 1u))
2682             result += " ColorSubpass1";
2683 
2684         if (result.empty())
2685             return tcu::TestStatus::pass("Pass");
2686         else
2687             return tcu::TestStatus::fail("Following parts of image are incorrect:" + result);
2688     }
2689 }
2690 
2691 class BaseTestCase : public TestCase
2692 {
2693 public:
2694     BaseTestCase(tcu::TestContext &context, const std::string &name, const TestParameters &parameters);
2695     virtual ~BaseTestCase(void);
2696 
2697 protected:
2698     virtual void checkSupport(Context &context) const;
2699     virtual void initPrograms(SourceCollections &programCollection) const;
2700     virtual TestInstance *createInstance(Context &context) const;
2701 
2702     const TestParameters m_parameters;
2703 };
2704 
BaseTestCase(tcu::TestContext & context,const std::string & name,const TestParameters & parameters)2705 BaseTestCase::BaseTestCase(tcu::TestContext &context, const std::string &name, const TestParameters &parameters)
2706     : TestCase(context, name)
2707     , m_parameters(parameters)
2708 {
2709 }
2710 
~BaseTestCase()2711 BaseTestCase::~BaseTestCase()
2712 {
2713 }
2714 
checkSupport(Context & context) const2715 void BaseTestCase::checkSupport(Context &context) const
2716 {
2717     if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
2718     {
2719         if (!context.getDeviceProperties().limits.standardSampleLocations)
2720             TCU_THROW(NotSupportedError, "Non-standard sample locations are not supported");
2721     }
2722 }
2723 
initPrograms(SourceCollections & programCollection) const2724 void BaseTestCase::initPrograms(SourceCollections &programCollection) const
2725 {
2726     // Vertex shader
2727     {
2728         std::ostringstream src;
2729 
2730         if (m_parameters.testType == TEST_TYPE_COLOR || m_parameters.testType == TEST_TYPE_COLOR_RESOLVE ||
2731             m_parameters.testType == TEST_TYPE_DEPTH_STENCIL)
2732         {
2733             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2734                 << "\n"
2735                 << "layout(location = 0) in highp vec4 a_position;\n"
2736                 << "layout(location = 0) out highp vec4 a_color;\n"
2737                 << "\n"
2738                 << "void main (void)\n"
2739                 << "{\n"
2740                 << "    gl_Position = a_position;\n"
2741                 << "    if (gl_VertexIndex < 6)\n"
2742                 << "        a_color = vec4(0.75f, 0.75f, 0.75f, 1.0f);\n"
2743                 << "    else\n"
2744                 << "        a_color = vec4(1.00f, 1.00f, 1.00f, 1.0f);\n"
2745                 << "}\n";
2746         }
2747 
2748         if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
2749         {
2750             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2751                 << "\n"
2752                 << "layout(location = 0) in highp vec4 a_position;\n"
2753                 << "layout(location = 0) out highp vec4 a_color;\n"
2754                 << "\n"
2755                 << "void main (void)\n"
2756                 << "{\n"
2757                 << "    gl_Position = a_position;\n"
2758                 << "    if (gl_VertexIndex < 3)\n"
2759                 << "        a_color = vec4(0.00f, 0.00f, 1.00f, 1.0f);\n"
2760                 << "    else\n"
2761                 << "        a_color = vec4(0.00f, 1.00f, 0.00f, 1.0f);\n"
2762                 << "}\n";
2763         }
2764 
2765         if (m_parameters.testType == TEST_TYPE_MULTISUBPASS || m_parameters.testType == TEST_TYPE_DIFFERENT_ATTACHMENTS)
2766         {
2767             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2768                 << "\n"
2769                 << "layout(location = 0) in highp vec4 a_position;\n"
2770                 << "layout(location = 0) out highp vec4 a_color;\n"
2771                 << "\n"
2772                 << "void main (void)\n"
2773                 << "{\n"
2774                 << "    gl_Position = a_position;\n"
2775                 << "    a_color = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n"
2776                 << "}\n";
2777         }
2778 
2779         programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
2780     }
2781 
2782     // Fragment shader
2783     {
2784         std::ostringstream src;
2785 
2786         src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2787             << "\n"
2788             << "layout(location = 0) in highp vec4 a_color;\n"
2789             << "layout(location = 0) out highp vec4 o_color;\n"
2790             << "\n"
2791             << "void main (void)\n"
2792             << "{\n"
2793             << "    o_color = a_color;\n"
2794             << "}\n";
2795 
2796         programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
2797     }
2798 
2799     // Additional shaders
2800     if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE || m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
2801     {
2802         // Vertex shader
2803         {
2804             std::ostringstream src;
2805 
2806             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2807                 << "\n"
2808                 << "layout(location = 0) in highp vec4 a_position;\n"
2809                 << "\n"
2810                 << "void main (void)\n"
2811                 << "{\n"
2812                 << "    gl_Position = a_position;\n"
2813                 << "}\n";
2814 
2815             programCollection.glslSources.add("demultisample-vert") << glu::VertexSource(src.str());
2816         }
2817 
2818         // Fragment shader
2819         {
2820             // Color
2821             {
2822                 std::ostringstream src;
2823 
2824                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2825                     << "\n"
2826                     << "layout(set = 0, binding = 0) uniform sampler2DMS u_ms_image_sampler;\n"
2827                     << "layout(push_constant) uniform PushConstantsBlock {\n"
2828                     << "    highp int sampleID;\n"
2829                     << "} pushConstants;\n"
2830                     << "layout(location = 0) out highp vec4 o_color;\n"
2831                     << "\n"
2832                     << "void main (void)\n"
2833                     << "{\n"
2834                     << "    o_color = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), pushConstants.sampleID);\n"
2835                     << "}\n";
2836 
2837                 programCollection.glslSources.add("demultisample-color-frag") << glu::FragmentSource(src.str());
2838             }
2839 
2840             // Depth
2841             {
2842                 std::ostringstream src;
2843 
2844                 // Depth-component textures are treated as one-component floating-point textures.
2845                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2846                     << "\n"
2847                     << "layout(binding = 0) uniform sampler2DMS u_ms_image_sampler;\n"
2848                     << "layout(push_constant) uniform PushConstantsBlock {\n"
2849                     << "    highp int sampleID;\n"
2850                     << "} pushConstants;\n"
2851                     << "layout(location = 0) out highp vec4 o_color;\n"
2852                     << "\n"
2853                     << "void main (void)\n"
2854                     << "{\n"
2855                     << "    vec4 val = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), "
2856                        "pushConstants.sampleID);\n"
2857                     << "    o_color = vec4(val.x, val.x, val.x, 1.0);\n"
2858                     << "}\n";
2859 
2860                 programCollection.glslSources.add("demultisample-depth-frag") << glu::FragmentSource(src.str());
2861             }
2862 
2863             // Stencil
2864             {
2865                 std::ostringstream src;
2866 
2867                 // Stencil-component textures are treated as one-component unsigned integer textures.
2868                 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2869                     << "\n"
2870                     << "layout(binding = 0) uniform usampler2DMS u_ms_image_sampler;\n"
2871                     << "layout(push_constant) uniform PushConstantsBlock {\n"
2872                     << "    highp int sampleID;\n"
2873                     << "} pushConstants;\n"
2874                     << "layout(location = 0) out highp vec4 o_color;\n"
2875                     << "\n"
2876                     << "void main (void)\n"
2877                     << "{\n"
2878                     << "    uvec4 uVal = texelFetch(u_ms_image_sampler, ivec2(gl_FragCoord.xy), "
2879                        "pushConstants.sampleID);\n"
2880                     << "    float val = float(uVal.x) / 4.0f;\n"
2881                     << "    o_color = vec4(val, val, val, 1.0);\n"
2882                     << "}\n";
2883 
2884                 programCollection.glslSources.add("demultisample-stencil-frag") << glu::FragmentSource(src.str());
2885             }
2886         }
2887     }
2888 
2889     if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
2890     {
2891         // Vertex shader
2892         {
2893             std::ostringstream src;
2894 
2895             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2896                 << "\n"
2897                 << "layout(location = 0) in highp vec4 a_position;\n"
2898                 << "\n"
2899                 << "void main (void)\n"
2900                 << "{\n"
2901                 << "    gl_Position = a_position;\n"
2902                 << "}\n";
2903 
2904             programCollection.glslSources.add("vert1") << glu::VertexSource(src.str());
2905         }
2906 
2907         // Fragment shader
2908         {
2909             std::ostringstream src;
2910 
2911             src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
2912                 << "\n"
2913                 << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput u_colors;\n"
2914                 << "layout(location = 0) out highp vec4 o_color;\n"
2915                 << "\n"
2916                 << "void main (void)\n"
2917                 << "{\n"
2918                 << "    o_color = subpassLoad(u_colors);\n"
2919                 << "    o_color.g = 1.0f;\n"
2920                 << "    o_color.a = 1.0f;\n"
2921                 << "}\n";
2922 
2923             programCollection.glslSources.add("frag1") << glu::FragmentSource(src.str());
2924         }
2925     }
2926 
2927     return;
2928 }
2929 
createInstance(Context & context) const2930 TestInstance *BaseTestCase::createInstance(Context &context) const
2931 {
2932     if (m_parameters.testType == TEST_TYPE_COLOR)
2933         return new ColorImagelessTestInstance(context, m_parameters);
2934 
2935     if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL)
2936         return new DepthImagelessTestInstance(context, m_parameters);
2937 
2938     if (m_parameters.testType == TEST_TYPE_COLOR_RESOLVE)
2939         return new ColorResolveImagelessTestInstance(context, m_parameters);
2940 
2941     if (m_parameters.testType == TEST_TYPE_DEPTH_STENCIL_RESOLVE)
2942         return new DepthResolveImagelessTestInstance(context, m_parameters);
2943 
2944     if (m_parameters.testType == TEST_TYPE_MULTISUBPASS)
2945         return new MultisubpassTestInstance(context, m_parameters);
2946 
2947     if (m_parameters.testType == TEST_TYPE_DIFFERENT_ATTACHMENTS)
2948         return new DifferentAttachmentsTestInstance(context, m_parameters);
2949 
2950     TCU_THROW(InternalError, "Unknown test type specified");
2951 }
2952 
imagelessColorTests(tcu::TestContext & testCtx)2953 tcu::TestNode *imagelessColorTests(tcu::TestContext &testCtx)
2954 {
2955     TestParameters parameters = {
2956         TEST_TYPE_COLOR,          //  TestType testType;
2957         VK_FORMAT_R8G8B8A8_UNORM, //  VkFormat colorFormat;
2958         VK_FORMAT_UNDEFINED,      //  VkFormat dsFormat;
2959     };
2960 
2961     // Imageless color attachment test
2962     return new BaseTestCase(testCtx, "color", parameters);
2963 }
2964 
imagelessDepthStencilTests(tcu::TestContext & testCtx)2965 tcu::TestNode *imagelessDepthStencilTests(tcu::TestContext &testCtx)
2966 {
2967     TestParameters parameters = {
2968         TEST_TYPE_DEPTH_STENCIL,     //  TestType testType;
2969         VK_FORMAT_R8G8B8A8_UNORM,    //  VkFormat colorFormat;
2970         VK_FORMAT_D24_UNORM_S8_UINT, //  VkFormat dsFormat;
2971     };
2972 
2973     // Imageless depth/stencil attachment test
2974     return new BaseTestCase(testCtx, "depth_stencil", parameters);
2975 }
2976 
imagelessColorResolveTests(tcu::TestContext & testCtx)2977 tcu::TestNode *imagelessColorResolveTests(tcu::TestContext &testCtx)
2978 {
2979     TestParameters parameters = {
2980         TEST_TYPE_COLOR_RESOLVE,  //  TestType testType;
2981         VK_FORMAT_R8G8B8A8_UNORM, //  VkFormat colorFormat;
2982         VK_FORMAT_UNDEFINED,      //  VkFormat dsFormat;
2983     };
2984 
2985     // Imageless color attachment resolve test
2986     return new BaseTestCase(testCtx, "color_resolve", parameters);
2987 }
2988 
imagelessDepthStencilResolveTests(tcu::TestContext & testCtx)2989 tcu::TestNode *imagelessDepthStencilResolveTests(tcu::TestContext &testCtx)
2990 {
2991     TestParameters parameters = {
2992         TEST_TYPE_DEPTH_STENCIL_RESOLVE, //  TestType testType;
2993         VK_FORMAT_R8G8B8A8_UNORM,        //  VkFormat colorFormat;
2994         VK_FORMAT_D24_UNORM_S8_UINT,     //  VkFormat dsFormat;
2995     };
2996 
2997     // Imageless color and depth/stencil attachment resolve test
2998     return new BaseTestCase(testCtx, "depth_stencil_resolve", parameters);
2999 }
3000 
imagelessMultisubpass(tcu::TestContext & testCtx)3001 tcu::TestNode *imagelessMultisubpass(tcu::TestContext &testCtx)
3002 {
3003     TestParameters parameters = {
3004         TEST_TYPE_MULTISUBPASS,   //  TestType testType;
3005         VK_FORMAT_R8G8B8A8_UNORM, //  VkFormat colorFormat;
3006         VK_FORMAT_UNDEFINED,      //  VkFormat dsFormat;
3007     };
3008 
3009     // Multi-subpass test
3010     return new BaseTestCase(testCtx, "multisubpass", parameters);
3011 }
3012 
imagelessDifferentAttachments(tcu::TestContext & testCtx)3013 tcu::TestNode *imagelessDifferentAttachments(tcu::TestContext &testCtx)
3014 {
3015     TestParameters parameters = {
3016         TEST_TYPE_DIFFERENT_ATTACHMENTS, //  TestType testType;
3017         VK_FORMAT_R8G8B8A8_UNORM,        //  VkFormat colorFormat;
3018         VK_FORMAT_UNDEFINED,             //  VkFormat dsFormat;
3019     };
3020 
3021     // Different attachments in multiple render passes
3022     return new BaseTestCase(testCtx, "different_attachments", parameters);
3023 }
3024 
3025 } // namespace
3026 
createTests(tcu::TestContext & testCtx,const std::string & name)3027 tcu::TestCaseGroup *createTests(tcu::TestContext &testCtx, const std::string &name)
3028 {
3029     de::MovePtr<tcu::TestCaseGroup> imagelessFramebufferGroup(new tcu::TestCaseGroup(testCtx, name.c_str()));
3030 
3031     imagelessFramebufferGroup->addChild(imagelessColorTests(testCtx));        // Color only test
3032     imagelessFramebufferGroup->addChild(imagelessDepthStencilTests(testCtx)); // Color and depth/stencil test
3033     imagelessFramebufferGroup->addChild(imagelessColorResolveTests(testCtx)); // Color and color resolve test
3034     imagelessFramebufferGroup->addChild(imagelessDepthStencilResolveTests(
3035         testCtx)); // Color, depth and depth resolve test (interaction with VK_KHR_depth_stencil_resolve)
3036     imagelessFramebufferGroup->addChild(imagelessMultisubpass(testCtx)); // Multi-subpass test
3037     imagelessFramebufferGroup->addChild(
3038         imagelessDifferentAttachments(testCtx)); // Different attachments in multiple render passes
3039 
3040     return imagelessFramebufferGroup.release();
3041 }
3042 
3043 } // namespace imageless
3044 } // namespace vkt
3045