1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 Google Inc.
6  * Copyright (c) 2018 The Khronos Group Inc.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Tests for subpass dependency
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktRenderPassSubpassDependencyTests.hpp"
26 #include "vktRenderPassTestsUtil.hpp"
27 
28 #include "vktTestCaseUtil.hpp"
29 #include "vktTestGroupUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 
38 #include "tcuImageCompare.hpp"
39 #include "tcuResultCollector.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuTextureUtil.hpp"
42 
43 #include "rrRenderer.hpp"
44 #include "deRandom.hpp"
45 #include "deMath.h"
46 
47 using namespace vk;
48 
49 using tcu::UVec2;
50 using tcu::UVec4;
51 using tcu::Vec2;
52 using tcu::Vec4;
53 
54 using tcu::ConstPixelBufferAccess;
55 using tcu::PixelBufferAccess;
56 
57 using tcu::TestLog;
58 
59 using de::SharedPtr;
60 using std::string;
61 using std::vector;
62 
63 typedef de::SharedPtr<Unique<VkImage>> SharedPtrVkImage;
64 typedef de::SharedPtr<Unique<VkImageView>> SharedPtrVkImageView;
65 typedef de::SharedPtr<Unique<VkPipeline>> SharedPtrVkPipeline;
66 typedef de::SharedPtr<Unique<VkSampler>> SharedPtrVkSampler;
67 typedef de::SharedPtr<Unique<VkRenderPass>> SharedPtrVkRenderPass;
68 typedef de::SharedPtr<Unique<VkFramebuffer>> SharedPtrVkFramebuffer;
69 typedef de::SharedPtr<Unique<VkDescriptorPool>> SharedPtrVkDescriptorPool;
70 typedef de::SharedPtr<Unique<VkDescriptorSetLayout>> SharedPtrVkDescriptorLayout;
71 typedef de::SharedPtr<Unique<VkDescriptorSet>> SharedPtrVkDescriptorSet;
72 typedef de::SharedPtr<Unique<VkPipelineLayout>> SharedPtrVkPipelineLayout;
73 typedef de::SharedPtr<Unique<VkPipeline>> SharedPtrVkPipeline;
74 
75 namespace vkt
76 {
77 namespace
78 {
79 using namespace renderpass;
80 
81 template <typename T>
makeSharedPtr(Move<T> move)82 inline SharedPtr<Unique<T>> makeSharedPtr(Move<T> move)
83 {
84     return SharedPtr<Unique<T>>(new Unique<T>(move));
85 }
86 
getRepresentableDepthChannel(const ConstPixelBufferAccess & access)87 tcu::TextureLevel getRepresentableDepthChannel(const ConstPixelBufferAccess &access)
88 {
89     tcu::TextureLevel depthChannel(mapVkFormat(VK_FORMAT_R8G8B8_UNORM), access.getWidth(), access.getHeight());
90 
91     for (int y = 0; y < access.getHeight(); y++)
92         for (int x = 0; x < access.getWidth(); x++)
93             depthChannel.getAccess().setPixel(tcu::Vec4(access.getPixDepth(x, y)), x, y);
94 
95     return depthChannel;
96 }
97 
verifyDepth(Context & context,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result,const float threshold)98 bool verifyDepth(Context &context, const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result,
99                  const float threshold)
100 {
101     tcu::TestLog &log(context.getTestContext().getLog());
102 
103     return tcu::floatThresholdCompare(log,                                     // log
104                                       "Depth channel",                         // imageSetName
105                                       "Depth compare",                         // imageSetDesc
106                                       getRepresentableDepthChannel(reference), // reference
107                                       getRepresentableDepthChannel(result),    // result
108                                       Vec4(threshold),                         // threshold
109                                       tcu::COMPARE_LOG_RESULT);                // logMode
110 }
111 
verifyStencil(Context & context,const ConstPixelBufferAccess & reference,const ConstPixelBufferAccess & result)112 bool verifyStencil(Context &context, const ConstPixelBufferAccess &reference, const ConstPixelBufferAccess &result)
113 {
114     tcu::TextureLevel stencilErrorImage(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
115                                         result.getWidth(), result.getHeight());
116     tcu::TestLog &log(context.getTestContext().getLog());
117     bool stencilOk(true);
118 
119     for (int y = 0; y < result.getHeight(); y++)
120         for (int x = 0; x < result.getWidth(); x++)
121         {
122             if (result.getPixStencil(x, y) != reference.getPixStencil(x, y))
123             {
124                 stencilErrorImage.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
125                 stencilOk = false;
126             }
127             else
128                 stencilErrorImage.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
129         }
130 
131     log << tcu::TestLog::ImageSet("Stencil compare", "Stencil compare")
132         << tcu::TestLog::Image("Result stencil channel", "Result stencil channel", result)
133         << tcu::TestLog::Image("Reference stencil channel", "Reference stencil channel", reference);
134 
135     if (!stencilOk)
136         log << tcu::TestLog::Image("Stencil error mask", "Stencil error mask", stencilErrorImage);
137 
138     log << tcu::TestLog::EndImageSet;
139 
140     return stencilOk;
141 }
142 
143 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(const DeviceInterface & vkd,VkCommandBuffer secCmdBuffer,VkFormat colorAttachmentFormat,VkFormat dsAttachmentFormat,bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)144 void beginSecondaryCmdBuffer(const DeviceInterface &vkd, VkCommandBuffer secCmdBuffer, VkFormat colorAttachmentFormat,
145                              VkFormat dsAttachmentFormat, bool secondaryCmdBufferCompletelyContainsDynamicRenderpass)
146 {
147     VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
148     if (!secondaryCmdBufferCompletelyContainsDynamicRenderpass)
149         usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
150 
151     const VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
152         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
153         DE_NULL,                                                         // const void* pNext;
154         0u,                                                              // VkRenderingFlagsKHR flags;
155         0u,                                                              // uint32_t viewMask;
156         1u,                                                              // uint32_t colorAttachmentCount;
157         &colorAttachmentFormat,                                          // const VkFormat* pColorAttachmentFormats;
158         dsAttachmentFormat,                                              // VkFormat depthAttachmentFormat;
159         dsAttachmentFormat,                                              // VkFormat stencilAttachmentFormat;
160         VK_SAMPLE_COUNT_1_BIT,                                           // VkSampleCountFlagBits rasterizationSamples;
161     };
162     const VkCommandBufferInheritanceInfo bufferInheritanceInfo{
163         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
164         &inheritanceRenderingInfo,                         // const void* pNext;
165         DE_NULL,                                           // VkRenderPass renderPass;
166         0u,                                                // uint32_t subpass;
167         DE_NULL,                                           // VkFramebuffer framebuffer;
168         VK_FALSE,                                          // VkBool32 occlusionQueryEnable;
169         (VkQueryControlFlags)0u,                           // VkQueryControlFlags queryFlags;
170         (VkQueryPipelineStatisticFlags)0u                  // VkQueryPipelineStatisticFlags pipelineStatistics;
171     };
172     const VkCommandBufferBeginInfo commandBufBeginParams{
173         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
174         DE_NULL,                                     // const void* pNext;
175         usageFlags,                                  // VkCommandBufferUsageFlags flags;
176         &bufferInheritanceInfo                       // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
177     };
178     VK_CHECK(vkd.beginCommandBuffer(secCmdBuffer, &commandBufBeginParams));
179 }
180 #endif // CTS_USES_VULKANSC
181 
182 // Reference renderer shaders
183 class DepthVertShader : public rr::VertexShader
184 {
185 public:
DepthVertShader(void)186     DepthVertShader(void) : rr::VertexShader(1, 1)
187     {
188         m_inputs[0].type  = rr::GENERICVECTYPE_FLOAT;
189         m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
190     }
191 
~DepthVertShader()192     virtual ~DepthVertShader()
193     {
194     }
195 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const196     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
197     {
198         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
199         {
200             packets[packetNdx]->position =
201                 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
202 
203             packets[packetNdx]->outputs[0] =
204                 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
205         }
206     }
207 };
208 
209 class DepthFragShader : public rr::FragmentShader
210 {
211 public:
DepthFragShader(void)212     DepthFragShader(void) : rr::FragmentShader(1, 1)
213     {
214         m_inputs[0].type  = rr::GENERICVECTYPE_FLOAT;
215         m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
216     }
217 
~DepthFragShader()218     virtual ~DepthFragShader()
219     {
220     }
221 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const222     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
223                         const rr::FragmentShadingContext &context) const
224     {
225         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
226         {
227             rr::FragmentPacket &packet = packets[packetNdx];
228             for (uint32_t fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
229             {
230                 const tcu::Vec4 vtxPosition = rr::readVarying<float>(packet, context, 0, fragNdx);
231 
232                 rr::writeFragmentDepth(context, packetNdx, fragNdx, 0, vtxPosition.z());
233             }
234         }
235     }
236 };
237 
238 class SelfDependencyBackwardsVertShader : public rr::VertexShader
239 {
240 public:
SelfDependencyBackwardsVertShader(void)241     SelfDependencyBackwardsVertShader(void) : rr::VertexShader(1, 0)
242     {
243         m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
244     }
245 
~SelfDependencyBackwardsVertShader()246     virtual ~SelfDependencyBackwardsVertShader()
247     {
248     }
249 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const250     void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
251     {
252         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
253         {
254             packets[packetNdx]->position =
255                 rr::readVertexAttribFloat(inputs[0], packets[packetNdx]->instanceNdx, packets[packetNdx]->vertexNdx);
256         }
257     }
258 };
259 
260 class SelfDependencyBackwardsFragShader : public rr::FragmentShader
261 {
262 public:
SelfDependencyBackwardsFragShader(void)263     SelfDependencyBackwardsFragShader(void) : rr::FragmentShader(0, 1)
264     {
265         m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
266     }
267 
~SelfDependencyBackwardsFragShader()268     virtual ~SelfDependencyBackwardsFragShader()
269     {
270     }
271 
shadeFragments(rr::FragmentPacket * packets,const int numPackets,const rr::FragmentShadingContext & context) const272     void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
273                         const rr::FragmentShadingContext &context) const
274     {
275         DE_UNREF(packets);
276 
277         for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
278             for (uint32_t fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
279                 rr::writeFragmentOutput<tcu::Vec4>(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
280     }
281 };
282 
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)283 de::MovePtr<Allocation> createBufferMemory(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
284                                            VkBuffer buffer)
285 {
286     de::MovePtr<Allocation> allocation(
287         allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
288 
289     VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
290 
291     return allocation;
292 }
293 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)294 Move<VkImageView> createImageView(const DeviceInterface &vk, VkDevice device, VkImageViewCreateFlags flags,
295                                   VkImage image, VkImageViewType viewType, VkFormat format,
296                                   VkComponentMapping components, VkImageSubresourceRange subresourceRange)
297 {
298     const VkImageViewCreateInfo pCreateInfo = {
299         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType
300         DE_NULL,                                  // const void*                pNext
301         flags,                                    // VkImageViewCreateFlags    flags
302         image,                                    // VkImage                    image
303         viewType,                                 // VkImageViewType            viewType
304         format,                                   // VkFormat                    format
305         components,                               // VkComponentMapping        components
306         subresourceRange,                         // VkImageSubresourceRange    subresourceRange
307     };
308 
309     return createImageView(vk, device, &pCreateInfo);
310 }
311 
createImageViews(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkImage> images,VkFormat format,VkImageAspectFlags aspect)312 vector<SharedPtrVkImageView> createImageViews(const DeviceInterface &vkd, VkDevice device,
313                                               vector<SharedPtrVkImage> images, VkFormat format,
314                                               VkImageAspectFlags aspect)
315 {
316     vector<SharedPtrVkImageView> imageViews;
317 
318     for (size_t imageViewNdx = 0; imageViewNdx < images.size(); imageViewNdx++)
319     {
320         const VkImageSubresourceRange range = {
321             aspect, // VkImageAspectFlags    aspectMask
322             0u,     // uint32_t                baseMipLevel
323             1u,     // uint32_t                levelCount
324             0u,     // uint32_t                baseArrayLayer
325             1u      // uint32_t                layerCount
326         };
327 
328         imageViews.push_back(
329             makeSharedPtr(createImageView(vkd, device, 0u, **images[imageViewNdx], VK_IMAGE_VIEW_TYPE_2D, format,
330                                           makeComponentMappingRGBA(), range)));
331     }
332 
333     return imageViews;
334 }
335 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,uint32_t width,uint32_t height)336 Move<VkBuffer> createBuffer(const DeviceInterface &vkd, VkDevice device, VkFormat format, uint32_t width,
337                             uint32_t height)
338 {
339     const VkBufferUsageFlags bufferUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
340     const VkDeviceSize pixelSize        = mapVkFormat(format).getPixelSize();
341     const VkBufferCreateInfo createInfo = {
342         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType        sType
343         DE_NULL,                              // const void*            pNext
344         0u,                                   // VkBufferCreateFlags    flags
345         width * height * pixelSize,           // VkDeviceSize            size
346         bufferUsage,                          // VkBufferUsageFlags    usage
347         VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode        sharingMode
348         0u,                                   // uint32_t                queueFamilyIndexCount
349         DE_NULL                               // const uint32_t*        pQueueFamilyIndices
350     };
351 
352     return createBuffer(vkd, device, &createInfo);
353 }
354 
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkSampler> & samplers)355 vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts(const DeviceInterface &vkd, VkDevice device,
356                                                                vector<SharedPtrVkSampler> &samplers)
357 {
358     vector<SharedPtrVkDescriptorLayout> layouts;
359 
360     for (size_t layoutNdx = 0; layoutNdx < samplers.size(); layoutNdx++)
361     {
362         const VkDescriptorSetLayoutBinding bindings = {
363             0u,                                        // uint32_t                binding
364             VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType        descriptorType
365             1u,                                        // uint32_t                descriptorCount
366             VK_SHADER_STAGE_FRAGMENT_BIT,              // VkShaderStageFlags    stageFlags
367             &**samplers[layoutNdx]                     // const VkSampler*        pImmutableSamplers
368         };
369 
370         const VkDescriptorSetLayoutCreateInfo createInfo = {
371             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType                        sType
372             DE_NULL,                                             // const void*                            pNext
373             0u,                                                  // VkDescriptorSetLayoutCreateFlags        flags
374             1u,                                                  // uint32_t                                bindingCount
375             &bindings                                            // const VkDescriptorSetLayoutBinding*    pBindings
376         };
377 
378         layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
379     }
380 
381     return layouts;
382 }
383 
createDescriptorPools(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorLayout> & layouts,VkDescriptorType type)384 vector<SharedPtrVkDescriptorPool> createDescriptorPools(const DeviceInterface &vkd, VkDevice device,
385                                                         vector<SharedPtrVkDescriptorLayout> &layouts,
386                                                         VkDescriptorType type)
387 {
388     vector<SharedPtrVkDescriptorPool> descriptorPools;
389 
390     for (size_t poolNdx = 0; poolNdx < layouts.size(); poolNdx++)
391     {
392         const VkDescriptorPoolSize size = {
393             type, // VkDescriptorType        type
394             1u    // uint32_t                descriptorCount
395         };
396 
397         const VkDescriptorPoolCreateInfo createInfo = {
398             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,     // VkStructureType                sType
399             DE_NULL,                                           // const void*                    pNext
400             VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags    flags
401             1u,                                                // uint32_t                        maxSets
402             1u,                                                // uint32_t                        poolSizeCount
403             &size                                              // const VkDescriptorPoolSize*    pPoolSizes
404         };
405 
406         descriptorPools.push_back(makeSharedPtr(createDescriptorPool(vkd, device, &createInfo)));
407     }
408 
409     return descriptorPools;
410 }
411 
412 struct ExternalTestConfig
413 {
ExternalTestConfigvkt::__anonc414995a0111::ExternalTestConfig414     ExternalTestConfig(VkFormat format_, UVec2 imageSize_, vector<RenderPass> renderPasses_,
415                        const SharedGroupParams groupParams_, SynchronizationType synchronizationType_,
416                        uint32_t blurKernel_ = 4)
417         : format(format_)
418         , imageSize(imageSize_)
419         , renderPasses(renderPasses_)
420         , groupParams(groupParams_)
421         , synchronizationType(synchronizationType_)
422         , blurKernel(blurKernel_)
423     {
424     }
425 
426     VkFormat format;
427     UVec2 imageSize;
428     vector<RenderPass> renderPasses;
429     const SharedGroupParams groupParams;
430     SynchronizationType synchronizationType;
431     uint32_t blurKernel;
432 };
433 
434 class ExternalDependencyTestInstance : public TestInstance
435 {
436 public:
437     ExternalDependencyTestInstance(Context &context, ExternalTestConfig testConfig);
438     ~ExternalDependencyTestInstance(void);
439 
440     vector<SharedPtrVkImage> createAndAllocateImages(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
441                                                      vector<de::SharedPtr<Allocation>> &imageMemories,
442                                                      uint32_t universalQueueFamilyIndex, VkFormat format,
443                                                      uint32_t width, uint32_t height, vector<RenderPass> renderPasses);
444 
445     vector<SharedPtrVkSampler> createSamplers(const DeviceInterface &vkd, const VkDevice device,
446                                               vector<RenderPass> &renderPasses);
447 
448     vector<SharedPtrVkRenderPass> createRenderPasses(const DeviceInterface &vkd, VkDevice device,
449                                                      vector<RenderPass> renderPassInfos,
450                                                      const RenderingType renderingType,
451                                                      const SynchronizationType synchronizationType);
452 
453     vector<SharedPtrVkFramebuffer> createFramebuffers(const DeviceInterface &vkd, VkDevice device,
454                                                       vector<SharedPtrVkRenderPass> &renderPasses,
455                                                       vector<SharedPtrVkImageView> &dstImageViews, uint32_t width,
456                                                       uint32_t height);
457 
458     vector<SharedPtrVkPipelineLayout> createRenderPipelineLayouts(
459         const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
460         vector<SharedPtrVkDescriptorLayout> &descriptorSetLayouts);
461 
462     vector<SharedPtrVkPipeline> createRenderPipelines(const DeviceInterface &vkd, VkDevice device,
463                                                       vector<SharedPtrVkRenderPass> &renderPasses,
464                                                       vector<SharedPtrVkPipelineLayout> &pipelineLayouts,
465                                                       const BinaryCollection &binaryCollection, uint32_t width,
466                                                       uint32_t height);
467 
468     vector<SharedPtrVkDescriptorSet> createDescriptorSets(const DeviceInterface &vkd, VkDevice device,
469                                                           vector<SharedPtrVkDescriptorPool> &pools,
470                                                           vector<SharedPtrVkDescriptorLayout> &layouts,
471                                                           vector<SharedPtrVkImageView> &imageViews,
472                                                           vector<SharedPtrVkSampler> &samplers);
473 
474     tcu::TestStatus iterate(void);
475 
476     template <typename RenderpassSubpass>
477     tcu::TestStatus iterateInternal(void);
478 
479 private:
480     const bool m_renderPass2Supported;
481     const bool m_synchronization2Supported;
482     const SharedGroupParams m_groupParams;
483 
484     const uint32_t m_width;
485     const uint32_t m_height;
486     const uint32_t m_blurKernel;
487     const VkFormat m_format;
488 
489     vector<de::SharedPtr<Allocation>> m_imageMemories;
490     vector<SharedPtrVkImage> m_images;
491     vector<SharedPtrVkImageView> m_imageViews;
492     vector<SharedPtrVkSampler> m_samplers;
493 
494     const Unique<VkBuffer> m_dstBuffer;
495     const de::UniquePtr<Allocation> m_dstBufferMemory;
496 
497     vector<SharedPtrVkRenderPass> m_renderPasses;
498     vector<SharedPtrVkFramebuffer> m_framebuffers;
499 
500     vector<SharedPtrVkDescriptorLayout> m_subpassDescriptorSetLayouts;
501     vector<SharedPtrVkDescriptorPool> m_subpassDescriptorPools;
502     vector<SharedPtrVkDescriptorSet> m_subpassDescriptorSets;
503 
504     vector<SharedPtrVkPipelineLayout> m_renderPipelineLayouts;
505     vector<SharedPtrVkPipeline> m_renderPipelines;
506 
507     const Unique<VkCommandPool> m_commandPool;
508     tcu::ResultCollector m_resultCollector;
509 };
510 
ExternalDependencyTestInstance(Context & context,ExternalTestConfig testConfig)511 ExternalDependencyTestInstance::ExternalDependencyTestInstance(Context &context, ExternalTestConfig testConfig)
512     : TestInstance(context)
513     , m_renderPass2Supported((testConfig.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) &&
514                              context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
515     , m_synchronization2Supported((testConfig.synchronizationType == SYNCHRONIZATION_TYPE_SYNCHRONIZATION2) &&
516                                   context.requireDeviceFunctionality("VK_KHR_synchronization2"))
517     , m_groupParams(testConfig.groupParams)
518     , m_width(testConfig.imageSize.x())
519     , m_height(testConfig.imageSize.y())
520     , m_blurKernel(testConfig.blurKernel)
521     , m_format(testConfig.format)
522     , m_images(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(),
523                                        m_imageMemories, context.getUniversalQueueFamilyIndex(), m_format, m_width,
524                                        m_height, testConfig.renderPasses))
525     , m_imageViews(createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format,
526                                     VK_IMAGE_ASPECT_COLOR_BIT))
527     , m_samplers(createSamplers(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses))
528     , m_dstBuffer(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
529     , m_dstBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
530                                            context.getDefaultAllocator(), *m_dstBuffer))
531     , m_renderPasses(createRenderPasses(context.getDeviceInterface(), context.getDevice(), testConfig.renderPasses,
532                                         testConfig.groupParams->renderingType, testConfig.synchronizationType))
533     , m_framebuffers(createFramebuffers(context.getDeviceInterface(), context.getDevice(), m_renderPasses, m_imageViews,
534                                         m_width, m_height))
535     , m_subpassDescriptorSetLayouts(
536           createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_samplers))
537     , m_subpassDescriptorPools(createDescriptorPools(context.getDeviceInterface(), context.getDevice(),
538                                                      m_subpassDescriptorSetLayouts,
539                                                      VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER))
540     , m_subpassDescriptorSets(createDescriptorSets(context.getDeviceInterface(), context.getDevice(),
541                                                    m_subpassDescriptorPools, m_subpassDescriptorSetLayouts,
542                                                    m_imageViews, m_samplers))
543     , m_renderPipelineLayouts(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(),
544                                                           m_renderPasses, m_subpassDescriptorSetLayouts))
545     , m_renderPipelines(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPasses,
546                                               m_renderPipelineLayouts, context.getBinaryCollection(), m_width,
547                                               m_height))
548     , m_commandPool(createCommandPool(context.getDeviceInterface(), context.getDevice(),
549                                       VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
550 {
551 }
552 
~ExternalDependencyTestInstance(void)553 ExternalDependencyTestInstance::~ExternalDependencyTestInstance(void)
554 {
555 }
556 
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,uint32_t universalQueueFamilyIndex,VkFormat format,uint32_t width,uint32_t height,vector<RenderPass> renderPasses)557 vector<SharedPtrVkImage> ExternalDependencyTestInstance::createAndAllocateImages(
558     const DeviceInterface &vk, VkDevice device, Allocator &allocator, vector<de::SharedPtr<Allocation>> &imageMemories,
559     uint32_t universalQueueFamilyIndex, VkFormat format, uint32_t width, uint32_t height,
560     vector<RenderPass> renderPasses)
561 {
562     vector<SharedPtrVkImage> images;
563 
564     for (size_t imageNdx = 0; imageNdx < renderPasses.size(); imageNdx++)
565     {
566         const VkExtent3D imageExtent = {
567             width,  // uint32_t        width
568             height, // uint32_t        height
569             1u      // uint32_t        depth
570         };
571 
572         const VkImageCreateInfo imageCreateInfo = {
573             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
574             DE_NULL,                             // const void*                pNext
575             0u,                                  // VkImageCreateFlags        flags
576             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
577             format,                              // VkFormat                    format
578             imageExtent,                         // VkExtent3D                extent
579             1u,                                  // uint32_t                    mipLevels
580             1u,                                  // uint32_t                    arrayLayers
581             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
582             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
583             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT |
584                 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags        usage
585             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
586             1u,                                  // uint32_t                    queueFamilyIndexCount
587             &universalQueueFamilyIndex,          // const uint32_t*            pQueueFamilyIndices
588             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
589         };
590 
591         images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
592         imageMemories.push_back(
593             (de::SharedPtr<Allocation>)allocator
594                 .allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any)
595                 .release());
596         VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(),
597                                     imageMemories[imageNdx]->getOffset()));
598     }
599 
600     return images;
601 }
602 
createSamplers(const DeviceInterface & vkd,const VkDevice device,vector<RenderPass> & renderPasses)603 vector<SharedPtrVkSampler> ExternalDependencyTestInstance::createSamplers(const DeviceInterface &vkd,
604                                                                           const VkDevice device,
605                                                                           vector<RenderPass> &renderPasses)
606 {
607     vector<SharedPtrVkSampler> samplers;
608 
609     for (size_t samplerNdx = 0; samplerNdx < renderPasses.size() - 1; samplerNdx++)
610     {
611         const VkSamplerCreateInfo samplerInfo = {
612             VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,   // VkStructureType            sType
613             DE_NULL,                                 // const void*                pNext
614             0u,                                      // VkSamplerCreateFlags        flags
615             VK_FILTER_NEAREST,                       // VkFilter                    magFilter
616             VK_FILTER_NEAREST,                       // VkFilter                    minFilter
617             VK_SAMPLER_MIPMAP_MODE_NEAREST,          // VkSamplerMipmapMode        mipmapMode
618             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode        addressModeU
619             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode        addressModeV
620             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode        addressModeW
621             0.0f,                                    // float                    mipLodBias
622             VK_FALSE,                                // VkBool32                    anisotropyEnable
623             1.0f,                                    // float                    maxAnisotropy
624             VK_FALSE,                                // VkBool32                    compareEnable
625             VK_COMPARE_OP_ALWAYS,                    // VkCompareOp                compareOp
626             0.0f,                                    // float                    minLod
627             0.0f,                                    // float                    maxLod
628             VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor            borderColor
629             VK_FALSE,                                // VkBool32                    unnormalizedCoordinates
630         };
631 
632         samplers.push_back(makeSharedPtr(createSampler(vkd, device, &samplerInfo)));
633     }
634 
635     return samplers;
636 }
637 
createRenderPasses(const DeviceInterface & vkd,VkDevice device,vector<RenderPass> renderPassInfos,const RenderingType renderingType,const SynchronizationType synchronizationType)638 vector<SharedPtrVkRenderPass> ExternalDependencyTestInstance::createRenderPasses(
639     const DeviceInterface &vkd, VkDevice device, vector<RenderPass> renderPassInfos, const RenderingType renderingType,
640     const SynchronizationType synchronizationType)
641 {
642     vector<SharedPtrVkRenderPass> renderPasses;
643     renderPasses.reserve(renderPassInfos.size());
644 
645     for (const auto &renderPassInfo : renderPassInfos)
646         renderPasses.push_back(
647             makeSharedPtr(createRenderPass(vkd, device, renderPassInfo, renderingType, synchronizationType)));
648 
649     return renderPasses;
650 }
651 
createFramebuffers(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkImageView> & dstImageViews,uint32_t width,uint32_t height)652 vector<SharedPtrVkFramebuffer> ExternalDependencyTestInstance::createFramebuffers(
653     const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
654     vector<SharedPtrVkImageView> &dstImageViews, uint32_t width, uint32_t height)
655 {
656     vector<SharedPtrVkFramebuffer> framebuffers;
657 
658     for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
659     {
660         VkRenderPass renderPass(**renderPasses[renderPassNdx]);
661 
662         const VkFramebufferCreateInfo createInfo = {
663             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType            sType
664             DE_NULL,                                   // const void*                pNext
665             0u,                                        // VkFramebufferCreateFlags    flags
666             renderPass,                                // VkRenderPass                renderPass
667             1u,                                        // uint32_t                    attachmentCount
668             &**dstImageViews[renderPassNdx],           // const VkImageView*        pAttachments
669             width,                                     // uint32_t                    width
670             height,                                    // uint32_t                    height
671             1u                                         // uint32_t                    layers
672         };
673 
674         framebuffers.push_back(makeSharedPtr(createFramebuffer(vkd, device, &createInfo)));
675     }
676 
677     return framebuffers;
678 }
679 
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews,vector<SharedPtrVkSampler> & samplers)680 vector<SharedPtrVkDescriptorSet> ExternalDependencyTestInstance::createDescriptorSets(
681     const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkDescriptorPool> &pools,
682     vector<SharedPtrVkDescriptorLayout> &layouts, vector<SharedPtrVkImageView> &imageViews,
683     vector<SharedPtrVkSampler> &samplers)
684 {
685     vector<SharedPtrVkDescriptorSet> descriptorSets;
686 
687     for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
688     {
689         const VkDescriptorSetAllocateInfo allocateInfo = {
690             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                    sType
691             DE_NULL,                                        // const void*                        pNext
692             **pools[setNdx],                                // VkDescriptorPool                    descriptorPool
693             1u,                                             // uint32_t                            descriptorSetCount
694             &**layouts[setNdx]                              // const VkDescriptorSetLayout*        pSetLayouts
695         };
696 
697         descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
698 
699         {
700             const VkDescriptorImageInfo imageInfo = {
701                 **samplers[setNdx],                      // VkSampler        sampler
702                 **imageViews[setNdx],                    // VkImageView        imageView
703                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout    imageLayout
704             };
705 
706             const VkWriteDescriptorSet write = {
707                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,    // VkStructureType                    sType
708                 DE_NULL,                                   // const void*                        pNext
709                 **descriptorSets[setNdx],                  // VkDescriptorSet                    dstSet
710                 0u,                                        // uint32_t                            dstBinding
711                 0u,                                        // uint32_t                            dstArrayElement
712                 1u,                                        // uint32_t                            descriptorCount
713                 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // VkDescriptorType                    descriptorType
714                 &imageInfo,                                // const VkDescriptorImageInfo*        pImageInfo
715                 DE_NULL,                                   // const VkDescriptorBufferInfo*    pBufferInfo
716                 DE_NULL                                    // const VkBufferView*                pTexelBufferView
717             };
718 
719             vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
720         }
721     }
722 
723     return descriptorSets;
724 }
725 
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkDescriptorLayout> & descriptorSetLayouts)726 vector<SharedPtrVkPipelineLayout> ExternalDependencyTestInstance::createRenderPipelineLayouts(
727     const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
728     vector<SharedPtrVkDescriptorLayout> &descriptorSetLayouts)
729 {
730     vector<SharedPtrVkPipelineLayout> pipelineLayouts;
731 
732     for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
733     {
734         const VkPipelineLayoutCreateInfo createInfo = {
735             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                sType
736             DE_NULL,                                       // const void*                    pNext
737             (vk::VkPipelineLayoutCreateFlags)0,            // VkPipelineLayoutCreateFlags    flags
738             renderPassNdx > 0 ? 1u : 0u,                   // uint32_t                        setLayoutCount
739             renderPassNdx > 0 ? &**descriptorSetLayouts[renderPassNdx - 1] :
740                                 DE_NULL, // const VkDescriptorSetLayout*    pSetLayouts
741             0u,                          // uint32_t                        pushConstantRangeCount
742             DE_NULL                      // const VkPushConstantRange*    pPushConstantRanges
743         };
744 
745         pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
746     }
747 
748     return pipelineLayouts;
749 }
750 
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,vector<SharedPtrVkRenderPass> & renderPasses,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,uint32_t width,uint32_t height)751 vector<SharedPtrVkPipeline> ExternalDependencyTestInstance::createRenderPipelines(
752     const DeviceInterface &vkd, VkDevice device, vector<SharedPtrVkRenderPass> &renderPasses,
753     vector<SharedPtrVkPipelineLayout> &pipelineLayouts, const BinaryCollection &binaryCollection, uint32_t width,
754     uint32_t height)
755 {
756     vector<SharedPtrVkPipeline> pipelines;
757 
758     for (size_t renderPassNdx = 0; renderPassNdx < renderPasses.size(); renderPassNdx++)
759     {
760         const Unique<VkShaderModule> vertexShaderModule(
761             createShaderModule(vkd, device, binaryCollection.get("quad-vert-" + de::toString(renderPassNdx)), 0u));
762         const Unique<VkShaderModule> fragmentShaderModule(
763             createShaderModule(vkd, device, binaryCollection.get("quad-frag-" + de::toString(renderPassNdx)), 0u));
764 
765         const VkPipelineVertexInputStateCreateInfo vertexInputState = {
766             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                            sType
767             DE_NULL,                                   // const void*                                pNext
768             (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags    flags
769             0u,      // uint32_t                                    vertexBindingDescriptionCount
770             DE_NULL, // const VkVertexInputBindingDescription*    pVertexBindingDescriptions
771             0u,      // uint32_t                                    vertexAttributeDescriptionCount
772             DE_NULL  // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
773         };
774 
775         const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(width, height)));
776         const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(width, height)));
777         const VkRenderPass renderPass(**renderPasses[renderPassNdx]);
778         const VkPipelineLayout layout(**pipelineLayouts[renderPassNdx]);
779 
780         pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(
781             vkd,                   // const DeviceInterface&                        vk
782             device,                // const VkDevice                                device
783             layout,                // const VkPipelineLayout                        pipelineLayout
784             *vertexShaderModule,   // const VkShaderModule                            vertexShaderModule
785             DE_NULL,               // const VkShaderModule                            tessellationControlShaderModule
786             DE_NULL,               // const VkShaderModule                            tessellationEvalShaderModule
787             DE_NULL,               // const VkShaderModule                            geometryShaderModule
788             *fragmentShaderModule, // const VkShaderModule                            fragmentShaderModule
789             renderPass,            // const VkRenderPass                            renderPass
790             viewports,             // const std::vector<VkViewport>&                viewports
791             scissors,              // const std::vector<VkRect2D>&                    scissors
792             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                    topology
793             0u,                                  // const uint32_t                                subpass
794             0u,                                  // const uint32_t                                patchControlPoints
795             &vertexInputState))); // const VkPipelineVertexInputStateCreateInfo*    vertexInputStateCreateInfo
796     }
797 
798     return pipelines;
799 }
800 
iterate(void)801 tcu::TestStatus ExternalDependencyTestInstance::iterate(void)
802 {
803     switch (m_groupParams->renderingType)
804     {
805     case RENDERING_TYPE_RENDERPASS_LEGACY:
806         return iterateInternal<RenderpassSubpass1>();
807     case RENDERING_TYPE_RENDERPASS2:
808         return iterateInternal<RenderpassSubpass2>();
809     default:
810         TCU_THROW(InternalError, "Impossible");
811     }
812 }
813 
814 template <typename RenderpassSubpass>
iterateInternal(void)815 tcu::TestStatus ExternalDependencyTestInstance::iterateInternal(void)
816 {
817     const DeviceInterface &vkd(m_context.getDeviceInterface());
818     const Unique<VkCommandBuffer> commandBuffer(
819         allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
820     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
821     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
822 
823     beginCommandBuffer(vkd, *commandBuffer);
824 
825     for (size_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
826     {
827         // Begin render pass
828         {
829             VkRect2D renderArea = {
830                 {0u, 0u},           // VkOffset2D    offset
831                 {m_width, m_height} // VkExtent2D    extent
832             };
833 
834             const VkRenderPassBeginInfo beginInfo = {
835                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
836                 DE_NULL,                                  // const void*            pNext
837                 **m_renderPasses[renderPassNdx],          // VkRenderPass            renderPass
838                 **m_framebuffers[renderPassNdx],          // VkFramebuffer        framebuffer
839                 renderArea,                               // VkRect2D                renderArea
840                 0u,                                       // uint32_t                clearValueCount
841                 DE_NULL                                   // const VkClearValue*    pClearValues
842             };
843 
844             RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
845         }
846 
847         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[renderPassNdx]);
848 
849         // Use results from the previous pass as input texture
850         if (renderPassNdx > 0)
851             vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
852                                       **m_renderPipelineLayouts[renderPassNdx], 0, 1,
853                                       &**m_subpassDescriptorSets[renderPassNdx - 1], 0, DE_NULL);
854 
855         vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
856 
857         RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
858     }
859 
860     // Memory barrier between rendering and copy
861     {
862         VkImageSubresourceRange imageSubresourceRange = {
863             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
864             0u,                        // uint32_t                baseMipLevel
865             1u,                        // uint32_t                levelCount
866             0u,                        // uint32_t                baseArrayLayer
867             1u                         // uint32_t                layerCount
868         };
869 
870         const VkImageMemoryBarrier barrier = {
871             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,   // VkStructureType            sType
872             DE_NULL,                                  // const void*                pNext
873             0,                                        // VkAccessFlags            srcAccessMask
874             VK_ACCESS_TRANSFER_READ_BIT,              // VkAccessFlags            dstAccessMask
875             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout            oldLayout
876             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,     // VkImageLayout            newLayout
877             VK_QUEUE_FAMILY_IGNORED,                  // uint32_t                    srcQueueFamilyIndex
878             VK_QUEUE_FAMILY_IGNORED,                  // uint32_t                    dstQueueFamilyIndex
879             **m_images[m_renderPasses.size() - 1],    // VkImage                    image
880             imageSubresourceRange                     // VkImageSubresourceRange    subresourceRange
881         };
882         // Since the implicit 'end' subpass dependency has VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT in its dstStageMask,
883         // we can't form an execution dependency chain with a specific pipeline stage. The cases that provide an explict
884         // 'end' subpass dependency could use a specific pipline stage, but there isn't a way to distinguish between the
885         // implicit and explicit cases here.
886         vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u,
887                                0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
888     }
889 
890     // Copy image memory to buffer
891     {
892         const VkImageSubresourceLayers imageSubresourceLayers = {
893             VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
894             0u,                        // uint32_t                mipLevel
895             0u,                        // uint32_t                baseArrayLayer
896             1u                         // uint32_t                layerCount
897         };
898 
899         const VkBufferImageCopy region = {
900             0u,                     // VkDeviceSize                bufferOffset
901             0u,                     // uint32_t                    bufferRowLength
902             0u,                     // uint32_t                    bufferImageHeight
903             imageSubresourceLayers, // VkImageSubresourceLayers    imageSubresource
904             {0u, 0u, 0u},           // VkOffset3D                imageOffset
905             {m_width, m_height, 1u} // VkExtent3D                imageExtent
906         };
907 
908         vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[m_renderPasses.size() - 1],
909                                  VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_dstBuffer, 1u, &region);
910     }
911 
912     // Memory barrier between copy and host access
913     {
914         const VkBufferMemoryBarrier barrier = {
915             VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType    sType
916             DE_NULL,                                 // const void*        pNext
917             VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags    srcAccessMask
918             VK_ACCESS_HOST_READ_BIT,                 // VkAccessFlags    dstAccessMask
919             VK_QUEUE_FAMILY_IGNORED,                 // uint32_t            srcQueueFamilyIndex
920             VK_QUEUE_FAMILY_IGNORED,                 // uint32_t            dstQueueFamilyIndex
921             *m_dstBuffer,                            // VkBuffer            buffer
922             0u,                                      // VkDeviceSize        offset
923             VK_WHOLE_SIZE                            // VkDeviceSize        size
924         };
925 
926         vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
927                                DE_NULL, 1u, &barrier, 0u, DE_NULL);
928     }
929 
930     endCommandBuffer(vkd, *commandBuffer);
931     submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
932     invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_dstBufferMemory->getMemory(),
933                                 m_dstBufferMemory->getOffset(), VK_WHOLE_SIZE);
934 
935     {
936         const tcu::TextureFormat format(mapVkFormat(m_format));
937         const void *const ptr(m_dstBufferMemory->getHostPtr());
938         const tcu::ConstPixelBufferAccess access(format, m_width, m_height, 1, ptr);
939         tcu::TextureLevel reference(format, m_width, m_height);
940         tcu::TextureLevel textureA(format, m_width, m_height);
941         tcu::TextureLevel textureB(format, m_width, m_height);
942 
943         for (uint32_t renderPassNdx = 0; renderPassNdx < m_renderPasses.size(); renderPassNdx++)
944         {
945             // First pass renders four quads of different color, which will be blurred in the following passes
946             if (renderPassNdx == 0)
947             {
948                 for (uint32_t y = 0; y < m_height; y++)
949                     for (uint32_t x = 0; x < m_width; x++)
950                     {
951                         if (x <= (m_width - 1) / 2 && y <= (m_height - 1) / 2)
952                             textureA.getAccess().setPixel(Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y);
953                         else if (x > (m_width - 1) / 2 && y <= (m_height - 1) / 2)
954                             textureA.getAccess().setPixel(Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
955                         else if (x <= (m_width - 1) / 2 && y > (m_height - 1) / 2)
956                             textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
957                         else
958                             textureA.getAccess().setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), x, y);
959                     }
960             }
961             // Blur previous pass
962             else
963             {
964                 for (uint32_t y = 0; y < m_height; y++)
965                     for (uint32_t x = 0; x < m_width; x++)
966                     {
967                         Vec4 blurColor(Vec4(0.0));
968 
969                         for (uint32_t sampleNdx = 0; sampleNdx < (m_blurKernel + 1); sampleNdx++)
970                         {
971                             if (renderPassNdx % 2 == 0)
972                             {
973                                 // Do a horizontal blur
974                                 blurColor +=
975                                     0.12f *
976                                     textureB.getAccess().getPixel(
977                                         deClamp32((int32_t)x - (m_blurKernel / 2) + sampleNdx, 0u, m_width - 1u), y);
978                             }
979                             else
980                             {
981                                 // Do a vertical blur
982                                 blurColor += 0.12f * textureA.getAccess().getPixel(
983                                                          x, deClamp32((int32_t)y - (m_blurKernel / 2) + sampleNdx, 0u,
984                                                                       m_height - 1u));
985                             }
986                         }
987 
988                         renderPassNdx % 2 == 0 ? textureA.getAccess().setPixel(blurColor, x, y) :
989                                                  textureB.getAccess().setPixel(blurColor, x, y);
990                     }
991             }
992         }
993 
994         reference = m_renderPasses.size() % 2 == 0 ? textureB : textureA;
995 
996         {
997             // Allow error of 4 times the minimum presentable difference
998             const Vec4 threshold(
999                 4.0f * 1.0f /
1000                 ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<uint32_t>()) - 1u).cast<float>());
1001 
1002             if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access,
1003                                             threshold, tcu::COMPARE_LOG_ON_ERROR))
1004                 m_resultCollector.fail("Compare failed.");
1005         }
1006     }
1007 
1008     return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1009 }
1010 
1011 struct SubpassTestConfig
1012 {
SubpassTestConfigvkt::__anonc414995a0111::SubpassTestConfig1013     SubpassTestConfig(VkFormat format_, UVec2 imageSize_, RenderPass renderPass_, SharedGroupParams groupParams_)
1014         : format(format_)
1015         , imageSize(imageSize_)
1016         , renderPass(renderPass_)
1017         , groupParams(groupParams_)
1018     {
1019     }
1020 
1021     VkFormat format;
1022     UVec2 imageSize;
1023     RenderPass renderPass;
1024     SharedGroupParams groupParams;
1025 };
1026 
1027 class SubpassDependencyTestInstance : public TestInstance
1028 {
1029 public:
1030     SubpassDependencyTestInstance(Context &context, SubpassTestConfig testConfig);
1031 
1032     ~SubpassDependencyTestInstance(void) = default;
1033 
1034     vector<SharedPtrVkImage> createAndAllocateImages(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
1035                                                      vector<de::SharedPtr<Allocation>> &imageMemories,
1036                                                      uint32_t universalQueueFamilyIndex, RenderPass renderPassInfo,
1037                                                      VkFormat format, uint32_t width, uint32_t height);
1038 
1039     vector<SharedPtrVkPipelineLayout> createRenderPipelineLayouts(
1040         const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo,
1041         vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts);
1042 
1043     vector<SharedPtrVkPipeline> createRenderPipelines(const DeviceInterface &vkd, VkDevice device,
1044                                                       RenderPass renderPassInfo, VkRenderPass renderPass,
1045                                                       vector<SharedPtrVkPipelineLayout> &pipelineLayouts,
1046                                                       const BinaryCollection &binaryCollection, VkFormat format,
1047                                                       uint32_t width, uint32_t height);
1048 
1049     Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo,
1050                                           VkRenderPass renderPass, vector<SharedPtrVkImageView> &dstImageViews,
1051                                           uint32_t width, uint32_t height);
1052 
1053     vector<SharedPtrVkDescriptorLayout> createDescriptorSetLayouts(const DeviceInterface &vkd, VkDevice device,
1054                                                                    RenderPass renderPassInfo);
1055 
1056     vector<SharedPtrVkDescriptorSet> createDescriptorSets(const DeviceInterface &vkd, VkDevice device, VkFormat format,
1057                                                           vector<SharedPtrVkDescriptorPool> &pools,
1058                                                           vector<SharedPtrVkDescriptorLayout> &layouts,
1059                                                           vector<SharedPtrVkImageView> &imageViews);
1060 
1061     tcu::TestStatus iterate(void);
1062 
1063     template <typename RenderpassSubpass>
1064     tcu::TestStatus iterateInternal(void);
1065 
1066 private:
1067     const RenderPass m_renderPassInfo;
1068     const SharedGroupParams m_groupParams;
1069 
1070     const uint32_t m_width;
1071     const uint32_t m_height;
1072     const VkFormat m_format;
1073 
1074     vector<de::SharedPtr<Allocation>> m_imageMemories;
1075     vector<SharedPtrVkImage> m_images;
1076     vector<SharedPtrVkImageView> m_imageViews;
1077 
1078     const Unique<VkBuffer> m_primaryBuffer;
1079     const Unique<VkBuffer> m_secondaryBuffer;
1080     const de::UniquePtr<Allocation> m_primaryBufferMemory;
1081     const de::UniquePtr<Allocation> m_secondaryBufferMemory;
1082 
1083     const Unique<VkRenderPass> m_renderPass;
1084     const Unique<VkFramebuffer> m_framebuffer;
1085 
1086     vector<SharedPtrVkDescriptorLayout> m_subpassDescriptorSetLayouts;
1087     vector<SharedPtrVkDescriptorPool> m_subpassDescriptorPools;
1088     vector<SharedPtrVkDescriptorSet> m_subpassDescriptorSets;
1089 
1090     vector<SharedPtrVkPipelineLayout> m_renderPipelineLayouts;
1091     vector<SharedPtrVkPipeline> m_renderPipelines;
1092 
1093     const Unique<VkCommandPool> m_commandPool;
1094     tcu::ResultCollector m_resultCollector;
1095 };
1096 
SubpassDependencyTestInstance(Context & context,SubpassTestConfig testConfig)1097 SubpassDependencyTestInstance::SubpassDependencyTestInstance(Context &context, SubpassTestConfig testConfig)
1098     : TestInstance(context)
1099     , m_renderPassInfo(testConfig.renderPass)
1100     , m_groupParams(testConfig.groupParams)
1101     , m_width(testConfig.imageSize.x())
1102     , m_height(testConfig.imageSize.y())
1103     , m_format(testConfig.format)
1104     , m_images(createAndAllocateImages(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(),
1105                                        m_imageMemories, context.getUniversalQueueFamilyIndex(), m_renderPassInfo,
1106                                        m_format, m_width, m_height))
1107     , m_imageViews(
1108           createImageViews(context.getDeviceInterface(), context.getDevice(), m_images, m_format,
1109                            isDepthStencilFormat(m_format) ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT))
1110     , m_primaryBuffer(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1111     , m_secondaryBuffer(createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
1112     , m_primaryBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
1113                                                context.getDefaultAllocator(), *m_primaryBuffer))
1114     , m_secondaryBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
1115                                                  context.getDefaultAllocator(), *m_secondaryBuffer))
1116     , m_renderPass(createRenderPass(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo,
1117                                     m_groupParams->renderingType))
1118     , m_framebuffer(createFramebuffer(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo,
1119                                       *m_renderPass, m_imageViews, m_width, m_height))
1120     , m_subpassDescriptorSetLayouts(
1121           createDescriptorSetLayouts(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo))
1122     , m_subpassDescriptorPools(createDescriptorPools(context.getDeviceInterface(), context.getDevice(),
1123                                                      m_subpassDescriptorSetLayouts,
1124                                                      VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT))
1125     , m_subpassDescriptorSets(createDescriptorSets(context.getDeviceInterface(), context.getDevice(), m_format,
1126                                                    m_subpassDescriptorPools, m_subpassDescriptorSetLayouts,
1127                                                    m_imageViews))
1128     , m_renderPipelineLayouts(createRenderPipelineLayouts(context.getDeviceInterface(), context.getDevice(),
1129                                                           m_renderPassInfo, m_subpassDescriptorSetLayouts))
1130     , m_renderPipelines(createRenderPipelines(context.getDeviceInterface(), context.getDevice(), m_renderPassInfo,
1131                                               *m_renderPass, m_renderPipelineLayouts, context.getBinaryCollection(),
1132                                               m_format, m_width, m_height))
1133     , m_commandPool(createCommandPool(context.getDeviceInterface(), context.getDevice(),
1134                                       VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1135 {
1136 }
1137 
createAndAllocateImages(const DeviceInterface & vk,VkDevice device,Allocator & allocator,vector<de::SharedPtr<Allocation>> & imageMemories,uint32_t universalQueueFamilyIndex,RenderPass renderPassInfo,VkFormat format,uint32_t width,uint32_t height)1138 vector<SharedPtrVkImage> SubpassDependencyTestInstance::createAndAllocateImages(
1139     const DeviceInterface &vk, VkDevice device, Allocator &allocator, vector<de::SharedPtr<Allocation>> &imageMemories,
1140     uint32_t universalQueueFamilyIndex, RenderPass renderPassInfo, VkFormat format, uint32_t width, uint32_t height)
1141 {
1142     // Verify format support
1143     {
1144         const VkFormatFeatureFlags flags =
1145             (isDepthStencilFormat(m_format) ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT :
1146                                               VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) |
1147             VK_FORMAT_FEATURE_TRANSFER_SRC_BIT;
1148         const VkFormatProperties properties = vk::getPhysicalDeviceFormatProperties(
1149             m_context.getInstanceInterface(), m_context.getPhysicalDevice(), format);
1150 
1151         if ((properties.optimalTilingFeatures & flags) != flags)
1152             TCU_THROW(NotSupportedError, "Format not supported");
1153     }
1154 
1155     vector<SharedPtrVkImage> images;
1156 
1157     for (size_t imageNdx = 0; imageNdx < renderPassInfo.getAttachments().size(); imageNdx++)
1158     {
1159         const VkExtent3D imageExtent = {
1160             width,  // uint32_t    width
1161             height, // uint32_t    height
1162             1u      // uint32_t    depth
1163         };
1164 
1165         VkImageUsageFlags usage = ((isDepthStencilFormat(format) ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT :
1166                                                                    VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) |
1167                                    VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT);
1168 
1169         const VkImageCreateInfo imageCreateInfo = {
1170             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
1171             DE_NULL,                             // const void*                pNext
1172             0u,                                  // VkImageCreateFlags        flags
1173             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
1174             format,                              // VkFormat                    format
1175             imageExtent,                         // VkExtent3D                extent
1176             1u,                                  // uint32_t                    mipLevels
1177             1u,                                  // uint32_t                    arrayLayers
1178             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
1179             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
1180             usage,                               // VkImageUsageFlags        usage
1181             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
1182             1u,                                  // uint32_t                    queueFamilyIndexCount
1183             &universalQueueFamilyIndex,          // const uint32_t*            pQueueFamilyIndices
1184             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
1185         };
1186 
1187         images.push_back(makeSharedPtr(vk::createImage(vk, device, &imageCreateInfo, DE_NULL)));
1188         imageMemories.push_back(
1189             (de::SharedPtr<Allocation>)allocator
1190                 .allocate(getImageMemoryRequirements(vk, device, **images[imageNdx]), MemoryRequirement::Any)
1191                 .release());
1192         VK_CHECK(vk.bindImageMemory(device, **images[imageNdx], imageMemories[imageNdx]->getMemory(),
1193                                     imageMemories[imageNdx]->getOffset()));
1194     }
1195 
1196     return images;
1197 }
1198 
createRenderPipelineLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)1199 vector<SharedPtrVkPipelineLayout> SubpassDependencyTestInstance::createRenderPipelineLayouts(
1200     const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo,
1201     vector<SharedPtrVkDescriptorLayout> descriptorSetLayouts)
1202 {
1203     vector<SharedPtrVkPipelineLayout> pipelineLayouts;
1204     vector<VkDescriptorSetLayout> descriptorSetLayoutHandles;
1205     const size_t descriptorSetLayoutCount = descriptorSetLayouts.size();
1206 
1207     for (size_t descriptorSetLayoutNdx = 0; descriptorSetLayoutNdx < descriptorSetLayoutCount; descriptorSetLayoutNdx++)
1208         descriptorSetLayoutHandles.push_back(**descriptorSetLayouts.at(descriptorSetLayoutNdx));
1209 
1210     for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1211     {
1212         const VkPipelineLayoutCreateInfo createInfo = {
1213             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                sType
1214             DE_NULL,                                       // const void*                    pNext
1215             (vk::VkPipelineLayoutCreateFlags)0,            // VkPipelineLayoutCreateFlags    flags
1216             (uint32_t)descriptorSetLayoutCount,            // uint32_t                        setLayoutCount
1217             descriptorSetLayoutHandles.data(),             // const VkDescriptorSetLayout*    pSetLayouts
1218             0u,                                            // uint32_t                        pushConstantRangeCount
1219             DE_NULL                                        // const VkPushConstantRange*    pPushConstantRanges
1220         };
1221 
1222         pipelineLayouts.push_back(makeSharedPtr(createPipelineLayout(vkd, device, &createInfo)));
1223     }
1224 
1225     return pipelineLayouts;
1226 }
1227 
createRenderPipelines(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkPipelineLayout> & pipelineLayouts,const BinaryCollection & binaryCollection,VkFormat format,uint32_t width,uint32_t height)1228 vector<SharedPtrVkPipeline> SubpassDependencyTestInstance::createRenderPipelines(
1229     const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo, VkRenderPass renderPass,
1230     vector<SharedPtrVkPipelineLayout> &pipelineLayouts, const BinaryCollection &binaryCollection, VkFormat format,
1231     uint32_t width, uint32_t height)
1232 {
1233     vector<SharedPtrVkPipeline> pipelines;
1234 
1235     for (size_t subpassNdx = 0; subpassNdx < renderPassInfo.getSubpasses().size(); subpassNdx++)
1236     {
1237         const Unique<VkShaderModule> vertexShaderModule(
1238             createShaderModule(vkd, device, binaryCollection.get("subpass-vert-" + de::toString(subpassNdx)), 0u));
1239         const Unique<VkShaderModule> fragmentShaderModule(
1240             createShaderModule(vkd, device, binaryCollection.get("subpass-frag-" + de::toString(subpassNdx)), 0u));
1241 
1242         const VkVertexInputBindingDescription vertexBinding0 = {
1243             0u,                         // uint32_t binding;
1244             sizeof(Vec4),               // uint32_t strideInBytes;
1245             VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
1246         };
1247 
1248         VkVertexInputAttributeDescription attr0 = {
1249             0u,                            // uint32_t location;
1250             0u,                            // uint32_t binding;
1251             VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1252             0u                             // uint32_t offsetInBytes;
1253         };
1254 
1255         const VkPipelineVertexInputStateCreateInfo vertexInputState = {
1256             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                            sType
1257             DE_NULL,                                   // const void*                                pNext
1258             (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags    flags
1259             1u,              // uint32_t                                    vertexBindingDescriptionCount
1260             &vertexBinding0, // const VkVertexInputBindingDescription*    pVertexBindingDescriptions
1261             1u,              // uint32_t                                    vertexAttributeDescriptionCount
1262             &attr0           // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
1263         };
1264 
1265         const VkStencilOpState stencilOpState = {
1266             VK_STENCIL_OP_KEEP,   // stencilFailOp
1267             VK_STENCIL_OP_KEEP,   // stencilPassOp
1268             VK_STENCIL_OP_KEEP,   // stencilDepthFailOp
1269             VK_COMPARE_OP_ALWAYS, // stencilCompareOp
1270             0x0u,                 // stencilCompareMask
1271             0x0u,                 // stencilWriteMask
1272             0u                    // stencilReference
1273         };
1274 
1275         const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo = {
1276             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                            sType
1277             DE_NULL,                     // const void*                                pNext
1278             0u,                          // VkPipelineDepthStencilStateCreateFlags    flags
1279             VK_TRUE,                     // VkBool32                                    depthTestEnable
1280             VK_TRUE,                     // VkBool32                                    depthWriteEnable
1281             VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp                                depthCompareOp
1282             VK_FALSE,                    // VkBool32                                    depthBoundsTestEnable
1283             VK_TRUE,                     // VkBool32                                    stencilTestEnable
1284             stencilOpState,              // VkStencilOpState                            front
1285             stencilOpState,              // VkStencilOpState                            back
1286             0.0f,                        // float                                    minDepthBounds
1287             1.0f,                        // float                                    maxDepthBounds
1288         };
1289 
1290         const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(width, height)));
1291         const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(width, height)));
1292         const VkPipelineLayout layout(**pipelineLayouts[subpassNdx]);
1293         const VkPipelineDepthStencilStateCreateInfo depthStencilCreateInfo(
1294             isDepthStencilFormat(format) ? depthStencilStateCreateInfo : VkPipelineDepthStencilStateCreateInfo());
1295 
1296         pipelines.push_back(makeSharedPtr(makeGraphicsPipeline(
1297             vkd,                 // const DeviceInterface&                            vk
1298             device,              // const VkDevice                                    device
1299             layout,              // const VkPipelineLayout                            pipelineLayout
1300             *vertexShaderModule, // const VkShaderModule                                vertexShaderModule
1301             DE_NULL,             // const VkShaderModule                                tessellationControlShaderModule
1302             DE_NULL,             // const VkShaderModule                                tessellationEvalShaderModule
1303             DE_NULL,             // const VkShaderModule                                geometryShaderModule
1304             *fragmentShaderModule, // const VkShaderModule                                fragmentShaderModule
1305             renderPass,            // const VkRenderPass                                renderPass
1306             viewports,             // const std::vector<VkViewport>&                    viewports
1307             scissors,              // const std::vector<VkRect2D>&                        scissors
1308             VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology                        topology
1309             (uint32_t)subpassNdx,                // const uint32_t                                    subpass
1310             0u,                                  // const uint32_t                                    patchControlPoints
1311             &vertexInputState,       // const VkPipelineVertexInputStateCreateInfo*        vertexInputStateCreateInfo
1312             DE_NULL,                 // const VkPipelineRasterizationStateCreateInfo*    rasterizationStateCreateInfo
1313             DE_NULL,                 // const VkPipelineMultisampleStateCreateInfo*        multisampleStateCreateInfo
1314             &depthStencilCreateInfo, // const VkPipelineDepthStencilStateCreateInfo*        depthStencilStateCreateInfo
1315             DE_NULL)));              // const VkPipelineDynamicStateCreateInfo*            pDynamicState
1316     }
1317 
1318     return pipelines;
1319 }
1320 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo,VkRenderPass renderPass,vector<SharedPtrVkImageView> & dstImageViews,uint32_t width,uint32_t height)1321 Move<VkFramebuffer> SubpassDependencyTestInstance::createFramebuffer(const DeviceInterface &vkd, VkDevice device,
1322                                                                      RenderPass renderPassInfo, VkRenderPass renderPass,
1323                                                                      vector<SharedPtrVkImageView> &dstImageViews,
1324                                                                      uint32_t width, uint32_t height)
1325 {
1326     const size_t attachmentCount(renderPassInfo.getAttachments().size());
1327     vector<VkImageView> attachmentHandles;
1328 
1329     for (uint32_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1330         attachmentHandles.push_back(**dstImageViews.at(attachmentNdx));
1331 
1332     const VkFramebufferCreateInfo createInfo = {
1333         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType            sType
1334         DE_NULL,                                   // const void*                pNext
1335         0u,                                        // VkFramebufferCreateFlags    flags
1336         renderPass,                                // VkRenderPass                renderPass
1337         (uint32_t)attachmentCount,                 // uint32_t                    attachmentCount
1338         attachmentHandles.data(),                  // const VkImageView*        pAttachments
1339         width,                                     // uint32_t                    width
1340         height,                                    // uint32_t                    height
1341         1u                                         // uint32_t                    layers
1342     };
1343 
1344     return vk::createFramebuffer(vkd, device, &createInfo);
1345 }
1346 
createDescriptorSetLayouts(const DeviceInterface & vkd,VkDevice device,RenderPass renderPassInfo)1347 vector<SharedPtrVkDescriptorLayout> SubpassDependencyTestInstance::createDescriptorSetLayouts(
1348     const DeviceInterface &vkd, VkDevice device, RenderPass renderPassInfo)
1349 {
1350     vector<SharedPtrVkDescriptorLayout> layouts;
1351 
1352     size_t attachmentCount = renderPassInfo.getAttachments().size();
1353 
1354     for (size_t layoutNdx = 0; layoutNdx < attachmentCount - 1; layoutNdx++)
1355     {
1356         const VkDescriptorSetLayoutBinding bindings = {
1357             0u,                                  // uint32_t                binding
1358             VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType        descriptorType
1359             1u,                                  // uint32_t                descriptorCount
1360             VK_SHADER_STAGE_FRAGMENT_BIT,        // VkShaderStageFlags    stageFlags
1361             DE_NULL                              // const VkSampler*        pImmutableSamplers
1362         };
1363 
1364         const VkDescriptorSetLayoutCreateInfo createInfo = {
1365             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType                        sType
1366             DE_NULL,                                             // const void*                            pNext
1367             0u,                                                  // VkDescriptorSetLayoutCreateFlags        flags
1368             1u,                                                  // uint32_t                                bindingCount
1369             &bindings                                            // const VkDescriptorSetLayoutBinding*    pBindings
1370         };
1371 
1372         layouts.push_back(makeSharedPtr(createDescriptorSetLayout(vkd, device, &createInfo)));
1373     }
1374 
1375     return layouts;
1376 }
1377 
createDescriptorSets(const DeviceInterface & vkd,VkDevice device,VkFormat format,vector<SharedPtrVkDescriptorPool> & pools,vector<SharedPtrVkDescriptorLayout> & layouts,vector<SharedPtrVkImageView> & imageViews)1378 vector<SharedPtrVkDescriptorSet> SubpassDependencyTestInstance::createDescriptorSets(
1379     const DeviceInterface &vkd, VkDevice device, VkFormat format, vector<SharedPtrVkDescriptorPool> &pools,
1380     vector<SharedPtrVkDescriptorLayout> &layouts, vector<SharedPtrVkImageView> &imageViews)
1381 {
1382     vector<SharedPtrVkDescriptorSet> descriptorSets;
1383 
1384     for (size_t setNdx = 0; setNdx < layouts.size(); setNdx++)
1385     {
1386         const VkDescriptorSetAllocateInfo allocateInfo = {
1387             VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                sType
1388             DE_NULL,                                        // const void*                    pNext
1389             **pools[setNdx],                                // VkDescriptorPool                descriptorPool
1390             1u,                                             // uint32_t                        descriptorSetCount
1391             &**layouts[setNdx]                              // const VkDescriptorSetLayout*    pSetLayouts
1392         };
1393 
1394         descriptorSets.push_back(makeSharedPtr(allocateDescriptorSet(vkd, device, &allocateInfo)));
1395 
1396         {
1397             VkImageLayout imageLayout = isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL :
1398                                                                        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1399 
1400             const VkDescriptorImageInfo imageInfo = {
1401                 DE_NULL,              // VkSampler        sampler
1402                 **imageViews[setNdx], // VkImageView        imageView
1403                 imageLayout           // VkImageLayout    imageLayout
1404             };
1405 
1406             const VkWriteDescriptorSet write = {
1407                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                    sType
1408                 DE_NULL,                                // const void*                        pNext
1409                 **descriptorSets[setNdx],               // VkDescriptorSet                    dstSet
1410                 0u,                                     // uint32_t                            dstBinding
1411                 0u,                                     // uint32_t                            dstArrayElement
1412                 1u,                                     // uint32_t                            descriptorCount
1413                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType                    descriptorType
1414                 &imageInfo,                             // const VkDescriptorImageInfo*        pImageInfo
1415                 DE_NULL,                                // const VkDescriptorBufferInfo*    pBufferInfo
1416                 DE_NULL                                 // const VkBufferView*                pTexelBufferView
1417             };
1418 
1419             vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
1420         }
1421     }
1422 
1423     return descriptorSets;
1424 }
1425 
iterate(void)1426 tcu::TestStatus SubpassDependencyTestInstance::iterate(void)
1427 {
1428     switch (m_groupParams->renderingType)
1429     {
1430     case RENDERING_TYPE_RENDERPASS_LEGACY:
1431         return iterateInternal<RenderpassSubpass1>();
1432     case RENDERING_TYPE_RENDERPASS2:
1433         return iterateInternal<RenderpassSubpass2>();
1434     default:
1435         TCU_THROW(InternalError, "Impossible");
1436     }
1437 }
1438 
1439 template <typename RenderpassSubpass>
iterateInternal(void)1440 tcu::TestStatus SubpassDependencyTestInstance::iterateInternal(void)
1441 {
1442     de::Random rand(5);
1443     const DeviceInterface &vkd(m_context.getDeviceInterface());
1444     const Unique<VkCommandBuffer> commandBuffer(
1445         allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1446     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1447     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
1448     const size_t attachmentCount(m_renderPassInfo.getAttachments().size());
1449     const size_t subpassCount(m_renderPassInfo.getSubpasses().size());
1450     vector<VkClearValue> clearValues;
1451     vector<Vec4> vertexData;
1452 
1453     beginCommandBuffer(vkd, *commandBuffer);
1454 
1455     // Transition stencil aspects to the final layout directly.
1456     if (isDepthStencilFormat(m_format))
1457     {
1458         const VkImageSubresourceRange imageSubresourceRange = {
1459             VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags    aspectMask
1460             0u,                          // uint32_t                baseMipLevel
1461             1u,                          // uint32_t                levelCount
1462             0u,                          // uint32_t                baseArrayLayer
1463             1u                           // uint32_t                layerCount
1464         };
1465 
1466         VkImageMemoryBarrier barrier = {
1467             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,          // VkStructureType            sType
1468             DE_NULL,                                         // const void*                pNext
1469             0u,                                              // VkAccessFlags            srcAccessMask
1470             VK_ACCESS_TRANSFER_READ_BIT,                     // VkAccessFlags            dstAccessMask
1471             VK_IMAGE_LAYOUT_UNDEFINED,                       // VkImageLayout            oldLayout
1472             VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, // VkImageLayout            newLayout
1473             VK_QUEUE_FAMILY_IGNORED,                         // uint32_t                    srcQueueFamilyIndex
1474             VK_QUEUE_FAMILY_IGNORED,                         // uint32_t                    dstQueueFamilyIndex
1475             DE_NULL,                                         // VkImage                    image
1476             imageSubresourceRange                            // VkImageSubresourceRange    subresourceRange
1477         };
1478 
1479         for (uint32_t attachmentNdx = 0; attachmentNdx < attachmentCount; ++attachmentNdx)
1480         {
1481             barrier.image = **m_images[attachmentNdx];
1482             vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1483                                    0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
1484         }
1485     }
1486 
1487     // Begin render pass
1488     {
1489         VkRect2D renderArea = {
1490             {0u, 0u},           // VkOffset2D    offset
1491             {m_width, m_height} // VkExtent2D    extent
1492         };
1493 
1494         for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
1495             clearValues.push_back(isDepthStencilFormat(m_format) ? makeClearValueDepthStencil(1.0f, 255u) :
1496                                                                    makeClearValueColor(Vec4(1.0f, 0.0f, 0.0f, 1.0f)));
1497 
1498         const VkRenderPassBeginInfo beginInfo = {
1499             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
1500             DE_NULL,                                  // const void*            pNext
1501             *m_renderPass,                            // VkRenderPass            renderPass
1502             *m_framebuffer,                           // VkFramebuffer        framebuffer
1503             renderArea,                               // VkRect2D                renderArea
1504             (uint32_t)attachmentCount,                // uint32_t                clearValueCount
1505             clearValues.data()                        // const VkClearValue*    pClearValues
1506         };
1507 
1508         RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1509     }
1510 
1511     // Generate vertices for 128 triangles with pseudorandom positions and depths values
1512     for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
1513     {
1514         float primitiveDepth = rand.getFloat();
1515 
1516         for (int vertexNdx = 0; vertexNdx < 3; vertexNdx++)
1517         {
1518             float x = 2.0f * rand.getFloat() - 1.0f;
1519             float y = 2.0f * rand.getFloat() - 1.0f;
1520 
1521             vertexData.push_back(Vec4(x, y, primitiveDepth, 1.0f));
1522         }
1523     }
1524 
1525     const size_t singleVertexDataSize = sizeof(Vec4);
1526     const size_t vertexCount          = vertexData.size();
1527     const size_t vertexDataSize       = vertexCount * singleVertexDataSize;
1528     const uint32_t queueFamilyIndices = m_context.getUniversalQueueFamilyIndex();
1529 
1530     const VkBufferCreateInfo vertexBufferParams = {
1531         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1532         DE_NULL,                              // const void* pNext;
1533         0u,                                   // VkBufferCreateFlags flags;
1534         (VkDeviceSize)vertexDataSize,         // VkDeviceSize size;
1535         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // VkBufferUsageFlags usage;
1536         VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
1537         1u,                                   // uint32_t queueFamilyCount;
1538         &queueFamilyIndices,                  // const uint32_t* pQueueFamilyIndices;
1539     };
1540 
1541     const Unique<VkBuffer> vertexBuffer(createBuffer(vkd, m_context.getDevice(), &vertexBufferParams));
1542     const de::UniquePtr<Allocation> vertexBufferMemory(m_context.getDefaultAllocator().allocate(
1543         getBufferMemoryRequirements(vkd, m_context.getDevice(), *vertexBuffer), MemoryRequirement::HostVisible));
1544 
1545     VK_CHECK(vkd.bindBufferMemory(m_context.getDevice(), *vertexBuffer, vertexBufferMemory->getMemory(),
1546                                   vertexBufferMemory->getOffset()));
1547 
1548     const VkDeviceSize bindingOffset = 0;
1549     vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
1550 
1551     for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
1552     {
1553         if (subpassNdx > 0)
1554         {
1555             RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1556             vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS,
1557                                       **m_renderPipelineLayouts[subpassNdx], 0, 1,
1558                                       &**m_subpassDescriptorSets[subpassNdx - 1], 0, DE_NULL);
1559         }
1560 
1561         vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_renderPipelines[subpassNdx]);
1562 
1563         if (subpassNdx == 0)
1564         {
1565             // Upload vertex data
1566             {
1567                 void *vertexBufPtr = vertexBufferMemory->getHostPtr();
1568                 deMemcpy(vertexBufPtr, vertexData.data(), vertexDataSize);
1569                 flushAlloc(vkd, m_context.getDevice(), *vertexBufferMemory);
1570             }
1571 
1572             vkd.cmdDraw(*commandBuffer, (uint32_t)vertexData.size(), 1u, 0u, 0u);
1573         }
1574         else
1575             vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1576     }
1577 
1578     RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1579 
1580     // Memory barrier between rendering and copy
1581     {
1582         const VkImageAspectFlags imageAspectFlags = isDepthStencilFormat(m_format) ?
1583                                                         VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT :
1584                                                         VK_IMAGE_ASPECT_COLOR_BIT;
1585         const VkAccessFlags srcAccessMask         = isDepthStencilFormat(m_format) ?
1586                                                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT :
1587                                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
1588         const VkImageLayout oldLayout             = isDepthStencilFormat(m_format) ?
1589                                                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL :
1590                                                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1591         const VkPipelineStageFlags srcStageMask   = isDepthStencilFormat(m_format) ?
1592                                                         VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT :
1593                                                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
1594 
1595         VkImageSubresourceRange imageSubresourceRange = {
1596             imageAspectFlags, // VkImageAspectFlags    aspectMask
1597             0u,               // uint32_t                baseMipLevel
1598             1u,               // uint32_t                levelCount
1599             0u,               // uint32_t                baseArrayLayer
1600             1u                // uint32_t                layerCount
1601         };
1602 
1603         const VkImageMemoryBarrier barrier = {
1604             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType            sType
1605             DE_NULL,                                // const void*                pNext
1606             srcAccessMask,                          // VkAccessFlags            srcAccessMask
1607             VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags            dstAccessMask
1608             oldLayout,                              // VkImageLayout            oldLayout
1609             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,   // VkImageLayout            newLayout
1610             VK_QUEUE_FAMILY_IGNORED,                // uint32_t                    srcQueueFamilyIndex
1611             VK_QUEUE_FAMILY_IGNORED,                // uint32_t                    dstQueueFamilyIndex
1612             **m_images[attachmentCount - 1],        // VkImage                    image
1613             imageSubresourceRange                   // VkImageSubresourceRange    subresourceRange
1614         };
1615 
1616         vkd.cmdPipelineBarrier(*commandBuffer, srcStageMask, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u,
1617                                DE_NULL, 1u, &barrier);
1618     }
1619 
1620     // Copy image memory to buffer
1621     {
1622         if (isDepthStencilFormat(m_format))
1623         {
1624             // Copy depth
1625             const VkImageSubresourceLayers subresourceLayersDepth = {
1626                 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags    aspectMask
1627                 0u,                        // uint32_t                mipLevel
1628                 0u,                        // uint32_t                baseArrayLayer
1629                 1u                         // uint32_t                layerCount
1630             };
1631 
1632             const VkBufferImageCopy regionDepth = {
1633                 0u,                     // VkDeviceSize                bufferOffset
1634                 0u,                     // uint32_t                    bufferRowLength
1635                 0u,                     // uint32_t                    bufferImageHeight
1636                 subresourceLayersDepth, // VkImageSubresourceLayers    imageSubresource
1637                 {0u, 0u, 0u},           // VkOffset3D                imageOffset
1638                 {m_width, m_height, 1u} // VkExtent3D                imageExtent
1639             };
1640 
1641             vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1],
1642                                      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &regionDepth);
1643 
1644             // Copy stencil
1645             const VkImageSubresourceLayers subresourceLayersStencil = {
1646                 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags    aspectMask
1647                 0u,                          // uint32_t                mipLevel
1648                 0u,                          // uint32_t                baseArrayLayer
1649                 1u                           // uint32_t                layerCount
1650             };
1651 
1652             const VkBufferImageCopy regionStencil = {
1653                 0u,                       // VkDeviceSize                bufferOffset
1654                 0u,                       // uint32_t                    bufferRowLength
1655                 0u,                       // uint32_t                    bufferImageHeight
1656                 subresourceLayersStencil, // VkImageSubresourceLayers    imageSubresource
1657                 {0u, 0u, 0u},             // VkOffset3D                imageOffset
1658                 {m_width, m_height, 1u}   // VkExtent3D                imageExtent
1659             };
1660 
1661             vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1],
1662                                      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_secondaryBuffer, 1u, &regionStencil);
1663         }
1664         else
1665         {
1666             // Copy color
1667             const VkImageSubresourceLayers imageSubresourceLayers = {
1668                 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
1669                 0u,                        // uint32_t                mipLevel
1670                 0u,                        // uint32_t                baseArrayLayer
1671                 1u                         // uint32_t                layerCount
1672             };
1673 
1674             const VkBufferImageCopy region = {
1675                 0u,                     // VkDeviceSize                bufferOffset
1676                 0u,                     // uint32_t                    bufferRowLength
1677                 0u,                     // uint32_t                    bufferImageHeight
1678                 imageSubresourceLayers, // VkImageSubresourceLayers    imageSubresource
1679                 {0u, 0u, 0u},           // VkOffset3D                imageOffset
1680                 {m_width, m_height, 1u} // VkExtent3D                imageExtent
1681             };
1682 
1683             vkd.cmdCopyImageToBuffer(*commandBuffer, **m_images[attachmentCount - 1],
1684                                      VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *m_primaryBuffer, 1u, &region);
1685         }
1686     }
1687 
1688     // Memory barrier between copy and host access
1689     {
1690         const VkBufferMemoryBarrier barrier = {
1691             VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType    sType
1692             DE_NULL,                                 // const void*        pNext
1693             VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags    srcAccessMask
1694             VK_ACCESS_HOST_READ_BIT,                 // VkAccessFlags    dstAccessMask
1695             VK_QUEUE_FAMILY_IGNORED,                 // uint32_t            srcQueueFamilyIndex
1696             VK_QUEUE_FAMILY_IGNORED,                 // uint32_t            dstQueueFamilyIndex
1697             *m_primaryBuffer,                        // VkBuffer            buffer
1698             0u,                                      // VkDeviceSize        offset
1699             VK_WHOLE_SIZE                            // VkDeviceSize        size
1700         };
1701 
1702         vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1703                                DE_NULL, 1u, &barrier, 0u, DE_NULL);
1704 
1705         if (isDepthStencilFormat(m_format))
1706         {
1707             const VkBufferMemoryBarrier stencilBarrier = {
1708                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType    sType
1709                 DE_NULL,                                 // const void*        pNext
1710                 VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags    srcAccessMask
1711                 VK_ACCESS_HOST_READ_BIT,                 // VkAccessFlags    dstAccessMask
1712                 VK_QUEUE_FAMILY_IGNORED,                 // uint32_t            srcQueueFamilyIndex
1713                 VK_QUEUE_FAMILY_IGNORED,                 // uint32_t            dstQueueFamilyIndex
1714                 *m_secondaryBuffer,                      // VkBuffer            buffer
1715                 0u,                                      // VkDeviceSize        offset
1716                 VK_WHOLE_SIZE                            // VkDeviceSize        size
1717             };
1718 
1719             vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u,
1720                                    DE_NULL, 1u, &stencilBarrier, 0u, DE_NULL);
1721         }
1722     }
1723 
1724     endCommandBuffer(vkd, *commandBuffer);
1725     submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
1726     invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_primaryBufferMemory->getMemory(),
1727                                 m_primaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1728     invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_secondaryBufferMemory->getMemory(),
1729                                 m_secondaryBufferMemory->getOffset(), VK_WHOLE_SIZE);
1730 
1731     // Verify result
1732     {
1733         const tcu::TextureFormat format(mapVkFormat(m_format));
1734 
1735         if (isDepthStencilFormat(m_format))
1736         {
1737             const void *const ptrDepth(m_primaryBufferMemory->getHostPtr());
1738             const void *const ptrStencil(m_secondaryBufferMemory->getHostPtr());
1739             tcu::TextureLevel reference(format, m_width, m_height);
1740             tcu::TextureLevel colorBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), m_width, m_height);
1741             const tcu::ConstPixelBufferAccess resultDepthAccess(getDepthCopyFormat(m_format), m_width, m_height, 1,
1742                                                                 ptrDepth);
1743             const tcu::ConstPixelBufferAccess resultStencilAccess(getStencilCopyFormat(m_format), m_width, m_height, 1,
1744                                                                   ptrStencil);
1745             const PixelBufferAccess referenceDepthAccess(
1746                 tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
1747             const PixelBufferAccess referenceStencilAccess(
1748                 tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
1749 
1750             tcu::clearDepth(referenceDepthAccess, 1.0f);
1751             tcu::clearStencil(referenceStencilAccess, 255);
1752 
1753             // Setup and run reference renderer
1754             {
1755                 const DepthVertShader vertShader;
1756                 const DepthFragShader fragShader;
1757                 const rr::Renderer renderer;
1758                 const rr::Program program(&vertShader, &fragShader);
1759                 const rr::MultisamplePixelBufferAccess depthBuffer(
1760                     rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceDepthAccess));
1761                 const rr::MultisamplePixelBufferAccess colorBufferAccess(
1762                     rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(colorBuffer.getAccess()));
1763                 const rr::RenderTarget renderTarget(rr::MultisamplePixelBufferAccess(colorBufferAccess), depthBuffer,
1764                                                     rr::MultisamplePixelBufferAccess());
1765                 const rr::PrimitiveType primitiveType(rr::PRIMITIVETYPE_TRIANGLES);
1766                 const rr::PrimitiveList primitiveList(rr::PrimitiveList(primitiveType, (uint32_t)vertexData.size(), 0));
1767                 rr::RenderState renderState((rr::ViewportState(depthBuffer)),
1768                                             m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1769 
1770                 const rr::VertexAttrib vertices =
1771                     rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &vertexData[0]);
1772 
1773                 renderState.fragOps.depthTestEnabled = true;
1774                 renderState.fragOps.depthFunc        = rr::TESTFUNC_LEQUAL;
1775 
1776                 renderer.draw(rr::DrawCommand(renderState, renderTarget, program, 1u, &vertices, primitiveList));
1777             }
1778 
1779             for (size_t subpassNdx = 0; subpassNdx < subpassCount - 1; subpassNdx++)
1780             {
1781                 for (int y = 0; y < reference.getHeight(); y++)
1782                     for (int x = 0; x < reference.getWidth(); x++)
1783                         reference.getAccess().setPixDepth(reference.getAccess().getPixDepth(x, y) - 0.02f, x, y);
1784             }
1785 
1786             // Threshold size of subpass count multiplied by the minimum representable difference is allowed for depth compare
1787             const float depthThreshold(
1788                 (float)subpassCount *
1789                 (1.0f /
1790                  ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<uint32_t>()) -
1791                   1u)
1792                      .cast<float>()
1793                      .x()));
1794 
1795             if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
1796                 m_resultCollector.fail("Depth compare failed.");
1797 
1798             if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
1799                 m_resultCollector.fail("Stencil compare failed.");
1800         }
1801         else
1802             DE_FATAL("Not implemented");
1803     }
1804 
1805     return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1806 }
1807 
1808 struct SubpassSelfDependencyBackwardsTestConfig
1809 {
SubpassSelfDependencyBackwardsTestConfigvkt::__anonc414995a0111::SubpassSelfDependencyBackwardsTestConfig1810     SubpassSelfDependencyBackwardsTestConfig(VkFormat format_, UVec2 imageSize_, RenderingType renderingType_)
1811         : format(format_)
1812         , imageSize(imageSize_)
1813         , renderingType(renderingType_)
1814     {
1815     }
1816 
1817     VkFormat format;
1818     UVec2 imageSize;
1819     RenderingType renderingType;
1820 };
1821 
1822 class SubpassSelfDependencyBackwardsTestInstance : public TestInstance
1823 {
1824 public:
1825     SubpassSelfDependencyBackwardsTestInstance(Context &context, SubpassSelfDependencyBackwardsTestConfig testConfig);
1826 
1827     ~SubpassSelfDependencyBackwardsTestInstance(void);
1828 
1829     tcu::TestStatus iterate(void);
1830 
1831     template <typename RenderpassSubpass>
1832     tcu::TestStatus iterateInternal(void);
1833 
1834 private:
1835     const bool m_extensionSupported;
1836     const bool m_featuresSupported;
1837     const RenderingType m_renderingType;
1838 
1839     const uint32_t m_width;
1840     const uint32_t m_height;
1841     const VkFormat m_format;
1842     tcu::ResultCollector m_resultCollector;
1843 };
1844 
SubpassSelfDependencyBackwardsTestInstance(Context & context,SubpassSelfDependencyBackwardsTestConfig testConfig)1845 SubpassSelfDependencyBackwardsTestInstance::SubpassSelfDependencyBackwardsTestInstance(
1846     Context &context, SubpassSelfDependencyBackwardsTestConfig testConfig)
1847     : TestInstance(context)
1848     , m_extensionSupported((testConfig.renderingType == RENDERING_TYPE_RENDERPASS2) &&
1849                            context.requireDeviceFunctionality("VK_KHR_create_renderpass2"))
1850     , m_featuresSupported(context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
1851     , m_renderingType(testConfig.renderingType)
1852     , m_width(testConfig.imageSize.x())
1853     , m_height(testConfig.imageSize.y())
1854     , m_format(testConfig.format)
1855 {
1856 }
1857 
~SubpassSelfDependencyBackwardsTestInstance(void)1858 SubpassSelfDependencyBackwardsTestInstance::~SubpassSelfDependencyBackwardsTestInstance(void)
1859 {
1860 }
1861 
iterate(void)1862 tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterate(void)
1863 {
1864     switch (m_renderingType)
1865     {
1866     case RENDERING_TYPE_RENDERPASS_LEGACY:
1867         return iterateInternal<RenderpassSubpass1>();
1868     case RENDERING_TYPE_RENDERPASS2:
1869         return iterateInternal<RenderpassSubpass2>();
1870     default:
1871         TCU_THROW(InternalError, "Impossible");
1872     }
1873 }
1874 
1875 template <typename RenderpassSubpass>
iterateInternal(void)1876 tcu::TestStatus SubpassSelfDependencyBackwardsTestInstance::iterateInternal(void)
1877 {
1878     de::Random rand(5);
1879     const DeviceInterface &vkd(m_context.getDeviceInterface());
1880     const VkDevice device           = m_context.getDevice();
1881     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1882     const Unique<VkCommandPool> commandPool(
1883         createCommandPool(vkd, m_context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
1884     const Unique<VkCommandBuffer> commandBuffer(
1885         allocateCommandBuffer(vkd, m_context.getDevice(), *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1886     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1887     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
1888     vector<Vec4> vertexData;
1889     Move<VkImage> outputImage;
1890     de::MovePtr<Allocation> outputImageAllocation;
1891     Move<VkImageView> outputImageView;
1892     Move<VkPipelineLayout> pipelineLayout;
1893     Move<VkPipeline> renderPipeline;
1894     Move<VkFramebuffer> framebuffer;
1895     Move<VkRenderPass> renderPass;
1896     Move<VkBuffer> indirectBuffer;
1897     de::MovePtr<Allocation> indirectBufferMemory;
1898     Move<VkBuffer> resultBuffer;
1899     de::MovePtr<Allocation> resultBufferMemory;
1900     const VkDeviceSize indirectBufferSize = 4 * sizeof(uint32_t);
1901     Move<VkBuffer> vertexBuffer;
1902     de::MovePtr<Allocation> vertexBufferMemory;
1903 
1904     // Create output image.
1905     {
1906         const VkExtent3D imageExtent = {
1907             m_width,  // uint32_t    width
1908             m_height, // uint32_t    height
1909             1u        // uint32_t    depth
1910         };
1911 
1912         VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1913 
1914         const VkImageCreateInfo imageCreateInfo = {
1915             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
1916             DE_NULL,                             // const void*                pNext
1917             0u,                                  // VkImageCreateFlags        flags
1918             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
1919             m_format,                            // VkFormat                    format
1920             imageExtent,                         // VkExtent3D                extent
1921             1u,                                  // uint32_t                    mipLevels
1922             1u,                                  // uint32_t                    arrayLayers
1923             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
1924             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
1925             usage,                               // VkImageUsageFlags        usage
1926             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
1927             1u,                                  // uint32_t                    queueFamilyIndexCount
1928             &queueFamilyIndex,                   // const uint32_t*            pQueueFamilyIndices
1929             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
1930         };
1931 
1932         outputImage           = createImage(vkd, device, &imageCreateInfo, DE_NULL);
1933         outputImageAllocation = m_context.getDefaultAllocator().allocate(
1934             getImageMemoryRequirements(vkd, device, *outputImage), MemoryRequirement::Any);
1935         VK_CHECK(vkd.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(),
1936                                      outputImageAllocation->getOffset()));
1937     }
1938 
1939     // Create indirect buffer and initialize.
1940     {
1941         const VkBufferUsageFlags bufferUsage(VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1942         const VkBufferCreateInfo bufferCreateInfo = {
1943             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType        sType
1944             DE_NULL,                              // const void*            pNext
1945             0u,                                   // VkBufferCreateFlags    flags
1946             indirectBufferSize,                   // VkDeviceSize            size
1947             bufferUsage,                          // VkBufferUsageFlags    usage
1948             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode        sharingMode
1949             0u,                                   // uint32_t                queueFamilyIndexCount
1950             DE_NULL                               // const uint32_t*        pQueueFamilyIndices
1951         };
1952 
1953         indirectBuffer       = createBuffer(vkd, device, &bufferCreateInfo);
1954         indirectBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *indirectBuffer);
1955 
1956         VkDrawIndirectCommand drawIndirectCommand = {
1957             64u, // uint32_t    vertexCount
1958             1u,  // uint32_t    instanceCount
1959             0u,  // uint32_t    firstVertex
1960             0u,  // uint32_t    firstInstance
1961         };
1962 
1963         deMemcpy(indirectBufferMemory->getHostPtr(), (void *)&drawIndirectCommand, sizeof(VkDrawIndirectCommand));
1964         flushAlloc(vkd, device, *indirectBufferMemory);
1965     }
1966 
1967     // Create result buffer.
1968     {
1969         resultBuffer       = createBuffer(vkd, device, m_format, m_width, m_height);
1970         resultBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *resultBuffer);
1971     }
1972 
1973     // Create descriptor set layout.
1974     Unique<VkDescriptorSetLayout> descriptorSetLayout(
1975         DescriptorSetLayoutBuilder()
1976             .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_GEOMETRY_BIT)
1977             .build(vkd, device));
1978     // Create descriptor pool.
1979     Unique<VkDescriptorPool> descriptorPool(
1980         DescriptorPoolBuilder()
1981             .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
1982             .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
1983     // Create descriptor set.
1984     Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vkd, device, *descriptorPool, *descriptorSetLayout));
1985 
1986     // Update descriptor set information.
1987     {
1988         VkDescriptorBufferInfo descIndirectBuffer = makeDescriptorBufferInfo(*indirectBuffer, 0, indirectBufferSize);
1989 
1990         DescriptorSetUpdateBuilder()
1991             .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1992                          VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descIndirectBuffer)
1993             .update(vkd, device);
1994     }
1995 
1996     // Create render pipeline layout.
1997     {
1998         const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1999             VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                sType
2000             DE_NULL,                                       // const void*                    pNext
2001             (vk::VkPipelineLayoutCreateFlags)0,            // VkPipelineLayoutCreateFlags    flags
2002             1u,                                            // uint32_t                        setLayoutCount
2003             &*descriptorSetLayout,                         // const VkDescriptorSetLayout*    pSetLayouts
2004             0u,                                            // uint32_t                        pushConstantRangeCount
2005             DE_NULL                                        // const VkPushConstantRange*    pPushConstantRanges
2006         };
2007 
2008         pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
2009     }
2010 
2011     // Create render pass.
2012     {
2013         vector<Attachment> attachments;
2014         vector<AttachmentReference> colorAttachmentReferences;
2015 
2016         attachments.push_back(Attachment(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
2017                                          VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2018                                          VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_UNDEFINED,
2019                                          VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
2020         colorAttachmentReferences.push_back(AttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
2021 
2022         const vector<Subpass> subpasses(1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
2023                                                    colorAttachmentReferences, vector<AttachmentReference>(),
2024                                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
2025                                                    vector<uint32_t>()));
2026         vector<SubpassDependency> deps;
2027 
2028         deps.push_back(SubpassDependency(0u,                                    // uint32_t                srcPass
2029                                          0u,                                    // uint32_t                dstPass
2030                                          VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, // VkPipelineStageFlags    srcStageMask
2031                                          VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,   // VkPipelineStageFlags    dstStageMask
2032                                          VK_ACCESS_SHADER_WRITE_BIT,            // VkAccessFlags        srcAccessMask
2033                                          VK_ACCESS_INDIRECT_COMMAND_READ_BIT,   // VkAccessFlags        dstAccessMask
2034                                          0));                                   // VkDependencyFlags    flags
2035 
2036         renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, deps), m_renderingType);
2037     }
2038 
2039     // Create render pipeline.
2040     {
2041         const Unique<VkShaderModule> vertexShaderModule(
2042             createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u));
2043         const Unique<VkShaderModule> geometryShaderModule(
2044             createShaderModule(vkd, device, m_context.getBinaryCollection().get("geom"), 0u));
2045         const Unique<VkShaderModule> fragmentShaderModule(
2046             createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u));
2047 
2048         const VkVertexInputBindingDescription vertexBinding0 = {
2049             0u,                         // uint32_t binding;
2050             sizeof(Vec4),               // uint32_t strideInBytes;
2051             VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
2052         };
2053 
2054         VkVertexInputAttributeDescription attr0 = {
2055             0u,                            // uint32_t location;
2056             0u,                            // uint32_t binding;
2057             VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2058             0u                             // uint32_t offsetInBytes;
2059         };
2060 
2061         const VkPipelineVertexInputStateCreateInfo vertexInputState = {
2062             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                            sType
2063             DE_NULL,                                   // const void*                                pNext
2064             (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags    flags
2065             1u,              // uint32_t                                    vertexBindingDescriptionCount
2066             &vertexBinding0, // const VkVertexInputBindingDescription*    pVertexBindingDescriptions
2067             1u,              // uint32_t                                    vertexAttributeDescriptionCount
2068             &attr0           // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
2069         };
2070 
2071         const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(m_width, m_height)));
2072         const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(m_width, m_height)));
2073 
2074         renderPipeline = makeGraphicsPipeline(
2075             vkd,                   // const DeviceInterface&                        vk
2076             device,                // const VkDevice                                device
2077             *pipelineLayout,       // const VkPipelineLayout                        pipelineLayout
2078             *vertexShaderModule,   // const VkShaderModule                            vertexShaderModule
2079             DE_NULL,               // const VkShaderModule                            tessellationControlShaderModule
2080             DE_NULL,               // const VkShaderModule                            tessellationEvalShaderModule
2081             *geometryShaderModule, // const VkShaderModule                            geometryShaderModule
2082             *fragmentShaderModule, // const VkShaderModule                            fragmentShaderModule
2083             *renderPass,           // const VkRenderPass                            renderPass
2084             viewports,             // const std::vector<VkViewport>&                viewports
2085             scissors,              // const std::vector<VkRect2D>&                    scissors
2086             VK_PRIMITIVE_TOPOLOGY_POINT_LIST, // const VkPrimitiveTopology                    topology
2087             0u,                               // const uint32_t                                subpass
2088             0u,                               // const uint32_t                                patchControlPoints
2089             &vertexInputState); // const VkPipelineVertexInputStateCreateInfo*    vertexInputStateCreateInfo
2090     }
2091 
2092     // Create framebuffer.
2093     {
2094         const VkImageViewCreateInfo imageViewCreateInfo = {
2095             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType
2096             DE_NULL,                                  // const void*                pNext
2097             0u,                                       // VkImageViewCreateFlags    flags
2098             *outputImage,                             // VkImage                    image
2099             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType
2100             m_format,                                 // VkFormat                    format
2101             makeComponentMappingRGBA(),               // VkComponentMapping        components
2102             {                                         // VkImageSubresourceRange    subresourceRange
2103              VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}};
2104         outputImageView = createImageView(vkd, device, &imageViewCreateInfo);
2105 
2106         const VkFramebufferCreateInfo framebufferCreateInfo = {
2107             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType            sType
2108             DE_NULL,                                   // const void*                pNext
2109             0u,                                        // VkFramebufferCreateFlags    flags
2110             *renderPass,                               // VkRenderPass                renderPass
2111             1u,                                        // uint32_t                    attachmentCount
2112             &*outputImageView,                         // const VkImageView*        pAttachments
2113             m_width,                                   // uint32_t                    width
2114             m_height,                                  // uint32_t                    height
2115             1u                                         // uint32_t                    layers
2116         };
2117 
2118         framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2119     }
2120 
2121     // Generate random point locations (pixel centered to make reference comparison easier).
2122     for (int primitiveNdx = 0; primitiveNdx < 128; primitiveNdx++)
2123     {
2124         vertexData.push_back(Vec4((float)((rand.getUint32() % m_width) * 2) / (float)m_width - 1.0f,
2125                                   (float)((rand.getUint32() % m_height) * 2) / (float)m_height - 1.0f, 1.0f, 1.0f));
2126     }
2127 
2128     // Upload vertex data.
2129     {
2130         const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
2131 
2132         const VkBufferCreateInfo vertexBufferParams = {
2133             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2134             DE_NULL,                              // const void* pNext;
2135             0u,                                   // VkBufferCreateFlags flags;
2136             (VkDeviceSize)vertexDataSize,         // VkDeviceSize size;
2137             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    // VkBufferUsageFlags usage;
2138             VK_SHARING_MODE_EXCLUSIVE,            // VkSharingMode sharingMode;
2139             1u,                                   // uint32_t queueFamilyCount;
2140             &queueFamilyIndex,                    // const uint32_t* pQueueFamilyIndices;
2141         };
2142 
2143         vertexBuffer       = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2144         vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *vertexBuffer);
2145 
2146         deMemcpy(vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2147         flushAlloc(vkd, device, *vertexBufferMemory);
2148     }
2149 
2150     beginCommandBuffer(vkd, *commandBuffer);
2151     vkd.cmdBindPipeline(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2152     vkd.cmdBindDescriptorSets(*commandBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u,
2153                               &*descriptorSet, 0u, DE_NULL);
2154 
2155     // Begin render pass.
2156     {
2157         VkRect2D renderArea = {
2158             {0u, 0u},           // VkOffset2D    offset
2159             {m_width, m_height} // VkExtent2D    extent
2160         };
2161 
2162         VkClearValue clearValue = makeClearValueColor(Vec4(0.0f, 1.0f, 0.0f, 1.0f));
2163 
2164         const VkRenderPassBeginInfo beginInfo = {
2165             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
2166             DE_NULL,                                  // const void*            pNext
2167             *renderPass,                              // VkRenderPass            renderPass
2168             *framebuffer,                             // VkFramebuffer        framebuffer
2169             renderArea,                               // VkRect2D                renderArea
2170             1u,                                       // uint32_t                clearValueCount
2171             &clearValue                               // const VkClearValue*    pClearValues
2172         };
2173 
2174         RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2175     }
2176 
2177     const VkDeviceSize bindingOffset = 0;
2178     vkd.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
2179 
2180     vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *renderPipeline);
2181 
2182     // The first indirect draw: Draw the first 64 items.
2183     vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);
2184 
2185     // Barrier for indirect buffer.
2186     {
2187         const VkMemoryBarrier barrier = {
2188             VK_STRUCTURE_TYPE_MEMORY_BARRIER,   // VkStructureType    sType
2189             DE_NULL,                            // const void*        pNext
2190             VK_ACCESS_SHADER_WRITE_BIT,         // VkAccessFlags    srcAccessMask
2191             VK_ACCESS_INDIRECT_COMMAND_READ_BIT // VkAccessFlags    dstAccessMask
2192         };
2193 
2194         vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
2195                                VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, 0u, 1u, &barrier, 0u, DE_NULL, 0u, DE_NULL);
2196     }
2197 
2198     // The second indirect draw: Draw the last 64 items.
2199     vkd.cmdDrawIndirect(*commandBuffer, *indirectBuffer, 0u, 1u, 0u);
2200 
2201     RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2202 
2203     // Copy results to a buffer.
2204     copyImageToBuffer(vkd, *commandBuffer, *outputImage, *resultBuffer, tcu::IVec2(m_width, m_height));
2205 
2206     endCommandBuffer(vkd, *commandBuffer);
2207     submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
2208     invalidateMappedMemoryRange(vkd, m_context.getDevice(), resultBufferMemory->getMemory(),
2209                                 resultBufferMemory->getOffset(), VK_WHOLE_SIZE);
2210 
2211     // Verify result.
2212     {
2213         const tcu::TextureFormat format(mapVkFormat(m_format));
2214 
2215         const void *const ptrResult(resultBufferMemory->getHostPtr());
2216         tcu::TextureLevel reference(format, m_width, m_height);
2217         const tcu::ConstPixelBufferAccess resultAccess(format, m_width, m_height, 1, ptrResult);
2218         const PixelBufferAccess referenceAccess(reference.getAccess());
2219 
2220         // Setup and run reference renderer.
2221         {
2222             vector<Vec4> triangles;
2223             const float offset = 0.03f;
2224 
2225             // Convert points into triangles to have quads similar to what GPU is producing from geometry shader.
2226             for (size_t vtxIdx = 0; vtxIdx < vertexData.size(); vtxIdx++)
2227             {
2228                 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, offset, 0.0f, 0.0f));
2229                 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
2230                 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
2231 
2232                 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(-offset, -offset, 0.0f, 0.0f));
2233                 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, offset, 0.0f, 0.0f));
2234                 triangles.push_back(vertexData[vtxIdx] + tcu::Vec4(offset, -offset, 0.0f, 0.0f));
2235             }
2236 
2237             const SelfDependencyBackwardsVertShader vertShader;
2238             const SelfDependencyBackwardsFragShader fragShader;
2239             const rr::Renderer renderer;
2240             const rr::Program program(&vertShader, &fragShader);
2241             const rr::MultisamplePixelBufferAccess msAccess(
2242                 rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(referenceAccess));
2243             const rr::RenderTarget renderTarget(msAccess);
2244             const rr::PrimitiveType primitiveType(rr::PRIMITIVETYPE_TRIANGLES);
2245             const rr::PrimitiveList primitiveList(rr::PrimitiveList(primitiveType, (uint32_t)triangles.size(), 0));
2246             const rr::ViewportState viewportState(msAccess);
2247             const rr::RenderState renderState(viewportState,
2248                                               m_context.getDeviceProperties().limits.subPixelPrecisionBits);
2249             const rr::VertexAttrib vertices =
2250                 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &triangles[0]);
2251 
2252             tcu::clear(referenceAccess, tcu::UVec4(0, 255, 0, 255));
2253             renderer.draw(rr::DrawCommand(renderState, renderTarget, program, 1u, &vertices, primitiveList));
2254         }
2255 
2256         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
2257                                         "Color buffer",                      // imageSetName
2258                                         "",                                  // imageSetDesc
2259                                         referenceAccess,                     // reference
2260                                         resultAccess,                        // result
2261                                         Vec4(0.01f),                         // threshold
2262                                         tcu::COMPARE_LOG_RESULT))            // logMode
2263         {
2264             m_resultCollector.fail("Image compare failed.");
2265         }
2266     }
2267 
2268     return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2269 }
2270 
2271 struct SeparateChannelsTestConfig
2272 {
SeparateChannelsTestConfigvkt::__anonc414995a0111::SeparateChannelsTestConfig2273     SeparateChannelsTestConfig(VkFormat format_, SharedGroupParams groupParams_)
2274         : format(format_)
2275         , groupParams(groupParams_)
2276     {
2277     }
2278 
2279     VkFormat format;
2280     SharedGroupParams groupParams;
2281 };
2282 
2283 class SeparateChannelsTestInstance : public TestInstance
2284 {
2285 public:
2286     SeparateChannelsTestInstance(Context &context, SeparateChannelsTestConfig testConfig);
2287 
2288     ~SeparateChannelsTestInstance(void) = default;
2289 
2290     tcu::TestStatus iterate(void);
2291 
2292 protected:
2293     void setup(void);
2294 #ifndef CTS_USES_VULKANSC
2295     void startDynamicRendering(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u);
2296 #endif // CTS_USES_VULKANSC
2297     void draw(VkCommandBuffer cmdBuffer);
2298     void postRenderCommands(VkCommandBuffer cmdBuffer);
2299     tcu::TestStatus verifyResults(void);
2300 
2301     template <typename RenderpassSubpass>
2302     void iterateInternal(void);
2303     void iterateInternalDynamicRendering(void);
2304 
2305 private:
2306     SharedGroupParams m_groupParams;
2307     const uint32_t m_width;
2308     const uint32_t m_height;
2309     const VkFormat m_format;
2310     const uint32_t m_stencilRefValue;
2311     const uint32_t m_tileSize;
2312     const tcu::Vec4 m_colorInitValues[2];
2313     const float m_depthInitValues[2];
2314     const uint32_t m_stencilInitValues[2];
2315 
2316     Move<VkImage> m_colorImage;
2317     de::MovePtr<Allocation> m_colorImageAllocation;
2318     Move<VkImage> m_dsImage;
2319     de::MovePtr<Allocation> m_dsImageAllocation;
2320     Move<VkImageView> m_imageView;
2321     Move<VkImageView> m_dsImageView;
2322     PipelineLayoutWrapper m_pipelineLayout;
2323     GraphicsPipelineWrapper m_renderPipeline;
2324     Move<VkFramebuffer> m_framebuffer;
2325     Move<VkRenderPass> m_renderPass;
2326     Move<VkBuffer> m_resultBuffer0;
2327     de::MovePtr<Allocation> m_resultBuffer0Memory;
2328     Move<VkBuffer> m_resultBuffer1;
2329     de::MovePtr<Allocation> m_resultBuffer1Memory;
2330     Move<VkBuffer> m_vertexBuffer;
2331     de::MovePtr<Allocation> m_vertexBufferMemory;
2332     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
2333     Move<VkDescriptorPool> m_descriptorPool;
2334     Move<VkDescriptorSet> m_descriptorSet;
2335 };
2336 
SeparateChannelsTestInstance(Context & context,SeparateChannelsTestConfig testConfig)2337 SeparateChannelsTestInstance::SeparateChannelsTestInstance(Context &context, SeparateChannelsTestConfig testConfig)
2338     : TestInstance(context)
2339     , m_groupParams(testConfig.groupParams)
2340     , m_width(256u)
2341     , m_height(256u)
2342     , m_format(testConfig.format)
2343     , m_stencilRefValue(200u)
2344     , m_tileSize(32u)
2345     , m_colorInitValues{tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f)}
2346     , m_depthInitValues{0.3f, 0.7f}
2347     , m_stencilInitValues{2u, 100u}
2348     , m_renderPipeline(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
2349                        context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
2350 {
2351 }
2352 
iterate(void)2353 tcu::TestStatus SeparateChannelsTestInstance::iterate(void)
2354 {
2355     setup();
2356 
2357     switch (m_groupParams->renderingType)
2358     {
2359     case RENDERING_TYPE_RENDERPASS_LEGACY:
2360         iterateInternal<RenderpassSubpass1>();
2361         break;
2362     case RENDERING_TYPE_RENDERPASS2:
2363         iterateInternal<RenderpassSubpass2>();
2364         break;
2365     case RENDERING_TYPE_DYNAMIC_RENDERING:
2366         iterateInternalDynamicRendering();
2367         break;
2368     default:
2369         TCU_THROW(InternalError, "Impossible");
2370     }
2371 
2372     return verifyResults();
2373 }
2374 
setup(void)2375 void SeparateChannelsTestInstance::setup(void)
2376 {
2377     const DeviceInterface &vkd      = m_context.getDeviceInterface();
2378     const VkDevice device           = m_context.getDevice();
2379     const VkQueue queue             = m_context.getUniversalQueue();
2380     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2381     const bool isDSFormat           = isDepthStencilFormat(m_format);
2382     const VkFormat colorFormat      = isDSFormat ? VK_FORMAT_R8G8B8A8_UNORM : m_format;
2383     const VkExtent3D imageExtent{
2384         m_width,  // uint32_t    width
2385         m_height, // uint32_t    height
2386         1u        // uint32_t    depth
2387     };
2388 
2389     // When testing color formats the same attachment is used as input and output.
2390     // This requires general layout to be used for render pass object or local_read for dynamic rendering.
2391     VkImageLayout colorImageLayout = isDSFormat ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_GENERAL;
2392 #ifndef CTS_USES_VULKANSC
2393     if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !isDSFormat)
2394         colorImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
2395 #endif
2396 
2397     // Create image used for both input and output in case of color test, and as a color output in depth/stencil test.
2398     {
2399         VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
2400                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2401 
2402         const VkImageCreateInfo imageCreateInfo = {
2403             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
2404             DE_NULL,                             // const void*                pNext
2405             0u,                                  // VkImageCreateFlags        flags
2406             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
2407             colorFormat,                         // VkFormat                    format
2408             imageExtent,                         // VkExtent3D                extent
2409             1u,                                  // uint32_t                    mipLevels
2410             1u,                                  // uint32_t                    arrayLayers
2411             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
2412             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
2413             usage,                               // VkImageUsageFlags        usage
2414             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
2415             1u,                                  // uint32_t                    queueFamilyIndexCount
2416             &queueFamilyIndex,                   // const uint32_t*            pQueueFamilyIndices
2417             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
2418         };
2419 
2420         checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2421 
2422         m_colorImage           = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2423         m_colorImageAllocation = m_context.getDefaultAllocator().allocate(
2424             getImageMemoryRequirements(vkd, device, *m_colorImage), MemoryRequirement::Any);
2425         VK_CHECK(vkd.bindImageMemory(device, *m_colorImage, m_colorImageAllocation->getMemory(),
2426                                      m_colorImageAllocation->getOffset()));
2427     }
2428 
2429     // Create depth/stencil image
2430     if (isDSFormat)
2431     {
2432         VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2433                                   VK_IMAGE_USAGE_TRANSFER_DST_BIT;
2434 
2435         const VkImageCreateInfo imageCreateInfo = {
2436             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
2437             DE_NULL,                             // const void*                pNext
2438             0u,                                  // VkImageCreateFlags        flags
2439             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
2440             m_format,                            // VkFormat                    format
2441             imageExtent,                         // VkExtent3D                extent
2442             1u,                                  // uint32_t                    mipLevels
2443             1u,                                  // uint32_t                    arrayLayers
2444             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
2445             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
2446             usage,                               // VkImageUsageFlags        usage
2447             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
2448             1u,                                  // uint32_t                    queueFamilyIndexCount
2449             &queueFamilyIndex,                   // const uint32_t*            pQueueFamilyIndices
2450             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
2451         };
2452 
2453         checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
2454 
2455         m_dsImage           = createImage(vkd, device, &imageCreateInfo, DE_NULL);
2456         m_dsImageAllocation = m_context.getDefaultAllocator().allocate(
2457             getImageMemoryRequirements(vkd, device, *m_dsImage), MemoryRequirement::Any);
2458         VK_CHECK(vkd.bindImageMemory(device, *m_dsImage, m_dsImageAllocation->getMemory(),
2459                                      m_dsImageAllocation->getOffset()));
2460 
2461         // Initialize depth / stencil image
2462         initDepthStencilImageChessboardPattern(
2463             vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_dsImage, m_format,
2464             m_depthInitValues[0], m_depthInitValues[1], m_stencilInitValues[0], m_stencilInitValues[1], m_width,
2465             m_height, m_tileSize, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2466             VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2467     }
2468 
2469     // Initialize color image
2470     initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(),
2471                                     *m_colorImage, colorFormat, m_colorInitValues[0], m_colorInitValues[1], m_width,
2472                                     m_height, m_tileSize, VK_IMAGE_LAYOUT_UNDEFINED, colorImageLayout,
2473                                     VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
2474 
2475     // Create color image views
2476     {
2477         const VkImageViewCreateInfo imageViewCreateInfo = {
2478             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType
2479             DE_NULL,                                  // const void*                pNext
2480             0u,                                       // VkImageViewCreateFlags    flags
2481             *m_colorImage,                            // VkImage                    image
2482             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType
2483             colorFormat,                              // VkFormat                    format
2484             makeComponentMappingRGBA(),               // VkComponentMapping        components
2485             {                                         // VkImageSubresourceRange    subresourceRange
2486              VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}};
2487 
2488         m_imageView = createImageView(vkd, device, &imageViewCreateInfo);
2489     }
2490 
2491     // Create depth/stencil image view
2492     if (isDSFormat)
2493     {
2494         const VkImageViewCreateInfo imageViewCreateInfo = {
2495             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType
2496             DE_NULL,                                  // const void*                pNext
2497             0u,                                       // VkImageViewCreateFlags    flags
2498             *m_dsImage,                               // VkImage                    image
2499             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType
2500             m_format,                                 // VkFormat                    format
2501             makeComponentMappingRGBA(),               // VkComponentMapping        components
2502             {                                         // VkImageSubresourceRange    subresourceRange
2503              VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u, 0u, 1u}};
2504 
2505         m_dsImageView = createImageView(vkd, device, &imageViewCreateInfo);
2506     }
2507 
2508     // Create result buffers.
2509     {
2510         m_resultBuffer0       = createBuffer(vkd, device, m_format, m_width, m_height);
2511         m_resultBuffer0Memory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_resultBuffer0);
2512         m_resultBuffer1       = createBuffer(vkd, device, m_format, m_width, m_height);
2513         m_resultBuffer1Memory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_resultBuffer1);
2514     }
2515 
2516     // Create descriptor set layout.
2517     m_descriptorSetLayout = DescriptorSetLayoutBuilder()
2518                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
2519                                 .build(vkd, device);
2520     // Create descriptor pool.
2521     m_descriptorPool = DescriptorPoolBuilder()
2522                            .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
2523                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
2524     // Create descriptor set.
2525     m_descriptorSet = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayout);
2526 
2527     // Update descriptor set information.
2528     if (!isDSFormat)
2529     {
2530         VkDescriptorImageInfo descInputAttachment =
2531             makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
2532 
2533         DescriptorSetUpdateBuilder()
2534             .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
2535                          VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descInputAttachment)
2536             .update(vkd, device);
2537     }
2538 
2539     // Create render pipeline layout.
2540     m_pipelineLayout =
2541         PipelineLayoutWrapper(m_groupParams->pipelineConstructionType, vkd, device, *m_descriptorSetLayout);
2542 
2543     if (m_groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
2544     {
2545         // Create render pass.
2546         vector<Attachment> attachments;
2547         vector<AttachmentReference> colorAttachmentReferences;
2548         vector<AttachmentReference> inputAttachmentReferences;
2549         AttachmentReference dsAttachmentReference(1u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2550                                                   VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
2551 
2552         const VkImageAspectFlags inputAttachmentAspectMask(
2553             (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
2554                 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
2555                 static_cast<VkImageAspectFlags>(0));
2556 
2557         attachments.push_back(Attachment(colorFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
2558                                          VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2559                                          VK_ATTACHMENT_STORE_OP_DONT_CARE, colorImageLayout, colorImageLayout));
2560         colorAttachmentReferences.push_back(AttachmentReference(0u, colorImageLayout));
2561 
2562         if (isDSFormat)
2563         {
2564             attachments.push_back(Attachment(
2565                 m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
2566                 VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
2567                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));
2568         }
2569         else
2570         {
2571             inputAttachmentReferences.push_back(
2572                 AttachmentReference(0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask));
2573         }
2574 
2575         const vector<Subpass> subpasses(
2576             1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences, colorAttachmentReferences,
2577                        vector<AttachmentReference>(),
2578                        isDSFormat ? dsAttachmentReference :
2579                                     AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
2580                        vector<uint32_t>()));
2581         vector<SubpassDependency> subpassDependency;
2582         if (!isDSFormat)
2583         {
2584             /* Self supass-dependency */
2585             subpassDependency.push_back(
2586                 SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2587                                   VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2588                                   VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
2589         }
2590         m_renderPass = createRenderPass(vkd, device, RenderPass(attachments, subpasses, subpassDependency),
2591                                         m_groupParams->renderingType);
2592 
2593         // Create framebuffer.
2594         const VkImageView dsAttachments[]{*m_imageView, *m_dsImageView};
2595 
2596         const VkFramebufferCreateInfo framebufferCreateInfo{
2597             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,  // VkStructureType            sType
2598             DE_NULL,                                    // const void*                pNext
2599             0u,                                         // VkFramebufferCreateFlags    flags
2600             *m_renderPass,                              // VkRenderPass                renderPass
2601             isDSFormat ? 2u : 1u,                       // uint32_t                    attachmentCount
2602             isDSFormat ? dsAttachments : &*m_imageView, // const VkImageView*        pAttachments
2603             m_width,                                    // uint32_t                    width
2604             m_height,                                   // uint32_t                    height
2605             1u                                          // uint32_t                    layers
2606         };
2607 
2608         m_framebuffer = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
2609     }
2610 
2611     // Create render pipeline.
2612     {
2613         const ShaderWrapper vertexShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
2614         const ShaderWrapper fragmentShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
2615 
2616         const VkVertexInputBindingDescription vertexBinding0{
2617             0u,                         // uint32_t                    binding
2618             sizeof(Vec4),               // uint32_t                    strideInBytes
2619             VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate    stepRate
2620         };
2621 
2622         const VkVertexInputAttributeDescription attr0{
2623             0u,                            // uint32_t    location
2624             0u,                            // uint32_t    binding
2625             VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat    format
2626             0u                             // uint32_t    offsetInBytes
2627         };
2628 
2629         const VkPipelineVertexInputStateCreateInfo vertexInputState{
2630             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                            sType
2631             DE_NULL,                                   // const void*                                pNext
2632             (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags    flags
2633             1u,              // uint32_t                                    vertexBindingDescriptionCount
2634             &vertexBinding0, // const VkVertexInputBindingDescription*    pVertexBindingDescriptions
2635             1u,              // uint32_t                                    vertexAttributeDescriptionCount
2636             &attr0           // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
2637         };
2638 
2639         // Use write mask to enable only B and A channels to prevent self dependency (reads are done for channels R and G).
2640         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState{
2641             VK_FALSE,                                           // VkBool32                    blendEnable
2642             VK_BLEND_FACTOR_ZERO,                               // VkBlendFactor            srcColorBlendFactor
2643             VK_BLEND_FACTOR_ZERO,                               // VkBlendFactor            dstColorBlendFactor
2644             VK_BLEND_OP_ADD,                                    // VkBlendOp                colorBlendOp
2645             VK_BLEND_FACTOR_ZERO,                               // VkBlendFactor            srcAlphaBlendFactor
2646             VK_BLEND_FACTOR_ZERO,                               // VkBlendFactor            dstAlphaBlendFactor
2647             VK_BLEND_OP_ADD,                                    // VkBlendOp                alphaBlendOp
2648             VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT // VkColorComponentFlags    colorWriteMask
2649         };
2650 
2651         const VkPipelineColorBlendStateCreateInfo colorBlendState{
2652             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                                sType
2653             DE_NULL,                    // const void*                                    pNext
2654             0u,                         // VkPipelineColorBlendStateCreateFlags            flags
2655             VK_FALSE,                   // VkBool32                                        logicOpEnable
2656             VK_LOGIC_OP_CLEAR,          // VkLogicOp                                    logicOp
2657             1u,                         // uint32_t                                        attachmentCount
2658             &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState*    pAttachments
2659             {0.0f, 0.0f, 0.0f, 0.0f}    // float                                        blendConstants[4]
2660         };
2661 
2662         const VkStencilOpState stencilOpState{
2663             VK_STENCIL_OP_REPLACE, // VkStencilOp    failOp
2664             VK_STENCIL_OP_REPLACE, // VkStencilOp    passOp
2665             VK_STENCIL_OP_ZERO,    // VkStencilOp    depthFailOp
2666             VK_COMPARE_OP_ALWAYS,  // VkCompareOp    compareOp
2667             0xff,                  // uint32_t        compareMask
2668             0xff,                  // uint32_t        writeMask
2669             m_stencilRefValue      // uint32_t        reference
2670         };
2671 
2672         const VkPipelineDepthStencilStateCreateInfo depthStencilState{
2673             VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                            sType
2674             DE_NULL,            // const void*                                pNext
2675             0u,                 // VkPipelineDepthStencilStateCreateFlags    flags
2676             VK_TRUE,            // VkBool32                                    depthTestEnable
2677             VK_FALSE,           // VkBool32                                    depthWriteEnable
2678             VK_COMPARE_OP_LESS, // VkCompareOp                                depthCompareOp
2679             VK_FALSE,           // VkBool32                                    depthBoundsTestEnable
2680             VK_TRUE,            // VkBool32                                    stencilTestEnable
2681             stencilOpState,     // VkStencilOpState                            front
2682             stencilOpState,     // VkStencilOpState                            back
2683             0.0f,               // float                                    minDepthBounds
2684             1.0f                // float                                    maxDepthBounds
2685         };
2686 
2687         PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
2688         RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
2689         const std::vector<VkViewport> viewports{makeViewport(m_width, m_height)};
2690         const std::vector<VkRect2D> scissors{makeRect2D(m_width, m_height)};
2691 
2692 #ifndef CTS_USES_VULKANSC
2693         const uint32_t inputAttachmentIndex   = 0;
2694         const uint32_t dsInputAttachmentIndex = VK_ATTACHMENT_UNUSED;
2695         VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo{
2696             VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR,
2697             DE_NULL,
2698             1u,
2699             &inputAttachmentIndex,
2700             (isDSFormat ? &dsInputAttachmentIndex : DE_NULL),
2701             (isDSFormat ? &dsInputAttachmentIndex : DE_NULL)};
2702         VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
2703                                                           DE_NULL,
2704                                                           0u,
2705                                                           1u,
2706                                                           &colorFormat,
2707                                                           (isDSFormat ? m_format : VK_FORMAT_UNDEFINED),
2708                                                           (isDSFormat ? m_format : VK_FORMAT_UNDEFINED)};
2709         if (*m_renderPass == DE_NULL)
2710         {
2711             renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
2712             if (!isDSFormat)
2713                 renderingInputAttachmentIndexInfoWrapper.ptr = &renderingInputAttachmentIndexInfo;
2714         }
2715 #endif
2716         if (isDSFormat)
2717             m_renderPipeline.setDefaultColorBlendState();
2718         else
2719             m_renderPipeline.setDefaultDepthStencilState();
2720 
2721         m_renderPipeline.setDefaultMultisampleState()
2722             .setDefaultRasterizationState()
2723             .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2724             .setupVertexInputState(&vertexInputState)
2725             .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayout, *m_renderPass, 0u,
2726                                               vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
2727                                               DE_NULL, DE_NULL, renderingCreateInfoWrapper, DE_NULL)
2728             .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fragmentShaderModule,
2729                                       (isDSFormat ? &depthStencilState : DE_NULL), 0, 0, 0, {},
2730                                       renderingInputAttachmentIndexInfoWrapper)
2731             .setupFragmentOutputState(*m_renderPass, 0u, (isDSFormat ? DE_NULL : &colorBlendState))
2732             .setMonolithicPipelineLayout(m_pipelineLayout)
2733             .buildPipeline();
2734     }
2735 
2736     // Generate quad vertices
2737     vector<Vec4> vertexData{tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f),
2738                             tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f)};
2739 
2740     // Upload vertex data.
2741     {
2742         const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
2743 
2744         const VkBufferCreateInfo vertexBufferParams{
2745             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, //    VkStructureType        sType
2746             DE_NULL,                              //    const void*            pNext
2747             0u,                                   //    VkBufferCreateFlags    flags
2748             (VkDeviceSize)vertexDataSize,         //    VkDeviceSize        size
2749             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    //    VkBufferUsageFlags    usage
2750             VK_SHARING_MODE_EXCLUSIVE,            //    VkSharingMode        sharingMode
2751             1u,                                   //    uint32_t            queueFamilyCount
2752             &queueFamilyIndex,                    //    const uint32_t*        pQueueFamilyIndices
2753         };
2754 
2755         m_vertexBuffer       = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
2756         m_vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_vertexBuffer);
2757 
2758         deMemcpy(m_vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
2759         flushAlloc(vkd, device, *m_vertexBufferMemory);
2760     }
2761 }
2762 
2763 #ifndef CTS_USES_VULKANSC
startDynamicRendering(VkCommandBuffer cmdBuffer,VkRenderingFlagsKHR renderingFlags)2764 void SeparateChannelsTestInstance::startDynamicRendering(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags)
2765 {
2766     const DeviceInterface &vkd(m_context.getDeviceInterface());
2767     const bool isDSFormat         = isDepthStencilFormat(m_format);
2768     const VkClearValue clearValue = makeClearValueColor(Vec4(0.0f));
2769     const VkRect2D renderArea     = makeRect2D(m_width, m_height);
2770 
2771     if (isDSFormat)
2772     {
2773         beginRendering(vkd, cmdBuffer, *m_imageView, *m_dsImageView, true, renderArea, clearValue, clearValue,
2774                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
2775                        VK_ATTACHMENT_LOAD_OP_LOAD, renderingFlags);
2776     }
2777     else
2778     {
2779         beginRendering(vkd, cmdBuffer, *m_imageView, renderArea, clearValue, VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR,
2780                        VK_ATTACHMENT_LOAD_OP_LOAD, renderingFlags);
2781     }
2782 }
2783 #endif
2784 
draw(VkCommandBuffer cmdBuffer)2785 void SeparateChannelsTestInstance::draw(VkCommandBuffer cmdBuffer)
2786 {
2787     const DeviceInterface &vkd(m_context.getDeviceInterface());
2788     const bool isDSFormat            = isDepthStencilFormat(m_format);
2789     const VkDeviceSize bindingOffset = 0;
2790 
2791     vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_renderPipeline.getPipeline());
2792     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
2793     if (!isDSFormat)
2794     {
2795         vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u,
2796                                   &*m_descriptorSet, 0u, DE_NULL);
2797 
2798         const VkMemoryBarrier memoryBarrier =
2799             makeMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
2800         vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
2801                                VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1u, &memoryBarrier,
2802                                0u, DE_NULL, 0u, DE_NULL);
2803     }
2804     vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
2805 }
2806 
postRenderCommands(VkCommandBuffer cmdBuffer)2807 void SeparateChannelsTestInstance::postRenderCommands(VkCommandBuffer cmdBuffer)
2808 {
2809     const DeviceInterface &vkd(m_context.getDeviceInterface());
2810     const bool isDSFormat = isDepthStencilFormat(m_format);
2811 
2812     if (isDSFormat)
2813         copyDepthStencilImageToBuffers(vkd, cmdBuffer, *m_dsImage, *m_resultBuffer0, *m_resultBuffer1,
2814                                        tcu::IVec2(m_width, m_height), VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
2815                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
2816     else
2817         copyImageToBuffer(vkd, cmdBuffer, *m_colorImage, *m_resultBuffer0, tcu::IVec2(m_width, m_height),
2818                           VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
2819 }
2820 
verifyResults(void)2821 tcu::TestStatus SeparateChannelsTestInstance::verifyResults(void)
2822 {
2823     const tcu::TextureFormat format(mapVkFormat(m_format));
2824     tcu::TextureLevel reference(format, m_width, m_height);
2825     tcu::ResultCollector resultCollector;
2826 
2827     if (isDepthStencilFormat(m_format))
2828     {
2829         const void *const ptrDepth(m_resultBuffer0Memory->getHostPtr());
2830         const void *const ptrStencil(m_resultBuffer1Memory->getHostPtr());
2831         const tcu::ConstPixelBufferAccess resultDepthAccess(getDepthCopyFormat(m_format), m_width, m_height, 1,
2832                                                             ptrDepth);
2833         const tcu::ConstPixelBufferAccess resultStencilAccess(getStencilCopyFormat(m_format), m_width, m_height, 1,
2834                                                               ptrStencil);
2835         const PixelBufferAccess referenceDepthAccess(
2836             tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_DEPTH));
2837         const PixelBufferAccess referenceStencilAccess(
2838             tcu::getEffectiveDepthStencilAccess(reference.getAccess(), tcu::Sampler::MODE_STENCIL));
2839         const float depthThreshold(
2840             1.0f /
2841             ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(resultDepthAccess.getFormat()).cast<uint32_t>()) - 1u)
2842                 .cast<float>()
2843                 .x());
2844 
2845         for (uint32_t x = 0; x < m_width; x++)
2846             for (uint32_t y = 0; y < m_height; y++)
2847             {
2848                 float depthValue =
2849                     ((x / m_tileSize) % 2 != (y / m_tileSize) % 2) ? m_depthInitValues[0] : m_depthInitValues[1];
2850                 referenceDepthAccess.setPixDepth(depthValue, x, y, 0);
2851                 referenceStencilAccess.setPixel(tcu::IVec4(0.5f < depthValue ? m_stencilRefValue : 0), x, y, 0);
2852             }
2853 
2854         if (!verifyDepth(m_context, reference.getAccess(), resultDepthAccess, depthThreshold))
2855             resultCollector.fail("Depth compare failed.");
2856 
2857         if (!verifyStencil(m_context, referenceStencilAccess, resultStencilAccess))
2858             resultCollector.fail("Stencil compare failed.");
2859     }
2860     else
2861     {
2862         const void *const ptrResult(m_resultBuffer0Memory->getHostPtr());
2863         const tcu::ConstPixelBufferAccess resultAccess(format, m_width, m_height, 1, ptrResult);
2864         const PixelBufferAccess referenceAccess(reference.getAccess());
2865 
2866         for (uint32_t x = 0; x < m_width; x++)
2867             for (uint32_t y = 0; y < m_height; y++)
2868             {
2869                 const tcu::Vec4 initValue =
2870                     ((x / m_tileSize) % 2 != (y / m_tileSize) % 2) ? m_colorInitValues[0] : m_colorInitValues[1];
2871                 const tcu::Vec4 refValue = tcu::Vec4(initValue.x(), initValue.y(), initValue.x() + initValue.y(), 1.0f);
2872 
2873                 referenceAccess.setPixel(refValue, x, y, 0);
2874             }
2875 
2876         if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
2877                                         "Rendered result",                   // imageSetName
2878                                         "",                                  // imageSetDesc
2879                                         referenceAccess,                     // reference
2880                                         resultAccess,                        // result
2881                                         Vec4(0.01f),                         // threshold
2882                                         tcu::COMPARE_LOG_RESULT))            // logMode
2883         {
2884             resultCollector.fail("Image compare failed.");
2885         }
2886     }
2887 
2888     return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
2889 }
2890 
2891 template <typename RenderpassSubpass>
iterateInternal(void)2892 void SeparateChannelsTestInstance::iterateInternal(void)
2893 {
2894     const DeviceInterface &vkd(m_context.getDeviceInterface());
2895     const VkDevice device           = m_context.getDevice();
2896     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2897     const Unique<VkCommandPool> commandPool(
2898         createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2899     const Unique<VkCommandBuffer> commandBuffer(
2900         allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2901     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
2902     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
2903 
2904     beginCommandBuffer(vkd, *commandBuffer);
2905 
2906     // Begin render pass.
2907     {
2908         VkRect2D renderArea                   = makeRect2D(m_width, m_height);
2909         const VkRenderPassBeginInfo beginInfo = {
2910             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
2911             DE_NULL,                                  // const void*            pNext
2912             *m_renderPass,                            // VkRenderPass            renderPass
2913             *m_framebuffer,                           // VkFramebuffer        framebuffer
2914             renderArea,                               // VkRect2D                renderArea
2915             0u,                                       // uint32_t                clearValueCount
2916             DE_NULL                                   // const VkClearValue*    pClearValues
2917         };
2918 
2919         RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2920     }
2921 
2922     draw(*commandBuffer);
2923     RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2924 
2925     // Copy results to a buffer.
2926     postRenderCommands(*commandBuffer);
2927 
2928     endCommandBuffer(vkd, *commandBuffer);
2929     submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
2930     invalidateMappedMemoryRange(vkd, device, m_resultBuffer0Memory->getMemory(), m_resultBuffer0Memory->getOffset(),
2931                                 VK_WHOLE_SIZE);
2932     invalidateMappedMemoryRange(vkd, device, m_resultBuffer1Memory->getMemory(), m_resultBuffer1Memory->getOffset(),
2933                                 VK_WHOLE_SIZE);
2934 }
2935 
iterateInternalDynamicRendering(void)2936 void SeparateChannelsTestInstance::iterateInternalDynamicRendering(void)
2937 {
2938 #ifndef CTS_USES_VULKANSC
2939     const DeviceInterface &vkd(m_context.getDeviceInterface());
2940     const VkDevice device           = m_context.getDevice();
2941     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
2942     const Unique<VkCommandPool> commandPool(
2943         createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
2944     const Unique<VkCommandBuffer> cmdBuffer(
2945         allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2946     Move<VkCommandBuffer> secCmdBuffer;
2947     const bool isDSFormat      = isDepthStencilFormat(m_format);
2948     const VkFormat colorFormat = isDSFormat ? VK_FORMAT_R8G8B8A8_UNORM : m_format;
2949     const VkFormat dsFormat    = isDSFormat ? m_format : VK_FORMAT_UNDEFINED;
2950 
2951     if (m_groupParams->useSecondaryCmdBuffer)
2952     {
2953         secCmdBuffer = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
2954 
2955         // record secondary command buffer
2956         {
2957             if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2958             {
2959                 beginSecondaryCmdBuffer(vkd, *secCmdBuffer, colorFormat, dsFormat, true);
2960                 startDynamicRendering(*secCmdBuffer);
2961             }
2962             else
2963                 beginSecondaryCmdBuffer(vkd, *secCmdBuffer, colorFormat, dsFormat, false);
2964 
2965             draw(*secCmdBuffer);
2966 
2967             if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2968                 vkd.cmdEndRendering(*secCmdBuffer);
2969 
2970             endCommandBuffer(vkd, *secCmdBuffer);
2971         }
2972 
2973         // record primary command buffer
2974         beginCommandBuffer(vkd, *cmdBuffer);
2975 
2976         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2977             startDynamicRendering(*cmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
2978         vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
2979         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
2980             vkd.cmdEndRendering(*cmdBuffer);
2981 
2982         postRenderCommands(*cmdBuffer);
2983         endCommandBuffer(vkd, *cmdBuffer);
2984     }
2985     else
2986     {
2987         beginCommandBuffer(vkd, *cmdBuffer);
2988 
2989         startDynamicRendering(*cmdBuffer);
2990         draw(*cmdBuffer);
2991         endRendering(vkd, *cmdBuffer);
2992 
2993         // Copy results to a buffer.
2994         postRenderCommands(*cmdBuffer);
2995 
2996         endCommandBuffer(vkd, *cmdBuffer);
2997     }
2998 
2999     submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
3000     invalidateMappedMemoryRange(vkd, device, m_resultBuffer0Memory->getMemory(), m_resultBuffer0Memory->getOffset(),
3001                                 VK_WHOLE_SIZE);
3002     invalidateMappedMemoryRange(vkd, device, m_resultBuffer1Memory->getMemory(), m_resultBuffer1Memory->getOffset(),
3003                                 VK_WHOLE_SIZE);
3004 #endif
3005 }
3006 
3007 struct SingleAttachmentTestConfig
3008 {
SingleAttachmentTestConfigvkt::__anonc414995a0111::SingleAttachmentTestConfig3009     SingleAttachmentTestConfig(VkFormat format_, SharedGroupParams groupParams_)
3010         : format(format_)
3011         , groupParams(groupParams_)
3012     {
3013     }
3014 
SingleAttachmentTestConfigvkt::__anonc414995a0111::SingleAttachmentTestConfig3015     SingleAttachmentTestConfig(const SingleAttachmentTestConfig &config)
3016         : format(config.format)
3017         , groupParams(config.groupParams)
3018     {
3019     }
3020 
3021     VkFormat format;
3022     SharedGroupParams groupParams;
3023 };
3024 
3025 class SingleAttachmentTestInstance : public TestInstance
3026 {
3027 public:
3028     SingleAttachmentTestInstance(Context &context, SingleAttachmentTestConfig testConfig);
3029 
3030     ~SingleAttachmentTestInstance(void) = default;
3031 
3032     tcu::TestStatus iterate(void);
3033 
3034 protected:
3035     void setup(void);
3036     tcu::TestStatus verifyResults(void);
3037 
3038     template <typename RenderpassSubpass>
3039     void iterateInternal(void);
3040     void iterateInternalDynamicRendering(void);
3041 
3042 #ifndef CTS_USES_VULKANSC
3043     void preRenderCommands(VkCommandBuffer cmdBuffer);
3044 #endif // CTS_USES_VULKANSC
3045 
3046     void drawThatUsesInputAttachment(VkCommandBuffer cmdBuffer);
3047     void inbetweenDrawsRenderBarriers(VkCommandBuffer cmdBuffer);
3048     void drawThatSamplesPreviousResult(VkCommandBuffer cmdBuffer);
3049     void postRenderCommands(VkCommandBuffer cmdBuffer);
3050 
3051 private:
3052     SharedGroupParams m_groupParams;
3053 
3054     const uint32_t m_width;
3055     const uint32_t m_height;
3056     const VkFormat m_format;
3057 
3058     Move<VkImage> m_colorImage;
3059     Move<VkImage> m_resultImage;
3060     de::MovePtr<Allocation> m_colorImageAllocation;
3061     de::MovePtr<Allocation> m_resultImageAllocation;
3062     Move<VkImageView> m_imageViewInput;
3063     Move<VkImageView> m_imageViewResult;
3064     PipelineLayoutWrapper m_pipelineLayoutInput;
3065     PipelineLayoutWrapper m_pipelineLayoutImageSampler;
3066     GraphicsPipelineWrapper m_pipelineSolidColor;
3067     GraphicsPipelineWrapper m_pipelineInputAtt;
3068     GraphicsPipelineWrapper m_pipelineImageSampler;
3069     Move<VkFramebuffer> m_framebuffer1;
3070     Move<VkFramebuffer> m_framebuffer0;
3071     Move<VkRenderPass> m_renderPass0;
3072     Move<VkRenderPass> m_renderPass1;
3073     Move<VkBuffer> m_resultBuffer;
3074     de::MovePtr<Allocation> m_resultBufferMemory;
3075     Move<VkBuffer> m_vertexBuffer;
3076     de::MovePtr<Allocation> m_vertexBufferMemory;
3077     Move<VkSampler> m_sampler;
3078     Move<VkDescriptorSetLayout> m_descriptorSetLayoutInput;
3079     Move<VkDescriptorSetLayout> m_descriptorSetLayoutImageSampler;
3080     Move<VkDescriptorPool> m_descriptorPool;
3081     Move<VkDescriptorSet> m_descriptorSetInput;
3082     Move<VkDescriptorSet> m_descriptorSetImageSampler;
3083 };
3084 
SingleAttachmentTestInstance(Context & context,SingleAttachmentTestConfig testConfig)3085 SingleAttachmentTestInstance::SingleAttachmentTestInstance(Context &context, SingleAttachmentTestConfig testConfig)
3086     : TestInstance(context)
3087     , m_groupParams(testConfig.groupParams)
3088     , m_width(256u)
3089     , m_height(256u)
3090     , m_format(testConfig.format)
3091     , m_pipelineSolidColor(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
3092                            context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
3093     , m_pipelineInputAtt(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
3094                          context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
3095     , m_pipelineImageSampler(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
3096                              context.getDevice(), context.getDeviceExtensions(),
3097                              m_groupParams->pipelineConstructionType)
3098 {
3099 }
3100 
iterate(void)3101 tcu::TestStatus SingleAttachmentTestInstance::iterate(void)
3102 {
3103     setup();
3104 
3105     switch (m_groupParams->renderingType)
3106     {
3107     case RENDERING_TYPE_RENDERPASS_LEGACY:
3108         iterateInternal<RenderpassSubpass1>();
3109         break;
3110     case RENDERING_TYPE_RENDERPASS2:
3111         iterateInternal<RenderpassSubpass2>();
3112         break;
3113     case RENDERING_TYPE_DYNAMIC_RENDERING:
3114         iterateInternalDynamicRendering();
3115         break;
3116     default:
3117         TCU_THROW(InternalError, "Impossible");
3118     }
3119 
3120     return verifyResults();
3121 }
3122 
setup(void)3123 void SingleAttachmentTestInstance::setup(void)
3124 {
3125     const DeviceInterface &vkd(m_context.getDeviceInterface());
3126     const VkDevice device              = m_context.getDevice();
3127     const VkQueue queue                = m_context.getUniversalQueue();
3128     const uint32_t queueFamilyIndex    = m_context.getUniversalQueueFamilyIndex();
3129     const tcu::Vec4 colorInitValues[2] = {tcu::Vec4(0.2f, 0.4f, 0.1f, 1.0f), tcu::Vec4(0.5f, 0.4f, 0.7f, 1.0f)};
3130     const VkExtent3D imageExtent       = {m_width, m_height, 1u};
3131 
3132     // Create image used for both input and output.
3133     {
3134         VkImageUsageFlags usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
3135                                   VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
3136                                   VK_IMAGE_USAGE_SAMPLED_BIT;
3137 
3138         const VkImageCreateInfo imageCreateInfo{
3139             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
3140             DE_NULL,                             // const void*                pNext
3141             0u,                                  // VkImageCreateFlags        flags
3142             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
3143             m_format,                            // VkFormat                    format
3144             imageExtent,                         // VkExtent3D                extent
3145             1u,                                  // uint32_t                    mipLevels
3146             1u,                                  // uint32_t                    arrayLayers
3147             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
3148             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
3149             usage,                               // VkImageUsageFlags        usage
3150             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
3151             1u,                                  // uint32_t                    queueFamilyIndexCount
3152             &queueFamilyIndex,                   // const uint32_t*            pQueueFamilyIndices
3153             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
3154         };
3155 
3156         checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3157 
3158         m_colorImage           = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3159         m_colorImageAllocation = m_context.getDefaultAllocator().allocate(
3160             getImageMemoryRequirements(vkd, device, *m_colorImage), MemoryRequirement::Any);
3161         VK_CHECK(vkd.bindImageMemory(device, *m_colorImage, m_colorImageAllocation->getMemory(),
3162                                      m_colorImageAllocation->getOffset()));
3163     }
3164 
3165     // Create image used for final result.
3166     {
3167         VkImageUsageFlags usage =
3168             VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
3169 
3170         const VkImageCreateInfo imageCreateInfo{
3171             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType            sType
3172             DE_NULL,                             // const void*                pNext
3173             0u,                                  // VkImageCreateFlags        flags
3174             VK_IMAGE_TYPE_2D,                    // VkImageType                imageType
3175             m_format,                            // VkFormat                    format
3176             imageExtent,                         // VkExtent3D                extent
3177             1u,                                  // uint32_t                    mipLevels
3178             1u,                                  // uint32_t                    arrayLayers
3179             VK_SAMPLE_COUNT_1_BIT,               // VkSampleCountFlagBits    samples
3180             VK_IMAGE_TILING_OPTIMAL,             // VkImageTiling            tiling
3181             usage,                               // VkImageUsageFlags        usage
3182             VK_SHARING_MODE_EXCLUSIVE,           // VkSharingMode            sharingMode
3183             1u,                                  // uint32_t                    queueFamilyIndexCount
3184             &queueFamilyIndex,                   // const uint32_t*            pQueueFamilyIndices
3185             VK_IMAGE_LAYOUT_UNDEFINED            // VkImageLayout            initialLayout
3186         };
3187 
3188         checkImageSupport(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), imageCreateInfo);
3189 
3190         m_resultImage           = createImage(vkd, device, &imageCreateInfo, DE_NULL);
3191         m_resultImageAllocation = m_context.getDefaultAllocator().allocate(
3192             getImageMemoryRequirements(vkd, device, *m_resultImage), MemoryRequirement::Any);
3193         VK_CHECK(vkd.bindImageMemory(device, *m_resultImage, m_resultImageAllocation->getMemory(),
3194                                      m_resultImageAllocation->getOffset()));
3195     }
3196 
3197     // Initialize color image. This is expected to be cleared later.
3198     initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(),
3199                                     *m_colorImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height,
3200                                     32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
3201                                     VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3202     // Initialize result image. This will be overwritten later.
3203     initColorImageChessboardPattern(vkd, device, queue, queueFamilyIndex, m_context.getDefaultAllocator(),
3204                                     *m_resultImage, m_format, colorInitValues[0], colorInitValues[1], m_width, m_height,
3205                                     32u, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3206                                     VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
3207 
3208     // Create image views.
3209     {
3210         VkImageViewCreateInfo imageViewCreateInfo{
3211             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType
3212             DE_NULL,                                  // const void*                pNext
3213             0u,                                       // VkImageViewCreateFlags    flags
3214             *m_colorImage,                            // VkImage                    image
3215             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType
3216             m_format,                                 // VkFormat                    format
3217             makeComponentMappingRGBA(),               // VkComponentMapping        components
3218             {                                         // VkImageSubresourceRange    subresourceRange
3219              VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u}};
3220 
3221         m_imageViewInput          = createImageView(vkd, device, &imageViewCreateInfo);
3222         imageViewCreateInfo.image = *m_resultImage;
3223         m_imageViewResult         = createImageView(vkd, device, &imageViewCreateInfo);
3224     }
3225 
3226     // Create result buffer.
3227     {
3228         m_resultBuffer       = createBuffer(vkd, device, m_format, m_width, m_height);
3229         m_resultBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_resultBuffer);
3230     }
3231 
3232     // Create sampler.
3233     {
3234         const VkSamplerCreateInfo samplerInfo{
3235             VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,   // VkStructureType            sType
3236             DE_NULL,                                 // const void*                pNext
3237             0u,                                      // VkSamplerCreateFlags        flags
3238             VK_FILTER_NEAREST,                       // VkFilter                    magFilter
3239             VK_FILTER_NEAREST,                       // VkFilter                    minFilter
3240             VK_SAMPLER_MIPMAP_MODE_NEAREST,          // VkSamplerMipmapMode        mipmapMode
3241             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode        addressModeU
3242             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode        addressModeV
3243             VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,   // VkSamplerAddressMode        addressModeW
3244             0.0f,                                    // float                    mipLodBias
3245             VK_FALSE,                                // VkBool32                    anisotropyEnable
3246             1.0f,                                    // float                    maxAnisotropy
3247             VK_FALSE,                                // VkBool32                    compareEnable
3248             VK_COMPARE_OP_ALWAYS,                    // VkCompareOp                compareOp
3249             0.0f,                                    // float                    minLod
3250             0.0f,                                    // float                    maxLod
3251             VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // VkBorderColor            borderColor
3252             VK_FALSE,                                // VkBool32                    unnormalizedCoordinates
3253         };
3254 
3255         m_sampler = createSampler(vkd, device, &samplerInfo);
3256     }
3257 
3258     // Create descriptor set layouts.
3259     m_descriptorSetLayoutInput =
3260         DescriptorSetLayoutBuilder()
3261             .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
3262             .build(vkd, device);
3263 
3264     m_descriptorSetLayoutImageSampler =
3265         DescriptorSetLayoutBuilder()
3266             .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
3267             .build(vkd, device);
3268 
3269     // Create descriptor pool.
3270     m_descriptorPool = DescriptorPoolBuilder()
3271                            .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
3272                            .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u)
3273                            .build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
3274 
3275     // Create desriptor sets.
3276     m_descriptorSetInput        = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutInput);
3277     m_descriptorSetImageSampler = makeDescriptorSet(vkd, device, *m_descriptorPool, *m_descriptorSetLayoutImageSampler);
3278 
3279     VkImageLayout ioImageLayout = VK_IMAGE_LAYOUT_GENERAL;
3280 #ifndef CTS_USES_VULKANSC
3281     if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3282         ioImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3283 #endif // CTS_USES_VULKANSC
3284 
3285     // Update descriptor set information.
3286     VkDescriptorImageInfo descIOAttachment = makeDescriptorImageInfo(DE_NULL, *m_imageViewInput, ioImageLayout);
3287     VkDescriptorImageInfo descImageSampler =
3288         makeDescriptorImageInfo(*m_sampler, *m_imageViewInput, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
3289 
3290     DescriptorSetUpdateBuilder()
3291         .writeSingle(*m_descriptorSetInput, DescriptorSetUpdateBuilder::Location::binding(0u),
3292                      VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descIOAttachment)
3293         .update(vkd, device);
3294 
3295     DescriptorSetUpdateBuilder()
3296         .writeSingle(*m_descriptorSetImageSampler, DescriptorSetUpdateBuilder::Location::binding(0u),
3297                      VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descImageSampler)
3298         .update(vkd, device);
3299 
3300     // Create pipeline layouts.
3301     m_pipelineLayoutInput =
3302         PipelineLayoutWrapper(m_groupParams->pipelineConstructionType, vkd, device, *m_descriptorSetLayoutInput);
3303     m_pipelineLayoutImageSampler =
3304         PipelineLayoutWrapper(m_groupParams->pipelineConstructionType, vkd, device, *m_descriptorSetLayoutImageSampler);
3305 
3306     if (m_groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3307     {
3308         // Create render passes.
3309 
3310         vector<Attachment> attachments{{m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
3311                                         VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3312                                         VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3313                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
3314 
3315         vector<AttachmentReference> colorAttachmentReferences{{0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}};
3316 
3317         vector<Subpass> subpasses{{VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
3318                                    colorAttachmentReferences, vector<AttachmentReference>(),
3319                                    AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL),
3320                                    vector<uint32_t>()}};
3321 
3322         m_renderPass1 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, vector<SubpassDependency>()),
3323                                          m_groupParams->renderingType);
3324 
3325         attachments.clear();
3326         attachments.emplace_back(m_format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_CLEAR,
3327                                  VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
3328                                  VK_ATTACHMENT_STORE_OP_DONT_CARE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL);
3329 
3330         colorAttachmentReferences[0].setImageLayout(VK_IMAGE_LAYOUT_GENERAL);
3331 
3332         const VkImageAspectFlags inputAttachmentAspectMask(
3333             (m_groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
3334                 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) :
3335                 static_cast<VkImageAspectFlags>(0));
3336         vector<AttachmentReference> inputAttachmentReferences{{0u, VK_IMAGE_LAYOUT_GENERAL, inputAttachmentAspectMask}};
3337 
3338         subpasses.clear();
3339         subpasses.emplace_back(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
3340                                colorAttachmentReferences, vector<AttachmentReference>(),
3341                                AttachmentReference(VK_ATTACHMENT_UNUSED, VK_IMAGE_LAYOUT_GENERAL), vector<uint32_t>());
3342 
3343         const vector<SubpassDependency> dependencies(
3344             1, SubpassDependency(0u, 0u, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3345                                  VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3346                                  VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_DEPENDENCY_BY_REGION_BIT));
3347 
3348         m_renderPass0 = createRenderPass(vkd, device, RenderPass(attachments, subpasses, dependencies),
3349                                          m_groupParams->renderingType);
3350 
3351         // Create framebuffers.
3352         VkFramebufferCreateInfo framebufferCreateInfo{
3353             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType            sType
3354             DE_NULL,                                   // const void*                pNext
3355             0u,                                        // VkFramebufferCreateFlags    flags
3356             *m_renderPass0,                            // VkRenderPass                renderPass
3357             1u,                                        // uint32_t                    attachmentCount
3358             &m_imageViewInput.get(),                   // const VkImageView*        pAttachments
3359             m_width,                                   // uint32_t                    width
3360             m_height,                                  // uint32_t                    height
3361             1u                                         // uint32_t                    layers
3362         };
3363 
3364         m_framebuffer0 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3365 
3366         framebufferCreateInfo.pAttachments = &m_imageViewResult.get();
3367         framebufferCreateInfo.renderPass   = *m_renderPass1;
3368 
3369         m_framebuffer1 = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
3370     }
3371 
3372     // Create pipelines.
3373     {
3374         const ShaderWrapper vertexShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
3375         const ShaderWrapper fragmentShaderModuleInputAtt(
3376             vkd, device, m_context.getBinaryCollection().get("frag_input_attachment"), 0u);
3377         const ShaderWrapper fragmentShaderModuleSolidColor(vkd, device,
3378                                                            m_context.getBinaryCollection().get("frag_solid_color"), 0u);
3379         const ShaderWrapper fragmentShaderModuleSampler(
3380             vkd, device, m_context.getBinaryCollection().get("frag_combined_image_sampler"), 0u);
3381 
3382         const VkVertexInputBindingDescription vertexBinding0 = {
3383             0u,                         // uint32_t                    binding
3384             sizeof(Vec4),               // uint32_t                    strideInBytes
3385             VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate    stepRate
3386         };
3387 
3388         const VkVertexInputAttributeDescription attr0 = {
3389             0u,                            // uint32_t    location
3390             0u,                            // uint32_t    binding
3391             VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat    format
3392             0u                             // uint32_t    offsetInBytes
3393         };
3394 
3395         const VkPipelineVertexInputStateCreateInfo vertexInputState = {
3396             VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                            sType
3397             DE_NULL,                                   // const void*                                pNext
3398             (VkPipelineVertexInputStateCreateFlags)0u, // VkPipelineVertexInputStateCreateFlags    flags
3399             1u,              // uint32_t                                    vertexBindingDescriptionCount
3400             &vertexBinding0, // const VkVertexInputBindingDescription*    pVertexBindingDescriptions
3401             1u,              // uint32_t                                    vertexAttributeDescriptionCount
3402             &attr0           // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
3403         };
3404 
3405         PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
3406         const std::vector<VkViewport> viewports{makeViewport(m_width, m_height)};
3407         const std::vector<VkRect2D> scissors{makeRect2D(m_width, m_height)};
3408 
3409         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
3410             VK_TRUE,                             // VkBool32                    blendEnable
3411             VK_BLEND_FACTOR_ONE,                 // VkBlendFactor            srcColorBlendFactor
3412             VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor            dstColorBlendFactor
3413             VK_BLEND_OP_ADD,                     // VkBlendOp                colorBlendOp
3414             VK_BLEND_FACTOR_ONE,                 // VkBlendFactor            srcAlphaBlendFactor
3415             VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor            dstAlphaBlendFactor
3416             VK_BLEND_OP_ADD,                     // VkBlendOp                alphaBlendOp
3417             VK_COLOR_COMPONENT_R_BIT             // VkColorComponentFlags    colorWriteMask
3418                 | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};
3419 
3420         const VkPipelineColorBlendStateCreateInfo colorBlendState = {
3421             VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                                sType
3422             DE_NULL,                    // const void*                                    pNext
3423             0u,                         // VkPipelineColorBlendStateCreateFlags            flags
3424             VK_FALSE,                   // VkBool32                                        logicOpEnable
3425             VK_LOGIC_OP_CLEAR,          // VkLogicOp                                    logicOp
3426             1u,                         // uint32_t                                        attachmentCount
3427             &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState*    pAttachments
3428             {0.0f, 0.0f, 0.0f, 0.0f}    // float                                        blendConstants[4]
3429         };
3430 
3431 #ifndef CTS_USES_VULKANSC
3432         VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
3433                                                           DE_NULL,
3434                                                           0u,
3435                                                           1u,
3436                                                           &m_format,
3437                                                           VK_FORMAT_UNDEFINED,
3438                                                           VK_FORMAT_UNDEFINED};
3439         if (*m_renderPass0 == DE_NULL)
3440             renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
3441 #endif
3442         m_pipelineSolidColor.setDefaultMultisampleState()
3443             .setDefaultDepthStencilState()
3444             .setDefaultRasterizationState()
3445             .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3446             .setupVertexInputState(&vertexInputState)
3447             .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayoutInput, *m_renderPass0, 0u,
3448                                               vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
3449                                               DE_NULL, DE_NULL, renderingCreateInfoWrapper)
3450             .setupFragmentShaderState(m_pipelineLayoutInput, *m_renderPass0, 0u, fragmentShaderModuleSolidColor)
3451             .setupFragmentOutputState(*m_renderPass0, 0u, &colorBlendState)
3452             .setMonolithicPipelineLayout(m_pipelineLayoutInput)
3453             .buildPipeline();
3454 
3455         m_pipelineInputAtt.setDefaultMultisampleState()
3456             .setDefaultDepthStencilState()
3457             .setDefaultRasterizationState()
3458             .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3459             .setupVertexInputState(&vertexInputState)
3460             .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayoutInput, *m_renderPass0, 0u,
3461                                               vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
3462                                               DE_NULL, DE_NULL, renderingCreateInfoWrapper)
3463             .setupFragmentShaderState(m_pipelineLayoutInput, *m_renderPass0, 0u, fragmentShaderModuleInputAtt)
3464             .setupFragmentOutputState(*m_renderPass0, 0u, &colorBlendState)
3465             .setMonolithicPipelineLayout(m_pipelineLayoutInput)
3466             .buildPipeline();
3467 
3468         m_pipelineImageSampler.setDefaultMultisampleState()
3469             .setDefaultDepthStencilState()
3470             .setDefaultRasterizationState()
3471             .setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3472             .setupVertexInputState(&vertexInputState)
3473             .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayoutImageSampler, *m_renderPass1, 0u,
3474                                               vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
3475                                               DE_NULL, DE_NULL, renderingCreateInfoWrapper)
3476             .setupFragmentShaderState(m_pipelineLayoutImageSampler, *m_renderPass1, 0u, fragmentShaderModuleSampler)
3477             .setupFragmentOutputState(*m_renderPass1, 0u, &colorBlendState)
3478             .setMonolithicPipelineLayout(m_pipelineLayoutImageSampler)
3479             .buildPipeline();
3480     }
3481 
3482     // Generate quad vertices.
3483     vector<Vec4> vertexData{tcu::Vec4(-1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f),
3484                             tcu::Vec4(1.0f, -1.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 1.0f)};
3485 
3486     // Upload vertex data.
3487     {
3488         const size_t vertexDataSize = vertexData.size() * sizeof(Vec4);
3489 
3490         const VkBufferCreateInfo vertexBufferParams = {
3491             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, //    VkStructureType        sType
3492             DE_NULL,                              //    const void*            pNext
3493             0u,                                   //    VkBufferCreateFlags    flags
3494             (VkDeviceSize)vertexDataSize,         //    VkDeviceSize        size
3495             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,    //    VkBufferUsageFlags    usage
3496             VK_SHARING_MODE_EXCLUSIVE,            //    VkSharingMode        sharingMode
3497             1u,                                   //    uint32_t            queueFamilyCount
3498             &queueFamilyIndex,                    //    const uint32_t*        pQueueFamilyIndices
3499         };
3500 
3501         m_vertexBuffer       = createBuffer(vkd, m_context.getDevice(), &vertexBufferParams);
3502         m_vertexBufferMemory = createBufferMemory(vkd, device, m_context.getDefaultAllocator(), *m_vertexBuffer);
3503 
3504         deMemcpy(m_vertexBufferMemory->getHostPtr(), vertexData.data(), vertexDataSize);
3505         flushAlloc(vkd, device, *m_vertexBufferMemory);
3506     }
3507 }
3508 
verifyResults()3509 tcu::TestStatus SingleAttachmentTestInstance::verifyResults()
3510 {
3511     const tcu::TextureFormat format(mapVkFormat(m_format));
3512     tcu::TextureLevel reference(format, m_width, m_height);
3513     const void *const ptrResult(m_resultBufferMemory->getHostPtr());
3514     const tcu::ConstPixelBufferAccess resultAccess(format, m_width, m_height, 1, ptrResult);
3515     const PixelBufferAccess referenceAccess(reference.getAccess());
3516     tcu::ResultCollector resultCollector;
3517 
3518     for (uint32_t x = 0; x < m_width; x++)
3519         for (uint32_t y = 0; y < m_height; y++)
3520         {
3521             referenceAccess.setPixel(tcu::Vec4(0.3f, 0.6f, 0.0f, 1.0f), x, y, 0);
3522         }
3523 
3524     if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), // log
3525                                     "Rendered result",                   // imageSetName
3526                                     "",                                  // imageSetDesc
3527                                     referenceAccess,                     // reference
3528                                     resultAccess,                        // result
3529                                     Vec4(0.05f),                         // threshold
3530                                     tcu::COMPARE_LOG_RESULT))            // logMode
3531     {
3532         resultCollector.fail("Image compare failed.");
3533     }
3534 
3535     return tcu::TestStatus(resultCollector.getResult(), resultCollector.getMessage());
3536 }
3537 
3538 template <typename RenderpassSubpass>
iterateInternal(void)3539 void SingleAttachmentTestInstance::iterateInternal(void)
3540 {
3541     const DeviceInterface &vkd(m_context.getDeviceInterface());
3542     const VkDevice device           = m_context.getDevice();
3543     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3544     const Unique<VkCommandPool> commandPool(
3545         createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
3546     const Unique<VkCommandBuffer> commandBuffer(
3547         allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3548     const VkRect2D renderArea = makeRect2D(m_width, m_height);
3549     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
3550     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
3551     vector<Vec4> vertexData;
3552 
3553     beginCommandBuffer(vkd, *commandBuffer);
3554 
3555     // Begin render pass.
3556     {
3557         const VkClearValue clearValue         = makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
3558         const VkRenderPassBeginInfo beginInfo = {
3559             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
3560             DE_NULL,                                  // const void*            pNext
3561             *m_renderPass0,                           // VkRenderPass            renderPass
3562             *m_framebuffer0,                          // VkFramebuffer        framebuffer
3563             renderArea,                               // VkRect2D                renderArea
3564             1u,                                       // uint32_t                clearValueCount
3565             &clearValue                               // const VkClearValue*    pClearValues
3566         };
3567 
3568         RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3569     }
3570 
3571     drawThatUsesInputAttachment(*commandBuffer);
3572 
3573     // End render pass.
3574     RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3575 
3576     // Pipeline barrier.
3577     inbetweenDrawsRenderBarriers(*commandBuffer);
3578 
3579     // Begin render pass.
3580     {
3581         const VkRenderPassBeginInfo beginInfo{
3582             VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
3583             DE_NULL,                                  // const void*            pNext
3584             *m_renderPass1,                           // VkRenderPass            renderPass
3585             *m_framebuffer1,                          // VkFramebuffer        framebuffer
3586             renderArea,                               // VkRect2D                renderArea
3587             0u,                                       // uint32_t                clearValueCount
3588             DE_NULL                                   // const VkClearValue*    pClearValues
3589         };
3590 
3591         RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
3592     }
3593 
3594     drawThatSamplesPreviousResult(*commandBuffer);
3595 
3596     // End render pass.
3597     RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
3598 
3599     // Copy results to a buffer.
3600     postRenderCommands(*commandBuffer);
3601 
3602     endCommandBuffer(vkd, *commandBuffer);
3603     submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
3604     invalidateMappedMemoryRange(vkd, device, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(),
3605                                 VK_WHOLE_SIZE);
3606 }
3607 
iterateInternalDynamicRendering(void)3608 void SingleAttachmentTestInstance::iterateInternalDynamicRendering(void)
3609 {
3610 #ifndef CTS_USES_VULKANSC
3611     const DeviceInterface &vkd(m_context.getDeviceInterface());
3612     const VkDevice device           = m_context.getDevice();
3613     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
3614     const Unique<VkCommandPool> commandPool(
3615         createCommandPool(vkd, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex));
3616     const Unique<VkCommandBuffer> cmdBuffer(
3617         allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3618     Move<VkCommandBuffer> secCmdBuffer[2];
3619     const VkClearValue clearValue = makeClearValueColor(Vec4(0.0f));
3620     const VkRect2D renderArea     = makeRect2D(m_width, m_height);
3621 
3622     if (m_groupParams->useSecondaryCmdBuffer)
3623     {
3624         secCmdBuffer[0] = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3625         secCmdBuffer[1] = allocateCommandBuffer(vkd, device, *commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
3626 
3627         // record first secondary command buffer
3628         {
3629             if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3630             {
3631                 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[0], m_format, VK_FORMAT_UNDEFINED, true);
3632                 beginRendering(vkd, *secCmdBuffer[0], *m_imageViewInput, renderArea, clearValue,
3633                                VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR);
3634             }
3635             else
3636                 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[0], m_format, VK_FORMAT_UNDEFINED, false);
3637 
3638             drawThatUsesInputAttachment(*secCmdBuffer[0]);
3639 
3640             if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3641                 vkd.cmdEndRendering(*secCmdBuffer[0]);
3642 
3643             endCommandBuffer(vkd, *secCmdBuffer[0]);
3644         }
3645 
3646         // record second secondary command buffer
3647         {
3648             if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3649             {
3650                 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[1], m_format, VK_FORMAT_UNDEFINED, true);
3651                 beginRendering(vkd, *secCmdBuffer[1], *m_imageViewResult, renderArea, clearValue);
3652             }
3653             else
3654                 beginSecondaryCmdBuffer(vkd, *secCmdBuffer[1], m_format, VK_FORMAT_UNDEFINED, false);
3655 
3656             drawThatSamplesPreviousResult(*secCmdBuffer[1]);
3657 
3658             if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3659                 vkd.cmdEndRendering(*secCmdBuffer[1]);
3660 
3661             endCommandBuffer(vkd, *secCmdBuffer[1]);
3662         }
3663 
3664         // record primary command buffer
3665         beginCommandBuffer(vkd, *cmdBuffer);
3666         preRenderCommands(*cmdBuffer);
3667 
3668         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3669         {
3670             beginRendering(vkd, *cmdBuffer, *m_imageViewInput, renderArea, clearValue,
3671                            VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR,
3672                            VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
3673         }
3674         vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer[0]);
3675         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3676             vkd.cmdEndRendering(*cmdBuffer);
3677 
3678         inbetweenDrawsRenderBarriers(*cmdBuffer);
3679 
3680         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3681         {
3682             beginRendering(vkd, *cmdBuffer, *m_imageViewResult, renderArea, clearValue, VK_IMAGE_LAYOUT_GENERAL,
3683                            VK_ATTACHMENT_LOAD_OP_LOAD, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
3684         }
3685         vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer[1]);
3686         if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
3687             vkd.cmdEndRendering(*cmdBuffer);
3688 
3689         postRenderCommands(*cmdBuffer);
3690         endCommandBuffer(vkd, *cmdBuffer);
3691     }
3692     else
3693     {
3694         beginCommandBuffer(vkd, *cmdBuffer);
3695         preRenderCommands(*cmdBuffer);
3696 
3697         beginRendering(vkd, *cmdBuffer, *m_imageViewInput, renderArea, clearValue,
3698                        VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, VK_ATTACHMENT_LOAD_OP_CLEAR);
3699         drawThatUsesInputAttachment(*cmdBuffer);
3700         vkd.cmdEndRendering(*cmdBuffer);
3701 
3702         inbetweenDrawsRenderBarriers(*cmdBuffer);
3703 
3704         beginRendering(vkd, *cmdBuffer, *m_imageViewResult, renderArea, clearValue);
3705         drawThatSamplesPreviousResult(*cmdBuffer);
3706         vkd.cmdEndRendering(*cmdBuffer);
3707 
3708         postRenderCommands(*cmdBuffer);
3709         endCommandBuffer(vkd, *cmdBuffer);
3710     }
3711 
3712     submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
3713     invalidateMappedMemoryRange(vkd, device, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset(),
3714                                 VK_WHOLE_SIZE);
3715 #endif
3716 }
3717 
3718 #ifndef CTS_USES_VULKANSC
preRenderCommands(VkCommandBuffer cmdBuffer)3719 void SingleAttachmentTestInstance::preRenderCommands(VkCommandBuffer cmdBuffer)
3720 {
3721     const DeviceInterface &vkd(m_context.getDeviceInterface());
3722     const VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
3723     VkImageMemoryBarrier imageBarrier =
3724         makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
3725                                VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR, *m_colorImage, subresourceRange);
3726 
3727     // Transition color attachment to proper layout.
3728     vkd.cmdPipelineBarrier(cmdBuffer, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
3729                            1u, &imageBarrier);
3730 }
3731 #endif // CTS_USES_VULKANSC
3732 
drawThatUsesInputAttachment(VkCommandBuffer cmdBuffer)3733 void SingleAttachmentTestInstance::drawThatUsesInputAttachment(VkCommandBuffer cmdBuffer)
3734 {
3735     const DeviceInterface &vkd(m_context.getDeviceInterface());
3736     const VkDeviceSize bindingOffset(0);
3737     const VkImageSubresourceRange subresourceRange{VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u};
3738     VkImageMemoryBarrier imageBarrier =
3739         makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
3740                                VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, *m_colorImage, subresourceRange);
3741     // Bind pipeline.
3742     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineSolidColor.getPipeline());
3743 
3744     // Bind vertex buffer.
3745     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
3746 
3747     // Bind descriptor set.
3748     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutInput, 0u, 1u,
3749                               &*m_descriptorSetInput, 0u, DE_NULL);
3750 
3751     // Draw solid color.
3752     vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
3753 
3754     // Pipeline barrier to handle self dependency.
3755 #ifndef CTS_USES_VULKANSC
3756     if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3757     {
3758         imageBarrier.newLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3759         imageBarrier.oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3760     }
3761 #endif
3762     vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
3763                            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u, DE_NULL,
3764                            1u, &imageBarrier);
3765 
3766     // Bind pipeline.
3767     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineInputAtt.getPipeline());
3768 
3769     // Bind descriptor set.
3770     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutInput, 0u, 1u,
3771                               &*m_descriptorSetInput, 0u, DE_NULL);
3772 
3773     // Draw. Adds (0.1, 0.2, 0.0, 0.0) to the previous result.
3774     vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
3775 }
3776 
inbetweenDrawsRenderBarriers(VkCommandBuffer cmdBuffer)3777 void SingleAttachmentTestInstance::inbetweenDrawsRenderBarriers(VkCommandBuffer cmdBuffer)
3778 {
3779     const DeviceInterface &vkd(m_context.getDeviceInterface());
3780     const VkImageSubresourceRange subresourceRange{1u, 0u, 1u, 0u, 1u};
3781     VkImageMemoryBarrier imageBarriers[]{
3782         makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_WRITE_BIT |
3783                                    VK_ACCESS_HOST_WRITE_BIT,
3784                                VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL,
3785                                VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, *m_colorImage, subresourceRange),
3786         makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3787                                VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
3788                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3789                                *m_resultImage, subresourceRange)};
3790 
3791 #ifndef CTS_USES_VULKANSC
3792     if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3793     {
3794         imageBarriers[0].oldLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
3795         imageBarriers[1].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
3796     }
3797 #endif
3798 
3799     vkd.cmdPipelineBarrier(cmdBuffer,
3800                            VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
3801                            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
3802                            0u, DE_NULL, 0u, DE_NULL, 2u, imageBarriers);
3803 }
3804 
drawThatSamplesPreviousResult(VkCommandBuffer cmdBuffer)3805 void SingleAttachmentTestInstance::drawThatSamplesPreviousResult(VkCommandBuffer cmdBuffer)
3806 {
3807     const DeviceInterface &vkd(m_context.getDeviceInterface());
3808     const VkDeviceSize bindingOffset(0);
3809 
3810     // Bind pipeline.
3811     vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineImageSampler.getPipeline());
3812 
3813     // Bind vertex buffer.
3814     vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &m_vertexBuffer.get(), &bindingOffset);
3815 
3816     // Bind descriptor set.
3817     vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutImageSampler, 0u, 1u,
3818                               &*m_descriptorSetImageSampler, 0u, DE_NULL);
3819 
3820     // Draw. Samples the previous results and adds (0.1, 0.2, 0.0, 0.0).
3821     vkd.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
3822 }
3823 
postRenderCommands(VkCommandBuffer cmdBuffer)3824 void SingleAttachmentTestInstance::postRenderCommands(VkCommandBuffer cmdBuffer)
3825 {
3826     const DeviceInterface &vkd(m_context.getDeviceInterface());
3827 
3828     // Copy results to a buffer.
3829     copyImageToBuffer(vkd, cmdBuffer, *m_resultImage, *m_resultBuffer, tcu::IVec2(m_width, m_height),
3830                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
3831 }
3832 
3833 // Shader programs for testing dependencies between render pass instances
3834 struct ExternalPrograms
3835 {
initvkt::__anonc414995a0111::ExternalPrograms3836     void init(vk::SourceCollections &dst, ExternalTestConfig testConfig) const
3837     {
3838         for (size_t renderPassNdx = 0; renderPassNdx < testConfig.renderPasses.size(); renderPassNdx++)
3839         {
3840             dst.glslSources.add("quad-vert-" + de::toString(renderPassNdx)) << glu::VertexSource(
3841                 "#version 450\n"
3842                 "layout(location = 0) out highp vec2 vtxTexCoords;\n"
3843                 "highp float;\n"
3844                 "void main (void)\n"
3845                 "{\n"
3846                 "    vec4 position;"
3847                 "    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3848                 "                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3849                 "    gl_Position = position;\n"
3850                 "    vtxTexCoords = position.xy / 2.0 + vec2(0.5);"
3851                 "}\n");
3852 
3853             // First pass renders four quads of different color
3854             if (renderPassNdx == 0)
3855             {
3856                 dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx))
3857                     << glu::FragmentSource("#version 450\n"
3858                                            "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3859                                            "layout(location = 0) out highp vec4 o_color;\n"
3860                                            "void main (void)\n"
3861                                            "{\n"
3862                                            "    if (gl_FragCoord.x <= " +
3863                                            de::toString(testConfig.imageSize.x() / 2) +
3864                                            " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) +
3865                                            ")\n"
3866                                            "        o_color = vec4(1.0, 0.0, 0.0, 1.0);\n"
3867                                            "    else if (gl_FragCoord.x > " +
3868                                            de::toString(testConfig.imageSize.x() / 2) +
3869                                            " && gl_FragCoord.y <= " + de::toString(testConfig.imageSize.y() / 2) +
3870                                            ")\n"
3871                                            "        o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3872                                            "    else if (gl_FragCoord.x <= " +
3873                                            de::toString(testConfig.imageSize.x() / 2) + " && gl_FragCoord.y > " +
3874                                            de::toString(testConfig.imageSize.y() / 2) +
3875                                            ")\n"
3876                                            "        o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
3877                                            "    else\n"
3878                                            "        o_color = vec4(0.0, 0.0, 0.0, 1.0);\n"
3879                                            ""
3880                                            "}\n");
3881             }
3882             else
3883             {
3884                 if (renderPassNdx % 2 == 0)
3885                 {
3886                     // Blur previous pass horizontally
3887                     dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3888                         "#version 450\n"
3889                         "layout(binding = 0) uniform sampler2D previousPass;\n"
3890                         "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3891                         "layout(location = 0) out highp vec4 o_color;\n"
3892                         "void main (void)\n"
3893                         "{\n"
3894                         "    vec2 step = vec2(1.0 / " +
3895                         de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) +
3896                         ");\n"
3897                         "    vec2 minCoord = vec2(0.0, 0.0);\n"
3898                         "    vec2 maxCoord = vec2(1.0, 1.0);\n"
3899                         "    vec4 blurColor = vec4(0.0);\n"
3900                         "    for(int sampleNdx = 0; sampleNdx < " +
3901                         de::toString(testConfig.blurKernel + 1) +
3902                         "; sampleNdx++)\n"
3903                         "    {\n"
3904                         "        vec2 sampleCoord = vec2((vtxTexCoords.x - " +
3905                         de::toString(testConfig.blurKernel / 2) +
3906                         " * step.x) + step.x * sampleNdx, vtxTexCoords.y);\n"
3907                         "        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3908                         "    }\n"
3909                         "    o_color = blurColor;\n"
3910                         "}\n");
3911                 }
3912                 else
3913                 {
3914                     // Blur previous pass vertically
3915                     dst.glslSources.add("quad-frag-" + de::toString(renderPassNdx)) << glu::FragmentSource(
3916                         "#version 450\n"
3917                         "layout(binding = 0) uniform highp sampler2D previousPass;\n"
3918                         "layout(location = 0) in highp vec2 vtxTexCoords;\n"
3919                         "layout(location = 0) out highp vec4 o_color;\n"
3920                         "void main (void)\n"
3921                         "{\n"
3922                         "    vec2 step = vec2(1.0 / " +
3923                         de::toString(testConfig.imageSize.x()) + ", 1.0 / " + de::toString(testConfig.imageSize.y()) +
3924                         ");\n"
3925                         "    vec2 minCoord = vec2(0.0, 0.0);\n"
3926                         "    vec2 maxCoord = vec2(1.0, 1.0);\n"
3927                         "    vec4 blurColor = vec4(0.0);\n"
3928                         "    for(int sampleNdx = 0; sampleNdx < " +
3929                         de::toString(testConfig.blurKernel + 1) +
3930                         "; sampleNdx++)\n"
3931                         "    {\n"
3932                         "        vec2 sampleCoord = vec2(vtxTexCoords.x, (vtxTexCoords.y - " +
3933                         de::toString(testConfig.blurKernel / 2) +
3934                         " * step.y) + step.y * sampleNdx);\n"
3935                         "        blurColor += 0.12 * texture(previousPass, clamp(sampleCoord, minCoord, maxCoord));\n"
3936                         "    }\n"
3937                         "    o_color = blurColor;\n"
3938                         "}\n");
3939                 }
3940             }
3941         }
3942     }
3943 };
3944 
3945 template <typename TestConfig>
checkSupport(Context & context,TestConfig config)3946 void checkSupport(Context &context, TestConfig config)
3947 {
3948     const InstanceInterface &vki        = context.getInstanceInterface();
3949     vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
3950 
3951     checkPipelineConstructionRequirements(vki, physicalDevice, config.groupParams->pipelineConstructionType);
3952     if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
3953         context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
3954     else if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3955         context.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
3956 }
3957 
3958 // Shader programs for testing dependencies between subpasses
3959 struct SubpassPrograms
3960 {
initvkt::__anonc414995a0111::SubpassPrograms3961     void init(vk::SourceCollections &dst, SubpassTestConfig testConfig) const
3962     {
3963         size_t subpassCount = testConfig.renderPass.getSubpasses().size();
3964 
3965         for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
3966         {
3967             if (subpassNdx == 0)
3968             {
3969                 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx))
3970                     << glu::VertexSource("#version 450\n"
3971                                          "highp float;\n"
3972                                          "layout(location = 0) in highp vec4 position;\n"
3973                                          "void main (void)\n"
3974                                          "{\n"
3975                                          "    gl_Position = position;\n"
3976                                          "}\n");
3977             }
3978             else
3979             {
3980                 dst.glslSources.add("subpass-vert-" + de::toString(subpassNdx)) << glu::VertexSource(
3981                     "#version 450\n"
3982                     "highp float;\n"
3983                     "void main (void)\n"
3984                     "{\n"
3985                     "    vec4 position;"
3986                     "    position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
3987                     "                    ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
3988                     "    gl_Position = position;\n"
3989                     "}\n");
3990             }
3991 
3992             if (isDepthStencilFormat(testConfig.format))
3993             {
3994                 if (subpassNdx == 0)
3995                 {
3996                     // Empty fragment shader: Fragment depth unmodified.
3997                     dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx))
3998                         << glu::FragmentSource("#version 450\n"
3999                                                "void main (void)\n"
4000                                                "{\n"
4001                                                "}\n");
4002                 }
4003                 else
4004                 {
4005                     // Use fragment depth from previous depth rendering result.
4006                     dst.glslSources.add("subpass-frag-" + de::toString(subpassNdx)) << glu::FragmentSource(
4007                         "#version 450\n"
4008                         "layout (input_attachment_index = 0, binding = 0) uniform subpassInput depthStencil;\n"
4009                         "void main (void)\n"
4010                         "{\n"
4011                         "    float inputDepth = subpassLoad(depthStencil).x;\n"
4012                         "    gl_FragDepth = inputDepth - 0.02;\n"
4013                         "}\n");
4014                 }
4015             }
4016             else
4017                 DE_FATAL("Unimplemented");
4018         }
4019     }
4020 };
4021 
4022 // Shader programs for testing backwards subpass self dependency from geometry stage to indirect draw
4023 struct SubpassSelfDependencyBackwardsPrograms
4024 {
initvkt::__anonc414995a0111::SubpassSelfDependencyBackwardsPrograms4025     void init(vk::SourceCollections &dst, SubpassSelfDependencyBackwardsTestConfig testConfig) const
4026     {
4027         DE_UNREF(testConfig);
4028 
4029         dst.glslSources.add("vert") << glu::VertexSource("#version 450\n"
4030                                                          "layout(location = 0) in highp vec4 position;\n"
4031                                                          "out gl_PerVertex {\n"
4032                                                          "    vec4 gl_Position;\n"
4033                                                          "};\n"
4034                                                          "void main (void)\n"
4035                                                          "{\n"
4036                                                          "    gl_Position = position;\n"
4037                                                          "}\n");
4038 
4039         dst.glslSources.add("geom") << glu::GeometrySource("#version 450\n"
4040                                                            "layout(points) in;\n"
4041                                                            "layout(triangle_strip, max_vertices = 4) out;\n"
4042                                                            "\n"
4043                                                            "in gl_PerVertex {\n"
4044                                                            "    vec4 gl_Position;\n"
4045                                                            "} gl_in[];\n"
4046                                                            "\n"
4047                                                            "out gl_PerVertex {\n"
4048                                                            "    vec4 gl_Position;\n"
4049                                                            "};\n"
4050                                                            "layout (binding = 0) buffer IndirectBuffer\n"
4051                                                            "{\n"
4052                                                            "    uint vertexCount;\n"
4053                                                            "    uint instanceCount;\n"
4054                                                            "    uint firstVertex;\n"
4055                                                            "    uint firstInstance;\n"
4056                                                            "} indirectBuffer;\n"
4057                                                            "\n"
4058                                                            "void main (void) {\n"
4059                                                            "    vec4 p = gl_in[0].gl_Position;\n"
4060                                                            "    float offset = 0.03f;\n"
4061                                                            "    gl_Position = p + vec4(-offset, offset, 0, 0);\n"
4062                                                            "    EmitVertex();\n"
4063                                                            "    gl_Position = p + vec4(-offset, -offset, 0, 0);\n"
4064                                                            "    EmitVertex();\n"
4065                                                            "    gl_Position = p + vec4(offset, offset, 0, 0);\n"
4066                                                            "    EmitVertex();\n"
4067                                                            "    gl_Position = p + vec4(offset, -offset, 0, 0);\n"
4068                                                            "    EmitVertex();\n"
4069                                                            "    EndPrimitive();\n"
4070                                                            "    indirectBuffer.vertexCount = 64;\n"
4071                                                            "    indirectBuffer.instanceCount = 1;\n"
4072                                                            "    indirectBuffer.firstVertex = 64;\n"
4073                                                            "    indirectBuffer.firstInstance = 0;\n"
4074                                                            "}\n");
4075 
4076         dst.glslSources.add("frag") << glu::FragmentSource("#version 450\n"
4077                                                            "layout(location = 0) out highp vec4 fragColor;\n"
4078                                                            "void main (void)\n"
4079                                                            "{\n"
4080                                                            "    fragColor = vec4(1, 0, 0, 1);\n"
4081                                                            "}\n");
4082     }
4083 };
4084 
4085 struct SeparateChannelsPrograms
4086 {
initvkt::__anonc414995a0111::SeparateChannelsPrograms4087     void init(vk::SourceCollections &dst, SeparateChannelsTestConfig testConfig) const
4088     {
4089         dst.glslSources.add("vert") << glu::VertexSource("#version 450\n"
4090                                                          "layout(location = 0) in highp vec4 position;\n"
4091                                                          "void main (void)\n"
4092                                                          "{\n"
4093                                                          "    gl_Position = position;\n"
4094                                                          "}\n");
4095 
4096         if (isDepthStencilFormat(testConfig.format))
4097         {
4098             dst.glslSources.add("frag") << glu::FragmentSource("#version 450\n"
4099                                                                "layout(location = 0) out highp vec4 fragColor;\n"
4100                                                                "void main (void)\n"
4101                                                                "{\n"
4102                                                                "    fragColor = vec4(1);\n"
4103                                                                "}\n");
4104         }
4105         else
4106         {
4107             dst.glslSources.add("frag") << glu::FragmentSource(
4108                 "#version 450\n"
4109                 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
4110                 "layout(location = 0) out highp vec4 fragColor;\n"
4111                 "void main (void)\n"
4112                 "{\n"
4113                 "    vec4 inputColor = subpassLoad(inputAtt);\n"
4114                 "    fragColor = vec4(1, 1, inputColor.r + inputColor.g, 1);\n"
4115                 "}\n");
4116         }
4117     }
4118 };
4119 
4120 struct SingleAttachmentPrograms
4121 {
initvkt::__anonc414995a0111::SingleAttachmentPrograms4122     void init(vk::SourceCollections &dst, SingleAttachmentTestConfig testConfig) const
4123     {
4124         DE_UNREF(testConfig);
4125 
4126         dst.glslSources.add("vert") << glu::VertexSource("#version 450\n"
4127                                                          "layout(location = 0) in highp vec4 position;\n"
4128                                                          "void main (void)\n"
4129                                                          "{\n"
4130                                                          "    gl_Position = position;\n"
4131                                                          "}\n");
4132 
4133         dst.glslSources.add("frag_solid_color")
4134             << glu::FragmentSource("#version 450\n"
4135                                    "layout(location = 0) out highp vec4 fragColor;\n"
4136                                    "void main (void)\n"
4137                                    "{\n"
4138                                    "    fragColor = vec4(0.1, 0.2, 0.0, 1.0);\n"
4139                                    "}\n");
4140 
4141         dst.glslSources.add("frag_input_attachment") << glu::FragmentSource(
4142             "#version 450\n"
4143             "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInput inputAtt;\n"
4144             "layout(location = 0) out highp vec4 fragColor;\n"
4145             "void main (void)\n"
4146             "{\n"
4147             "    vec4 inputColor = subpassLoad(inputAtt);\n"
4148             "    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
4149             "}\n");
4150 
4151         dst.glslSources.add("frag_combined_image_sampler")
4152             << glu::FragmentSource("#version 450\n"
4153                                    "layout(set = 0, binding = 0) uniform highp sampler2D tex;\n"
4154                                    "layout(location = 0) out highp vec4 fragColor;\n"
4155                                    "void main (void)\n"
4156                                    "{\n"
4157                                    "    vec2 uv = vec2(gl_FragCoord) / 255.0;\n"
4158                                    "    vec4 inputColor = texture(tex, uv);\n"
4159                                    "    fragColor = inputColor + vec4(0.1, 0.2, 0.0, 0.0);\n"
4160                                    "}\n");
4161     }
4162 };
4163 
formatToName(VkFormat format)4164 std::string formatToName(VkFormat format)
4165 {
4166     const std::string formatStr = de::toString(format);
4167     const std::string prefix    = "VK_FORMAT_";
4168 
4169     DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
4170 
4171     return de::toLower(formatStr.substr(prefix.length()));
4172 }
4173 
initTests(tcu::TestCaseGroup * group,const renderpass::SharedGroupParams groupParams)4174 void initTests(tcu::TestCaseGroup *group, const renderpass::SharedGroupParams groupParams)
4175 {
4176     tcu::TestContext &testCtx(group->getTestContext());
4177 
4178     // Test external subpass dependencies
4179     if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4180     {
4181         const uint32_t renderPassCounts[] = {2u, 3u, 5u};
4182 
4183         const UVec2 renderSizes[] = {UVec2(64, 64), UVec2(128, 128), UVec2(512, 512)};
4184 
4185         de::MovePtr<tcu::TestCaseGroup> externalGroup(new tcu::TestCaseGroup(testCtx, "external_subpass"));
4186 
4187         for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4188         {
4189             string groupName("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" +
4190                              de::toString(renderSizes[renderSizeNdx].y()));
4191             de::MovePtr<tcu::TestCaseGroup> renderSizeGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
4192 
4193             for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts);
4194                  renderPassCountNdx++)
4195             {
4196                 vector<RenderPass> renderPasses;
4197 
4198                 for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
4199                 {
4200                     vector<Attachment> attachments;
4201                     vector<AttachmentReference> colorAttachmentReferences;
4202 
4203                     const VkFormat format(VK_FORMAT_R8G8B8A8_UNORM);
4204                     const VkSampleCountFlagBits sampleCount(VK_SAMPLE_COUNT_1_BIT);
4205                     const VkAttachmentLoadOp loadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4206                     const VkAttachmentStoreOp storeOp(VK_ATTACHMENT_STORE_OP_STORE);
4207                     const VkAttachmentLoadOp stencilLoadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4208                     const VkAttachmentStoreOp stencilStoreOp(VK_ATTACHMENT_STORE_OP_DONT_CARE);
4209                     const VkImageLayout initialLayout(VK_IMAGE_LAYOUT_UNDEFINED);
4210                     const VkImageLayout finalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4211                     const VkImageLayout subpassLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4212 
4213                     attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
4214                                                      stencilStoreOp, initialLayout, finalLayout));
4215                     colorAttachmentReferences.push_back(AttachmentReference((uint32_t)0, subpassLayout));
4216 
4217                     const VkImageLayout depthStencilLayout(VK_IMAGE_LAYOUT_GENERAL);
4218                     const vector<Subpass> subpasses(
4219                         1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
4220                                    colorAttachmentReferences, vector<AttachmentReference>(),
4221                                    AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<uint32_t>()));
4222                     vector<SubpassDependency> deps;
4223 
4224                     deps.push_back(SubpassDependency(
4225                         VK_SUBPASS_EXTERNAL,                           // uint32_t                srcPass
4226                         0,                                             // uint32_t                dstPass
4227                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags    srcStageMask
4228                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
4229                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags    dstStageMask
4230                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,              // VkAccessFlags        srcAccessMask
4231                         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
4232                             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags        dstAccessMask
4233                         0));                                      // VkDependencyFlags    flags
4234 
4235                     deps.push_back(SubpassDependency(
4236                         0,                   // uint32_t                srcPass
4237                         VK_SUBPASS_EXTERNAL, // uint32_t                dstPass
4238                         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
4239                             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags    srcStageMask
4240                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,     // VkPipelineStageFlags    dstStageMask
4241                         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
4242                             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags        srcAccessMask
4243                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,     // VkAccessFlags        dstAccessMask
4244                         0));                                      // VkDependencyFlags    flags
4245 
4246                     RenderPass renderPass(attachments, subpasses, deps);
4247 
4248                     renderPasses.push_back(renderPass);
4249                 }
4250 
4251                 const uint32_t blurKernel(12u);
4252                 string testName("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4253                 ExternalTestConfig testConfig{VK_FORMAT_R8G8B8A8_UNORM,
4254                                               renderSizes[renderSizeNdx],
4255                                               renderPasses,
4256                                               groupParams,
4257                                               SYNCHRONIZATION_TYPE_LEGACY,
4258                                               blurKernel};
4259 
4260                 renderSizeGroup->addChild(
4261                     new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(
4262                         testCtx, testName.c_str(), testConfig));
4263                 if (groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
4264                 {
4265                     testName += "_sync_2";
4266                     testConfig.synchronizationType = SYNCHRONIZATION_TYPE_SYNCHRONIZATION2;
4267                     renderSizeGroup->addChild(
4268                         new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(
4269                             testCtx, testName.c_str(), testConfig));
4270                 }
4271             }
4272 
4273             externalGroup->addChild(renderSizeGroup.release());
4274         }
4275 
4276         group->addChild(externalGroup.release());
4277     }
4278 
4279     // Test implicit subpass dependencies
4280     if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4281     {
4282         const uint32_t renderPassCounts[] = {2u, 3u, 5u};
4283 
4284         de::MovePtr<tcu::TestCaseGroup> implicitGroup(new tcu::TestCaseGroup(testCtx, "implicit_dependencies"));
4285 
4286         for (size_t renderPassCountNdx = 0; renderPassCountNdx < DE_LENGTH_OF_ARRAY(renderPassCounts);
4287              renderPassCountNdx++)
4288         {
4289             vector<RenderPass> renderPasses;
4290 
4291             for (size_t renderPassNdx = 0; renderPassNdx < renderPassCounts[renderPassCountNdx]; renderPassNdx++)
4292             {
4293                 vector<Attachment> attachments;
4294                 vector<AttachmentReference> colorAttachmentReferences;
4295 
4296                 const VkFormat format(VK_FORMAT_R8G8B8A8_UNORM);
4297                 const VkSampleCountFlagBits sampleCount(VK_SAMPLE_COUNT_1_BIT);
4298                 const VkAttachmentLoadOp loadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4299                 const VkAttachmentStoreOp storeOp(VK_ATTACHMENT_STORE_OP_STORE);
4300                 const VkAttachmentLoadOp stencilLoadOp(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
4301                 const VkAttachmentStoreOp stencilStoreOp(VK_ATTACHMENT_STORE_OP_DONT_CARE);
4302                 const VkImageLayout initialLayout(VK_IMAGE_LAYOUT_UNDEFINED);
4303                 const VkImageLayout finalLayout(VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4304                 const VkImageLayout subpassLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
4305 
4306                 attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp, stencilStoreOp,
4307                                                  initialLayout, finalLayout));
4308                 colorAttachmentReferences.push_back(AttachmentReference((uint32_t)0, subpassLayout));
4309 
4310                 const VkImageLayout depthStencilLayout(VK_IMAGE_LAYOUT_GENERAL);
4311                 const vector<Subpass> subpasses(
4312                     1, Subpass(VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, vector<AttachmentReference>(),
4313                                colorAttachmentReferences, vector<AttachmentReference>(),
4314                                AttachmentReference(VK_ATTACHMENT_UNUSED, depthStencilLayout), vector<uint32_t>()));
4315                 vector<SubpassDependency> deps;
4316 
4317                 // The first render pass lets the implementation add all subpass dependencies implicitly.
4318                 // On the following passes only the dependency from external to first subpass is defined as
4319                 // we need to make sure we have the image ready from previous render pass. In this case
4320                 // the dependency from subpass 0 to external is added implicitly by the implementation.
4321                 if (renderPassNdx > 0)
4322                 {
4323                     deps.push_back(SubpassDependency(
4324                         VK_SUBPASS_EXTERNAL,                  // uint32_t                srcPass
4325                         0,                                    // uint32_t                dstPass
4326                         VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, // VkPipelineStageFlags    srcStageMask
4327                         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
4328                             VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags    dstStageMask
4329                         0,                                         // VkAccessFlags        srcAccessMask
4330                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT |
4331                             VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags        dstAccessMask
4332                         0));                            // VkDependencyFlags    flags
4333                 }
4334 
4335                 RenderPass renderPass(attachments, subpasses, deps);
4336 
4337                 renderPasses.push_back(renderPass);
4338             }
4339 
4340             const uint32_t blurKernel(12u);
4341             const ExternalTestConfig testConfig(VK_FORMAT_R8G8B8A8_UNORM, UVec2(128, 128), renderPasses, groupParams,
4342                                                 SYNCHRONIZATION_TYPE_LEGACY, blurKernel);
4343             const string testName("render_passes_" + de::toString(renderPassCounts[renderPassCountNdx]));
4344 
4345             implicitGroup->addChild(
4346                 new InstanceFactory1<ExternalDependencyTestInstance, ExternalTestConfig, ExternalPrograms>(
4347                     testCtx, testName.c_str(), testConfig));
4348         }
4349 
4350         group->addChild(implicitGroup.release());
4351     }
4352 
4353     // Test late fragment operations using depth_stencil attachments in multipass rendering
4354     if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4355     {
4356         const UVec2 renderSizes[] = {UVec2(32, 32), UVec2(64, 64), UVec2(128, 128)};
4357 
4358         const uint32_t subpassCounts[] = {2u, 3u, 5u};
4359 
4360         // Implementations must support at least one of the following formats
4361         // for depth_stencil attachments
4362         const VkFormat formats[] = {VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
4363 
4364         de::MovePtr<tcu::TestCaseGroup> lateFragmentTestsGroup(new tcu::TestCaseGroup(testCtx, "late_fragment_tests"));
4365 
4366         for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4367         {
4368             string renderSizeGroupName("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" +
4369                                        de::toString(renderSizes[renderSizeNdx].y()));
4370             de::MovePtr<tcu::TestCaseGroup> renderSizeGroup(
4371                 new tcu::TestCaseGroup(testCtx, renderSizeGroupName.c_str()));
4372 
4373             for (size_t subpassCountNdx = 0; subpassCountNdx < DE_LENGTH_OF_ARRAY(subpassCounts); subpassCountNdx++)
4374             {
4375                 string subpassGroupName("subpass_count_" + de::toString(subpassCounts[subpassCountNdx]));
4376                 de::MovePtr<tcu::TestCaseGroup> subpassCountGroup(
4377                     new tcu::TestCaseGroup(testCtx, subpassGroupName.c_str()));
4378 
4379                 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
4380                 {
4381                     const uint32_t subpassCount(subpassCounts[subpassCountNdx]);
4382                     const uint32_t attachmentCount(subpassCount);
4383                     vector<Subpass> subpasses;
4384                     vector<Attachment> attachments;
4385                     vector<SubpassDependency> deps;
4386 
4387                     // Attachments
4388                     for (size_t attachmentNdx = 0; attachmentNdx < attachmentCount; attachmentNdx++)
4389                     {
4390                         const VkFormat format(formats[formatNdx]);
4391                         const VkSampleCountFlagBits sampleCount(VK_SAMPLE_COUNT_1_BIT);
4392                         const VkAttachmentLoadOp loadOp(VK_ATTACHMENT_LOAD_OP_CLEAR);
4393                         const VkAttachmentStoreOp storeOp((attachmentNdx == attachmentCount - 1) ?
4394                                                               VK_ATTACHMENT_STORE_OP_STORE :
4395                                                               VK_ATTACHMENT_STORE_OP_DONT_CARE);
4396                         const VkAttachmentLoadOp stencilLoadOp(VK_ATTACHMENT_LOAD_OP_CLEAR);
4397                         const VkAttachmentStoreOp stencilStoreOp((attachmentNdx == attachmentCount - 1) ?
4398                                                                      VK_ATTACHMENT_STORE_OP_STORE :
4399                                                                      VK_ATTACHMENT_STORE_OP_DONT_CARE);
4400                         const VkImageLayout initialLayout(VK_IMAGE_LAYOUT_UNDEFINED);
4401                         const VkImageLayout finalLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL);
4402 
4403                         attachments.push_back(Attachment(format, sampleCount, loadOp, storeOp, stencilLoadOp,
4404                                                          stencilStoreOp, initialLayout, finalLayout));
4405                     }
4406 
4407                     // Subpasses
4408                     for (size_t subpassNdx = 0; subpassNdx < subpassCount; subpassNdx++)
4409                     {
4410                         vector<AttachmentReference> inputAttachmentReferences;
4411                         const VkImageAspectFlags inputAttachmentAspectMask(
4412                             (groupParams->renderingType == RENDERING_TYPE_RENDERPASS2) ?
4413                                 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
4414                                 static_cast<VkImageAspectFlags>(0));
4415 
4416                         // Input attachment references
4417                         if (subpassNdx > 0)
4418                             inputAttachmentReferences.push_back(AttachmentReference(
4419                                 (uint32_t)subpassNdx - 1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,
4420                                 inputAttachmentAspectMask));
4421 
4422                         subpasses.push_back(Subpass(
4423                             VK_PIPELINE_BIND_POINT_GRAPHICS, 0u, inputAttachmentReferences,
4424                             vector<AttachmentReference>(), vector<AttachmentReference>(),
4425                             AttachmentReference((uint32_t)subpassNdx, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL),
4426                             vector<uint32_t>()));
4427 
4428                         // Subpass dependencies from current subpass to previous subpass.
4429                         // Subpasses will wait for the late fragment operations before reading the contents
4430                         // of previous subpass.
4431                         if (subpassNdx > 0)
4432                         {
4433                             deps.push_back(SubpassDependency(
4434                                 (uint32_t)subpassNdx - 1,                  // uint32_t                srcPass
4435                                 (uint32_t)subpassNdx,                      // uint32_t                dstPass
4436                                 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags    srcStageMask
4437                                 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
4438                                     VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags    dstStageMask
4439                                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,  // VkAccessFlags        srcAccessMask
4440                                 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,           // VkAccessFlags        dstAccessMask
4441                                 VK_DEPENDENCY_BY_REGION_BIT));                 // VkDependencyFlags    flags
4442                         }
4443                     }
4444                     deps.push_back(SubpassDependency(
4445                         (uint32_t)subpassCount - 1,                   // uint32_t                srcPass
4446                         VK_SUBPASS_EXTERNAL,                          // uint32_t                dstPass
4447                         VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,    // VkPipelineStageFlags    srcStageMask
4448                         VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,    // VkPipelineStageFlags    dstStageMask
4449                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags        srcAccessMask
4450                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
4451                             VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags        dstAccessMask
4452                         VK_DEPENDENCY_BY_REGION_BIT));                    // VkDependencyFlags    flags
4453 
4454                     const RenderPass renderPass(attachments, subpasses, deps);
4455                     const SubpassTestConfig testConfig(formats[formatNdx], renderSizes[renderSizeNdx], renderPass,
4456                                                        groupParams);
4457                     const string format(formatToName(formats[formatNdx]).c_str());
4458 
4459                     subpassCountGroup->addChild(
4460                         new InstanceFactory1WithSupport<SubpassDependencyTestInstance, SubpassTestConfig,
4461                                                         FunctionSupport1<SubpassTestConfig>, SubpassPrograms>(
4462                             testCtx, format, testConfig,
4463                             typename FunctionSupport1<SubpassTestConfig>::Args(checkSupport<SubpassTestConfig>,
4464                                                                                testConfig)));
4465                 }
4466 
4467                 renderSizeGroup->addChild(subpassCountGroup.release());
4468             }
4469 
4470             lateFragmentTestsGroup->addChild(renderSizeGroup.release());
4471         }
4472 
4473         group->addChild(lateFragmentTestsGroup.release());
4474     }
4475 
4476     // Test subpass self dependency
4477     if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
4478     {
4479         const UVec2 renderSizes[] = {UVec2(64, 64), UVec2(128, 128), UVec2(512, 512)};
4480 
4481         de::MovePtr<tcu::TestCaseGroup> selfDependencyGroup(new tcu::TestCaseGroup(testCtx, "self_dependency"));
4482 
4483         for (size_t renderSizeNdx = 0; renderSizeNdx < DE_LENGTH_OF_ARRAY(renderSizes); renderSizeNdx++)
4484         {
4485             string groupName("render_size_" + de::toString(renderSizes[renderSizeNdx].x()) + "_" +
4486                              de::toString(renderSizes[renderSizeNdx].y()));
4487             de::MovePtr<tcu::TestCaseGroup> renderSizeGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
4488 
4489             const SubpassSelfDependencyBackwardsTestConfig testConfig(
4490                 VK_FORMAT_R8G8B8A8_UNORM, renderSizes[renderSizeNdx], groupParams->renderingType);
4491             renderSizeGroup->addChild(
4492                 new InstanceFactory1<SubpassSelfDependencyBackwardsTestInstance,
4493                                      SubpassSelfDependencyBackwardsTestConfig, SubpassSelfDependencyBackwardsPrograms>(
4494                     testCtx, "geometry_to_indirectdraw", testConfig));
4495 
4496             selfDependencyGroup->addChild(renderSizeGroup.release());
4497         }
4498 
4499         group->addChild(selfDependencyGroup.release());
4500     }
4501 
4502     // Test using a single attachment with reads and writes using separate channels. This should work without subpass self-dependency.
4503     {
4504         de::MovePtr<tcu::TestCaseGroup> separateChannelsGroup(new tcu::TestCaseGroup(testCtx, "separate_channels"));
4505 
4506         struct TestConfig
4507         {
4508             string name;
4509             VkFormat format;
4510         } configs[] = {{"r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM},
4511                        {"r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT},
4512                        {"d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT},
4513                        {"d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT}};
4514 
4515         for (uint32_t configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4516         {
4517             const SeparateChannelsTestConfig testConfig(configs[configIdx].format, groupParams);
4518 
4519             separateChannelsGroup->addChild(
4520                 new InstanceFactory1WithSupport<SeparateChannelsTestInstance, SeparateChannelsTestConfig,
4521                                                 FunctionSupport1<SeparateChannelsTestConfig>, SeparateChannelsPrograms>(
4522                     testCtx, configs[configIdx].name, testConfig,
4523                     typename FunctionSupport1<SeparateChannelsTestConfig>::Args(
4524                         checkSupport<SeparateChannelsTestConfig>, testConfig)));
4525         }
4526 
4527         group->addChild(separateChannelsGroup.release());
4528     }
4529 
4530     // Test using a single attachment for input and output.
4531     {
4532         de::MovePtr<tcu::TestCaseGroup> singleAttachmentGroup(new tcu::TestCaseGroup(testCtx, "single_attachment"));
4533 
4534         struct TestConfig
4535         {
4536             string name;
4537             VkFormat format;
4538         } configs[] = {{"r8g8b8a8_unorm", VK_FORMAT_R8G8B8A8_UNORM},
4539                        {"b8g8r8a8_unorm", VK_FORMAT_B8G8R8A8_UNORM},
4540                        {"r16g16b16a16_sfloat", VK_FORMAT_R16G16B16A16_SFLOAT},
4541                        {"r5g6b5_unorm_pack16", VK_FORMAT_R5G6B5_UNORM_PACK16},
4542                        {"a1r5g5b5_unorm_pack16", VK_FORMAT_A1R5G5B5_UNORM_PACK16}};
4543 
4544         for (uint32_t configIdx = 0; configIdx < DE_LENGTH_OF_ARRAY(configs); configIdx++)
4545         {
4546             const SingleAttachmentTestConfig testConfig(configs[configIdx].format, groupParams);
4547 
4548             singleAttachmentGroup->addChild(
4549                 new InstanceFactory1WithSupport<SingleAttachmentTestInstance, SingleAttachmentTestConfig,
4550                                                 FunctionSupport1<SingleAttachmentTestConfig>, SingleAttachmentPrograms>(
4551                     testCtx, configs[configIdx].name, testConfig,
4552                     typename FunctionSupport1<SingleAttachmentTestConfig>::Args(
4553                         checkSupport<SingleAttachmentTestConfig>, testConfig)));
4554         }
4555 
4556         group->addChild(singleAttachmentGroup.release());
4557     }
4558 }
4559 } // namespace
4560 
createRenderPassSubpassDependencyTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)4561 tcu::TestCaseGroup *createRenderPassSubpassDependencyTests(tcu::TestContext &testCtx,
4562                                                            const renderpass::SharedGroupParams groupParams)
4563 {
4564     return createTestGroup(testCtx, "subpass_dependencies", initTests, groupParams);
4565 }
4566 
4567 } // namespace vkt
4568