1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 The Khronos Group Inc.
6  * Copyright (c) 2021 Google 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 load and store op "none"
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktRenderPassLoadStoreOpNoneTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vktRenderPassTestsUtil.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkBarrierUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkRef.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "tcuPlatform.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "deStringUtil.hpp"
44 #include "deUniquePtr.hpp"
45 #include "deRandom.hpp"
46 #include <cstring>
47 #include <cmath>
48 #include <vector>
49 
50 namespace vkt
51 {
52 namespace renderpass
53 {
54 
55 using namespace vk;
56 
57 namespace
58 {
59 
60 enum AttachmentInit
61 {
62     ATTACHMENT_INIT_PRE       = 1,
63     ATTACHMENT_INIT_CMD_CLEAR = 2
64 };
65 
66 enum AttachmentUsage
67 {
68     ATTACHMENT_USAGE_UNDEFINED         = 0,
69     ATTACHMENT_USAGE_COLOR             = 1,
70     ATTACHMENT_USAGE_DEPTH             = 2,
71     ATTACHMENT_USAGE_STENCIL           = 4,
72     ATTACHMENT_USAGE_DEPTH_STENCIL     = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL,
73     ATTACHMENT_USAGE_INPUT             = 8,
74     ATTACHMENT_USAGE_COLOR_WRITE_OFF   = 16,
75     ATTACHMENT_USAGE_DEPTH_WRITE_OFF   = 32,
76     ATTACHMENT_USAGE_STENCIL_WRITE_OFF = 64,
77     ATTACHMENT_USAGE_DEPTH_TEST_OFF    = 128,
78     ATTACHMENT_USAGE_STENCIL_TEST_OFF  = 256,
79     ATTACHMENT_USAGE_MULTISAMPLE       = 512,
80     ATTACHMENT_USAGE_RESOLVE_TARGET    = 1024,
81     ATTACHMENT_USAGE_INTEGER           = 2048
82 };
83 
84 struct VerifyAspect
85 {
86     VkImageAspectFlagBits aspect;
87     bool verifyInner;
88     tcu::Vec4 innerRef;
89     bool verifyOuter;
90     tcu::Vec4 outerRef;
91 };
92 
93 struct AttachmentParams
94 {
95     uint32_t usage;
96     VkAttachmentLoadOp loadOp;
97     VkAttachmentStoreOp storeOp;
98     VkAttachmentLoadOp stencilLoadOp;
99     VkAttachmentStoreOp stencilStoreOp;
100     uint32_t init;
101     std::vector<VerifyAspect> verifyAspects;
102 };
103 
104 struct AttachmentRef
105 {
106     uint32_t idx;
107     uint32_t usage;
108 };
109 
110 struct SubpassParams
111 {
112     std::vector<AttachmentRef> attachmentRefs;
113     uint32_t numDraws;
114 };
115 
116 enum class ExtensionPreference
117 {
118     EXT,
119     KHR,
120 };
121 
122 struct TestParams
123 {
124     std::vector<AttachmentParams> attachments;
125     std::vector<SubpassParams> subpasses;
126     const SharedGroupParams groupParams;
127     VkFormat depthStencilFormat;
128     bool alphaBlend;
129 
130     // To ensure both VK_EXT_load_store_op_none and VK_KHR_load_store_op_none are tested, use KHR by
131     // default (if available), but have some tests use EXT (if available).  Either way, if one
132     // extension is not available, the other is always used.
133     ExtensionPreference extPreference;
134 };
135 
136 struct Vertex4RGBA
137 {
138     tcu::Vec4 position;
139     tcu::Vec4 color;
140 };
141 
142 template <typename T>
makeSharedPtr(vk::Move<T> move)143 inline de::SharedPtr<vk::Move<T>> makeSharedPtr(vk::Move<T> move)
144 {
145     return de::SharedPtr<vk::Move<T>>(new vk::Move<T>(move));
146 }
147 
createQuad(void)148 std::vector<Vertex4RGBA> createQuad(void)
149 {
150     std::vector<Vertex4RGBA> vertices;
151 
152     const float size = 1.0f;
153     const tcu::Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
154     const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
155     const Vertex4RGBA lowerLeftVertexRed   = {tcu::Vec4(-size, -size, 0.0f, 1.0f), red};
156     const Vertex4RGBA lowerRightVertexRed  = {tcu::Vec4(size, -size, 0.0f, 1.0f), red};
157     const Vertex4RGBA upperLeftVertexRed   = {tcu::Vec4(-size, size, 0.0f, 1.0f), red};
158     const Vertex4RGBA upperRightVertexRed  = {tcu::Vec4(size, size, 0.0f, 1.0f), red};
159     const Vertex4RGBA lowerLeftVertexBlue  = {tcu::Vec4(-size, -size, 0.0f, 1.0f), blue};
160     const Vertex4RGBA lowerRightVertexBlue = {tcu::Vec4(size, -size, 0.0f, 1.0f), blue};
161     const Vertex4RGBA upperLeftVertexBlue  = {tcu::Vec4(-size, size, 0.0f, 1.0f), blue};
162     const Vertex4RGBA upperRightVertexBlue = {tcu::Vec4(size, size, 0.0f, 1.0f), blue};
163 
164     vertices.push_back(lowerLeftVertexRed);
165     vertices.push_back(lowerRightVertexRed);
166     vertices.push_back(upperLeftVertexRed);
167     vertices.push_back(upperLeftVertexRed);
168     vertices.push_back(lowerRightVertexRed);
169     vertices.push_back(upperRightVertexRed);
170 
171     vertices.push_back(lowerLeftVertexBlue);
172     vertices.push_back(lowerRightVertexBlue);
173     vertices.push_back(upperLeftVertexBlue);
174     vertices.push_back(upperLeftVertexBlue);
175     vertices.push_back(lowerRightVertexBlue);
176     vertices.push_back(upperRightVertexBlue);
177 
178     return vertices;
179 }
180 
getFirstUsage(uint32_t attachmentIdx,const std::vector<SubpassParams> & subpasses)181 uint32_t getFirstUsage(uint32_t attachmentIdx, const std::vector<SubpassParams> &subpasses)
182 {
183     for (const auto &subpass : subpasses)
184         for (const auto &ref : subpass.attachmentRefs)
185             if (ref.idx == attachmentIdx)
186                 return ref.usage;
187 
188     return ATTACHMENT_USAGE_UNDEFINED;
189 }
190 
getFormatCaseName(VkFormat format)191 std::string getFormatCaseName(VkFormat format)
192 {
193     return de::toLower(de::toString(getFormatStr(format)).substr(10));
194 }
195 
196 // Selects an image format based on the usage flags.
getFormat(uint32_t usage,VkFormat depthStencilFormat)197 VkFormat getFormat(uint32_t usage, VkFormat depthStencilFormat)
198 {
199     if (usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
200     {
201         return depthStencilFormat;
202     }
203 
204     if (usage & ATTACHMENT_USAGE_INTEGER)
205     {
206         // Color attachment using integer format.
207         return VK_FORMAT_R8G8B8A8_UINT;
208     }
209 
210     return VK_FORMAT_R8G8B8A8_UNORM;
211 }
212 
213 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
214           typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,const TestParams testParams)215 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice vkDevice, const TestParams testParams)
216 {
217     const VkImageAspectFlags aspectMask =
218         testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
219     std::vector<AttachmentDesc> attachmentDescriptions;
220     std::vector<SubpassDesc> subpassDescriptions;
221 
222     struct Refs
223     {
224         std::vector<AttachmentRef> colorAttachmentRefs;
225         std::vector<AttachmentRef> resolveAttachmentRefs;
226         std::vector<AttachmentRef> depthStencilAttachmentRefs;
227         std::vector<AttachmentRef> inputAttachmentRefs;
228     };
229 
230     std::vector<Refs> subpassRefs;
231     bool hasInputAttachment = false;
232 
233     for (size_t i = 0; i < testParams.attachments.size(); i++)
234     {
235         VkImageLayout initialLayout;
236         VkImageLayout finalLayout;
237         VkFormat format = getFormat(testParams.attachments[i].usage, testParams.depthStencilFormat);
238 
239         // Search for the first reference to determine the initial layout.
240         uint32_t firstUsage = getFirstUsage((uint32_t)i, testParams.subpasses);
241 
242         // No subpasses using this attachment. Use the usage flags of the attachment.
243         if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
244             firstUsage = testParams.attachments[i].usage;
245 
246         if (firstUsage & ATTACHMENT_USAGE_COLOR)
247             initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
248         else if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
249             initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
250         else
251         {
252             DE_ASSERT(firstUsage & ATTACHMENT_USAGE_INPUT);
253             initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
254         }
255 
256         // Set final layout to transfer src if it's being verified. Otherwise
257         // just use the initial layout as it's known to be supported by
258         // the usage flags.
259         if (!testParams.attachments[i].verifyAspects.empty())
260             finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
261         else
262             finalLayout = initialLayout;
263 
264         const VkSampleCountFlagBits sampleCount = testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE ?
265                                                       VK_SAMPLE_COUNT_4_BIT :
266                                                       VK_SAMPLE_COUNT_1_BIT;
267 
268         const AttachmentDesc attachmentDesc = {
269             DE_NULL,                                  // const void*                        pNext
270             (VkAttachmentDescriptionFlags)0,          // VkAttachmentDescriptionFlags        flags
271             format,                                   // VkFormat                            format
272             sampleCount,                              // VkSampleCountFlagBits            samples
273             testParams.attachments[i].loadOp,         // VkAttachmentLoadOp                loadOp
274             testParams.attachments[i].storeOp,        // VkAttachmentStoreOp                storeOp
275             testParams.attachments[i].stencilLoadOp,  // VkAttachmentLoadOp                stencilLoadOp
276             testParams.attachments[i].stencilStoreOp, // VkAttachmentStoreOp                stencilStoreOp
277             initialLayout,                            // VkImageLayout                    initialLayout
278             finalLayout                               // VkImageLayout                    finalLayout
279         };
280 
281         attachmentDescriptions.push_back(attachmentDesc);
282     }
283 
284     for (const auto &subpass : testParams.subpasses)
285     {
286         subpassRefs.push_back({});
287         auto &refs = subpassRefs.back();
288 
289         for (const auto &ref : subpass.attachmentRefs)
290         {
291             VkImageLayout layout;
292 
293             if (ref.usage & ATTACHMENT_USAGE_RESOLVE_TARGET)
294             {
295                 layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
296                 refs.resolveAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
297             }
298             else if (ref.usage & ATTACHMENT_USAGE_COLOR)
299             {
300                 layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
301                 refs.colorAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
302             }
303             else if (ref.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
304             {
305                 layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
306                 const auto depthStencilAspectMask =
307                     testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ?
308                         0 :
309                         getImageAspectFlags(mapVkFormat(testParams.depthStencilFormat));
310                 refs.depthStencilAttachmentRefs.push_back({DE_NULL, ref.idx, layout, depthStencilAspectMask});
311             }
312             else
313             {
314                 DE_ASSERT(ref.usage & ATTACHMENT_USAGE_INPUT);
315                 layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
316                 refs.inputAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
317                 hasInputAttachment = true;
318             }
319         }
320 
321         const SubpassDesc subpassDescription = {
322             DE_NULL,
323             (VkSubpassDescriptionFlags)0,              // VkSubpassDescriptionFlags        flags
324             VK_PIPELINE_BIND_POINT_GRAPHICS,           // VkPipelineBindPoint                pipelineBindPoint
325             0u,                                        // uint32_t                            viewMask
326             (uint32_t)refs.inputAttachmentRefs.size(), // uint32_t                            inputAttachmentCount
327             refs.inputAttachmentRefs.empty() ?
328                 DE_NULL :
329                 refs.inputAttachmentRefs.data(),       // const VkAttachmentReference*        pInputAttachments
330             (uint32_t)refs.colorAttachmentRefs.size(), // uint32_t                            colorAttachmentCount
331             refs.colorAttachmentRefs.empty() ?
332                 DE_NULL :
333                 refs.colorAttachmentRefs.data(), // const VkAttachmentReference*        pColorAttachments
334             refs.resolveAttachmentRefs.empty() ?
335                 DE_NULL :
336                 refs.resolveAttachmentRefs.data(), // const VkAttachmentReference*        pResolveAttachments
337             refs.depthStencilAttachmentRefs.empty() ?
338                 DE_NULL :
339                 refs.depthStencilAttachmentRefs.data(), // const VkAttachmentReference*        pDepthStencilAttachment
340             0u,                                         // uint32_t                            preserveAttachmentCount
341             DE_NULL                                     // const uint32_t*                    pPreserveAttachments
342         };
343 
344         subpassDescriptions.push_back(subpassDescription);
345     }
346 
347     // Dependency of color attachment of subpass 0 to input attachment of subpass 1.
348     // Determined later if it's being used.
349     const SubpassDep subpassDependency = {
350         DE_NULL,                                       // const void*                pNext
351         0u,                                            // uint32_t                    srcSubpass
352         1u,                                            // uint32_t                    dstSubpass
353         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags        srcStageMask
354         VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,         // VkPipelineStageFlags        dstStageMask
355         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,          // VkAccessFlags            srcAccessMask
356         VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,           // VkAccessFlags            dstAccessMask
357         VK_DEPENDENCY_BY_REGION_BIT,                   // VkDependencyFlags        dependencyFlags
358         0u                                             // int32_t                    viewOffset
359     };
360 
361     const RenderPassCreateInfo renderPassInfo = {
362         DE_NULL,                                           // const void*                        pNext
363         (VkRenderPassCreateFlags)0,                        // VkRenderPassCreateFlags            flags
364         (uint32_t)attachmentDescriptions.size(),           // uint32_t                            attachmentCount
365         attachmentDescriptions.data(),                     // const VkAttachmentDescription*    pAttachments
366         (uint32_t)subpassDescriptions.size(),              // uint32_t                            subpassCount
367         subpassDescriptions.data(),                        // const VkSubpassDescription*        pSubpasses
368         hasInputAttachment ? 1u : 0u,                      // uint32_t                            dependencyCount
369         hasInputAttachment ? &subpassDependency : DE_NULL, // const VkSubpassDependency*        pDependencies
370         0u,     // uint32_t                            correlatedViewMaskCount
371         DE_NULL // const uint32_t*                    pCorrelatedViewMasks
372     };
373 
374     return renderPassInfo.createRenderPass(vk, vkDevice);
375 }
376 
377 class LoadStoreOpNoneTest : public vkt::TestCase
378 {
379 public:
380     LoadStoreOpNoneTest(tcu::TestContext &testContext, const std::string &name, const TestParams &testParams);
381     virtual ~LoadStoreOpNoneTest(void) = default;
382     virtual void initPrograms(SourceCollections &sourceCollections) const;
383     virtual void checkSupport(Context &context) const;
384     virtual TestInstance *createInstance(Context &context) const;
385 
386 private:
387     const TestParams m_testParams;
388 };
389 
390 class LoadStoreOpNoneTestInstance : public vkt::TestInstance
391 {
392 public:
393     LoadStoreOpNoneTestInstance(Context &context, const TestParams &testParams);
394     virtual ~LoadStoreOpNoneTestInstance(void) = default;
395     virtual tcu::TestStatus iterate(void);
396 
397     template <typename RenderpassSubpass>
398     void createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice,
399                              std::vector<Move<VkDescriptorSet>> &descriptorSets,
400                              std::vector<PipelineLayoutWrapper> &pipelineLayouts,
401                              std::vector<GraphicsPipelineWrapper> &pipelines);
402     void createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice, std::vector<Move<VkImageView>> &imageViews,
403                              std::vector<Move<VkDescriptorSet>> &descriptorSets,
404                              std::vector<PipelineLayoutWrapper> &pipelineLayouts,
405                              std::vector<GraphicsPipelineWrapper> &pipelines);
406     void drawCommands(VkCommandBuffer cmdBuffer, std::vector<Move<VkDescriptorSet>> &descriptorSets,
407                       std::vector<PipelineLayoutWrapper> &pipelineLayouts,
408                       std::vector<GraphicsPipelineWrapper> &pipelines) const;
409 
410 private:
411     TestParams m_testParams;
412 
413     const tcu::UVec2 m_imageSize;
414     const tcu::UVec2 m_renderSize;
415 
416     Move<VkDescriptorPool> m_descriptorPool;
417     Move<VkRenderPass> m_renderPass;
418     Move<VkFramebuffer> m_framebuffer;
419 
420     Move<VkBuffer> m_vertexBuffer;
421     std::vector<Vertex4RGBA> m_vertices;
422     de::MovePtr<Allocation> m_vertexBufferAlloc;
423 
424     Move<VkCommandPool> m_cmdPool;
425     Move<VkCommandBuffer> m_cmdBuffer;
426     Move<VkCommandBuffer> m_secCmdBuffer;
427 };
428 
LoadStoreOpNoneTest(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)429 LoadStoreOpNoneTest::LoadStoreOpNoneTest(tcu::TestContext &testContext, const std::string &name,
430                                          const TestParams &testParams)
431     : vkt::TestCase(testContext, name)
432     , m_testParams(testParams)
433 {
434 }
435 
createInstance(Context & context) const436 TestInstance *LoadStoreOpNoneTest::createInstance(Context &context) const
437 {
438     return new LoadStoreOpNoneTestInstance(context, m_testParams);
439 }
440 
checkSupport(Context & ctx) const441 void LoadStoreOpNoneTest::checkSupport(Context &ctx) const
442 {
443     const auto &vki    = ctx.getInstanceInterface();
444     const auto physDev = ctx.getPhysicalDevice();
445 
446     checkPipelineConstructionRequirements(vki, physDev, m_testParams.groupParams->pipelineConstructionType);
447 
448     // Check for renderpass2 extension if used.
449     if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
450         ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2");
451 
452     // Check for dynamic_rendering extension if used
453     if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
454     {
455         ctx.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
456         if (m_testParams.subpasses.size() > 1)
457             ctx.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
458     }
459 
460     const bool supportsExt = ctx.isDeviceFunctionalitySupported("VK_EXT_load_store_op_none");
461     const bool supportsKHR = ctx.isDeviceFunctionalitySupported("VK_KHR_load_store_op_none");
462     // Prefer VK_EXT_load_store_op_none if supported, and either explicitly preferred or KHR is not
463     // supported.  Otherwise require VK_KHR_load_store_op_none.  The tests are skipped if neither
464     // extension is supported.
465     if (supportsExt && (m_testParams.extPreference == ExtensionPreference::EXT || !supportsKHR))
466         ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none");
467     else
468         ctx.requireDeviceFunctionality("VK_KHR_load_store_op_none");
469 
470     // Check depth/stencil format support.
471     for (const auto &att : m_testParams.attachments)
472     {
473         if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
474         {
475             const VkFormat format   = getFormat(att.usage, m_testParams.depthStencilFormat);
476             VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
477             const auto aspectFlags  = getImageAspectFlags(mapVkFormat(format));
478 
479             if (att.usage & ATTACHMENT_USAGE_DEPTH)
480                 DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT) != 0u);
481 
482             if (att.usage & ATTACHMENT_USAGE_STENCIL)
483                 DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0u);
484 
485             DE_UNREF(aspectFlags); // For release builds.
486 
487             if (!att.verifyAspects.empty())
488                 usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
489 
490             if (att.init & ATTACHMENT_INIT_PRE)
491                 usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
492 
493             const auto imgType = VK_IMAGE_TYPE_2D;
494             const auto tiling  = VK_IMAGE_TILING_OPTIMAL;
495             VkImageFormatProperties properties;
496             const auto result =
497                 vki.getPhysicalDeviceImageFormatProperties(physDev, format, imgType, tiling, usage, 0u, &properties);
498 
499             if (result != VK_SUCCESS)
500                 TCU_THROW(NotSupportedError, "Depth-stencil format not supported");
501         }
502     }
503 }
504 
initPrograms(SourceCollections & sourceCollections) const505 void LoadStoreOpNoneTest::initPrograms(SourceCollections &sourceCollections) const
506 {
507     std::ostringstream fragmentSource;
508 
509     sourceCollections.glslSources.add("color_vert")
510         << glu::VertexSource("#version 450\n"
511                              "layout(location = 0) in highp vec4 position;\n"
512                              "layout(location = 1) in highp vec4 color;\n"
513                              "layout(location = 0) out highp vec4 vtxColor;\n"
514                              "void main (void)\n"
515                              "{\n"
516                              "    gl_Position = position;\n"
517                              "    vtxColor = color;\n"
518                              "}\n");
519 
520     sourceCollections.glslSources.add("color_frag")
521         << glu::FragmentSource("#version 450\n"
522                                "layout(location = 0) in highp vec4 vtxColor;\n"
523                                "layout(location = 0) out highp vec4 fragColor;\n"
524                                "void main (void)\n"
525                                "{\n"
526                                "    fragColor = vtxColor;\n"
527                                "    gl_FragDepth = 1.0;\n"
528                                "}\n");
529 
530     sourceCollections.glslSources.add("color_frag_uint")
531         << glu::FragmentSource("#version 450\n"
532                                "layout(location = 0) in highp vec4 vtxColor;\n"
533                                "layout(location = 0) out highp uvec4 fragColor;\n"
534                                "void main (void)\n"
535                                "{\n"
536                                "    fragColor = uvec4(vtxColor * vec4(255));\n"
537                                "    gl_FragDepth = 1.0;\n"
538                                "}\n");
539 
540     sourceCollections.glslSources.add("color_frag_blend")
541         << glu::FragmentSource("#version 450\n"
542                                "layout(location = 0) in highp vec4 vtxColor;\n"
543                                "layout(location = 0) out highp vec4 fragColor;\n"
544                                "void main (void)\n"
545                                "{\n"
546                                "    fragColor = vec4(vtxColor.rgb, 0.5);\n"
547                                "    gl_FragDepth = 1.0;\n"
548                                "}\n");
549 
550     sourceCollections.glslSources.add("color_frag_input") << glu::FragmentSource(
551         "#version 450\n"
552         "layout(location = 0) in highp vec4 vtxColor;\n"
553         "layout(location = 0) out highp vec4 fragColor;\n"
554         "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;\n"
555         "void main (void)\n"
556         "{\n"
557         "    fragColor = subpassLoad(inputColor) + vtxColor;\n"
558         "    gl_FragDepth = 1.0;\n"
559         "}\n");
560 }
561 
LoadStoreOpNoneTestInstance(Context & context,const TestParams & testParams)562 LoadStoreOpNoneTestInstance::LoadStoreOpNoneTestInstance(Context &context, const TestParams &testParams)
563     : vkt::TestInstance(context)
564     , m_testParams(testParams)
565     , m_imageSize(32u, 32u)
566     , m_renderSize(27u, 19u)
567     , m_vertices(createQuad())
568 {
569 }
570 
571 template <typename RenderpassSubpass>
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice,std::vector<Move<VkDescriptorSet>> & descriptorSets,std::vector<PipelineLayoutWrapper> & pipelineLayouts,std::vector<GraphicsPipelineWrapper> & pipelines)572 void LoadStoreOpNoneTestInstance::createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice,
573                                                       std::vector<Move<VkDescriptorSet>> &descriptorSets,
574                                                       std::vector<PipelineLayoutWrapper> &pipelineLayouts,
575                                                       std::vector<GraphicsPipelineWrapper> &pipelines)
576 {
577     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
578     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
579 
580     m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
581 
582     beginCommandBuffer(vk, *m_cmdBuffer, 0u);
583     const VkRenderPassBeginInfo renderPassBeginInfo{
584         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType        sType
585         DE_NULL,                                  // const void*            pNext
586         *m_renderPass,                            // VkRenderPass            renderPass
587         *m_framebuffer,                           // VkFramebuffer        framebuffer
588         makeRect2D(m_renderSize),                 // VkRect2D                renderArea
589         0u,                                       // uint32_t                clearValueCount
590         DE_NULL                                   // const VkClearValue*    pClearValues
591     };
592     RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
593 
594     drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines);
595 
596     RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
597     endCommandBuffer(vk, *m_cmdBuffer);
598 }
599 
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice,std::vector<Move<VkImageView>> & imageViews,std::vector<Move<VkDescriptorSet>> & descriptorSets,std::vector<PipelineLayoutWrapper> & pipelineLayouts,std::vector<GraphicsPipelineWrapper> & pipelines)600 void LoadStoreOpNoneTestInstance::createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice,
601                                                       std::vector<Move<VkImageView>> &imageViews,
602                                                       std::vector<Move<VkDescriptorSet>> &descriptorSets,
603                                                       std::vector<PipelineLayoutWrapper> &pipelineLayouts,
604                                                       std::vector<GraphicsPipelineWrapper> &pipelines)
605 {
606     std::vector<VkRenderingAttachmentInfo> colorAttachments;
607 
608     VkRenderingAttachmentInfo depthAttachment{
609         VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,      // VkStructureType sType;
610         DE_NULL,                                          // const void* pNext;
611         DE_NULL,                                          // VkImageView imageView;
612         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
613         VK_RESOLVE_MODE_NONE,                             // VkResolveModeFlagBits resolveMode;
614         DE_NULL,                                          // VkImageView resolveImageView;
615         VK_IMAGE_LAYOUT_UNDEFINED,                        // VkImageLayout resolveImageLayout;
616         VK_ATTACHMENT_LOAD_OP_LOAD,                       // VkAttachmentLoadOp loadOp;
617         VK_ATTACHMENT_STORE_OP_STORE,                     // VkAttachmentStoreOp storeOp;
618         makeClearValueDepthStencil(0.0f, 0u)              // VkClearValue clearValue;
619     };
620 
621     VkRenderingAttachmentInfo stencilAttachment{
622         VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,      // VkStructureType sType;
623         DE_NULL,                                          // const void* pNext;
624         DE_NULL,                                          // VkImageView imageView;
625         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
626         VK_RESOLVE_MODE_NONE,                             // VkResolveModeFlagBits resolveMode;
627         DE_NULL,                                          // VkImageView resolveImageView;
628         VK_IMAGE_LAYOUT_UNDEFINED,                        // VkImageLayout resolveImageLayout;
629         VK_ATTACHMENT_LOAD_OP_LOAD,                       // VkAttachmentLoadOp loadOp;
630         VK_ATTACHMENT_STORE_OP_STORE,                     // VkAttachmentStoreOp storeOp;
631         makeClearValueDepthStencil(0.0f, 0u)              // VkClearValue clearValue;
632     };
633 
634     bool useDepth   = false;
635     bool useStencil = false;
636 
637     VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
638     std::vector<VkFormat> colorAttachmentFormats;
639 
640     for (size_t i = 0; i < imageViews.size(); i++)
641     {
642         if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE)
643         {
644             DE_ASSERT(m_testParams.attachments[i + 1].usage & ATTACHMENT_USAGE_RESOLVE_TARGET);
645             const auto resolveMode =
646                 ((m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INTEGER) ? VK_RESOLVE_MODE_SAMPLE_ZERO_BIT :
647                                                                                   VK_RESOLVE_MODE_AVERAGE_BIT);
648             colorAttachments.push_back({
649                 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
650                 DE_NULL,                                     // const void* pNext;
651                 *imageViews[i],                              // VkImageView imageView;
652                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,    // VkImageLayout imageLayout;
653                 resolveMode,                                 // VkResolveModeFlagBits resolveMode;
654                 *imageViews[i + 1],                          // VkImageView resolveImageView;
655                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,    // VkImageLayout resolveImageLayout;
656                 m_testParams.attachments[i].loadOp,          // VkAttachmentLoadOp loadOp;
657                 m_testParams.attachments[i].storeOp,         // VkAttachmentStoreOp storeOp;
658                 makeClearValueColor(tcu::Vec4(0.0f))         // VkClearValue clearValue;
659             });
660             colorAttachmentFormats.push_back(
661                 getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat));
662             sampleCount = VK_SAMPLE_COUNT_4_BIT;
663             i += 1;
664         }
665         else if (m_testParams.attachments[i].usage & (ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT))
666         {
667             VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
668             if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
669                 imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
670 
671             colorAttachments.push_back({
672                 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
673                 DE_NULL,                                     // const void* pNext;
674                 *imageViews[i],                              // VkImageView imageView;
675                 imageLayout,                                 // VkImageLayout imageLayout;
676                 VK_RESOLVE_MODE_NONE,                        // VkResolveModeFlagBits resolveMode;
677                 DE_NULL,                                     // VkImageView resolveImageView;
678                 VK_IMAGE_LAYOUT_UNDEFINED,                   // VkImageLayout resolveImageLayout;
679                 m_testParams.attachments[i].loadOp,          // VkAttachmentLoadOp loadOp;
680                 m_testParams.attachments[i].storeOp,         // VkAttachmentStoreOp storeOp;
681                 makeClearValueColor(tcu::Vec4(0.0f))         // VkClearValue clearValue;
682             });
683             colorAttachmentFormats.push_back(
684                 getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat));
685         }
686         else
687         {
688             uint32_t usage = m_testParams.attachments[i].usage;
689             useDepth       = usage & ATTACHMENT_USAGE_DEPTH;
690             useStencil     = usage & ATTACHMENT_USAGE_STENCIL;
691 
692             depthAttachment.imageView   = *imageViews[i];
693             depthAttachment.loadOp      = m_testParams.attachments[i].loadOp;
694             depthAttachment.storeOp     = m_testParams.attachments[i].storeOp;
695             stencilAttachment.imageView = *imageViews[i];
696             stencilAttachment.loadOp    = m_testParams.attachments[i].stencilLoadOp;
697             stencilAttachment.storeOp   = m_testParams.attachments[i].stencilStoreOp;
698         }
699     }
700 
701     VkCommandBufferInheritanceRenderingInfo inheritanceRenderingInfo{
702         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO,        // VkStructureType sType;
703         DE_NULL,                                                            // const void* pNext;
704         0u,                                                                 // VkRenderingFlagsKHR flags;
705         0u,                                                                 // uint32_t viewMask;
706         static_cast<uint32_t>(colorAttachmentFormats.size()),               // uint32_t colorAttachmentCount;
707         colorAttachmentFormats.data(),                                      // const VkFormat* pColorAttachmentFormats;
708         useDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,   // VkFormat depthAttachmentFormat;
709         useStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
710         sampleCount // VkSampleCountFlagBits rasterizationSamples;
711     };
712 
713     const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
714     VkCommandBufferBeginInfo commandBufBeginParams{
715         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
716         DE_NULL,                                     // const void* pNext;
717         VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
718         &bufferInheritanceInfo};
719 
720     VkRenderingInfo renderingInfo{
721         VK_STRUCTURE_TYPE_RENDERING_INFO,
722         DE_NULL,
723         0u,                                       // VkRenderingFlagsKHR flags;
724         makeRect2D(m_renderSize),                 // VkRect2D renderArea;
725         1u,                                       // uint32_t layerCount;
726         0u,                                       // uint32_t viewMask;
727         (uint32_t)colorAttachments.size(),        // uint32_t colorAttachmentCount;
728         de::dataOrNull(colorAttachments),         // const VkRenderingAttachmentInfoKHR* pColorAttachments;
729         useDepth ? &depthAttachment : DE_NULL,    // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
730         useStencil ? &stencilAttachment : DE_NULL // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
731     };
732 
733     m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
734 
735     if (m_testParams.groupParams->useSecondaryCmdBuffer)
736     {
737         m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
738 
739         // record secondary command buffer
740         if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
741         {
742             inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
743             vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
744             vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
745         }
746         else
747         {
748             commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
749             vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
750         }
751 
752         drawCommands(*m_secCmdBuffer, descriptorSets, pipelineLayouts, pipelines);
753 
754         if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
755             vk.cmdEndRendering(*m_secCmdBuffer);
756         endCommandBuffer(vk, *m_secCmdBuffer);
757 
758         // record primary command buffer
759         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
760         if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
761         {
762             renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
763             vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
764         }
765         vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
766         if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
767             vk.cmdEndRendering(*m_cmdBuffer);
768         endCommandBuffer(vk, *m_cmdBuffer);
769     }
770     else
771     {
772         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
773         vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
774 
775         drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines);
776 
777         vk.cmdEndRendering(*m_cmdBuffer);
778         endCommandBuffer(vk, *m_cmdBuffer);
779     }
780 }
781 
drawCommands(VkCommandBuffer cmdBuffer,std::vector<Move<VkDescriptorSet>> & descriptorSets,std::vector<PipelineLayoutWrapper> & pipelineLayouts,std::vector<GraphicsPipelineWrapper> & pipelines) const782 void LoadStoreOpNoneTestInstance::drawCommands(VkCommandBuffer cmdBuffer,
783                                                std::vector<Move<VkDescriptorSet>> &descriptorSets,
784                                                std::vector<PipelineLayoutWrapper> &pipelineLayouts,
785                                                std::vector<GraphicsPipelineWrapper> &pipelines) const
786 {
787     const DeviceInterface &vk             = m_context.getDeviceInterface();
788     const VkClearRect rect                = {makeRect2D(m_renderSize), 0u, 1u};
789     const VkDeviceSize vertexBufferOffset = 0;
790 
791     // Add clear commands for selected attachments
792     std::vector<VkClearAttachment> clearAttachments;
793     uint32_t colorAttIdx = 0u;
794     for (const auto &att : m_testParams.attachments)
795     {
796         if (att.init & ATTACHMENT_INIT_CMD_CLEAR)
797         {
798             if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
799             {
800                 VkImageAspectFlags aspectMask = 0;
801                 if (att.usage & ATTACHMENT_USAGE_DEPTH)
802                     aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
803                 if (att.usage & ATTACHMENT_USAGE_STENCIL)
804                     aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
805                 clearAttachments.push_back({aspectMask, 0u, makeClearValueDepthStencil(0.25, 64)});
806             }
807             else
808             {
809                 clearAttachments.push_back(
810                     {VK_IMAGE_ASPECT_COLOR_BIT, colorAttIdx++, makeClearValueColorF32(0.0f, 0.0f, 0.5f, 1.0f)});
811             }
812         }
813     }
814     if (!clearAttachments.empty())
815         vk.cmdClearAttachments(cmdBuffer, (uint32_t)clearAttachments.size(), clearAttachments.data(), 1u, &rect);
816 
817     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
818 
819     uint32_t descriptorSetIdx = 0u;
820     uint32_t vertexOffset     = 0u;
821     for (size_t i = 0; i < m_testParams.subpasses.size(); i++)
822     {
823         if (i != 0)
824         {
825             if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
826             {
827                 // if more subpasses are ever needed code should be adjusted
828                 DE_ASSERT(m_testParams.subpasses.size() < 3);
829 
830                 // barier before next subpass
831                 VkMemoryBarrier memoryBarrier =
832                     makeMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
833                 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
834                                       VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1u,
835                                       &memoryBarrier, 0u, DE_NULL, 0u, DE_NULL);
836 
837                 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo     = initVulkanStructure();
838                 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
839                 std::vector<uint32_t> colorAttachmentLocations(m_testParams.attachments.size(), VK_ATTACHMENT_UNUSED);
840                 std::vector<uint32_t> colorAttachmentInputs(m_testParams.attachments.size(), VK_ATTACHMENT_UNUSED);
841                 const auto &subpass    = m_testParams.subpasses[1];
842                 uint32_t locationIndex = 0u;
843                 uint32_t inputIndex    = 0u;
844 
845                 // remap color attachment locations and input attachment indices
846                 for (uint32_t attIdx = 0; attIdx < (uint32_t)subpass.attachmentRefs.size(); ++attIdx)
847                 {
848                     if (subpass.attachmentRefs[attIdx].usage == ATTACHMENT_USAGE_COLOR)
849                         colorAttachmentLocations[attIdx] = locationIndex++;
850                     else if (subpass.attachmentRefs[attIdx].usage == ATTACHMENT_USAGE_INPUT)
851                         colorAttachmentInputs[attIdx] = inputIndex++;
852                 }
853 
854                 renderingAttachmentLocationInfo.colorAttachmentCount      = (uint32_t)colorAttachmentLocations.size();
855                 renderingAttachmentLocationInfo.pColorAttachmentLocations = colorAttachmentLocations.data();
856                 renderingInputAttachmentIndexInfo.colorAttachmentCount    = (uint32_t)colorAttachmentInputs.size();
857                 renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices = colorAttachmentInputs.data();
858 
859                 vk.cmdSetRenderingAttachmentLocationsKHR(cmdBuffer, &renderingAttachmentLocationInfo);
860                 vk.cmdSetRenderingInputAttachmentIndicesKHR(cmdBuffer, &renderingInputAttachmentIndexInfo);
861             }
862             else
863                 vk.cmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
864         }
865 
866         vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[i].getPipeline());
867 
868         bool hasInput = false;
869         for (const auto &ref : m_testParams.subpasses[i].attachmentRefs)
870             if (ref.usage & ATTACHMENT_USAGE_INPUT)
871                 hasInput = true;
872 
873         if (hasInput)
874             vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayouts[i], 0, 1,
875                                      &descriptorSets[descriptorSetIdx++].get(), 0, DE_NULL);
876 
877         for (uint32_t d = 0; d < m_testParams.subpasses[i].numDraws; d++)
878         {
879             vk.cmdDraw(cmdBuffer, 6u, 1, vertexOffset, 0);
880             vertexOffset += 6u;
881         }
882     }
883 }
884 
iterate(void)885 tcu::TestStatus LoadStoreOpNoneTestInstance::iterate(void)
886 {
887     const DeviceInterface &vk       = m_context.getDeviceInterface();
888     const VkDevice vkDevice         = m_context.getDevice();
889     const VkQueue queue             = m_context.getUniversalQueue();
890     const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
891     SimpleAllocator memAlloc(
892         vk, vkDevice,
893         getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
894     const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
895                                                      VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
896     const bool isDynamicRendering = (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
897     bool depthIsUndefined         = false;
898     bool stencilIsUndefined       = false;
899 
900     std::vector<Move<VkImage>> attachmentImages;
901     std::vector<de::MovePtr<Allocation>> attachmentImageAllocs;
902     std::vector<Move<VkImageView>> imageViews;
903     std::vector<GraphicsPipelineWrapper> pipelines;
904 
905     for (const auto &att : m_testParams.attachments)
906     {
907         VkFormat format         = getFormat(att.usage, m_testParams.depthStencilFormat);
908         VkImageUsageFlags usage = 0;
909         VkImageAspectFlags aspectFlags;
910 
911         if (!att.verifyAspects.empty())
912             usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
913         if (att.init & ATTACHMENT_INIT_PRE)
914             usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
915 
916         if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
917         {
918             aspectFlags = getImageAspectFlags(mapVkFormat(format));
919             usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
920 
921             // If depth or stencil load op is NONE, "the previous contents of the image will be undefined inside the render pass. No
922             // access type is used as the image is not accessed."
923             if (att.loadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
924                 depthIsUndefined = true;
925 
926             if (att.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
927                 stencilIsUndefined = true;
928         }
929         else
930         {
931             // Color and input attachments.
932             aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
933 
934             if (att.usage & ATTACHMENT_USAGE_COLOR)
935                 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
936             if (att.usage & ATTACHMENT_USAGE_INPUT)
937                 usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
938         }
939 
940         const VkSampleCountFlagBits sampleCount =
941             att.usage & ATTACHMENT_USAGE_MULTISAMPLE ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
942 
943         const VkImageCreateInfo imageParams = {
944             VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,    // VkStructureType            sType
945             DE_NULL,                                // const void*                pNext
946             0u,                                     // VkImageCreateFlags        flags
947             VK_IMAGE_TYPE_2D,                       // VkImageType                imageType
948             format,                                 // VkFormat                    format
949             {m_imageSize.x(), m_imageSize.y(), 1u}, // VkExtent3D                extent
950             1u,                                     // uint32_t                    mipLevels
951             1u,                                     // uint32_t                    arrayLayers
952             sampleCount,                            // VkSampleCountFlagBits    samples
953             VK_IMAGE_TILING_OPTIMAL,                // VkImageTiling            tiling
954             usage,                                  // VkImageUsageFlags        usage
955             VK_SHARING_MODE_EXCLUSIVE,              // VkSharingMode            sharingMode
956             1u,                                     // uint32_t                    queueFamilyIndexCount
957             &queueFamilyIndex,                      // const uint32_t*            pQueueFamilyIndices
958             VK_IMAGE_LAYOUT_UNDEFINED               // VkImageLayout            initialLayout
959         };
960 
961         attachmentImages.push_back(createImage(vk, vkDevice, &imageParams));
962 
963         // Allocate and bind image memory.
964         attachmentImageAllocs.push_back(memAlloc.allocate(
965             getImageMemoryRequirements(vk, vkDevice, *attachmentImages.back()), MemoryRequirement::Any));
966         VK_CHECK(vk.bindImageMemory(vkDevice, *attachmentImages.back(), attachmentImageAllocs.back()->getMemory(),
967                                     attachmentImageAllocs.back()->getOffset()));
968 
969         // Create image view.
970         const VkImageViewCreateInfo imageViewParams = {
971             VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType            sType
972             DE_NULL,                                  // const void*                pNext
973             0u,                                       // VkImageViewCreateFlags    flags
974             *attachmentImages.back(),                 // VkImage                    image
975             VK_IMAGE_VIEW_TYPE_2D,                    // VkImageViewType            viewType
976             format,                                   // VkFormat                    format
977             componentMappingRGBA,                     // VkChannelMapping            channels
978             {aspectFlags, 0u, 1u, 0u, 1u}             // VkImageSubresourceRange    subresourceRange
979         };
980 
981         imageViews.push_back(createImageView(vk, vkDevice, &imageViewParams));
982 
983         if (att.init & ATTACHMENT_INIT_PRE)
984         {
985             // Preinitialize image
986             uint32_t attachmentIdx = (uint32_t)attachmentImages.size() - 1;
987             uint32_t firstUsage    = getFirstUsage(attachmentIdx, m_testParams.subpasses);
988             if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
989                 firstUsage = att.usage;
990 
991             if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
992             {
993                 const auto dstAccess =
994                     (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
995                 const auto dstStage =
996                     (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
997 
998                 clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), format, 0.5f,
999                                        128u, VK_IMAGE_LAYOUT_UNDEFINED,
1000                                        VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, dstAccess, dstStage);
1001             }
1002             else
1003             {
1004                 const auto dstAccess = (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
1005                                         VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
1006                 const auto dstStage =
1007                     (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1008                 const auto clearColor =
1009                     ((att.usage & ATTACHMENT_USAGE_INTEGER) ? makeClearValueColorU32(0u, 255u, 0u, 255u).color :
1010                                                               makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f).color);
1011                 auto layout = ((firstUsage & ATTACHMENT_USAGE_COLOR) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
1012                                                                        VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1013 
1014                 if (isDynamicRendering && (m_testParams.attachments[attachmentIdx].usage & ATTACHMENT_USAGE_INPUT))
1015                     layout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
1016 
1017                 clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), clearColor,
1018                                 VK_IMAGE_LAYOUT_UNDEFINED, layout, dstAccess, dstStage);
1019             }
1020         }
1021     }
1022 
1023     if (!isDynamicRendering)
1024     {
1025         // Create render pass.
1026         if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1027             m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1,
1028                                             SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, m_testParams);
1029         else
1030             m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2,
1031                                             SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, m_testParams);
1032 
1033         std::vector<VkImageView> views;
1034         for (const auto &view : imageViews)
1035             views.push_back(*view);
1036 
1037         // Create framebuffer.
1038         const VkFramebufferCreateInfo framebufferParams = {
1039             VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType            sType
1040             DE_NULL,                                   // const void*                pNext
1041             0u,                                        // VkFramebufferCreateFlags    flags
1042             *m_renderPass,                             // VkRenderPass                renderPass
1043             (uint32_t)views.size(),                    // uint32_t                    attachmentCount
1044             views.data(),                              // const VkImageView*        pAttachments
1045             (uint32_t)m_imageSize.x(),                 // uint32_t                    width
1046             (uint32_t)m_imageSize.y(),                 // uint32_t                    height
1047             1u                                         // uint32_t                    layers
1048         };
1049 
1050         m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1051     }
1052 
1053     // Create shader modules
1054     ShaderWrapper vertexShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
1055     ShaderWrapper fragmentShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
1056     ShaderWrapper fragmentShaderModuleUint(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_uint"), 0);
1057     ShaderWrapper fragmentShaderModuleBlend(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_blend"), 0);
1058     ShaderWrapper fragmentShaderModuleInput(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_input"), 0);
1059 
1060     // Create descriptor pool. Prepare for using one input attachment at most.
1061     {
1062         const VkDescriptorPoolSize descriptorPoolSize = {
1063             VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType        type
1064             1u                                   // uint32_t                descriptorCount
1065         };
1066 
1067         const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
1068             VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,     // VkStructureType                sType
1069             DE_NULL,                                           // const void*                    pNext
1070             VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags    flags
1071             1u,                                                // uint32_t                        maxSets
1072             1u,                                                // uint32_t                        poolSizeCount
1073             &descriptorPoolSize                                // const VkDescriptorPoolSize*    pPoolSizes
1074         };
1075 
1076         m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
1077     }
1078 
1079     const auto subpassCount = (uint32_t)m_testParams.subpasses.size();
1080     std::vector<Move<VkDescriptorSetLayout>> descriptorSetLayouts;
1081     std::vector<Move<VkDescriptorSet>> descriptorSets;
1082     std::vector<PipelineLayoutWrapper> pipelineLayouts(subpassCount);
1083 
1084     for (uint32_t subpassIdx = 0; subpassIdx < subpassCount; ++subpassIdx)
1085     {
1086         const auto &subpass          = m_testParams.subpasses[subpassIdx];
1087         uint32_t numInputAttachments = 0u;
1088         bool noColorWrite            = false;
1089         bool depthTest               = false;
1090         bool stencilTest             = false;
1091         bool depthWrite              = true;
1092         bool stencilWrite            = true;
1093         bool multisample             = false;
1094         bool uintColorBuffer         = false;
1095         VkCompareOp depthCompareOp   = VK_COMPARE_OP_GREATER;
1096         VkCompareOp stencilCompareOp = VK_COMPARE_OP_GREATER;
1097 
1098         // Create pipeline layout.
1099         {
1100             std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
1101 
1102             for (const auto ref : subpass.attachmentRefs)
1103             {
1104                 if (ref.usage & ATTACHMENT_USAGE_INPUT)
1105                 {
1106                     const VkDescriptorSetLayoutBinding layoutBinding = {
1107                         0u,                                  // uint32_t                binding
1108                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType        descriptorType
1109                         1u,                                  // uint32_t                descriptorCount
1110                         VK_SHADER_STAGE_FRAGMENT_BIT,        // VkShaderStageFlags    stageFlags
1111                         DE_NULL                              // const VkSampler*        pImmutableSamplers
1112                     };
1113 
1114                     layoutBindings.push_back(layoutBinding);
1115                     numInputAttachments++;
1116                 }
1117                 if (ref.usage & ATTACHMENT_USAGE_COLOR)
1118                 {
1119                     if (ref.usage & ATTACHMENT_USAGE_COLOR_WRITE_OFF)
1120                         noColorWrite = true;
1121                 }
1122                 if (ref.usage & ATTACHMENT_USAGE_DEPTH)
1123                 {
1124                     if (!(ref.usage & ATTACHMENT_USAGE_DEPTH_TEST_OFF))
1125                         depthTest = true;
1126                     if (ref.usage & ATTACHMENT_USAGE_DEPTH_WRITE_OFF)
1127                         depthWrite = false;
1128 
1129                     // Enabling depth testing with undefined depth buffer contents. Let's make sure
1130                     // all samples pass the depth test.
1131                     if (depthIsUndefined && depthTest)
1132                         depthCompareOp = VK_COMPARE_OP_ALWAYS;
1133                 }
1134                 if (ref.usage & ATTACHMENT_USAGE_STENCIL)
1135                 {
1136                     if (!(ref.usage & ATTACHMENT_USAGE_STENCIL_TEST_OFF))
1137                         stencilTest = true;
1138                     if (ref.usage & ATTACHMENT_USAGE_STENCIL_WRITE_OFF)
1139                         stencilWrite = false;
1140 
1141                     if (stencilIsUndefined && stencilTest)
1142                         stencilCompareOp = VK_COMPARE_OP_ALWAYS;
1143                 }
1144                 if (ref.usage & ATTACHMENT_USAGE_MULTISAMPLE)
1145                 {
1146                     multisample = true;
1147                 }
1148                 if (ref.usage & ATTACHMENT_USAGE_INTEGER)
1149                 {
1150                     uintColorBuffer = true;
1151                 }
1152             }
1153 
1154             const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams = {
1155                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType                        sType
1156                 DE_NULL,                                             // const void*                            pNext
1157                 0u,                                                  // VkDescriptorSetLayoutCreateFlags        flags
1158                 (uint32_t)layoutBindings.size(), // uint32_t                                bindingCount
1159                 layoutBindings.empty() ? DE_NULL :
1160                                          layoutBindings.data() // const VkDescriptorSetLayoutBinding*    pBindings
1161             };
1162             descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams));
1163             pipelineLayouts[subpassIdx] = PipelineLayoutWrapper(m_testParams.groupParams->pipelineConstructionType, vk,
1164                                                                 vkDevice, *descriptorSetLayouts.back());
1165         }
1166 
1167         // Update descriptor set if needed.
1168         if (numInputAttachments > 0u)
1169         {
1170             VkImageLayout inputImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1171             if (isDynamicRendering)
1172                 inputImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
1173 
1174             // Assuming there's only one input attachment at most.
1175             DE_ASSERT(numInputAttachments == 1u);
1176 
1177             const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
1178                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                sType
1179                 DE_NULL,                                        // const void*                    pNext
1180                 *m_descriptorPool,                              // VkDescriptorPool                descriptorPool
1181                 1u,                                             // uint32_t                        descriptorSetCount
1182                 &descriptorSetLayouts.back().get(),             // const VkDescriptorSetLayout*    pSetLayouts
1183             };
1184 
1185             descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo));
1186 
1187             for (size_t i = 0; i < imageViews.size(); i++)
1188             {
1189                 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
1190                 {
1191                     const VkDescriptorImageInfo inputImageInfo{
1192                         DE_NULL,         // VkSampler        sampler
1193                         *imageViews[i],  // VkImageView        imageView
1194                         inputImageLayout // VkImageLayout    imageLayout
1195                     };
1196 
1197                     const VkWriteDescriptorSet descriptorWrite = {
1198                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                    sType
1199                         DE_NULL,                                // const void*                        pNext
1200                         *descriptorSets.back(),                 // VkDescriptorSet                    dstSet
1201                         0u,                                     // uint32_t                            dstBinding
1202                         0u,                                     // uint32_t                            dstArrayElement
1203                         1u,                                     // uint32_t                            descriptorCount
1204                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType                    descriptorType
1205                         &inputImageInfo,                        // const VkDescriptorImageInfo*        pImageInfo
1206                         DE_NULL,                                // const VkDescriptorBufferInfo*    pBufferInfo
1207                         DE_NULL                                 // const VkBufferView*                pTexelBufferView
1208                     };
1209                     vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
1210                 }
1211             }
1212         }
1213 
1214         // Create pipeline.
1215         {
1216             const VkVertexInputBindingDescription vertexInputBindingDescription = {
1217                 0u,                            // uint32_t                    binding
1218                 (uint32_t)sizeof(Vertex4RGBA), // uint32_t                    strideInBytes
1219                 VK_VERTEX_INPUT_RATE_VERTEX    // VkVertexInputStepRate    inputRate
1220             };
1221 
1222             const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = {
1223                 {
1224                     0u,                            // uint32_t    location
1225                     0u,                            // uint32_t    binding
1226                     VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat    format
1227                     0u                             // uint32_t    offset
1228                 },
1229                 {
1230                     1u,                            // uint32_t    location
1231                     0u,                            // uint32_t    binding
1232                     VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat    format
1233                     (uint32_t)(sizeof(float) * 4), // uint32_t    offset
1234                 }};
1235 
1236             const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1237                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                            sType
1238                 DE_NULL, // const void*                                pNext
1239                 0u,      // VkPipelineVertexInputStateCreateFlags    flags
1240                 1u,      // uint32_t                                    vertexBindingDescriptionCount
1241                 &vertexInputBindingDescription, // const VkVertexInputBindingDescription*    pVertexBindingDescriptions
1242                 2u, // uint32_t                                    vertexAttributeDescriptionCount
1243                 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
1244             };
1245 
1246             const VkColorComponentFlags writeMask =
1247                 noColorWrite ? 0 :
1248                                VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags    colorWriteMask
1249                                    | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1250 
1251             VkPipelineRenderingCreateInfoKHR renderingCreateInfo = initVulkanStructure();
1252 
1253             std::vector<VkFormat> colorVector;
1254             for (const auto &att : m_testParams.attachments)
1255             {
1256                 VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat);
1257 
1258                 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
1259                 {
1260                     const auto tcuFormat                      = mapVkFormat(format);
1261                     const auto hasDepth                       = tcu::hasDepthComponent(tcuFormat.order);
1262                     const auto hasStencil                     = tcu::hasStencilComponent(tcuFormat.order);
1263                     const auto useDepth                       = att.usage & ATTACHMENT_USAGE_DEPTH;
1264                     const auto useStencil                     = att.usage & ATTACHMENT_USAGE_STENCIL;
1265                     renderingCreateInfo.depthAttachmentFormat = (hasDepth && useDepth ? format : VK_FORMAT_UNDEFINED);
1266                     renderingCreateInfo.stencilAttachmentFormat =
1267                         (hasStencil && useStencil ? format : VK_FORMAT_UNDEFINED);
1268                 }
1269                 else if (!(att.usage & ATTACHMENT_USAGE_RESOLVE_TARGET))
1270                 {
1271                     colorVector.push_back(format);
1272                 }
1273             }
1274 
1275             uint32_t attachmentCount = (*m_renderPass == DE_NULL) ? static_cast<uint32_t>(colorVector.size()) : 1u;
1276             std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
1277                 attachmentCount,
1278                 {
1279                     false,                               // VkBool32                    blendEnable
1280                     VK_BLEND_FACTOR_SRC_ALPHA,           // VkBlendFactor            srcColorBlendFactor
1281                     VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor            dstColorBlendFactor
1282                     VK_BLEND_OP_ADD,                     // VkBlendOp                colorBlendOp
1283                     VK_BLEND_FACTOR_ONE,                 // VkBlendFactor            srcAlphaBlendFactor
1284                     VK_BLEND_FACTOR_ZERO,                // VkBlendFactor            dstAlphaBlendFactor
1285                     VK_BLEND_OP_ADD,                     // VkBlendOp                alphaBlendOp
1286                     writeMask                            // VkColorComponentFlags    colorWriteMask
1287                 });
1288 
1289             if (m_testParams.alphaBlend)
1290             {
1291                 uint32_t attachmentIndex = (*m_renderPass == DE_NULL) ? (uint32_t)pipelines.size() : 0u;
1292                 colorBlendAttachmentState[attachmentIndex].blendEnable = true;
1293             }
1294 
1295             const VkPipelineColorBlendStateCreateInfo colorBlendStateParams{
1296                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType                                sType
1297                 DE_NULL,                          // const void*                                    pNext
1298                 0u,                               // VkPipelineColorBlendStateCreateFlags            flags
1299                 VK_FALSE,                         // VkBool32                                        logicOpEnable
1300                 VK_LOGIC_OP_CLEAR,                // VkLogicOp                                    logicOp
1301                 attachmentCount,                  // uint32_t                                        attachmentCount
1302                 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState*    pAttachments
1303                 {0.0f, 0.0f, 0.0f, 0.0f}          // float                                        blendConstants[4]
1304             };
1305 
1306             const VkStencilOpState stencilOpState = {
1307                 VK_STENCIL_OP_KEEP,                                        // VkStencilOp    failOp
1308                 stencilWrite ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP, // VkStencilOp    passOp
1309                 VK_STENCIL_OP_KEEP,                                        // VkStencilOp    depthFailOp
1310                 stencilCompareOp,                                          // VkCompareOp    compareOp
1311                 0xff,                                                      // uint32_t        compareMask
1312                 0xff,                                                      // uint32_t        writeMask
1313                 0xff                                                       // uint32_t        reference
1314             };
1315 
1316             const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = {
1317                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType                            sType
1318                 DE_NULL,                         // const void*                                pNext
1319                 0u,                              // VkPipelineDepthStencilStateCreateFlags    flags
1320                 depthTest,                       // VkBool32                                    depthTestEnable
1321                 depthWrite ? VK_TRUE : VK_FALSE, // VkBool32                                    depthWriteEnable
1322                 depthCompareOp,                  // VkCompareOp                                depthCompareOp
1323                 VK_FALSE,                        // VkBool32                                    depthBoundsTestEnable
1324                 stencilTest,                     // VkBool32                                    stencilTestEnable
1325                 stencilOpState,                  // VkStencilOpState                            front
1326                 stencilOpState,                  // VkStencilOpState                            back
1327                 0.0f,                            // float                                    minDepthBounds
1328                 1.0f,                            // float                                    maxDepthBounds
1329             };
1330 
1331             const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
1332                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType                            sType
1333                 DE_NULL, // const void*                                pNext
1334                 0u,      // VkPipelineMultisampleStateCreateFlags    flags
1335                 multisample ? VK_SAMPLE_COUNT_4_BIT :
1336                               VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits                    rasterizationSamples
1337                 VK_FALSE,                            // VkBool32                                    sampleShadingEnable
1338                 1.0f,                                // float                                    minSampleShading
1339                 DE_NULL,                             // const VkSampleMask*                        pSampleMask
1340                 VK_FALSE, // VkBool32                                    alphaToCoverageEnable
1341                 VK_FALSE  // VkBool32                                    alphaToOneEnable
1342             };
1343 
1344             const std::vector<VkViewport> viewports(1, makeViewport(m_imageSize));
1345             const std::vector<VkRect2D> scissors(1, makeRect2D(m_renderSize));
1346             ShaderWrapper *fragShader = &fragmentShaderModule;
1347 
1348             if (numInputAttachments > 0u)
1349                 fragShader = &fragmentShaderModuleInput;
1350             else if (uintColorBuffer)
1351                 fragShader = &fragmentShaderModuleUint;
1352             else if (m_testParams.alphaBlend)
1353                 fragShader = &fragmentShaderModuleBlend;
1354 
1355             VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo     = initVulkanStructure();
1356             VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
1357             PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
1358             RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfoWrapper;
1359             RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
1360             std::vector<uint32_t> colorAttachmentLocations(colorVector.size(), VK_ATTACHMENT_UNUSED);
1361             std::vector<uint32_t> colorAttachmentInputs(colorVector.size(), VK_ATTACHMENT_UNUSED);
1362 
1363             if (isDynamicRendering)
1364             {
1365                 renderingCreateInfo.colorAttachmentCount    = static_cast<uint32_t>(colorVector.size());
1366                 renderingCreateInfo.pColorAttachmentFormats = colorVector.data();
1367                 renderingCreateInfoWrapper.ptr              = &renderingCreateInfo;
1368 
1369                 if (numInputAttachments > 0u)
1370                 {
1371                     uint32_t locationIndex = 0u;
1372                     uint32_t inputIndex    = 0u;
1373                     for (uint32_t i = 0; i < (uint32_t)subpass.attachmentRefs.size(); ++i)
1374                     {
1375                         if (subpass.attachmentRefs[i].usage == ATTACHMENT_USAGE_COLOR)
1376                             colorAttachmentLocations[i] = locationIndex++;
1377                         else if (subpass.attachmentRefs[i].usage == ATTACHMENT_USAGE_INPUT)
1378                             colorAttachmentInputs[i] = inputIndex++;
1379                     }
1380 
1381                     renderingAttachmentLocationInfo.colorAttachmentCount = renderingCreateInfo.colorAttachmentCount;
1382                     renderingAttachmentLocationInfo.pColorAttachmentLocations = colorAttachmentLocations.data();
1383                     renderingAttachmentLocationInfoWrapper.ptr                = &renderingAttachmentLocationInfo;
1384                     renderingInputAttachmentIndexInfo.colorAttachmentCount = renderingCreateInfo.colorAttachmentCount;
1385                     renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices = colorAttachmentInputs.data();
1386                     renderingInputAttachmentIndexInfoWrapper.ptr                   = &renderingInputAttachmentIndexInfo;
1387                 }
1388             }
1389 
1390             const auto &pipelineLayout = pipelineLayouts[subpassIdx];
1391             pipelines.emplace_back(m_context.getInstanceInterface(), vk, m_context.getPhysicalDevice(), vkDevice,
1392                                    m_context.getDeviceExtensions(), m_testParams.groupParams->pipelineConstructionType);
1393             pipelines.back()
1394                 .setDefaultRasterizationState()
1395                 .setupVertexInputState(&vertexInputStateParams)
1396                 .setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *m_renderPass, subpassIdx,
1397                                                   vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(),
1398                                                   ShaderWrapper(), DE_NULL, DE_NULL, renderingCreateInfoWrapper)
1399                 .setupFragmentShaderState(pipelineLayout, *m_renderPass, subpassIdx, *fragShader,
1400                                           &depthStencilStateParams, &multisampleStateParams, 0, 0, {},
1401                                           renderingInputAttachmentIndexInfoWrapper)
1402                 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams, &multisampleStateParams, 0,
1403                                           {}, renderingAttachmentLocationInfoWrapper)
1404                 .setMonolithicPipelineLayout(pipelineLayout)
1405                 .buildPipeline();
1406         }
1407     }
1408 
1409     // Create vertex buffer.
1410     {
1411         const VkBufferCreateInfo vertexBufferParams = {
1412             VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                    // VkStructureType        sType
1413             DE_NULL,                                                 // const void*            pNext
1414             0u,                                                      // VkBufferCreateFlags    flags
1415             (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize            size
1416             VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                       // VkBufferUsageFlags    usage
1417             VK_SHARING_MODE_EXCLUSIVE,                               // VkSharingMode        sharingMode
1418             1u,                                                      // uint32_t                queueFamilyIndexCount
1419             &queueFamilyIndex                                        // const uint32_t*        pQueueFamilyIndices
1420         };
1421 
1422         m_vertexBuffer      = createBuffer(vk, vkDevice, &vertexBufferParams);
1423         m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer),
1424                                                 MemoryRequirement::HostVisible);
1425 
1426         VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
1427                                      m_vertexBufferAlloc->getOffset()));
1428 
1429         // Upload vertex data.
1430         deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1431         flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1432     }
1433 
1434     // Create command pool.
1435     m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1436 
1437     // Create command buffer.
1438     if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1439         createCommandBuffer<RenderpassSubpass1>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1440     else if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
1441         createCommandBuffer<RenderpassSubpass2>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1442     else
1443         createCommandBuffer(vk, vkDevice, imageViews, descriptorSets, pipelineLayouts, pipelines);
1444 
1445     // Submit commands.
1446     submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1447 
1448     bool pass = true;
1449 
1450     // Verify selected attachments.
1451     for (size_t i = 0; i < m_testParams.attachments.size(); i++)
1452     {
1453         bool transitioned = false;
1454         for (const auto &verify : m_testParams.attachments[i].verifyAspects)
1455         {
1456             de::MovePtr<tcu::TextureLevel> textureLevelResult;
1457 
1458             SimpleAllocator allocator(
1459                 vk, vkDevice,
1460                 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1461             VkFormat format = getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat);
1462 
1463             if (verify.aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
1464             {
1465                 VkImageLayout layout = (isDynamicRendering && !transitioned) ?
1466                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1467                                            VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1468                 textureLevelResult   = pipeline::readDepthAttachment(
1469                     vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i],
1470                     m_testParams.depthStencilFormat, m_imageSize, layout);
1471                 transitioned = true;
1472             }
1473             else if (verify.aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
1474             {
1475                 VkImageLayout layout = (isDynamicRendering && !transitioned) ?
1476                                            VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1477                                            VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1478                 textureLevelResult   = pipeline::readStencilAttachment(
1479                     vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i],
1480                     m_testParams.depthStencilFormat, m_imageSize, layout);
1481                 transitioned = true;
1482             }
1483             else
1484             {
1485                 DE_ASSERT(verify.aspect == VK_IMAGE_ASPECT_COLOR_BIT);
1486                 VkImageLayout layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1487                 if (isDynamicRendering && !transitioned)
1488                     layout = (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT) ?
1489                                  VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR :
1490                                  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1491                 textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator,
1492                                                                    *attachmentImages[i], format, m_imageSize, layout);
1493                 transitioned       = true;
1494             }
1495 
1496             const tcu::ConstPixelBufferAccess &access = textureLevelResult->getAccess();
1497 
1498             // Log attachment contents
1499             m_context.getTestContext().getLog()
1500                 << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "")
1501                 << tcu::TestLog::Image("Attachment " + de::toString(i), "", access) << tcu::TestLog::EndImageSet;
1502 
1503             for (int y = 0; y < access.getHeight(); y++)
1504                 for (int x = 0; x < access.getWidth(); x++)
1505                 {
1506                     const bool inner = x < (int)m_renderSize.x() && y < (int)m_renderSize.y();
1507 
1508                     if (inner && !verify.verifyInner)
1509                         continue;
1510                     if (!inner && !verify.verifyOuter)
1511                         continue;
1512 
1513                     const tcu::Vec4 ref = inner ? verify.innerRef : verify.outerRef;
1514                     const tcu::Vec4 p   = access.getPixel(x, y);
1515 
1516                     for (int c = 0; c < 4; c++)
1517                         if (fabs(p[c] - ref[c]) > 0.01f)
1518                             pass = false;
1519                 }
1520         }
1521     }
1522 
1523     if (pass)
1524         return tcu::TestStatus::pass("Pass");
1525     else
1526         return tcu::TestStatus::fail("Fail");
1527 }
1528 
1529 } // namespace
1530 
createRenderPassLoadStoreOpNoneTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1531 tcu::TestCaseGroup *createRenderPassLoadStoreOpNoneTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
1532 {
1533     de::MovePtr<tcu::TestCaseGroup> opNoneTests(new tcu::TestCaseGroup(testCtx, "load_store_op_none"));
1534 
1535     const tcu::Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
1536     const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
1537     const tcu::Vec4 magenta(1.0f, 0.0f, 1.0f, 1.0f);
1538     const tcu::Vec4 darkBlue(0.0f, 0.0f, 0.5f, 1.0f);
1539     const tcu::Vec4 blend(0.5f, 0.0f, 0.25f, 0.5f);
1540     const tcu::Vec4 depthInit(0.5f, 0.0f, 0.0f, 1.0f);
1541     const tcu::Vec4 depthFull(1.0f, 0.0f, 0.0f, 1.0f);
1542     const tcu::Vec4 stencilInit(128.0f, 0.0f, 0.0f, 1.0f);
1543     const tcu::Vec4 stencilFull(255.0f, 0.0f, 0.0f, 1.0f);
1544     const tcu::Vec4 redUint(255.0f, 0.0f, 0.0f, 255.0f);
1545     const tcu::Vec4 greenUint(0.0f, 255.0f, 0.0f, 255.0f);
1546 
1547     // Preinitialize attachments 0 and 1 to green.
1548     // Subpass 0: draw a red rectangle inside attachment 0.
1549     // Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to
1550     // attachment 1.
1551     // After the render pass attachment 0 has undefined values inside the render area because of the shader writes with
1552     // store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the
1553     // preinitialized green outside the render area and magenta inside.
1554     if (!groupParams->useSecondaryCmdBuffer)
1555     {
1556         TestParams params{
1557             {// std::vector<AttachmentParams> attachments;
1558              {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1559               VK_ATTACHMENT_LOAD_OP_LOAD,
1560               VK_ATTACHMENT_STORE_OP_NONE_EXT,
1561               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1562               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1563               ATTACHMENT_INIT_PRE,
1564               {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}},
1565              {ATTACHMENT_USAGE_COLOR,
1566               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1567               VK_ATTACHMENT_STORE_OP_STORE,
1568               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1569               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1570               ATTACHMENT_INIT_PRE,
1571               {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}}},
1572             {// std::vector<SubpassParams> subpasses;
1573              {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1574              {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1575             groupParams,         // const SharedGroupParams groupParams;
1576             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1577             false,               // bool alphaBlend;
1578             ExtensionPreference::KHR,
1579         };
1580 
1581         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", params));
1582     }
1583 
1584     // Preinitialize color attachment to green. Use a render pass with load and store ops none, but
1585     // disable color writes using an empty color mask. The color attachment image should have the original
1586     // preinitialized value after the render pass.
1587     if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1588     {
1589         TestParams params{
1590             {// std::vector<AttachmentParams> attachments;
1591              {ATTACHMENT_USAGE_COLOR,
1592               VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1593               VK_ATTACHMENT_STORE_OP_NONE_EXT,
1594               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1595               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1596               ATTACHMENT_INIT_PRE,
1597               {{VK_IMAGE_ASPECT_COLOR_BIT, true, green, true, green}}}},
1598             {// std::vector<SubpassParams> subpasses;
1599              {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_COLOR_WRITE_OFF}}, 1u}},
1600             groupParams,         // const SharedGroupParams groupParams;
1601             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1602             false,               // bool alphaBlend;
1603             ExtensionPreference::EXT,
1604         };
1605 
1606         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", params));
1607     }
1608 
1609     // Preinitialize color attachment to green. Use a render pass with load and store ops none, and
1610     // write a rectangle to the color buffer. The render area is undefined, but the outside area should
1611     // still have the preinitialized color.
1612     if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1613     {
1614         TestParams params{
1615             {// std::vector<AttachmentParams> attachments;
1616              {ATTACHMENT_USAGE_COLOR,
1617               VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1618               VK_ATTACHMENT_STORE_OP_NONE_EXT,
1619               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1620               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1621               ATTACHMENT_INIT_PRE,
1622               {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}}},
1623             {// std::vector<SubpassParams> subpasses;
1624              {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1625             groupParams,         // const SharedGroupParams groupParams;
1626             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1627             false,               // bool alphaBlend;
1628             ExtensionPreference::KHR,
1629         };
1630 
1631         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", params));
1632     }
1633 
1634     // Preinitialize color attachment to green. Use a subpass with no draw calls but instead
1635     // do an attachment clear command using dark blue color. Using load op none preserves the preinitialized
1636     // data and store op store causes the cleared blue render area to be present after the render pass.
1637     if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1638     {
1639         TestParams params{
1640             {// std::vector<AttachmentParams> attachments;
1641              {ATTACHMENT_USAGE_COLOR,
1642               VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1643               VK_ATTACHMENT_STORE_OP_STORE,
1644               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1645               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1646               ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1647               {{VK_IMAGE_ASPECT_COLOR_BIT, true, darkBlue, true, green}}}},
1648             {// std::vector<SubpassParams> subpasses;
1649              {{{0u, ATTACHMENT_USAGE_COLOR}}, 0u}},
1650             groupParams,         // const SharedGroupParams groupParams;
1651             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1652             false,               // bool alphaBlend;
1653             ExtensionPreference::EXT,
1654         };
1655 
1656         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", params));
1657     }
1658 
1659     // Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed
1660     // by an alpha blender draw. Load op none preserves the preinitialized data and store op store
1661     // keeps the blended color inside the render area after the render pass.
1662     if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1663     {
1664         TestParams params{
1665             {// std::vector<AttachmentParams> attachments;
1666              {ATTACHMENT_USAGE_COLOR,
1667               VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1668               VK_ATTACHMENT_STORE_OP_STORE,
1669               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1670               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1671               ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1672               {{VK_IMAGE_ASPECT_COLOR_BIT, true, blend, true, green}}}},
1673             {// std::vector<SubpassParams> subpasses;
1674              {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1675             groupParams,         // const SharedGroupParams groupParams;
1676             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1677             true,                // bool alphaBlend;
1678             ExtensionPreference::KHR,
1679         };
1680 
1681         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", params));
1682     }
1683 
1684     // Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined  because load op 'none'.
1685     // Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values.
1686     // Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1.
1687     // After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care',
1688     // but the outside area should still have the preinitialized content.
1689     // Attachment 1 should have the preinitialized green outside render area and magenta inside.
1690     if (!groupParams->useSecondaryCmdBuffer)
1691     {
1692         TestParams params{
1693             {// std::vector<AttachmentParams> attachments;
1694              {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1695               VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1696               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1697               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1698               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1699               ATTACHMENT_INIT_PRE,
1700               {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}},
1701              {ATTACHMENT_USAGE_COLOR,
1702               VK_ATTACHMENT_LOAD_OP_LOAD,
1703               VK_ATTACHMENT_STORE_OP_STORE,
1704               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1705               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1706               ATTACHMENT_INIT_PRE,
1707               {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}}},
1708             {// std::vector<SubpassParams> subpasses;
1709              {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1710              {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1711             groupParams,         // const SharedGroupParams groupParams;
1712             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1713             false,               // bool alphaBlend;
1714             ExtensionPreference::EXT,
1715         };
1716 
1717         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", params));
1718     }
1719 
1720     // Preinitialize color attachment to green. Use a render pass with load and store ops none for a multisample color
1721     // target. Write a red rectangle and check it ends up in the resolved buffer even though the multisample attachment
1722     // doesn't store the results.
1723     if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1724     {
1725         TestParams params{
1726             {// std::vector<AttachmentParams> attachments;
1727              {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER,
1728               VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1729               VK_ATTACHMENT_STORE_OP_NONE_EXT,
1730               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1731               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1732               ATTACHMENT_INIT_PRE,
1733               {}},
1734              {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET | ATTACHMENT_USAGE_INTEGER,
1735               VK_ATTACHMENT_LOAD_OP_LOAD,
1736               VK_ATTACHMENT_STORE_OP_STORE,
1737               VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1738               VK_ATTACHMENT_STORE_OP_DONT_CARE,
1739               ATTACHMENT_INIT_PRE,
1740               {{VK_IMAGE_ASPECT_COLOR_BIT, true, redUint, true, greenUint}}}},
1741             {// std::vector<SubpassParams> subpasses;
1742              {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER},
1743                {1u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET}},
1744               1u}},
1745             groupParams,         // const SharedGroupParams groupParams;
1746             VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1747             false,               // bool alphaBlend;
1748             ExtensionPreference::KHR,
1749         };
1750 
1751         opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_resolve", params));
1752     }
1753 
1754     if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1755     {
1756         std::vector<VkFormat> formats = {VK_FORMAT_D16_UNORM,          VK_FORMAT_D32_SFLOAT,
1757                                          VK_FORMAT_D16_UNORM_S8_UINT,  VK_FORMAT_D24_UNORM_S8_UINT,
1758                                          VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_S8_UINT};
1759 
1760         for (uint32_t f = 0; f < formats.size(); ++f)
1761         {
1762             const auto tcuFormat         = mapVkFormat(formats[f]);
1763             const bool hasDepth          = tcu::hasDepthComponent(tcuFormat.order);
1764             const bool hasStencil        = tcu::hasStencilComponent(tcuFormat.order);
1765             const std::string formatName = getFormatCaseName(formats[f]);
1766 
1767             // Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5.
1768             // Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1769             // depth buffer to 1.0.
1770             // This is followed by another draw with a blue rectangle using the same depth of 1.0. This time
1771             // the depth test fails and nothing is written.
1772             // After the renderpass the red color should remain inside the render area of the color buffer.
1773             // Store op 'none' for depth buffer makes the written values undefined, but the pixels outside
1774             // render area should still contain the original value of 0.5.
1775             if (hasDepth)
1776             {
1777                 TestParams params{
1778                     {// std::vector<AttachmentParams> attachments;
1779                      {ATTACHMENT_USAGE_COLOR,
1780                       VK_ATTACHMENT_LOAD_OP_LOAD,
1781                       VK_ATTACHMENT_STORE_OP_STORE,
1782                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1783                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1784                       ATTACHMENT_INIT_PRE,
1785                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1786                      {ATTACHMENT_USAGE_DEPTH,
1787                       VK_ATTACHMENT_LOAD_OP_LOAD,
1788                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
1789                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1790                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1791                       ATTACHMENT_INIT_PRE,
1792                       {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthInit, true, depthInit}}}},
1793                     {// std::vector<SubpassParams> subpasses;
1794                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u}},
1795                     groupParams, // const SharedGroupParams groupParams;
1796                     formats[f],  // VkFormat depthStencilFormat;
1797                     false,       // bool alphaBlend;
1798                     f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1799                 };
1800 
1801                 opNoneTests->addChild(
1802                     new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_load_store_op_none", params));
1803             }
1804 
1805             // Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but
1806             // disable depth test which also disables depth writes. The depth attachment should have the original
1807             // preinitialized value after the render pass.
1808             if (hasDepth)
1809             {
1810                 TestParams params{
1811                     {// std::vector<AttachmentParams> attachments;
1812                      {ATTACHMENT_USAGE_COLOR,
1813                       VK_ATTACHMENT_LOAD_OP_LOAD,
1814                       VK_ATTACHMENT_STORE_OP_STORE,
1815                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1816                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1817                       ATTACHMENT_INIT_PRE,
1818                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1819                      {ATTACHMENT_USAGE_DEPTH,
1820                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1821                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
1822                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1823                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1824                       ATTACHMENT_INIT_PRE,
1825                       {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}}}},
1826                     {// std::vector<SubpassParams> subpasses;
1827                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
1828                       1u}},
1829                     groupParams, // const SharedGroupParams groupParams;
1830                     formats[f],  // VkFormat depthStencilFormat;
1831                     false,       // bool alphaBlend;
1832                     f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1833                 };
1834 
1835                 opNoneTests->addChild(new LoadStoreOpNoneTest(
1836                     testCtx, "depth_" + formatName + "_load_op_none_store_op_none_write_off", params));
1837             }
1838 
1839             // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1840             // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1841             // depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the
1842             // shader updated value of 1.0.
1843             if (hasDepth)
1844             {
1845                 TestParams params{
1846                     {// std::vector<AttachmentParams> attachments;
1847                      {ATTACHMENT_USAGE_COLOR,
1848                       VK_ATTACHMENT_LOAD_OP_LOAD,
1849                       VK_ATTACHMENT_STORE_OP_STORE,
1850                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1851                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1852                       ATTACHMENT_INIT_PRE,
1853                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1854                      {ATTACHMENT_USAGE_DEPTH,
1855                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1856                       VK_ATTACHMENT_STORE_OP_STORE,
1857                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1858                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1859                       ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1860                       {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}}}},
1861                     {// std::vector<SubpassParams> subpasses;
1862                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}},
1863                     groupParams, // const SharedGroupParams groupParams;
1864                     formats[f],  // VkFormat depthStencilFormat;
1865                     false,       // bool alphaBlend;
1866                     f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1867                 };
1868 
1869                 opNoneTests->addChild(
1870                     new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_store", params));
1871             }
1872 
1873             // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1874             // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass.
1875             // After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render
1876             // area is undefined because of store op 'don't care', but the outside should have the original value of 0.5.
1877             if (hasDepth)
1878             {
1879                 TestParams params{
1880                     {// std::vector<AttachmentParams> attachments;
1881                      {ATTACHMENT_USAGE_COLOR,
1882                       VK_ATTACHMENT_LOAD_OP_LOAD,
1883                       VK_ATTACHMENT_STORE_OP_STORE,
1884                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1885                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1886                       ATTACHMENT_INIT_PRE,
1887                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1888                      {ATTACHMENT_USAGE_DEPTH,
1889                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1890                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1891                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1892                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1893                       ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1894                       {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthFull, true, depthInit}}}},
1895                     {// std::vector<SubpassParams> subpasses;
1896                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}},
1897                     groupParams, // const SharedGroupParams groupParams;
1898                     formats[f],  // VkFormat depthStencilFormat;
1899                     false,       // bool alphaBlend;
1900                     f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1901                 };
1902 
1903                 opNoneTests->addChild(new LoadStoreOpNoneTest(
1904                     testCtx, "depth_" + formatName + "_load_op_none_store_op_dontcare", params));
1905             }
1906 
1907             // Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128.
1908             // Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test
1909             // will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time
1910             // the stencil test fails and nothing is written.
1911             // After the renderpass the red color should remain inside the render area of the color buffer.
1912             // Store op 'none' for stencil buffer makes the written values undefined, but the pixels outside
1913             // render area should still contain the original value of 128.
1914             if (hasStencil)
1915             {
1916                 TestParams params{
1917                     {// std::vector<AttachmentParams> attachments;
1918                      {ATTACHMENT_USAGE_COLOR,
1919                       VK_ATTACHMENT_LOAD_OP_LOAD,
1920                       VK_ATTACHMENT_STORE_OP_STORE,
1921                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1922                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1923                       ATTACHMENT_INIT_PRE,
1924                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1925                      {ATTACHMENT_USAGE_STENCIL,
1926                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1927                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1928                       VK_ATTACHMENT_LOAD_OP_LOAD,
1929                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
1930                       ATTACHMENT_INIT_PRE,
1931                       {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilInit, true, stencilInit}}}},
1932                     {// std::vector<SubpassParams> subpasses;
1933                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u}},
1934                     groupParams, // const SharedGroupParams groupParams;
1935                     formats[f],  // VkFormat depthStencilFormat;
1936                     false,       // bool alphaBlend;
1937                     f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1938                 };
1939 
1940                 opNoneTests->addChild(
1941                     new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_load_store_op_none", params));
1942             }
1943 
1944             // Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but
1945             // disable stencil test which also disables stencil writes. The stencil attachment should have the original
1946             // preinitialized value after the render pass.
1947             if (hasStencil)
1948             {
1949                 TestParams params{
1950                     {// std::vector<AttachmentParams> attachments;
1951                      {ATTACHMENT_USAGE_COLOR,
1952                       VK_ATTACHMENT_LOAD_OP_LOAD,
1953                       VK_ATTACHMENT_STORE_OP_STORE,
1954                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1955                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1956                       ATTACHMENT_INIT_PRE,
1957                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1958                      {ATTACHMENT_USAGE_STENCIL,
1959                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1960                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1961                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1962                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
1963                       ATTACHMENT_INIT_PRE,
1964                       {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}}}},
1965                     {// std::vector<SubpassParams> subpasses;
1966                      {{{0u, ATTACHMENT_USAGE_COLOR},
1967                        {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF |
1968                                 ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
1969                       1u}},
1970                     groupParams, // const SharedGroupParams groupParams;
1971                     formats[f],  // VkFormat depthStencilFormat;
1972                     false,       // bool alphaBlend;
1973                     f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1974                 };
1975 
1976                 opNoneTests->addChild(new LoadStoreOpNoneTest(
1977                     testCtx, "stencil_" + formatName + "_load_op_none_store_op_none_write_off", params));
1978             }
1979 
1980             // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1981             // using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update
1982             // stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the
1983             // shader updated value of 255.
1984             if (hasStencil)
1985             {
1986                 TestParams params{
1987                     {// std::vector<AttachmentParams> attachments;
1988                      {ATTACHMENT_USAGE_COLOR,
1989                       VK_ATTACHMENT_LOAD_OP_LOAD,
1990                       VK_ATTACHMENT_STORE_OP_STORE,
1991                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1992                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1993                       ATTACHMENT_INIT_PRE,
1994                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1995                      {ATTACHMENT_USAGE_STENCIL,
1996                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1997                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
1998                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1999                       VK_ATTACHMENT_STORE_OP_STORE,
2000                       ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
2001                       {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2002                     {// std::vector<SubpassParams> subpasses;
2003                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}},
2004                     groupParams, // const SharedGroupParams groupParams;
2005                     formats[f],  // VkFormat depthStencilFormat;
2006                     false,       // bool alphaBlend;
2007                     f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2008                 };
2009 
2010                 opNoneTests->addChild(
2011                     new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_store", params));
2012             }
2013 
2014             // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
2015             // using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass.
2016             // After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render
2017             // are is undefined because of store op 'don't care', but the outside should have the original value of 128.
2018             if (hasStencil)
2019             {
2020                 TestParams params{
2021                     {// std::vector<AttachmentParams> attachments;
2022                      {ATTACHMENT_USAGE_COLOR,
2023                       VK_ATTACHMENT_LOAD_OP_LOAD,
2024                       VK_ATTACHMENT_STORE_OP_STORE,
2025                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2026                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2027                       ATTACHMENT_INIT_PRE,
2028                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2029                      {ATTACHMENT_USAGE_STENCIL,
2030                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2031                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2032                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2033                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2034                       ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
2035                       {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilFull, true, stencilInit}}}},
2036                     {// std::vector<SubpassParams> subpasses;
2037                      {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}},
2038                     groupParams, // const SharedGroupParams groupParams;
2039                     formats[f],  // VkFormat depthStencilFormat;
2040                     false,       // bool alphaBlend;
2041                     f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2042                 };
2043 
2044                 opNoneTests->addChild(new LoadStoreOpNoneTest(
2045                     testCtx, "stencil_" + formatName + "_load_op_none_store_op_dontcare", params));
2046             }
2047 
2048             // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2049             // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2050             // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2051             // store ops none, and stencil writes are disabled by disabling stencil test. Therefore, stencil should not be modified even when
2052             // the depth aspect is written.
2053             if (hasDepth && hasStencil)
2054             {
2055                 TestParams params{
2056                     {// std::vector<AttachmentParams> attachments;
2057                      {ATTACHMENT_USAGE_COLOR,
2058                       VK_ATTACHMENT_LOAD_OP_LOAD,
2059                       VK_ATTACHMENT_STORE_OP_STORE,
2060                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2061                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2062                       ATTACHMENT_INIT_PRE,
2063                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2064                      {ATTACHMENT_USAGE_DEPTH_STENCIL,
2065                       VK_ATTACHMENT_LOAD_OP_LOAD,
2066                       VK_ATTACHMENT_STORE_OP_STORE,
2067                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2068                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
2069                       ATTACHMENT_INIT_PRE,
2070                       {
2071                           {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2072                           {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2073                       }}},
2074                     {// std::vector<SubpassParams> subpasses;
2075                      {{{0u, ATTACHMENT_USAGE_COLOR},
2076                        {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF}},
2077                       1u}},
2078                     groupParams, // const SharedGroupParams groupParams;
2079                     formats[f],  // VkFormat depthStencilFormat;
2080                     false,       // bool alphaBlend;
2081                     f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2082                 };
2083 
2084                 opNoneTests->addChild(new LoadStoreOpNoneTest(
2085                     testCtx,
2086                     "depthstencil_" + formatName +
2087                         "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_test_off",
2088                     params));
2089             }
2090 
2091             // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2092             // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2093             // the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store
2094             // ops none, and depth writes are disabled by having depth test off. Therefore, depth should not be modified even when the stencil aspect is
2095             // written.
2096             if (hasDepth && hasStencil)
2097             {
2098                 TestParams params{
2099                     {// std::vector<AttachmentParams> attachments;
2100                      {ATTACHMENT_USAGE_COLOR,
2101                       VK_ATTACHMENT_LOAD_OP_LOAD,
2102                       VK_ATTACHMENT_STORE_OP_STORE,
2103                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2104                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2105                       ATTACHMENT_INIT_PRE,
2106                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2107                      {ATTACHMENT_USAGE_DEPTH_STENCIL,
2108                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2109                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
2110                       VK_ATTACHMENT_LOAD_OP_LOAD,
2111                       VK_ATTACHMENT_STORE_OP_STORE,
2112                       ATTACHMENT_INIT_PRE,
2113                       {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2114                        {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2115                     {// std::vector<SubpassParams> subpasses;
2116                      {{{0u, ATTACHMENT_USAGE_COLOR},
2117                        {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
2118                       1u}},
2119                     groupParams, // const SharedGroupParams groupParams;
2120                     formats[f],  // VkFormat depthStencilFormat;
2121                     false,       // bool alphaBlend;
2122                     f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2123                 };
2124 
2125                 opNoneTests->addChild(new LoadStoreOpNoneTest(
2126                     testCtx,
2127                     "depthstencil_" + formatName +
2128                         "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_test_off",
2129                     params));
2130             }
2131 
2132             // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2133             // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2134             // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2135             // store ops none, and stencil writes are disabled. Therefore, stencil should not be modified even when the depth aspect is written.
2136             if (hasDepth && hasStencil)
2137             {
2138                 TestParams params{
2139                     {// std::vector<AttachmentParams> attachments;
2140                      {ATTACHMENT_USAGE_COLOR,
2141                       VK_ATTACHMENT_LOAD_OP_LOAD,
2142                       VK_ATTACHMENT_STORE_OP_STORE,
2143                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2144                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2145                       ATTACHMENT_INIT_PRE,
2146                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2147                      {ATTACHMENT_USAGE_DEPTH_STENCIL,
2148                       VK_ATTACHMENT_LOAD_OP_LOAD,
2149                       VK_ATTACHMENT_STORE_OP_STORE,
2150                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2151                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
2152                       ATTACHMENT_INIT_PRE,
2153                       {
2154                           {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2155                           {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2156                       }}},
2157                     {// std::vector<SubpassParams> subpasses;
2158                      {{{0u, ATTACHMENT_USAGE_COLOR},
2159                        {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_WRITE_OFF}},
2160                       1u}},
2161                     groupParams, // const SharedGroupParams groupParams;
2162                     formats[f],  // VkFormat depthStencilFormat;
2163                     false,       // bool alphaBlend;
2164                     f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2165                 };
2166 
2167                 opNoneTests->addChild(new LoadStoreOpNoneTest(
2168                     testCtx,
2169                     "depthstencil_" + formatName +
2170                         "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_write_off",
2171                     params));
2172             }
2173 
2174             // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2175             // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2176             // the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store
2177             // ops none, the depth buffer contents will be undefined and depth test is enabled but op will be 'always' so depth testing will pass. Depth
2178             // writes are disabled, so depth should not be modified even when the stencil aspect is written.
2179             if (hasDepth && hasStencil)
2180             {
2181                 TestParams params{
2182                     {// std::vector<AttachmentParams> attachments;
2183                      {ATTACHMENT_USAGE_COLOR,
2184                       VK_ATTACHMENT_LOAD_OP_LOAD,
2185                       VK_ATTACHMENT_STORE_OP_STORE,
2186                       VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2187                       VK_ATTACHMENT_STORE_OP_DONT_CARE,
2188                       ATTACHMENT_INIT_PRE,
2189                       {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2190                      {ATTACHMENT_USAGE_DEPTH_STENCIL,
2191                       VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2192                       VK_ATTACHMENT_STORE_OP_NONE_EXT,
2193                       VK_ATTACHMENT_LOAD_OP_LOAD,
2194                       VK_ATTACHMENT_STORE_OP_STORE,
2195                       ATTACHMENT_INIT_PRE,
2196                       {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2197                        {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2198                     {// std::vector<SubpassParams> subpasses;
2199                      {{{0u, ATTACHMENT_USAGE_COLOR},
2200                        {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_WRITE_OFF}},
2201                       1u}},
2202                     groupParams, // const SharedGroupParams groupParams;
2203                     formats[f],  // VkFormat depthStencilFormat;
2204                     false,       // bool alphaBlend;
2205                     f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2206                 };
2207 
2208                 opNoneTests->addChild(new LoadStoreOpNoneTest(
2209                     testCtx,
2210                     "depthstencil_" + formatName +
2211                         "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_write_off",
2212                     params));
2213             }
2214         } // for over DS formats
2215     }
2216     return opNoneTests.release();
2217 }
2218 
2219 } // namespace renderpass
2220 } // namespace vkt
2221