Merge vk-gl-cts/vulkan-cts-1.3.3 into vk-gl-cts/vulkan-cts-1.3.4
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / renderpass / vktRenderPassUnusedAttachmentTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 Google Inc.
7  * Copyright (c) 2015 Imagination Technologies Ltd.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Tests attachments unused by subpasses
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktRenderPassUnusedAttachmentTests.hpp"
27 #include "pipeline/vktPipelineImageUtil.hpp"
28 #include "vktRenderPassTestsUtil.hpp"
29 #include "vktTestCase.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuPlatform.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTestLog.hpp"
45 #include "deStringUtil.hpp"
46 #include "deUniquePtr.hpp"
47 #include "deRandom.hpp"
48 #include <cstring>
49 #include <set>
50 #include <sstream>
51 #include <vector>
52
53 namespace vkt
54 {
55 namespace renderpass
56 {
57
58 using namespace vk;
59
60 namespace
61 {
62
63 struct TestParams
64 {
65         VkAttachmentLoadOp      loadOp;
66         VkAttachmentStoreOp     storeOp;
67         VkAttachmentLoadOp      stencilLoadOp;
68         VkAttachmentStoreOp     stencilStoreOp;
69         RenderingType           renderingType;
70 };
71
72 struct Vertex4RGBA
73 {
74         tcu::Vec4 position;
75         tcu::Vec4 color;
76 };
77
78 std::vector<Vertex4RGBA> createQuad (void)
79 {
80         std::vector<Vertex4RGBA>        vertices;
81
82         const float                     size                            = 0.8f;
83         const tcu::Vec4         color                           (0.2f, 0.3f, 0.1f, 1.0f);
84         const Vertex4RGBA       lowerLeftVertex         = {tcu::Vec4(-size, -size, 0.0f, 1.0f), color};
85         const Vertex4RGBA       lowerRightVertex        = {tcu::Vec4(size, -size, 0.0f, 1.0f), color};
86         const Vertex4RGBA       upperLeftVertex         = {tcu::Vec4(-size, size, 0.0f, 1.0f), color};
87         const Vertex4RGBA       upperRightVertex        = {tcu::Vec4(size, size, 0.0f, 1.0f), color};
88
89         vertices.push_back(lowerLeftVertex);
90         vertices.push_back(lowerRightVertex);
91         vertices.push_back(upperLeftVertex);
92         vertices.push_back(upperLeftVertex);
93         vertices.push_back(lowerRightVertex);
94         vertices.push_back(upperRightVertex);
95
96         return vertices;
97 }
98
99 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
100 Move<VkRenderPass> createRenderPass (const DeviceInterface&     vk,
101                                                                          VkDevice                               vkDevice,
102                                                                          const TestParams               testParams)
103 {
104         const VkImageAspectFlags        aspectMask                                              = testParams.renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
105         const AttachmentDesc            attachmentDescriptions[]                =
106         {
107                 // Result attachment
108                 AttachmentDesc (
109                         DE_NULL,                                                                        // const void*                                          pNext
110                         (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags
111                         VK_FORMAT_R8G8B8A8_UNORM,                                       // VkFormat                                                     format
112                         VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples
113                         VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp
114                         VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp
115                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp
116                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp
117                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                                        initialLayout
118                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout
119                 ),
120                 // Unused attachment
121                 AttachmentDesc (
122                         DE_NULL,                                                                        // const void*                                          pNext
123                         (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags
124                         VK_FORMAT_R8G8B8A8_UNORM,                                       // VkFormat                                                     format
125                         VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples
126                         testParams.loadOp,                                                      // VkAttachmentLoadOp                           loadOp
127                         testParams.storeOp,                                                     // VkAttachmentStoreOp                          storeOp
128                         testParams.stencilLoadOp,                                       // VkAttachmentLoadOp                           stencilLoadOp
129                         testParams.stencilStoreOp,                                      // VkAttachmentStoreOp                          stencilStoreOp
130                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout
131                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout
132                 ),
133                 // Input attachment
134                 AttachmentDesc (
135                         DE_NULL,                                                                        // const void*                                          pNext
136                         (VkAttachmentDescriptionFlags)0,                        // VkAttachmentDescriptionFlags         flags
137                         VK_FORMAT_R8G8B8A8_UNORM,                                       // VkFormat                                                     format
138                         VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                        samples
139                         VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp
140                         VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp
141                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp
142                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp
143                         VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout                                        initialLayout
144                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout
145                 )
146         };
147
148         // Note: Attachment 1 is not referenced by any subpass.
149         const AttachmentRef                     resultAttachmentRefSubpass0             (
150                 DE_NULL,                                                                        // const void*                  pNext
151                 2u,                                                                                     // deUint32                             attachment
152                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                layout
153                 aspectMask                                                                      // VkImageAspectFlags   aspectMask
154         );
155
156         const AttachmentRef                     resultAttachmentRefSubpass1             (
157                 DE_NULL,                                                                        // const void*                  pNext
158                 0u,                                                                                     // deUint32                             attachment
159                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                layout
160                 aspectMask                                                                      // VkImageAspectFlags   aspectMask
161         );
162
163         const AttachmentRef                     inputAttachmentRefSubpass1              (
164                 DE_NULL,                                                                        // const void*                  pNext
165                 2u,                                                                                     // deUint32                             attachment
166                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,       // VkImageLayout                layout
167                 aspectMask                                                                      // VkImageAspectFlags   aspectMask
168         );
169
170         const SubpassDesc                       subpassDescriptions[]                   =
171         {
172                 SubpassDesc (
173                         DE_NULL,
174                         (VkSubpassDescriptionFlags)0,           // VkSubpassDescriptionFlags            flags
175                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                          pipelineBindPoint
176                         0u,                                                                     // deUint32                                                     viewMask
177                         0u,                                                                     // deUint32                                                     inputAttachmentCount
178                         DE_NULL,                                                        // const VkAttachmentReference*         pInputAttachments
179                         1u,                                                                     // deUint32                                                     colorAttachmentCount
180                         &resultAttachmentRefSubpass0,           // const VkAttachmentReference*         pColorAttachments
181                         DE_NULL,                                                        // const VkAttachmentReference*         pResolveAttachments
182                         DE_NULL,                                                        // const VkAttachmentReference*         pDepthStencilAttachment
183                         0u,                                                                     // deUint32                                                     preserveAttachmentCount
184                         DE_NULL                                                         // const deUint32*                                      pPreserveAttachments
185                 ),
186                 SubpassDesc (
187                         DE_NULL,
188                         (VkSubpassDescriptionFlags)0,           // VkSubpassDescriptionFlags            flags
189                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                          pipelineBindPoint
190                         0u,                                                                     // deUint32                                                     viewMask
191                         1u,                                                                     // deUint32                                                     inputAttachmentCount
192                         &inputAttachmentRefSubpass1,            // const VkAttachmentReference*         pInputAttachments
193                         1u,                                                                     // deUint32                                                     colorAttachmentCount
194                         &resultAttachmentRefSubpass1,           // const VkAttachmentReference*         pColorAttachments
195                         DE_NULL,                                                        // const VkAttachmentReference*         pResolveAttachments
196                         DE_NULL,                                                        // const VkAttachmentReference*         pDepthStencilAttachment
197                         0u,                                                                     // deUint32                                                     preserveAttachmentCount
198                         DE_NULL                                                         // const deUint32*                                      pPreserveAttachments
199                 )
200         };
201
202         const SubpassDep                        subpassDependency                               (
203                 DE_NULL,                                                                                // const void*                          pNext
204                 0u,                                                                                             // uint32_t                                     srcSubpass
205                 1u,                                                                                             // uint32_t                                     dstSubpass
206                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,  // VkPipelineStageFlags         srcStageMask
207                 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                  // VkPipelineStageFlags         dstStageMask
208                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        srcAccessMask
209                 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                    // VkAccessFlags                        dstAccessMask
210                 VK_DEPENDENCY_BY_REGION_BIT,                                    // VkDependencyFlags            dependencyFlags
211                 0u                                                                                              // deInt32                                      viewOffset
212         );
213
214         const RenderPassCreateInfo      renderPassInfo                                  (
215                 DE_NULL,                                                                        // const void*                                          pNext
216                 (VkRenderPassCreateFlags)0,                                     // VkRenderPassCreateFlags                      flags
217                 3u,                                                                                     // deUint32                                                     attachmentCount
218                 attachmentDescriptions,                                         // const VkAttachmentDescription*       pAttachments
219                 2u,                                                                                     // deUint32                                                     subpassCount
220                 subpassDescriptions,                                            // const VkSubpassDescription*          pSubpasses
221                 1u,                                                                                     // deUint32                                                     dependencyCount
222                 &subpassDependency,                                                     // const VkSubpassDependency*           pDependencies
223                 0u,                                                                                     // deUint32                                                     correlatedViewMaskCount
224                 DE_NULL                                                                         // const deUint32*                                      pCorrelatedViewMasks
225         );
226
227         return renderPassInfo.createRenderPass(vk, vkDevice);
228 }
229
230 class UnusedAttachmentTest : public vkt::TestCase
231 {
232 public:
233                                                                                 UnusedAttachmentTest    (tcu::TestContext&      testContext,
234                                                                                                                                  const std::string&     name,
235                                                                                                                                  const std::string&     description,
236                                                                                                                                  const TestParams&      testParams);
237         virtual                                                         ~UnusedAttachmentTest   (void);
238         virtual void                                            initPrograms                    (SourceCollections&     sourceCollections) const;
239         virtual TestInstance*                           createInstance                  (Context&                       context) const;
240 private:
241         const TestParams                                        m_testParams;
242 };
243
244 class UnusedAttachmentTestInstance : public vkt::TestInstance
245 {
246 public:
247                                                                                 UnusedAttachmentTestInstance    (Context&                               context,
248                                                                                                                                                  const TestParams&              testParams);
249         virtual                                                         ~UnusedAttachmentTestInstance   (void);
250         virtual tcu::TestStatus                         iterate                                                 (void);
251         template<typename RenderpassSubpass>
252         void                                                            createCommandBuffer                             (const DeviceInterface& vk,
253                                                                                                                                                  VkDevice                               vkDevice);
254 private:
255         tcu::TestStatus                                         verifyImage                                             (void);
256
257         const tcu::UVec2                                        m_renderSize;
258
259         Move<VkImage>                                           m_colorImage;
260         de::MovePtr<Allocation>                         m_colorImageAlloc;
261         Move<VkImageView>                                       m_colorAttachmentView;
262
263         Move<VkImage>                                           m_unusedImage;
264         de::MovePtr<Allocation>                         m_unusedImageAlloc;
265         Move<VkImageView>                                       m_unusedAttachmentView;
266
267         Move<VkImage>                                           m_inputImage;
268         de::MovePtr<Allocation>                         m_inputImageAlloc;
269         Move<VkImageView>                                       m_inputAttachmentView;
270
271         Move<VkDescriptorSetLayout>                     m_descriptorSetLayoutSubpass0;
272         Move<VkDescriptorSetLayout>                     m_descriptorSetLayoutSubpass1;
273         Move<VkDescriptorPool>                          m_descriptorPool;
274         Move<VkDescriptorSet>                           m_descriptorSetSubpass1;
275         Move<VkRenderPass>                                      m_renderPass;
276         Move<VkFramebuffer>                                     m_framebuffer;
277
278         Move<VkShaderModule>                            m_vertexShaderModule;
279         Move<VkShaderModule>                            m_fragmentShaderModuleSubpass0;
280         Move<VkShaderModule>                            m_fragmentShaderModuleSubpass1;
281
282         Move<VkBuffer>                                          m_vertexBuffer;
283         std::vector<Vertex4RGBA>                        m_vertices;
284         de::MovePtr<Allocation>                         m_vertexBufferAlloc;
285
286         Move<VkBuffer>                                          m_backingBuffer;
287         de::MovePtr<Allocation>                         m_backingBufferAlloc;
288
289         Move<VkPipelineLayout>                          m_pipelineLayoutSubpass0;
290         Move<VkPipelineLayout>                          m_pipelineLayoutSubpass1;
291         Move<VkPipeline>                                        m_graphicsPipelineSubpass0;
292         Move<VkPipeline>                                        m_graphicsPipelineSubpass1;
293
294         Move<VkCommandPool>                                     m_cmdPool;
295         Move<VkCommandBuffer>                           m_cmdBuffer;
296 };
297
298 UnusedAttachmentTest::UnusedAttachmentTest (tcu::TestContext&   testContext,
299                                                                                         const std::string&      name,
300                                                                                         const std::string&      description,
301                                                                                         const TestParams&       testParams)
302         : vkt::TestCase (testContext, name, description)
303         , m_testParams  (testParams)
304 {
305 }
306
307 UnusedAttachmentTest::~UnusedAttachmentTest (void)
308 {
309 }
310
311 TestInstance* UnusedAttachmentTest::createInstance (Context& context) const
312 {
313         return new UnusedAttachmentTestInstance(context, m_testParams);
314 }
315
316 void UnusedAttachmentTest::initPrograms (SourceCollections& sourceCollections) const
317 {
318         std::ostringstream fragmentSource;
319
320         sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
321                 "#version 450\n"
322                 "layout(location = 0) in highp vec4 position;\n"
323                 "layout(location = 1) in highp vec4 color;\n"
324                 "layout(location = 0) out highp vec4 vtxColor;\n"
325                 "void main (void)\n"
326                 "{\n"
327                 "       gl_Position = position;\n"
328                 "       vtxColor = color;\n"
329                 "}\n");
330
331         sourceCollections.glslSources.add("color_frag_sb0") << glu::FragmentSource(
332                 "#version 450\n"
333                 "layout(location = 0) in highp vec4 vtxColor;\n"
334                 "layout(location = 0) out highp vec4 fragColor;\n"
335                 "void main (void)\n"
336                 "{\n"
337                 "       fragColor = vtxColor;\n"
338                 "}\n");
339
340         sourceCollections.glslSources.add("color_frag_sb1") << glu::FragmentSource(
341                 "#version 450\n"
342                 "layout(location = 0) in highp vec4 vtxColor;\n"
343                 "layout(location = 0) out highp vec4 fragColor;\n"
344                 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;"
345                 "void main (void)\n"
346                 "{\n"
347                 "       fragColor = subpassLoad(inputColor) + vtxColor;\n"
348                 "}\n");
349 }
350
351 UnusedAttachmentTestInstance::UnusedAttachmentTestInstance (Context&                    context,
352                                                                                                                         const TestParams&       testParams)
353         : vkt::TestInstance     (context)
354         , m_renderSize          (32u, 32u)
355         , m_vertices            (createQuad())
356 {
357         const DeviceInterface&          vk                                              = m_context.getDeviceInterface();
358         const VkDevice                          vkDevice                                = m_context.getDevice();
359         const deUint32                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
360         SimpleAllocator                         memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
361         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
362
363         // Check for renderpass2 extension if used
364         if (testParams.renderingType == RENDERING_TYPE_RENDERPASS2)
365                 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
366
367         // Create color image
368         {
369                 const VkImageCreateInfo colorImageParams =
370                 {
371                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
372                         DE_NULL,                                                                                                                                        // const void*                          pNext;
373                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
374                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
375                         VK_FORMAT_R8G8B8A8_UNORM,                                                                                                       // VkFormat                                     format;
376                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
377                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
378                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
379                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
380                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
381                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
382                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
383                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
384                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
385                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
386                 };
387
388                 m_colorImage                    = createImage(vk, vkDevice, &colorImageParams);
389
390                 // Allocate and bind color image memory
391                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
392                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
393         }
394
395         // Create image which is not used by any subpass
396         {
397                 const VkImageCreateInfo unusedImageParams =
398                 {
399                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
400                         DE_NULL,                                                                                                                                        // const void*                          pNext;
401                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
402                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
403                         VK_FORMAT_R8G8B8A8_UNORM,                                                                                                       // VkFormat                                     format;
404                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
405                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
406                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
407                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
408                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
409                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
410                                 | VK_IMAGE_USAGE_TRANSFER_DST_BIT,                                                                              // VkImageUsageFlags            usage;
411                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
412                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
413                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
414                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
415                 };
416
417                 m_unusedImage                   = createImage(vk, vkDevice, &unusedImageParams);
418
419                 // Allocate and bind unused image memory
420                 VkMemoryRequirements    memoryRequirements      = getImageMemoryRequirements(vk, vkDevice, *m_unusedImage);
421
422                 m_unusedImageAlloc              = memAlloc.allocate(memoryRequirements, MemoryRequirement::Any);
423                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_unusedImage, m_unusedImageAlloc->getMemory(), m_unusedImageAlloc->getOffset()));
424
425                 // Clear image with specific value to verify the contents don't change
426                 {
427                         const VkImageAspectFlags                aspectMask      = VK_IMAGE_ASPECT_COLOR_BIT;
428                         Move<VkCommandPool>                             cmdPool;
429                         Move<VkCommandBuffer>                   cmdBuffer;
430
431                         VkClearValue                                    clearValue;
432                         clearValue.color.float32[0] = 0.1f;
433                         clearValue.color.float32[1] = 0.2f;
434                         clearValue.color.float32[2] = 0.3f;
435                         clearValue.color.float32[3] = 0.4f;
436
437                         // Create command pool and buffer
438                         cmdPool         = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
439                         cmdBuffer       = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
440
441                         const VkImageMemoryBarrier preImageBarrier =
442                         {
443                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType                      sType;
444                                 DE_NULL,                                                                // const void*                          pNext;
445                                 0u,                                                                             // VkAccessFlags                        srcAccessMask;
446                                 VK_ACCESS_TRANSFER_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
447                                 VK_IMAGE_LAYOUT_UNDEFINED,                              // VkImageLayout                        oldLayout;
448                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,   // VkImageLayout                        newLayout;
449                                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     srcQueueFamilyIndex;
450                                 VK_QUEUE_FAMILY_IGNORED,                                // deUint32                                     dstQueueFamilyIndex;
451                                 *m_unusedImage,                                                 // VkImage                                      image;
452                                 {                                                                               // VkImageSubresourceRange      subresourceRange;
453                                         aspectMask,                                                     // VkImageAspect                        aspect;
454                                         0u,                                                                     // deUint32                                     baseMipLevel;
455                                         1u,                                                                     // deUint32                                     mipLevels;
456                                         0u,                                                                     // deUint32                                     baseArraySlice;
457                                         1u                                                                      // deUint32                                     arraySize;
458                                 }
459                         };
460
461                         const VkImageMemoryBarrier postImageBarrier =
462                         {
463                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,         // VkStructureType                      sType;
464                                 DE_NULL,                                                                        // const void*                          pNext;
465                                 VK_ACCESS_TRANSFER_WRITE_BIT,                           // VkAccessFlags                        srcAccessMask;
466                                 VK_ACCESS_SHADER_READ_BIT,                                      // VkAccessFlags                        dstAccessMask;
467                                 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,           // VkImageLayout                        oldLayout;
468                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
469                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     srcQueueFamilyIndex;
470                                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                                     dstQueueFamilyIndex;
471                                 *m_unusedImage,                                                         // VkImage                                      image;
472                                 {                                                                                       // VkImageSubresourceRange      subresourceRange;
473                                         aspectMask,                                                             // VkImageAspect                        aspect;
474                                         0u,                                                                             // deUint32                                     baseMipLevel;
475                                         1u,                                                                             // deUint32                                     mipLevels;
476                                         0u,                                                                             // deUint32                                     baseArraySlice;
477                                         1u                                                                              // deUint32                                     arraySize;
478                                 }
479                         };
480
481                         const VkImageSubresourceRange clearRange        =
482                         {
483                                 aspectMask,     // VkImageAspectFlags   aspectMask;
484                                 0u,                     // deUint32                             baseMipLevel;
485                                 1u,                     // deUint32                             levelCount;
486                                 0u,                     // deUint32                             baseArrayLayer;
487                                 1u                      // deUint32                             layerCount;
488                         };
489
490                         // Clear image
491                         beginCommandBuffer(vk, *cmdBuffer);
492                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
493                         vk.cmdClearColorImage(*cmdBuffer, *m_unusedImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.color, 1, &clearRange);
494                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
495                         endCommandBuffer(vk, *cmdBuffer);
496
497                         submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
498                 }
499         }
500
501         // Create input image
502         {
503                 const VkImageCreateInfo inputImageParams =
504                 {
505                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
506                         DE_NULL,                                                                                                                                        // const void*                          pNext;
507                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
508                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
509                         VK_FORMAT_R8G8B8A8_UNORM,                                                                                                       // VkFormat                                     format;
510                         { m_renderSize.x(), m_renderSize.y(), 1u },                                                                     // VkExtent3D                           extent;
511                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
512                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
513                         VK_SAMPLE_COUNT_1_BIT,                                                                                                          // VkSampleCountFlagBits        samples;
514                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
515                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,      // VkImageUsageFlags            usage;
516                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
517                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
518                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
519                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                       // VkImageLayout                        initialLayout;
520                 };
521
522                 m_inputImage = createImage(vk, vkDevice, &inputImageParams);
523
524                 // Allocate and bind input image memory
525                 m_inputImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_inputImage), MemoryRequirement::Any);
526                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_inputImage, m_inputImageAlloc->getMemory(), m_inputImageAlloc->getOffset()));
527         }
528
529         // Create color attachment view
530         {
531                 const VkImageViewCreateInfo colorAttachmentViewParams =
532                 {
533                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
534                         DE_NULL,                                                                                        // const void*                          pNext;
535                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
536                         *m_colorImage,                                                                          // VkImage                                      image;
537                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
538                         VK_FORMAT_R8G8B8A8_UNORM,                                                       // VkFormat                                     format;
539                         componentMappingRGBA,                                                           // VkChannelMapping                     channels;
540                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }           // VkImageSubresourceRange      subresourceRange;
541                 };
542
543                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
544         }
545
546         // Create unused attachment view
547         {
548                 const VkImageViewCreateInfo unusedAttachmentViewParams =
549                 {
550                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
551                         DE_NULL,                                                                                        // const void*                          pNext;
552                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
553                         *m_unusedImage,                                                                         // VkImage                                      image;
554                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
555                         VK_FORMAT_R8G8B8A8_UNORM,                                                       // VkFormat                                     format;
556                         componentMappingRGBA,                                                           // VkChannelMapping                     channels;
557                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }           // VkImageSubresourceRange      subresourceRange;
558                 };
559
560                 m_unusedAttachmentView = createImageView(vk, vkDevice, &unusedAttachmentViewParams);
561         }
562
563         // Create input attachment view
564         {
565                 const VkImageViewCreateInfo inputAttachmentViewParams =
566                 {
567                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
568                         DE_NULL,                                                                                        // const void*                          pNext;
569                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
570                         *m_inputImage,                                                                          // VkImage                                      image;
571                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
572                         VK_FORMAT_R8G8B8A8_UNORM,                                                       // VkFormat                                     format;
573                         componentMappingRGBA,                                                           // VkChannelMapping                     channels;
574                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }           // VkImageSubresourceRange      subresourceRange;
575                 };
576
577                 m_inputAttachmentView = createImageView(vk, vkDevice, &inputAttachmentViewParams);
578         }
579
580         // Create render pass
581         if (testParams.renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
582                 m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, testParams);
583         else
584                 m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
585
586         // Create framebuffer
587         {
588                 const VkImageView                               imageViews[]            =
589                 {
590                         *m_colorAttachmentView,
591                         *m_unusedAttachmentView,
592                         *m_inputAttachmentView
593                 };
594
595                 const VkFramebufferCreateInfo   framebufferParams       =
596                 {
597                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                      sType;
598                         DE_NULL,                                                                        // const void*                          pNext;
599                         0u,                                                                                     // VkFramebufferCreateFlags     flags;
600                         *m_renderPass,                                                          // VkRenderPass                         renderPass;
601                         3u,                                                                                     // deUint32                                     attachmentCount;
602                         imageViews,                                                                     // const VkImageView*           pAttachments;
603                         (deUint32)m_renderSize.x(),                                     // deUint32                                     width;
604                         (deUint32)m_renderSize.y(),                                     // deUint32                                     height;
605                         1u                                                                                      // deUint32                                     layers;
606                 };
607
608                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
609         }
610
611         // Create pipeline layout for subpass 0
612         {
613                 const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutParams       =
614                 {
615                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // VkStructureType                                              sType
616                         DE_NULL,                                                                                                // const void*                                                  pNext
617                         0u,                                                                                                             // VkDescriptorSetLayoutCreateFlags             flags
618                         0u,                                                                                                             // deUint32                                                             bindingCount
619                         DE_NULL                                                                                                 // const VkDescriptorSetLayoutBinding*  pBindings
620                 };
621                 m_descriptorSetLayoutSubpass0 = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
622
623                 const VkPipelineLayoutCreateInfo                pipelineLayoutParams            =
624                 {
625                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
626                         DE_NULL,                                                                                        // const void*                                          pNext;
627                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
628                         1u,                                                                                                     // deUint32                                                     setLayoutCount;
629                         &m_descriptorSetLayoutSubpass0.get(),                           // const VkDescriptorSetLayout*         pSetLayouts;
630                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
631                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
632                 };
633
634                 m_pipelineLayoutSubpass0 = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
635         }
636
637         // Create pipeline layout for subpass 1
638         {
639                 const VkDescriptorSetLayoutBinding              layoutBinding                           =
640                 {
641                         0u,                                                                             // deUint32                             binding;
642                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType             descriptorType;
643                         1u,                                                                             // deUint32                             descriptorCount;
644                         VK_SHADER_STAGE_FRAGMENT_BIT,                   // VkShaderStageFlags   stageFlags;
645                         DE_NULL                                                                 // const VkSampler*             pImmutableSamplers;
646                 };
647
648                 const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutParams       =
649                 {
650                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,    // VkStructureType                                              sType
651                         DE_NULL,                                                                                                // const void*                                                  pNext
652                         0u,                                                                                                             // VkDescriptorSetLayoutCreateFlags             flags
653                         1u,                                                                                                             // deUint32                                                             bindingCount
654                         &layoutBinding                                                                                  // const VkDescriptorSetLayoutBinding*  pBindings
655                 };
656                 m_descriptorSetLayoutSubpass1 = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
657
658                 const VkPipelineLayoutCreateInfo                pipelineLayoutParams            =
659                 {
660                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
661                         DE_NULL,                                                                                        // const void*                                          pNext;
662                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
663                         1u,                                                                                                     // deUint32                                                     setLayoutCount;
664                         &m_descriptorSetLayoutSubpass1.get(),                           // const VkDescriptorSetLayout*         pSetLayouts;
665                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
666                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
667                 };
668
669                 m_pipelineLayoutSubpass1 = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
670         }
671
672         // Update descriptor set
673         {
674                 const VkDescriptorPoolSize                      descriptorPoolSize                      =
675         {
676                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,    // VkDescriptorType             type;
677                         1u                                                                              // deUint32                             descriptorCount;
678                 };
679
680                 const VkDescriptorPoolCreateInfo        descriptorPoolCreateInfo        =
681                 {
682                         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,          // VkStructureType                              sType
683                         DE_NULL,                                                                                        // const void*                                  pNext
684                         VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,      // VkDescriptorPoolCreateFlags  flags
685                         1u,                                                 // deUint32                                         maxSets
686                         1u,                                                                                                     // deUint32                                             poolSizeCount
687                         &descriptorPoolSize                                                                     // const VkDescriptorPoolSize*  pPoolSizes
688                 };
689
690                 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
691
692                 const VkDescriptorSetAllocateInfo       descriptorSetAllocateInfo       =
693                 {
694                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                                      sType
695                         DE_NULL,                                                                                        // const void*                                          pNext
696                         *m_descriptorPool,                                                                      // VkDescriptorPool                                     descriptorPool
697                         1u,                                                                                                     // deUint32                                                     descriptorSetCount
698                         &m_descriptorSetLayoutSubpass1.get(),                           // const VkDescriptorSetLayout*         pSetLayouts
699                 };
700
701                 m_descriptorSetSubpass1 = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
702
703                 const VkDescriptorImageInfo                     inputImageInfo                          =
704                 {
705                         DE_NULL,                                                                        // VkSampleri           sampler;
706                         *m_inputAttachmentView,                                         // VkImageView          imageView;
707                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        imageLayout;
708                 };
709
710                 const VkWriteDescriptorSet                      descriptorWrite                         =
711                 {
712                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,         // VkStructureType                                      sType;
713                         DE_NULL,                                                                        // const void*                                          pNext;
714                         *m_descriptorSetSubpass1,                                       // VkDescriptorSet                                      dstSet;
715                         0u,                                                                                     // deUint32                                                     dstBinding;
716                         0u,                                                                                     // deUint32                                                     dstArrayElement;
717                         1u,                                                                                     // deUint32                                                     descriptorCount;
718                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,            // VkDescriptorType                                     descriptorType;
719                         &inputImageInfo,                                                        // const VkDescriptorImageInfo*         pImageInfo;
720                         DE_NULL,                                                                        // const VkDescriptorBufferInfo*        pBufferInfo;
721                         DE_NULL                                                                         // const VkBufferView*                          pTexelBufferView;
722                 };
723
724                 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
725         }
726
727         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
728         m_fragmentShaderModuleSubpass0  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_sb0"), 0);
729         m_fragmentShaderModuleSubpass1  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_sb1"), 0);
730
731         // Create pipelines
732         {
733                 const VkVertexInputBindingDescription           vertexInputBindingDescription           =
734                 {
735                         0u,                                                                     // deUint32                                     binding;
736                         sizeof(Vertex4RGBA),                            // deUint32                                     strideInBytes;
737                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        inputRate;
738                 };
739
740                 const VkVertexInputAttributeDescription         vertexInputAttributeDescriptions[2]     =
741                 {
742                         {
743                                 0u,                                                             // deUint32             location;
744                                 0u,                                                             // deUint32             binding;
745                                 VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat             format;
746                                 0u                                                              // deUint32             offset;
747                         },
748                         {
749                                 1u,                                                             // deUint32             location;
750                                 0u,                                                             // deUint32             binding;
751                                 VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat             format;
752                                 (deUint32)(sizeof(float) * 4),  // deUint32             offset;
753                         }
754                 };
755
756                 const VkPipelineVertexInputStateCreateInfo      vertexInputStateParams                          =
757                 {
758                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,      // VkStructureType                                                      sType;
759                         DE_NULL,                                                                                                        // const void*                                                          pNext;
760                         0u,                                                                                                                     // VkPipelineVertexInputStateCreateFlags        flags;
761                         1u,                                                                                                                     // deUint32                                                                     vertexBindingDescriptionCount;
762                         &vertexInputBindingDescription,                                                         // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
763                         2u,                                                                                                                     // deUint32                                                                     vertexAttributeDescriptionCount;
764                         vertexInputAttributeDescriptions                                                        // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
765                 };
766
767                 const std::vector<VkViewport>                           viewports                                                       (1, makeViewport(m_renderSize));
768                 const std::vector<VkRect2D>                                     scissors                                                        (1, makeRect2D(m_renderSize));
769
770                 {
771                         m_graphicsPipelineSubpass0 = makeGraphicsPipeline(vk,                                                                   // const DeviceInterface&                                               vk
772                                                                                                                           vkDevice,                                                             // const VkDevice                                                               device
773                                                                                                                           *m_pipelineLayoutSubpass0,                    // const VkPipelineLayout                                               pipelineLayout
774                                                                                                                           *m_vertexShaderModule,                                // const VkShaderModule                                                 vertexShaderModule
775                                                                                                                           DE_NULL,                                                              // const VkShaderModule                                                 tessellationControlModule
776                                                                                                                           DE_NULL,                                                              // const VkShaderModule                                                 tessellationEvalModule
777                                                                                                                           DE_NULL,                                                              // const VkShaderModule                                                 geometryShaderModule
778                                                                                                                           *m_fragmentShaderModuleSubpass0,              // const VkShaderModule                                                 fragmentShaderModule
779                                                                                                                           *m_renderPass,                                                // const VkRenderPass                                                   renderPass
780                                                                                                                           viewports,                                                    // const std::vector<VkViewport>&                               viewports
781                                                                                                                           scissors,                                                             // const std::vector<VkRect2D>&                                 scissors
782                                                                                                                           VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,  // const VkPrimitiveTopology                                    topology
783                                                                                                                           0u,                                                                   // const deUint32                                                               subpass
784                                                                                                                           0u,                                                                   // const deUint32                                                               patchControlPoints
785                                                                                                                           &vertexInputStateParams);                             // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
786
787                         m_graphicsPipelineSubpass1 = makeGraphicsPipeline(vk,                                                                   // const DeviceInterface&                                               vk
788                                                                                                                           vkDevice,                                                             // const VkDevice                                                               device
789                                                                                                                           *m_pipelineLayoutSubpass1,                    // const VkPipelineLayout                                               pipelineLayout
790                                                                                                                           *m_vertexShaderModule,                                // const VkShaderModule                                                 vertexShaderModule
791                                                                                                                           DE_NULL,                                                              // const VkShaderModule                                                 tessellationControlModule
792                                                                                                                           DE_NULL,                                                              // const VkShaderModule                                                 tessellationEvalModule
793                                                                                                                           DE_NULL,                                                              // const VkShaderModule                                                 geometryShaderModule
794                                                                                                                           *m_fragmentShaderModuleSubpass1,              // const VkShaderModule                                                 fragmentShaderModule
795                                                                                                                           *m_renderPass,                                                // const VkRenderPass                                                   renderPass
796                                                                                                                           viewports,                                                    // const std::vector<VkViewport>&                               viewports
797                                                                                                                           scissors,                                                             // const std::vector<VkRect2D>&                                 scissors
798                                                                                                                           VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,  // const VkPrimitiveTopology                                    topology
799                                                                                                                           1u,                                                                   // const deUint32                                                               subpass
800                                                                                                                           0u,                                                                   // const deUint32                                                               patchControlPoints
801                                                                                                                           &vertexInputStateParams);                             // const VkPipelineVertexInputStateCreateInfo*  vertexInputStateCreateInfo
802                 }
803         }
804
805         // Create vertex buffer
806         {
807                 const VkBufferCreateInfo vertexBufferParams =
808                 {
809                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,                                           // VkStructureType              sType;
810                         DE_NULL,                                                                                                        // const void*                  pNext;
811                         0u,                                                                                                                     // VkBufferCreateFlags  flags;
812                         (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),        // VkDeviceSize                 size;
813                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                                                      // VkBufferUsageFlags   usage;
814                         VK_SHARING_MODE_EXCLUSIVE,                                                                      // VkSharingMode                sharingMode;
815                         1u,                                                                                                                     // deUint32                             queueFamilyIndexCount;
816                         &queueFamilyIndex                                                                                       // const deUint32*              pQueueFamilyIndices;
817                 };
818
819                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
820                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
821
822                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
823
824                 // Upload vertex data
825                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
826                 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
827         }
828
829         // Create command pool
830         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
831
832         // Create command buffer
833         if (testParams.renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
834                 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice);
835         else
836                 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice);
837 }
838
839 UnusedAttachmentTestInstance::~UnusedAttachmentTestInstance (void)
840 {
841 }
842
843 template<typename RenderpassSubpass>
844 void UnusedAttachmentTestInstance::createCommandBuffer (const DeviceInterface&  vk,
845                                                                                                                 VkDevice                                vkDevice)
846 {
847         const typename RenderpassSubpass::SubpassBeginInfo      subpassBeginInfo        (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
848         const typename RenderpassSubpass::SubpassEndInfo        subpassEndInfo          (DE_NULL);
849
850         const VkClearValue attachmentClearValues[] =
851         {
852                 makeClearValueColorF32(0.5f, 0.5f, 0.5f, 1.0f), // color
853                 makeClearValueColorF32(0.5f, 0.5f, 0.5f, 1.0f), // unused
854                 makeClearValueColorF32(0.5f, 0.2f, 0.1f, 1.0f)  // input
855         };
856
857         const VkDeviceSize vertexBufferOffset = 0;
858
859         m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
860
861         beginCommandBuffer(vk, *m_cmdBuffer, 0u);
862
863         const VkRenderPassBeginInfo renderPassBeginInfo =
864         {
865                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,       // VkStructureType              sType;
866                 DE_NULL,                                                                        // const void*                  pNext;
867                 *m_renderPass,                                                          // VkRenderPass                 renderPass;
868                 *m_framebuffer,                                                         // VkFramebuffer                framebuffer;
869                 makeRect2D(m_renderSize),                                       // VkRect2D                             renderArea;
870                 3u,                                                                                     // uint32_t                             clearValueCount;
871                 attachmentClearValues                                           // const VkClearValue*  pClearValues;
872         };
873         RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
874
875         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineSubpass0);
876         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
877         vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
878         vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
879         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineSubpass1);
880         vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutSubpass1, 0, 1, &m_descriptorSetSubpass1.get(), 0, DE_NULL);
881         vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
882
883         RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
884         endCommandBuffer(vk, *m_cmdBuffer);
885 }
886
887 tcu::TestStatus UnusedAttachmentTestInstance::iterate (void)
888 {
889         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
890         const VkDevice                          vkDevice        = m_context.getDevice();
891         const VkQueue                           queue           = m_context.getUniversalQueue();
892
893         submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
894
895         return verifyImage();
896 }
897
898 tcu::TestStatus UnusedAttachmentTestInstance::verifyImage (void)
899 {
900         const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
901         const VkDevice                                          vkDevice                                = m_context.getDevice();
902         const VkQueue                                           queue                                   = m_context.getUniversalQueue();
903         const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
904         SimpleAllocator                                         allocator                               (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
905         de::UniquePtr<tcu::TextureLevel>        textureLevelResult              (pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, VK_FORMAT_R8G8B8A8_UNORM, m_renderSize).release());
906         const tcu::ConstPixelBufferAccess&      resultAccess                    = textureLevelResult->getAccess();
907         de::UniquePtr<tcu::TextureLevel>        textureLevelUnused              (pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_unusedImage, VK_FORMAT_R8G8B8A8_UNORM, m_renderSize).release());
908         const tcu::ConstPixelBufferAccess&      unusedAccess                    = textureLevelUnused->getAccess();
909         tcu::TestLog&                                           log                                             = m_context.getTestContext().getLog();
910
911         // Log images
912         log << tcu::TestLog::ImageSet("Result", "Result images")
913                 << tcu::TestLog::Image("Rendered", "Rendered image", resultAccess)
914                 << tcu::TestLog::Image("Unused", "Unused image", unusedAccess)
915                 << tcu::TestLog::EndImageSet;
916
917         // Check the unused image data hasn't changed.
918         for (int y = 0; y < unusedAccess.getHeight(); y++)
919                 for (int x = 0; x < unusedAccess.getWidth(); x++)
920                 {
921                         const tcu::Vec4 color = unusedAccess.getPixel(x, y);
922                         const tcu::Vec4 refColor = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f);
923                         for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
924                                 if (de::abs(color[cpnt] - refColor[cpnt]) > 0.01f)
925                                         return tcu::TestStatus::fail("Unused image contents has changed.");
926                 }
927
928         // Check for rendered result. Just a quick sanity check to see if correct color is found at the center of the quad.
929         const tcu::Vec4 resultColor = resultAccess.getPixel(resultAccess.getWidth() / 2, resultAccess.getHeight() / 2);
930         const tcu::Vec4 refColor = tcu::Vec4(0.4f, 0.6f, 0.2f, 1.0f);
931         for (deUint32 cpnt = 0; cpnt < 4; cpnt++)
932                 if (de::abs(resultColor[cpnt] - refColor[cpnt]) > 0.01f)
933                         return tcu::TestStatus::fail("Result image mismatch");
934
935         return tcu::TestStatus::pass("Pass");
936 }
937
938 std::string loadOpToString (VkAttachmentLoadOp loadOp)
939 {
940         switch (loadOp)
941         {
942                 case VK_ATTACHMENT_LOAD_OP_LOAD:
943                         return "load";
944                 case VK_ATTACHMENT_LOAD_OP_CLEAR:
945                         return "clear";
946                 case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
947                         return "dontcare";
948                 default:
949                         DE_FATAL("unexpected attachment load op");
950                         return "";
951         }
952 }
953
954 std::string storeOpToString (VkAttachmentStoreOp storeOp)
955 {
956         switch (storeOp)
957         {
958                 case VK_ATTACHMENT_STORE_OP_STORE:
959                         return "store";
960                 case VK_ATTACHMENT_STORE_OP_DONT_CARE:
961                         return "dontcare";
962                 default:
963                         DE_FATAL("unexpected attachment store op");
964                         return "";
965         }
966 }
967
968 } // anonymous
969
970 tcu::TestCaseGroup* createRenderPassUnusedAttachmentTests (tcu::TestContext& testCtx, const RenderingType renderingType)
971 {
972         de::MovePtr<tcu::TestCaseGroup>         unusedAttTests          (new tcu::TestCaseGroup(testCtx, "unused_attachment", "Unused attachment tests"));
973
974         const VkAttachmentLoadOp                        loadOps[]                       =
975         {
976                 VK_ATTACHMENT_LOAD_OP_LOAD,
977                 VK_ATTACHMENT_LOAD_OP_CLEAR,
978                 VK_ATTACHMENT_LOAD_OP_DONT_CARE
979         };
980
981         const VkAttachmentStoreOp                       storeOps[]                      =
982         {
983                 VK_ATTACHMENT_STORE_OP_STORE,
984                 VK_ATTACHMENT_STORE_OP_DONT_CARE
985         };
986
987         for (deUint32 loadOpIdx = 0; loadOpIdx < DE_LENGTH_OF_ARRAY(loadOps); loadOpIdx++)
988         {
989                 de::MovePtr<tcu::TestCaseGroup> loadOpGroup(new tcu::TestCaseGroup(testCtx, (std::string("loadop") + loadOpToString(loadOps[loadOpIdx])).c_str(), ""));
990
991                 for (deUint32 storeOpIdx = 0; storeOpIdx < DE_LENGTH_OF_ARRAY(storeOps); storeOpIdx++)
992                 {
993                         de::MovePtr<tcu::TestCaseGroup> storeOpGroup(new tcu::TestCaseGroup(testCtx, (std::string("storeop") + storeOpToString(storeOps[storeOpIdx])).c_str(), ""));
994
995                         for (deUint32 stencilLoadOpIdx = 0; stencilLoadOpIdx < DE_LENGTH_OF_ARRAY(loadOps); stencilLoadOpIdx++)
996                         {
997                                 de::MovePtr<tcu::TestCaseGroup> stencilLoadOpGroup(new tcu::TestCaseGroup(testCtx, (std::string("stencilloadop") + loadOpToString(loadOps[stencilLoadOpIdx])).c_str(), ""));
998
999                                 for (deUint32 stencilStoreOpIdx = 0; stencilStoreOpIdx < DE_LENGTH_OF_ARRAY(storeOps); stencilStoreOpIdx++)
1000                                 {
1001                                         TestParams                      params;
1002                                         const std::string       testName = std::string("stencilstoreop") + storeOpToString(storeOps[stencilStoreOpIdx]);
1003
1004                                         params.loadOp                   = loadOps[loadOpIdx];
1005                                         params.storeOp                  = storeOps[storeOpIdx];
1006                                         params.stencilLoadOp    = loadOps[stencilLoadOpIdx];
1007                                         params.stencilStoreOp   = storeOps[stencilStoreOpIdx];
1008                                         params.renderingType    = renderingType;
1009
1010                                         stencilLoadOpGroup->addChild(new UnusedAttachmentTest(testCtx, testName, "", params));
1011                                 }
1012                                 storeOpGroup->addChild(stencilLoadOpGroup.release());
1013                         }
1014                         loadOpGroup->addChild(storeOpGroup.release());
1015                 }
1016                 unusedAttTests->addChild(loadOpGroup.release());
1017         }
1018
1019         return unusedAttTests.release();
1020 }
1021
1022 } // renderpass
1023 } // vkt