Add tests for VK_EXT_load_store_op_none
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / renderpass / vktRenderPassLoadStoreOpNoneTests.cpp
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 "vktTestCase.hpp"
28 #include "vkImageUtil.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkRef.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkObjUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuPlatform.hpp"
39 #include "tcuTestLog.hpp"
40 #include "deStringUtil.hpp"
41 #include "deUniquePtr.hpp"
42 #include "deRandom.hpp"
43 #include <cstring>
44 #include <cmath>
45 #include <vector>
46
47 namespace vkt
48 {
49 namespace renderpass
50 {
51
52 using namespace vk;
53
54 namespace
55 {
56
57 enum AttachmentInit
58 {
59         ATTACHMENT_INIT_PRE = 1,
60         ATTACHMENT_INIT_CMD_CLEAR = 2
61 };
62
63 enum AttachmentUsage
64 {
65         ATTACHMENT_USAGE_UNDEFINED = 0,
66         ATTACHMENT_USAGE_COLOR = 1,
67         ATTACHMENT_USAGE_DEPTH = 2,
68         ATTACHMENT_USAGE_STENCIL = 4,
69         ATTACHMENT_USAGE_INPUT = 8,
70         ATTACHMENT_USAGE_WRITE_OFF = 16,
71         ATTACHMENT_USAGE_DEPTH_STENCIL = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL
72 };
73
74 struct AttachmentParams
75 {
76         deUint32                        usage;
77         VkAttachmentLoadOp      loadOp;
78         VkAttachmentStoreOp     storeOp;
79         deUint32                        init;
80         bool                            verifyInner;
81         tcu::Vec4                       innerRef;
82         bool                            verifyOuter;
83         tcu::Vec4                       outerRef;
84 };
85
86 struct AttachmentRef
87 {
88         deUint32        idx;
89         deUint32        usage;
90 };
91
92 struct SubpassParams
93 {
94         std::vector<AttachmentRef>      attachmentRefs;
95         deUint32                                        numDraws;
96 };
97
98 struct TestParams
99 {
100         std::vector<AttachmentParams>   attachments;
101         std::vector<SubpassParams>              subpasses;
102         RenderPassType                                  renderPassType;
103         bool                                                    alphaBlend;
104 };
105
106 struct Vertex4RGBA
107 {
108         tcu::Vec4 position;
109         tcu::Vec4 color;
110 };
111
112 template<typename T>
113 inline de::SharedPtr<vk::Move<T> > makeSharedPtr(vk::Move<T> move)
114 {
115         return de::SharedPtr<vk::Move<T> >(new vk::Move<T>(move));
116 }
117
118 std::vector<Vertex4RGBA> createQuad (void)
119 {
120         std::vector<Vertex4RGBA>        vertices;
121
122         const float                     size                                    = 1.0f;
123         const tcu::Vec4         red                                             (1.0f, 0.0f, 0.0f, 1.0f);
124         const tcu::Vec4         blue                                    (0.0f, 0.0f, 1.0f, 1.0f);
125         const Vertex4RGBA       lowerLeftVertexRed              = {tcu::Vec4(-size, -size, 0.0f, 1.0f), red};
126         const Vertex4RGBA       lowerRightVertexRed             = {tcu::Vec4(size, -size, 0.0f, 1.0f), red};
127         const Vertex4RGBA       upperLeftVertexRed              = {tcu::Vec4(-size, size, 0.0f, 1.0f), red};
128         const Vertex4RGBA       upperRightVertexRed             = {tcu::Vec4(size, size, 0.0f, 1.0f), red};
129         const Vertex4RGBA       lowerLeftVertexBlue             = {tcu::Vec4(-size, -size, 0.0f, 1.0f), blue};
130         const Vertex4RGBA       lowerRightVertexBlue    = {tcu::Vec4(size, -size, 0.0f, 1.0f), blue};
131         const Vertex4RGBA       upperLeftVertexBlue             = {tcu::Vec4(-size, size, 0.0f, 1.0f), blue};
132         const Vertex4RGBA       upperRightVertexBlue    = {tcu::Vec4(size, size, 0.0f, 1.0f), blue};
133
134         vertices.push_back(lowerLeftVertexRed);
135         vertices.push_back(lowerRightVertexRed);
136         vertices.push_back(upperLeftVertexRed);
137         vertices.push_back(upperLeftVertexRed);
138         vertices.push_back(lowerRightVertexRed);
139         vertices.push_back(upperRightVertexRed);
140
141         vertices.push_back(lowerLeftVertexBlue);
142         vertices.push_back(lowerRightVertexBlue);
143         vertices.push_back(upperLeftVertexBlue);
144         vertices.push_back(upperLeftVertexBlue);
145         vertices.push_back(lowerRightVertexBlue);
146         vertices.push_back(upperRightVertexBlue);
147
148         return vertices;
149 }
150
151 deUint32 getFirstUsage (deUint32 attachmentIdx, const std::vector<SubpassParams>& subpasses)
152 {
153         for (const auto& subpass : subpasses)
154                 for (const auto& ref : subpass.attachmentRefs)
155                         if (ref.idx == attachmentIdx)
156                                 return ref.usage;
157
158         return ATTACHMENT_USAGE_UNDEFINED;
159 }
160
161 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
162 Move<VkRenderPass> createRenderPass (const DeviceInterface&     vk,
163                                                                          VkDevice                               vkDevice,
164                                                                          const TestParams               testParams)
165 {
166         const VkImageAspectFlags        aspectMask                                              = testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
167         const VkImageAspectFlags        depthStencilAspectMask                  = testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
168         std::vector<AttachmentDesc>     attachmentDescriptions;
169         std::vector<SubpassDesc>        subpassDescriptions;
170
171         struct Refs
172         {
173                 std::vector<AttachmentRef>      colorAttachmentRefs;
174                 std::vector<AttachmentRef>      depthStencilAttachmentRefs;
175                 std::vector<AttachmentRef>      inputAttachmentRefs;
176         };
177
178         std::vector<Refs>                       subpassRefs;
179         bool                                            hasInputAttachment                              = false;
180
181         for (size_t i = 0; i < testParams.attachments.size(); i++)
182         {
183                 VkImageLayout   initialLayout;
184                 VkImageLayout   finalLayout;
185                 VkFormat                format;
186
187                 if (testParams.attachments[i].usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
188                 {
189                         format = VK_FORMAT_D24_UNORM_S8_UINT;
190                 }
191                 else
192                 {
193                         // Color and input attachments.
194                         format = VK_FORMAT_R8G8B8A8_UNORM;
195                 }
196
197                 // Search for the first reference to determine the initial layout.
198                 deUint32 firstUsage = getFirstUsage((deUint32)i, testParams.subpasses);
199
200                 // No subpasses using this attachment. Use the usage flags of the attachment.
201                 if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
202                         firstUsage = testParams.attachments[i].usage;
203
204                 if (firstUsage & ATTACHMENT_USAGE_COLOR)
205                         initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
206                 else if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
207                         initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
208                 else
209                 {
210                         DE_ASSERT(firstUsage & ATTACHMENT_USAGE_INPUT);
211                         initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
212                 }
213
214                 // Set final layout to transfer src if it's being verified. Otherwise
215                 // just use the initial layout as it's known to be supported by
216                 // the usage flags.
217                 if (testParams.attachments[i].verifyInner || testParams.attachments[i].verifyOuter)
218                         finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
219                 else
220                         finalLayout = initialLayout;
221
222                 const AttachmentDesc attachmentDesc =
223                 {
224                         DE_NULL,                                                        // const void*                                          pNext
225                         (VkAttachmentDescriptionFlags) 0,       // VkAttachmentDescriptionFlags         flags
226                         format,                                                         // VkFormat                                                     format
227                         VK_SAMPLE_COUNT_1_BIT,                          // VkSampleCountFlagBits                        samples
228                         testParams.attachments[i].loadOp,       // VkAttachmentLoadOp                           loadOp
229                         testParams.attachments[i].storeOp,      // VkAttachmentStoreOp                          storeOp
230                         testParams.attachments[i].loadOp,       // VkAttachmentLoadOp                           stencilLoadOp
231                         testParams.attachments[i].storeOp,      // VkAttachmentStoreOp                          stencilStoreOp
232                         initialLayout,                                          // VkImageLayout                                        initialLayout
233                         finalLayout                                                     // VkImageLayout                                        finalLayout
234                 };
235
236                 attachmentDescriptions.push_back(attachmentDesc);
237         }
238
239         for (const auto& subpass : testParams.subpasses)
240         {
241                 subpassRefs.push_back({});
242                 auto& refs = subpassRefs.back();
243
244                 for (const auto& ref : subpass.attachmentRefs)
245                 {
246                         VkImageLayout layout;
247
248                         if (ref.usage & ATTACHMENT_USAGE_COLOR)
249                         {
250                                 layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
251                                 refs.colorAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
252                         }
253                         else if (ref.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
254                         {
255                                 layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
256                                 refs.depthStencilAttachmentRefs.push_back({DE_NULL, ref.idx, layout, depthStencilAspectMask});
257                         }
258                         else
259                         {
260                                 DE_ASSERT(ref.usage & ATTACHMENT_USAGE_INPUT);
261                                 layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
262                                 refs.inputAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
263                                 hasInputAttachment = true;
264                         }
265                 }
266
267                 const SubpassDesc                       subpassDescription                      =
268                 {
269                         DE_NULL,
270                         (VkSubpassDescriptionFlags)0,                                                                                                                           // VkSubpassDescriptionFlags            flags
271                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                                                                                                        // VkPipelineBindPoint                          pipelineBindPoint
272                         0u,                                                                                                                                                                                     // deUint32                                                     viewMask
273                         (deUint32)refs.inputAttachmentRefs.size(),                                                                                                      // deUint32                                                     inputAttachmentCount
274                         refs.inputAttachmentRefs.empty() ? DE_NULL : refs.inputAttachmentRefs.data(),                           // const VkAttachmentReference*         pInputAttachments
275                         (deUint32)refs.colorAttachmentRefs.size(),                                                                                                      // deUint32                                                     colorAttachmentCount
276                         refs.colorAttachmentRefs.empty() ? DE_NULL : refs.colorAttachmentRefs.data(),                           // const VkAttachmentReference*         pColorAttachments
277                         DE_NULL,                                                                                                                                                                        // const VkAttachmentReference*         pResolveAttachments
278                         refs.depthStencilAttachmentRefs.empty() ? DE_NULL : refs.depthStencilAttachmentRefs.data(),     // const VkAttachmentReference*         pDepthStencilAttachment
279                         0u,                                                                                                                                                                                     // deUint32                                                     preserveAttachmentCount
280                         DE_NULL                                                                                                                                                                         // const deUint32*                                      pPreserveAttachments
281                 };
282
283                 subpassDescriptions.push_back(subpassDescription);
284         }
285
286         // Dependency of color attachment of subpass 0 to input attachment of subpass 1.
287         // Determined later if it's being used.
288         const SubpassDep                        subpassDependency                               =
289         {
290                 DE_NULL,                                                                                // const void*                          pNext
291                 0u,                                                                                             // uint32_t                                     srcSubpass
292                 1u,                                                                                             // uint32_t                                     dstSubpass
293                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  // VkPipelineStageFlags         srcStageMask
294                 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                  // VkPipelineStageFlags         dstStageMask
295                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask
296                 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                    // VkAccessFlags                        dstAccessMask
297                 VK_DEPENDENCY_BY_REGION_BIT,                                    // VkDependencyFlags            dependencyFlags
298                 0u                                                                                              // deInt32                                      viewOffset
299         };
300
301         const RenderPassCreateInfo      renderPassInfo                                  =
302         {
303                 DE_NULL,                                                                                        // const void*                                          pNext
304                 (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags
305                 (deUint32)attachmentDescriptions.size(),                        // deUint32                                                     attachmentCount
306                 attachmentDescriptions.data(),                                          // const VkAttachmentDescription*       pAttachments
307                 (deUint32)subpassDescriptions.size(),                           // deUint32                                                     subpassCount
308                 subpassDescriptions.data(),                                                     // const VkSubpassDescription*          pSubpasses
309                 hasInputAttachment ? 1u : 0u,                                           // deUint32                                                     dependencyCount
310                 hasInputAttachment ? &subpassDependency : DE_NULL,      // const VkSubpassDependency*           pDependencies
311                 0u,                                                                                                     // deUint32                                                     correlatedViewMaskCount
312                 DE_NULL                                                                                         // const deUint32*                                      pCorrelatedViewMasks
313         };
314
315         return renderPassInfo.createRenderPass(vk, vkDevice);
316 }
317
318 class LoadStoreOpNoneTest : public vkt::TestCase
319 {
320 public:
321                                                         LoadStoreOpNoneTest             (tcu::TestContext&      testContext,
322                                                                                                          const std::string&     name,
323                                                                                                          const std::string&     description,
324                                                                                                          const TestParams&      testParams);
325         virtual                                 ~LoadStoreOpNoneTest    (void);
326         virtual void                    initPrograms                    (SourceCollections&     sourceCollections) const;
327         virtual void                    checkSupport                    (Context& context) const;
328         virtual TestInstance*   createInstance                  (Context& context) const;
329 private:
330         const TestParams                m_testParams;
331 };
332
333 class LoadStoreOpNoneTestInstance : public vkt::TestInstance
334 {
335 public:
336                                                                 LoadStoreOpNoneTestInstance             (Context&                       context,
337                                                                                                                                  const TestParams&      testParams);
338         virtual                                         ~LoadStoreOpNoneTestInstance    (void);
339         virtual tcu::TestStatus         iterate                                                 (void);
340         template<typename RenderpassSubpass>
341         void                                            createCommandBuffer                             (const DeviceInterface&                                 vk,
342                                                                                                                                  VkDevice                                                               vkDevice,
343                                                                                                                                  std::vector<Move<VkDescriptorSet>>&    descriptorSets,
344                                                                                                                                  std::vector<Move<VkPipelineLayout>>&   pipelineLayouts,
345                                                                                                                                  std::vector<Move<VkPipeline>>&                 pipelines);
346 private:
347         TestParams                                      m_testParams;
348
349         const tcu::UVec2                        m_imageSize;
350         const tcu::UVec2                        m_renderSize;
351
352         Move<VkDescriptorPool>          m_descriptorPool;
353         Move<VkRenderPass>                      m_renderPass;
354         Move<VkFramebuffer>                     m_framebuffer;
355
356         Move<VkBuffer>                          m_vertexBuffer;
357         std::vector<Vertex4RGBA>        m_vertices;
358         de::MovePtr<Allocation>         m_vertexBufferAlloc;
359
360         Move<VkCommandPool>                     m_cmdPool;
361         Move<VkCommandBuffer>           m_cmdBuffer;
362 };
363
364 LoadStoreOpNoneTest::LoadStoreOpNoneTest (tcu::TestContext&             testContext,
365                                                                                   const std::string&    name,
366                                                                                   const std::string&    description,
367                                                                                   const TestParams&             testParams)
368         : vkt::TestCase (testContext, name, description)
369         , m_testParams(testParams)
370 {
371 }
372
373 LoadStoreOpNoneTest::~LoadStoreOpNoneTest (void)
374 {
375 }
376
377 TestInstance* LoadStoreOpNoneTest::createInstance (Context& context) const
378 {
379         return new LoadStoreOpNoneTestInstance(context, m_testParams);
380 }
381
382 void LoadStoreOpNoneTest::checkSupport (Context& ctx) const
383 {
384         // Check for renderpass2 extension if used.
385         if (m_testParams.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
386                 ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2");
387
388         ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none");
389 }
390
391 void LoadStoreOpNoneTest::initPrograms (SourceCollections& sourceCollections) const
392 {
393         std::ostringstream fragmentSource;
394
395         sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
396                 "#version 450\n"
397                 "layout(location = 0) in highp vec4 position;\n"
398                 "layout(location = 1) in highp vec4 color;\n"
399                 "layout(location = 0) out highp vec4 vtxColor;\n"
400                 "void main (void)\n"
401                 "{\n"
402                 "       gl_Position = position;\n"
403                 "       vtxColor = color;\n"
404                 "}\n");
405
406         sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
407                 "#version 450\n"
408                 "layout(location = 0) in highp vec4 vtxColor;\n"
409                 "layout(location = 0) out highp vec4 fragColor;\n"
410                 "void main (void)\n"
411                 "{\n"
412                 "       fragColor = vtxColor;\n"
413                 "       gl_FragDepth = 1.0;\n"
414                 "}\n");
415
416         sourceCollections.glslSources.add("color_frag_blend") << glu::FragmentSource(
417                 "#version 450\n"
418                 "layout(location = 0) in highp vec4 vtxColor;\n"
419                 "layout(location = 0) out highp vec4 fragColor;\n"
420                 "void main (void)\n"
421                 "{\n"
422                 "       fragColor = vec4(vtxColor.rgb, 0.5);\n"
423                 "       gl_FragDepth = 1.0;\n"
424                 "}\n");
425
426         sourceCollections.glslSources.add("color_frag_input") << glu::FragmentSource(
427                 "#version 450\n"
428                 "layout(location = 0) in highp vec4 vtxColor;\n"
429                 "layout(location = 0) out highp vec4 fragColor;\n"
430                 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;"
431                 "void main (void)\n"
432                 "{\n"
433                 "       fragColor = subpassLoad(inputColor) + vtxColor;\n"
434                 "       gl_FragDepth = 1.0;\n"
435                 "}\n");
436 }
437
438 LoadStoreOpNoneTestInstance::LoadStoreOpNoneTestInstance        (Context&                       context,
439                                                                                                                          const TestParams&      testParams)
440         : vkt::TestInstance     (context)
441         , m_testParams          (testParams)
442         , m_imageSize           (32u, 32u)
443         , m_renderSize          (27u, 19u)
444         , m_vertices            (createQuad())
445 {
446 }
447
448 LoadStoreOpNoneTestInstance::~LoadStoreOpNoneTestInstance (void)
449 {
450 }
451
452 template<typename RenderpassSubpass>
453 void LoadStoreOpNoneTestInstance::createCommandBuffer   (const DeviceInterface&                                 vk,
454                                                                                                                  VkDevice                                                               vkDevice,
455                                                                                                                  std::vector<Move<VkDescriptorSet>>&    descriptorSets,
456                                                                                                                  std::vector<Move<VkPipelineLayout>>&   pipelineLayouts,
457                                                                                                                  std::vector<Move<VkPipeline>>&                 pipelines)
458 {
459         const typename RenderpassSubpass::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
460         const typename RenderpassSubpass::SubpassEndInfo        subpassEndInfo          (DE_NULL);
461
462         const VkDeviceSize vertexBufferOffset = 0;
463
464         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
465
466         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
467
468         const VkRenderPassBeginInfo renderPassBeginInfo =
469         {
470                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType
471                 DE_NULL,                                                                        // const void*                  pNext
472                 *m_renderPass,                                                          // VkRenderPass                 renderPass
473                 *m_framebuffer,                                                         // VkFramebuffer                framebuffer
474                 makeRect2D(m_renderSize),                                       // VkRect2D                             renderArea
475                 0u,                                                                                     // uint32_t                             clearValueCount
476                 DE_NULL                                                                         // const VkClearValue*  pClearValues
477         };
478         RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
479
480         // Add clear commands for selected attachments
481         std::vector<VkClearAttachment> clearAttachments;
482         deUint32 colorAttIdx = 0u;
483         for (const auto& att : m_testParams.attachments)
484         {
485                 if (att.init & ATTACHMENT_INIT_CMD_CLEAR)
486                 {
487                         if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
488                         {
489                                 clearAttachments.push_back({VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u,
490                                                                                         makeClearValueDepthStencil(0.25, 64)});
491                         }
492                         else
493                         {
494                                 clearAttachments.push_back({VK_IMAGE_ASPECT_COLOR_BIT, colorAttIdx++,
495                                                                                         makeClearValueColorF32(0.0f, 0.0f, 0.5f, 1.0f)});
496                         }
497                 }
498         }
499         if (!clearAttachments.empty())
500         {
501                 VkClearRect rect = { makeRect2D(m_renderSize), 0u, 1u };
502                 vk.cmdClearAttachments(*m_cmdBuffer, (deUint32) clearAttachments.size(), clearAttachments.data(), 1u, &rect);
503         }
504
505         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
506
507         deUint32        descriptorSetIdx        = 0u;
508         deUint32        vertexOffset            = 0u;
509         for (size_t i = 0; i < m_testParams.subpasses.size(); i++)
510         {
511                 if (i != 0)
512                         vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
513
514                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[i]);
515
516                 bool hasInput = false;
517                 for (const auto &ref : m_testParams.subpasses[i].attachmentRefs)
518                         if (ref.usage & ATTACHMENT_USAGE_INPUT)
519                                 hasInput = true;
520
521                 if (hasInput)
522                         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayouts[i], 0, 1,
523                                                                          &descriptorSets[descriptorSetIdx++].get(), 0, DE_NULL);
524
525                 for (deUint32 d = 0; d < m_testParams.subpasses[i].numDraws; d++)
526                 {
527                         vk.cmdDraw(*m_cmdBuffer, 6u, 1, vertexOffset, 0);
528                         vertexOffset += 6u;
529                 }
530         }
531         RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
532         endCommandBuffer(vk, *m_cmdBuffer);
533 }
534
535 tcu::TestStatus LoadStoreOpNoneTestInstance::iterate (void)
536 {
537         const DeviceInterface&                                  vk                                              = m_context.getDeviceInterface();
538         const VkDevice                                                  vkDevice                                = m_context.getDevice();
539         const VkQueue                                                   queue                                   = m_context.getUniversalQueue();
540         const deUint32                                                  queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
541         SimpleAllocator                                                 memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
542         const VkComponentMapping                                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
543
544         std::vector<Move<VkImage>>                              attachmentImages;
545         std::vector<de::MovePtr<Allocation>>    attachmentImageAllocs;
546         std::vector<Move<VkImageView>>                  imageViews;
547         std::vector<Move<VkPipeline>>                   pipelines;
548
549         for (const auto& att : m_testParams.attachments)
550         {
551                 VkFormat                                format;
552                 VkImageUsageFlags               usage                           = 0;
553                 VkImageAspectFlags              aspectFlags;
554
555                 if (att.verifyInner || att.verifyOuter) usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
556                 if (att.init & ATTACHMENT_INIT_PRE) usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
557                 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
558                 {
559                         format = VK_FORMAT_D24_UNORM_S8_UINT;
560                         aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
561                         usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
562                 }
563                 else
564                 {
565                         // Color and input attachments.
566                         format = VK_FORMAT_R8G8B8A8_UNORM;
567                         aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
568
569                         if (att.usage & ATTACHMENT_USAGE_COLOR)
570                                 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
571                         if (att.usage & ATTACHMENT_USAGE_INPUT)
572                                 usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
573                 }
574
575                 const VkImageCreateInfo         imageParams             =
576                 {
577                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType                      sType
578                         DE_NULL,                                                                        // const void*                          pNext
579                         0u,                                                                                     // VkImageCreateFlags           flags
580                         VK_IMAGE_TYPE_2D,                                                       // VkImageType                          imageType
581                         format,                                                                         // VkFormat                                     format
582                         { m_imageSize.x(), m_imageSize.y(), 1u },       // VkExtent3D                           extent
583                         1u,                                                                                     // deUint32                                     mipLevels
584                         1u,                                                                                     // deUint32                                     arrayLayers
585                         VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits        samples
586                         VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling                        tiling
587                         usage,                                                                          // VkImageUsageFlags            usage
588                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                        sharingMode
589                         1u,                                                                                     // deUint32                                     queueFamilyIndexCount
590                         &queueFamilyIndex,                                                      // const deUint32*                      pQueueFamilyIndices
591                         VK_IMAGE_LAYOUT_UNDEFINED                                       // VkImageLayout                        initialLayout
592                 };
593
594                 attachmentImages.push_back(createImage(vk, vkDevice, &imageParams));
595
596                 // Allocate and bind image memory.
597                 attachmentImageAllocs.push_back(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *attachmentImages.back()), MemoryRequirement::Any));
598                 VK_CHECK(vk.bindImageMemory(vkDevice, *attachmentImages.back(), attachmentImageAllocs.back()->getMemory(), attachmentImageAllocs.back()->getOffset()));
599
600                 // Create image view.
601                 const VkImageViewCreateInfo     imageViewParams =
602                 {
603                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,       // VkStructureType                      sType
604                         DE_NULL,                                                                        // const void*                          pNext
605                         0u,                                                                                     // VkImageViewCreateFlags       flags
606                         *attachmentImages.back(),                                       // VkImage                                      image
607                         VK_IMAGE_VIEW_TYPE_2D,                                          // VkImageViewType                      viewType
608                         format,                                                                         // VkFormat                                     format
609                         componentMappingRGBA,                                           // VkChannelMapping                     channels
610                         { aspectFlags, 0u, 1u, 0u, 1u }                         // VkImageSubresourceRange      subresourceRange
611                 };
612
613                 imageViews.push_back(createImageView(vk, vkDevice, &imageViewParams));
614
615                 if (att.init & ATTACHMENT_INIT_PRE)
616                 {
617                         // Preinitialize image
618                         deUint32 firstUsage = getFirstUsage((deUint32)attachmentImages.size() - 1, m_testParams.subpasses);
619                         if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
620                                 firstUsage = att.usage;
621
622                         if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
623                         {
624                                 clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), 0.5f, 128u,
625                                                                            VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
626                                                                            VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
627                         }
628                         else
629                         {
630                                 clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
631                                                                 VK_IMAGE_LAYOUT_UNDEFINED, firstUsage & ATTACHMENT_USAGE_COLOR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
632                                                                 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
633                         }
634                 }
635         }
636
637         // Create render pass.
638         if (m_testParams.renderPassType == RENDERPASS_TYPE_LEGACY)
639                 m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, m_testParams);
640         else
641                 m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, m_testParams);
642
643         // Create framebuffer.
644         {
645                 std::vector<VkImageView>                views;
646                 for (const auto& view : imageViews)
647                         views.push_back(*view);
648
649                 const VkFramebufferCreateInfo   framebufferParams       =
650                 {
651                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType
652                         DE_NULL,                                                                        // const void*                          pNext
653                         0u,                                                                                     // VkFramebufferCreateFlags     flags
654                         *m_renderPass,                                                          // VkRenderPass                         renderPass
655                         (deUint32)views.size(),                                         // deUint32                                     attachmentCount
656                         views.data(),                                                           // const VkImageView*           pAttachments
657                         (deUint32)m_imageSize.x(),                                      // deUint32                                     width
658                         (deUint32)m_imageSize.y(),                                      // deUint32                                     height
659                         1u                                                                                      // deUint32                                     layers
660                 };
661
662                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
663         }
664
665         // Create shader modules
666         Unique<VkShaderModule>          vertexShaderModule                      (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0));
667         Unique<VkShaderModule>          fragmentShaderModule            (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0));
668         Unique<VkShaderModule>          fragmentShaderModuleBlend       (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_blend"), 0));
669         Unique<VkShaderModule>          fragmentShaderModuleInput       (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_input"), 0));
670
671         // Create descriptor pool. Prepare for using one input attachment at most.
672         {
673                 const VkDescriptorPoolSize                      descriptorPoolSize                      =
674                 {
675                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType             type
676                         1u                                                                              // deUint32                             descriptorCount
677                 };
678
679                 const VkDescriptorPoolCreateInfo        descriptorPoolCreateInfo        =
680                 {
681                         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,          // VkStructureType                              sType
682                         DE_NULL,                                                                                        // const void*                                  pNext
683                         VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,      // VkDescriptorPoolCreateFlags  flags
684                         1u,                                                                                                     // deUint32                                             maxSets
685                         1u,                                                                                                     // deUint32                                             poolSizeCount
686                         &descriptorPoolSize                                                                     // const VkDescriptorPoolSize*  pPoolSizes
687                 };
688
689                 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
690         }
691
692         std::vector<Move<VkDescriptorSetLayout>>                descriptorSetLayouts;
693         std::vector<Move<VkDescriptorSet>>                              descriptorSets;
694         std::vector<Move<VkPipelineLayout>>                             pipelineLayouts;
695
696         for (const auto& subpass : m_testParams.subpasses)
697         {
698                 deUint32        numInputAttachments     = 0u;
699                 bool            noColorWrite            = false;
700                 bool            depthTest                       = false;
701                 bool            stencilTest                     = false;
702
703                 // Create pipeline layout.
704                 {
705                         std::vector<VkDescriptorSetLayoutBinding>       layoutBindings;
706
707                         for (const auto ref : subpass.attachmentRefs)
708                         {
709                                 if (ref.usage & ATTACHMENT_USAGE_INPUT)
710                                 {
711                                         const VkDescriptorSetLayoutBinding      layoutBinding   =
712                                         {
713                                                 0u,                                                                             // deUint32                             binding
714                                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType             descriptorType
715                                                 1u,                                                                             // deUint32                             descriptorCount
716                                                 VK_SHADER_STAGE_FRAGMENT_BIT,                   // VkShaderStageFlags   stageFlags
717                                                 DE_NULL                                                                 // const VkSampler*             pImmutableSamplers
718                                         };
719
720                                         layoutBindings.push_back(layoutBinding);
721                                         numInputAttachments++;
722                                 }
723                                 if (ref.usage & ATTACHMENT_USAGE_COLOR)
724                                 {
725                                         if (ref.usage & ATTACHMENT_USAGE_WRITE_OFF)
726                                                 noColorWrite = true;
727                                 }
728                                 if (ref.usage & ATTACHMENT_USAGE_DEPTH)
729                                 {
730                                         if (!(ref.usage & ATTACHMENT_USAGE_WRITE_OFF))
731                                                 depthTest = true;
732                                 }
733                                 if (ref.usage & ATTACHMENT_USAGE_STENCIL)
734                                 {
735                                         if (!(ref.usage & ATTACHMENT_USAGE_WRITE_OFF))
736                                                 stencilTest = true;
737                                 }
738                         }
739
740                         const VkDescriptorSetLayoutCreateInfo           descriptorSetLayoutParams       =
741                         {
742                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType
743                                 DE_NULL,                                                                                                        // const void*                                                  pNext
744                                 0u,                                                                                                                     // VkDescriptorSetLayoutCreateFlags             flags
745                                 (deUint32) layoutBindings.size(),                                                       // deUint32                                                             bindingCount
746                                 layoutBindings.empty() ? DE_NULL : layoutBindings.data()        // const VkDescriptorSetLayoutBinding*  pBindings
747                         };
748                         descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams));
749
750                         const VkPipelineLayoutCreateInfo                        pipelineLayoutParams            =
751                         {
752                                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                              sType
753                                 DE_NULL,                                                                                // const void*                                  pNext
754                                 0u,                                                                                             // VkPipelineLayoutCreateFlags  flags
755                                 1u,                                                                                             // deUint32                                             setLayoutCount
756                                 &descriptorSetLayouts.back().get(),                             // const VkDescriptorSetLayout* pSetLayouts
757                                 0u,                                                                                             // deUint32                                             pushConstantRangeCount
758                                 DE_NULL                                                                                 // const VkPushConstantRange*   pPushConstantRanges
759                         };
760
761                         pipelineLayouts.push_back(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
762                 }
763
764                 // Update descriptor set if needed.
765                 if (numInputAttachments > 0u)
766                 {
767                         // Assuming there's only one input attachment at most.
768                         DE_ASSERT(numInputAttachments == 1u);
769
770
771                         const VkDescriptorSetAllocateInfo       descriptorSetAllocateInfo       =
772                         {
773                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                              sType
774                                 DE_NULL,                                                                                // const void*                                  pNext
775                                 *m_descriptorPool,                                                              // VkDescriptorPool                             descriptorPool
776                                 1u,                                                                                             // deUint32                                             descriptorSetCount
777                                 &descriptorSetLayouts.back().get(),                             // const VkDescriptorSetLayout* pSetLayouts
778                         };
779
780                         descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo));
781
782                         for (size_t i = 0; i < imageViews.size(); i++)
783                         {
784                                 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
785                                 {
786                                         const VkDescriptorImageInfo     inputImageInfo  =
787                                         {
788                                                 DE_NULL,                                                                        // VkSampler            sampler
789                                                 *imageViews[i],                                                         // VkImageView          imageView
790                                                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        imageLayout
791                                         };
792
793                                         const VkWriteDescriptorSet      descriptorWrite =
794                                         {
795                                                 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType                                      sType
796                                                 DE_NULL,                                                                // const void*                                          pNext
797                                                 *descriptorSets.back(),                                 // VkDescriptorSet                                      dstSet
798                                                 0u,                                                                             // deUint32                                                     dstBinding
799                                                 0u,                                                                             // deUint32                                                     dstArrayElement
800                                                 1u,                                                                             // deUint32                                                     descriptorCount
801                                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType                                     descriptorType
802                                                 &inputImageInfo,                                                // const VkDescriptorImageInfo*         pImageInfo
803                                                 DE_NULL,                                                                // const VkDescriptorBufferInfo*        pBufferInfo
804                                                 DE_NULL                                                                 // const VkBufferView*                          pTexelBufferView
805                                         };
806                                         vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
807                                 }
808                         }
809                 }
810
811                 // Create pipeline.
812                 {
813                         const VkVertexInputBindingDescription           vertexInputBindingDescription           =
814                         {
815                                 0u,                                                             // deUint32                                     binding
816                                 (deUint32)sizeof(Vertex4RGBA),                  // deUint32                                     strideInBytes
817                                 VK_VERTEX_INPUT_RATE_VERTEX             // VkVertexInputStepRate        inputRate
818                         };
819
820                         const VkVertexInputAttributeDescription         vertexInputAttributeDescriptions[2]     =
821                         {
822                                 {
823                                         0u,                                                             // deUint32     location
824                                         0u,                                                             // deUint32     binding
825                                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat     format
826                                         0u                                                              // deUint32     offset
827                                 },
828                                 {
829                                         1u,                                                             // deUint32     location
830                                         0u,                                                             // deUint32     binding
831                                         VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat     format
832                                         (deUint32)(sizeof(float) * 4),  // deUint32     offset
833                                 }
834                         };
835
836                         const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams                          =
837                         {
838                                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType
839                                 DE_NULL,                                                                                                        // const void*                                                          pNext
840                                 0u,                                                                                                                     // VkPipelineVertexInputStateCreateFlags        flags
841                                 1u,                                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount
842                                 &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions
843                                 2u,                                                                                                                     // deUint32                                                                     vertexAttributeDescriptionCount
844                                 vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions
845                         };
846
847                         const VkColorComponentFlags                                     writeMask                                                       = noColorWrite ? 0 : VK_COLOR_COMPONENT_R_BIT   // VkColorComponentFlags        colorWriteMask
848                                                                                                                                                                                                                            | VK_COLOR_COMPONENT_G_BIT
849                                                                                                                                                                                                                            | VK_COLOR_COMPONENT_B_BIT
850                                                                                                                                                                                                                            | VK_COLOR_COMPONENT_A_BIT;
851
852                         const VkPipelineColorBlendAttachmentState       colorBlendAttachmentState                       =
853                         {
854                                 m_testParams.alphaBlend,                                // VkBool32                                     blendEnable
855                                 VK_BLEND_FACTOR_SRC_ALPHA,                              // VkBlendFactor                        srcColorBlendFactor
856                                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,    // VkBlendFactor                        dstColorBlendFactor
857                                 VK_BLEND_OP_ADD,                                                // VkBlendOp                            colorBlendOp
858                                 VK_BLEND_FACTOR_ONE,                                    // VkBlendFactor                        srcAlphaBlendFactor
859                                 VK_BLEND_FACTOR_ZERO,                                   // VkBlendFactor                        dstAlphaBlendFactor
860                                 VK_BLEND_OP_ADD,                                                // VkBlendOp                            alphaBlendOp
861                                 writeMask                                                               // VkColorComponentFlags        colorWriteMask
862                         };
863
864                         const VkPipelineColorBlendStateCreateInfo       colorBlendStateParams                           =
865                         {
866                                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType
867                                 DE_NULL,                                                                                                        // const void*                                                                  pNext
868                                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags
869                                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable
870                                 VK_LOGIC_OP_CLEAR,                                                                                      // VkLogicOp                                                                    logicOp
871                                 1u,                                                                                                                     // deUint32                                                                             attachmentCount
872                                 &colorBlendAttachmentState,                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments
873                                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4]
874                         };
875
876                         const VkStencilOpState                                                  stencilOpState                                  =
877                         {
878                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  failOp
879                                 VK_STENCIL_OP_REPLACE,  // VkStencilOp  passOp
880                                 VK_STENCIL_OP_KEEP,             // VkStencilOp  depthFailOp
881                                 VK_COMPARE_OP_GREATER,  // VkCompareOp  compareOp
882                                 0xff,                                   // deUint32             compareMask
883                                 0xff,                                   // deUint32             writeMask
884                                 0xff                                    // deUint32             reference
885                         };
886
887                         const VkPipelineDepthStencilStateCreateInfo             depthStencilStateParams                 =
888                         {
889                                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType
890                                 DE_NULL,                                                                                                        // const void*                                                          pNext
891                                 0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags
892                                 depthTest,                                                                                                      // VkBool32                                                                     depthTestEnable
893                                 VK_TRUE,                                                                                                        // VkBool32                                                                     depthWriteEnable
894                                 VK_COMPARE_OP_GREATER,                                                                          // VkCompareOp                                                          depthCompareOp
895                                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable
896                                 stencilTest,                                                                                            // VkBool32                                                                     stencilTestEnable
897                                 stencilOpState,                                                                                         // VkStencilOpState                                                     front
898                                 stencilOpState,                                                                                         // VkStencilOpState                                                     back
899                                 0.0f,                                                                                                           // float                                                                        minDepthBounds
900                                 1.0f,                                                                                                           // float                                                                        maxDepthBounds
901                         };
902
903                         const std::vector<VkViewport>                                   viewports                                               (1, makeViewport(m_imageSize));
904                         const std::vector<VkRect2D>                                             scissors                                                (1, makeRect2D(m_renderSize));
905                         VkShaderModule                                                                  fragShader                                              = *fragmentShaderModule;
906
907                         if (numInputAttachments > 0u)
908                                 fragShader = *fragmentShaderModuleInput;
909                         else if (m_testParams.alphaBlend)
910                                 fragShader = *fragmentShaderModuleBlend;
911
912                         pipelines.push_back(makeGraphicsPipeline(
913                                 vk,                                                                             // const DeviceInterface&                                               vk
914                                 vkDevice,                                                               // const VkDevice                                                               device
915                                 *pipelineLayouts.back(),                                // const VkPipelineLayout                                               pipelineLayout
916                                 *vertexShaderModule,                                    // const VkShaderModule                                                 vertexShaderModule
917                                 DE_NULL,                                                                // const VkShaderModule                                                 tessellationControlModule
918                                 DE_NULL,                                                                // const VkShaderModule                                                 tessellationEvalModule
919                                 DE_NULL,                                                                // const VkShaderModule                                                 geometryShaderModule
920                                 fragShader,                                                             // const VkShaderModule                                                 fragmentShaderModule
921                                 *m_renderPass,                                                  // const VkRenderPass                                                   renderPass
922                                 viewports,                                                              // const std::vector<VkViewport>&                               viewports
923                                 scissors,                                                               // const std::vector<VkRect2D>&                                 scissors
924                                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,    // const VkPrimitiveTopology                                    topology
925                                 (deUint32)pipelines.size(),                             // const deUint32                                                               subpass
926                                 0u,                                                                             // const deUint32                                                               patchControlPoints
927                                 &vertexInputStateParams,                                // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
928                                 DE_NULL,                                                                // const VkPipelineRasterizationStateCreateInfo*        rasterizationStateCreateInfo
929                                 DE_NULL,                                                                // const VkPipelineMultisampleStateCreateInfo*  multisampleStateCreateInfo
930                                 &depthStencilStateParams,                               // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
931                                 &colorBlendStateParams));                               // const VkPipelineColorBlendStateCreateInfo*   colorBlendStateCreateInfo
932                 }
933         }
934
935         // Create vertex buffer.
936         {
937                 const VkBufferCreateInfo        vertexBufferParams      =
938                 {
939                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                           // VkStructureType              sType
940                         DE_NULL,                                                                                                        // const void*                  pNext
941                         0u,                                                                                                                     // VkBufferCreateFlags  flags
942                         (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),        // VkDeviceSize                 size
943                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                                                      // VkBufferUsageFlags   usage
944                         VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                sharingMode
945                         1u,                                                                                                                     // deUint32                             queueFamilyIndexCount
946                         &queueFamilyIndex                                                                                       // const deUint32*              pQueueFamilyIndices
947                 };
948
949                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
950                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
951
952                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
953
954                 // Upload vertex data.
955                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
956                 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
957         }
958
959         // Create command pool.
960         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
961
962         // Create command buffer.
963         if (m_testParams.renderPassType == RENDERPASS_TYPE_LEGACY)
964                 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
965         else
966                 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
967
968         // Submit commands.
969         submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
970
971         bool pass = true;
972
973         // Verify selected attachments.
974         for (size_t i = 0; i < m_testParams.attachments.size(); i++)
975         {
976                 if (m_testParams.attachments[i].verifyInner || m_testParams.attachments[i].verifyOuter)
977                 {
978                         de::MovePtr<tcu::TextureLevel>          textureLevelResult;
979
980                         SimpleAllocator                                         allocator                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
981
982                         if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_DEPTH)
983                         {
984                                 textureLevelResult = pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_D24_UNORM_S8_UINT, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
985                         }
986                         else if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_STENCIL)
987                         {
988                                 textureLevelResult = pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_D24_UNORM_S8_UINT, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
989                         }
990                         else
991                         {
992                                 textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_R8G8B8A8_UNORM, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
993                         }
994
995                         const tcu::ConstPixelBufferAccess&      access                          = textureLevelResult->getAccess();
996
997                         // Log attachment contents
998                         m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "")
999                                                                                                 << tcu::TestLog::Image("Attachment " + de::toString(i), "", access)
1000                                                                                                 << tcu::TestLog::EndImageSet;
1001
1002                         for (int y = 0; y < access.getHeight(); y++)
1003                                 for (int x = 0; x < access.getWidth(); x++)
1004                                 {
1005                                         const bool              inner   = x < (int)m_renderSize.x() && y < (int)m_renderSize.y();
1006
1007                                         if (inner && !m_testParams.attachments[i].verifyInner)
1008                                                 continue;
1009                                         if (!inner && !m_testParams.attachments[i].verifyOuter)
1010                                                 continue;
1011
1012                                         const tcu::Vec4 ref             = inner ? m_testParams.attachments[i].innerRef : m_testParams.attachments[i].outerRef;
1013                                         const tcu::Vec4 p               = access.getPixel(x, y);
1014
1015                                         for (int c = 0; c < 4; c++)
1016                                                 if (fabs(p[c] - ref[c]) > 0.01f)
1017                                                         pass = false;
1018                                 }
1019
1020                 }
1021         }
1022
1023         if (pass)
1024                 return tcu::TestStatus::pass("Pass");
1025         else
1026                 return tcu::TestStatus::fail("Fail");
1027 }
1028
1029 } // anonymous
1030
1031 tcu::TestCaseGroup* createRenderPassLoadStoreOpNoneTests (tcu::TestContext& testCtx, const RenderPassType renderPassType)
1032 {
1033         de::MovePtr<tcu::TestCaseGroup>         opNoneTests             (new tcu::TestCaseGroup(testCtx, "load_store_op_none", ""));
1034
1035         const tcu::Vec4 red                     (1.0f, 0.0f, 0.0f, 1.0f);
1036         const tcu::Vec4 green           (0.0f, 1.0f, 0.0f, 1.0f);
1037         const tcu::Vec4 magenta         (1.0f, 0.0f, 1.0f, 1.0f);
1038         const tcu::Vec4 darkBlue        (0.0f, 0.0f, 0.5f, 1.0f);
1039         const tcu::Vec4 blend           (0.5f, 0.0f, 0.25f, 0.5f);
1040         const tcu::Vec4 depthInit       (0.5f, 0.0f, 0.0f, 1.0f);
1041         const tcu::Vec4 depthFull       (1.0f, 0.0f, 0.0f, 1.0f);
1042         const tcu::Vec4 stencilInit     (128.0f, 0.0f, 0.0f, 1.0f);
1043         const tcu::Vec4 stencilFull     (255.0f, 0.0f, 0.0f, 1.0f);
1044
1045         // Preinitialize attachments 0 and 1 to green.
1046         // Subpass 0: draw a red rectangle inside attachment 0.
1047         // Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to
1048         // attachment 1.
1049         // After the render pass attachment 0 has undefined values inside the render area because of the shader writes with
1050         // store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the
1051         // preinitialized green outside the render area and magenta inside.
1052         {
1053                 TestParams params;
1054                 params.alphaBlend = false;
1055                 params.renderPassType = renderPassType;
1056                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1057                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1058                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1059                                                                           ATTACHMENT_INIT_PRE,
1060                                                                           false, green,
1061                                                                           true, green});
1062                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1063                                                                           VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1064                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1065                                                                           ATTACHMENT_INIT_PRE,
1066                                                                           true, magenta,
1067                                                                           true, green});
1068                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1069                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u});
1070
1071                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", "", params));
1072         }
1073
1074         // Preinitialize color attachment to green. Use a render pass with load and store ops none, but
1075         // disable color writes using an empty color mask. The color attachment image should have the original
1076         // preinitialized value after the render pass.
1077         {
1078                 TestParams params;
1079                 params.alphaBlend = false;
1080                 params.renderPassType = renderPassType;
1081                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1082                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1083                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1084                                                                           ATTACHMENT_INIT_PRE,
1085                                                                           true, green,
1086                                                                           true, green});
1087                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_WRITE_OFF}}, 1u});
1088
1089                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", "", params));
1090         }
1091
1092         // Preinitialize color attachment to green. Use a render pass with load and store ops none, and
1093         // write a rectange to the color buffer. The render area is undefined, but the outside area should
1094         // still have the preinitialized color.
1095         {
1096                 TestParams params;
1097                 params.alphaBlend = false;
1098                 params.renderPassType = renderPassType;
1099                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1100                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1101                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1102                                                                           ATTACHMENT_INIT_PRE,
1103                                                                           false, green,
1104                                                                           true, green});
1105                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1106
1107                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", "", params));
1108         }
1109
1110         // Preinitialize color attachment to green. Use a subpass with no draw calls but instead
1111         // do an attachment clear command using dark blue color. Using load op none preserves the preinitialized
1112         // data and store op store causes the cleared blue render area to be present after the render pass.
1113         {
1114                 TestParams params;
1115                 params.alphaBlend = false;
1116                 params.renderPassType = renderPassType;
1117                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1118                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1119                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1120                                                                           ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1121                                                                           true, darkBlue,
1122                                                                           true, green});
1123                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 0u});
1124
1125                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", "", params));
1126         }
1127
1128         // Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed
1129         // by an alpha blender draw. Load op is none preserves the preinitialized data and store op store
1130         // keeps the blended color inside the render area after the render pass.
1131         {
1132                 TestParams params;
1133                 params.alphaBlend = true;
1134                 params.renderPassType = renderPassType;
1135                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1136                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1137                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1138                                                                           ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1139                                                                           true, blend,
1140                                                                           true, green});
1141                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1142
1143                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", "", params));
1144         }
1145
1146         // Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined  because load op 'none'.
1147         // Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values.
1148         // Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1.
1149         // After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care',
1150         // but the outside area should still have the preinitialized content.
1151         // Attachment 1 should have the preinitialized green outside render area and magenta inside.
1152         {
1153                 TestParams params;
1154                 params.alphaBlend = false;
1155                 params.renderPassType = renderPassType;
1156                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1157                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1158                                                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
1159                                                                           ATTACHMENT_INIT_PRE,
1160                                                                           false, green,
1161                                                                           true, green});
1162                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1163                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1164                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1165                                                                           ATTACHMENT_INIT_PRE,
1166                                                                           true, magenta,
1167                                                                           true, green});
1168                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1169                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u});
1170
1171                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", "", params));
1172         }
1173
1174         // Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5.
1175         // Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1176         // depth buffer to 1.0.
1177         // This is followed by another draw with a blue rectangle using the same depth of 1.0. This time
1178         // the depth test fails and nothing is written.
1179         // After the renderpass the red color should remain inside the render area of the color buffer.
1180         // Store op 'store' for depth buffer makes the written values undefined, but the pixels outside
1181         // render area should still contain the original value of 0.5.
1182         {
1183                 TestParams params;
1184                 params.alphaBlend = false;
1185                 params.renderPassType = renderPassType;
1186                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1187                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1188                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1189                                                                           ATTACHMENT_INIT_PRE,
1190                                                                           true, red,
1191                                                                           true, green});
1192                 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1193                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1194                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1195                                                                           ATTACHMENT_INIT_PRE,
1196                                                                           false, depthInit,
1197                                                                           true, depthInit});
1198                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u});
1199
1200                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_load_store_op_none", "", params));
1201         }
1202
1203         // Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but
1204         // disable depth test which also disables depth writes. The depth attachment should have the original
1205         // preinitialized value after the render pass.
1206         {
1207                 TestParams params;
1208                 params.alphaBlend = false;
1209                 params.renderPassType = renderPassType;
1210                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1211                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1212                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1213                                                                           ATTACHMENT_INIT_PRE,
1214                                                                           true, red,
1215                                                                           true, green});
1216                 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1217                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1218                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1219                                                                           ATTACHMENT_INIT_PRE,
1220                                                                           true, depthInit,
1221                                                                           true, depthInit});
1222                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_WRITE_OFF}}, 1u});
1223
1224                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_none_store_op_none_write_off", "", params));
1225         }
1226
1227         // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1228         // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1229         // depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the
1230         // shader updated value of 1.0.
1231         {
1232                 TestParams params;
1233                 params.alphaBlend = false;
1234                 params.renderPassType = renderPassType;
1235                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1236                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1237                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1238                                                                           ATTACHMENT_INIT_PRE,
1239                                                                           true, red,
1240                                                                           true, green});
1241                 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1242                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1243                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1244                                                                           ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1245                                                                           true, depthFull,
1246                                                                           true, depthInit});
1247                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u});
1248
1249                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_none_store_op_store", "", params));
1250         }
1251
1252         // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1253         // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass.
1254         // After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render
1255         // are is undefined because of store op 'don't care', but the outside should have the original value of 0.5.
1256         {
1257                 TestParams params;
1258                 params.alphaBlend = false;
1259                 params.renderPassType = renderPassType;
1260                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1261                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1262                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1263                                                                           ATTACHMENT_INIT_PRE,
1264                                                                           true, red,
1265                                                                           true, green});
1266                 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1267                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1268                                                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
1269                                                                           ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1270                                                                           false, depthFull,
1271                                                                           true, depthInit});
1272                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u});
1273
1274                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_none_store_op_dontcare", "", params));
1275         }
1276
1277         // Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128.
1278         // Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test
1279         // will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time
1280         // the stencil test fails and nothing is written.
1281         // After the renderpass the red color should remain inside the render area of the color buffer.
1282         // Store op 'store' for stencil buffer makes the written values undefined, but the pixels outside
1283         // render area should still contain the original value of 128.
1284         {
1285                 TestParams params;
1286                 params.alphaBlend = false;
1287                 params.renderPassType = renderPassType;
1288                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1289                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1290                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1291                                                                           ATTACHMENT_INIT_PRE,
1292                                                                           true, red,
1293                                                                           true, green});
1294                 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1295                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1296                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1297                                                                           ATTACHMENT_INIT_PRE,
1298                                                                           false, stencilInit,
1299                                                                           true, stencilInit});
1300                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u});
1301
1302                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_load_store_op_none", "", params));
1303         }
1304
1305         // Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but
1306         // disable stencil test which also disables stencil writes. The stencil attachment should have the original
1307         // preinitialized value after the render pass.
1308         {
1309                 TestParams params;
1310                 params.alphaBlend = false;
1311                 params.renderPassType = renderPassType;
1312                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1313                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1314                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1315                                                                           ATTACHMENT_INIT_PRE,
1316                                                                           true, red,
1317                                                                           true, green});
1318                 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1319                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1320                                                                           VK_ATTACHMENT_STORE_OP_NONE_EXT,
1321                                                                           ATTACHMENT_INIT_PRE,
1322                                                                           true, stencilInit,
1323                                                                           true, stencilInit});
1324                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_WRITE_OFF}}, 1u});
1325
1326                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_none_write_off", "", params));
1327         }
1328
1329         // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1330         // using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update
1331         // stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the
1332         // shader updated value of 255.
1333         {
1334                 TestParams params;
1335                 params.alphaBlend = false;
1336                 params.renderPassType = renderPassType;
1337                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1338                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1339                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1340                                                                           ATTACHMENT_INIT_PRE,
1341                                                                           true, red,
1342                                                                           true, green});
1343                 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1344                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1345                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1346                                                                           ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1347                                                                           true, stencilFull,
1348                                                                           true, stencilInit});
1349                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u});
1350
1351                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_store", "", params));
1352         }
1353
1354         // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1355         // using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass.
1356         // After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render
1357         // are is undefined because of store op 'don't care', but the outside should have the original value of 128.
1358         {
1359                 TestParams params;
1360                 params.alphaBlend = false;
1361                 params.renderPassType = renderPassType;
1362                 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1363                                                                           VK_ATTACHMENT_LOAD_OP_LOAD,
1364                                                                           VK_ATTACHMENT_STORE_OP_STORE,
1365                                                                           ATTACHMENT_INIT_PRE,
1366                                                                           true, red,
1367                                                                           true, green});
1368                 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1369                                                                           VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1370                                                                           VK_ATTACHMENT_STORE_OP_DONT_CARE,
1371                                                                           ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1372                                                                           false, stencilFull,
1373                                                                           true, stencilInit});
1374                 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u});
1375
1376                 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_dontcare", "", params));
1377         }
1378
1379         return opNoneTests.release();
1380 }
1381
1382 } // renderpass
1383 } // vkt