Merge "Merge "Optimize swapchain OOM tests" into nougat-cts-dev am: c811d42d99 am...
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineMultisampleBaseResolveAndPerSampleFetch.cpp
1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*
20 * \file vktPipelineMultisampleBaseResolveAndPerSampleFetch.cpp
21 * \brief Base class for tests that check results of multisample resolve
22 *                 and/or values of individual samples
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineMultisampleBaseResolveAndPerSampleFetch.hpp"
26 #include "vktPipelineMakeUtil.hpp"
27 #include "vkBuilderUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "tcuTestLog.hpp"
30 #include <vector>
31
32 namespace vkt
33 {
34 namespace pipeline
35 {
36 namespace multisample
37 {
38
39 using namespace vk;
40
41 void MSCaseBaseResolveAndPerSampleFetch::initPrograms (vk::SourceCollections& programCollection) const
42 {
43         // Create vertex shader
44         std::ostringstream vs;
45
46         vs << "#version 440\n"
47                 << "layout(location = 0) in vec4 vs_in_position_ndc;\n"
48                 << "\n"
49                 << "out gl_PerVertex {\n"
50                 << "    vec4  gl_Position;\n"
51                 << "};\n"
52                 << "void main (void)\n"
53                 << "{\n"
54                 << "    gl_Position     = vs_in_position_ndc;\n"
55                 << "}\n";
56
57         programCollection.glslSources.add("per_sample_fetch_vs") << glu::VertexSource(vs.str());
58
59         // Create fragment shader
60         std::ostringstream fs;
61
62         fs << "#version 440\n"
63                 << "\n"
64                 << "layout(location = 0) out vec4 fs_out_color;\n"
65                 << "\n"
66                 << "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
67                 << "\n"
68                 << "layout(set = 0, binding = 1, std140) uniform SampleBlock {\n"
69                 << "    int sampleNdx;\n"
70                 << "};\n"
71                 << "void main (void)\n"
72                 << "{\n"
73                 << "    fs_out_color = subpassLoad(imageMS, sampleNdx);\n"
74                 << "}\n";
75
76         programCollection.glslSources.add("per_sample_fetch_fs") << glu::FragmentSource(fs.str());
77 }
78
79 VkPipelineMultisampleStateCreateInfo MSInstanceBaseResolveAndPerSampleFetch::getMSStateCreateInfo (const ImageMSParams& imageMSParams) const
80 {
81         const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
82         {
83                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
84                 DE_NULL,                                                                                                                // const void*                                                          pNext;
85                 (VkPipelineMultisampleStateCreateFlags)0u,                                              // VkPipelineMultisampleStateCreateFlags        flags;
86                 imageMSParams.numSamples,                                                                               // VkSampleCountFlagBits                                        rasterizationSamples;
87                 VK_TRUE,                                                                                                                // VkBool32                                                                     sampleShadingEnable;
88                 1.0f,                                                                                                                   // float                                                                        minSampleShading;
89                 DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
90                 VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
91                 VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToOneEnable;
92         };
93
94         return multisampleStateInfo;
95 }
96
97 const VkDescriptorSetLayout* MSInstanceBaseResolveAndPerSampleFetch::createMSPassDescSetLayout(const ImageMSParams& imageMSParams)
98 {
99         DE_UNREF(imageMSParams);
100
101         return DE_NULL;
102 }
103
104 const VkDescriptorSet* MSInstanceBaseResolveAndPerSampleFetch::createMSPassDescSet(const ImageMSParams& imageMSParams, const VkDescriptorSetLayout* descSetLayout)
105 {
106         DE_UNREF(imageMSParams);
107         DE_UNREF(descSetLayout);
108
109         return DE_NULL;
110 }
111
112 tcu::TestStatus MSInstanceBaseResolveAndPerSampleFetch::iterate (void)
113 {
114         const InstanceInterface&        instance                        = m_context.getInstanceInterface();
115         const DeviceInterface&          deviceInterface         = m_context.getDeviceInterface();
116         const VkDevice                          device                          = m_context.getDevice();
117         const VkPhysicalDevice          physicalDevice          = m_context.getPhysicalDevice();
118         Allocator&                                      allocator                       = m_context.getDefaultAllocator();
119         const VkQueue                           queue                           = m_context.getUniversalQueue();
120         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
121
122         VkImageCreateInfo                       imageMSInfo;
123         VkImageCreateInfo                       imageRSInfo;
124         const deUint32                          firstSubpassAttachmentsCount = 2u;
125
126         // Check if image size does not exceed device limits
127         validateImageSize(instance, physicalDevice, m_imageType, m_imageMSParams.imageSize);
128
129         // Check if device supports image format as color attachment
130         validateImageFeatureFlags(instance, physicalDevice, mapTextureFormat(m_imageFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT);
131
132         imageMSInfo.sType                                       = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
133         imageMSInfo.pNext                                       = DE_NULL;
134         imageMSInfo.flags                                       = 0u;
135         imageMSInfo.imageType                           = mapImageType(m_imageType);
136         imageMSInfo.format                                      = mapTextureFormat(m_imageFormat);
137         imageMSInfo.extent                                      = makeExtent3D(getLayerSize(m_imageType, m_imageMSParams.imageSize));
138         imageMSInfo.arrayLayers                         = getNumLayers(m_imageType, m_imageMSParams.imageSize);
139         imageMSInfo.mipLevels                           = 1u;
140         imageMSInfo.samples                                     = m_imageMSParams.numSamples;
141         imageMSInfo.tiling                                      = VK_IMAGE_TILING_OPTIMAL;
142         imageMSInfo.initialLayout                       = VK_IMAGE_LAYOUT_UNDEFINED;
143         imageMSInfo.usage                                       = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
144         imageMSInfo.sharingMode                         = VK_SHARING_MODE_EXCLUSIVE;
145         imageMSInfo.queueFamilyIndexCount       = 0u;
146         imageMSInfo.pQueueFamilyIndices         = DE_NULL;
147
148         if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
149         {
150                 imageMSInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
151         }
152
153         validateImageInfo(instance, physicalDevice, imageMSInfo);
154
155         const de::UniquePtr<Image> imageMS(new Image(deviceInterface, device, allocator, imageMSInfo, MemoryRequirement::Any));
156
157         imageRSInfo                     = imageMSInfo;
158         imageRSInfo.samples     = VK_SAMPLE_COUNT_1_BIT;
159         imageRSInfo.usage       = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
160
161         validateImageInfo(instance, physicalDevice, imageRSInfo);
162
163         const de::UniquePtr<Image> imageRS(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
164
165         const deUint32 numSamples = static_cast<deUint32>(imageMSInfo.samples);
166
167         std::vector<de::SharedPtr<Image> > imagesPerSampleVec(numSamples);
168
169         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
170         {
171                 imagesPerSampleVec[sampleNdx] = de::SharedPtr<Image>(new Image(deviceInterface, device, allocator, imageRSInfo, MemoryRequirement::Any));
172         }
173
174         // Create render pass
175         std::vector<VkAttachmentDescription> attachments(firstSubpassAttachmentsCount + numSamples);
176
177         {
178                 const VkAttachmentDescription attachmentMSDesc =
179                 {
180                         (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
181                         imageMSInfo.format,                                                     // VkFormat                                                     format;
182                         imageMSInfo.samples,                                            // VkSampleCountFlagBits                        samples;
183                         VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
184                         VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
185                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
186                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
187                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
188                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout                                        finalLayout;
189                 };
190
191                 attachments[0] = attachmentMSDesc;
192
193                 const VkAttachmentDescription attachmentRSDesc =
194                 {
195                         (VkAttachmentDescriptionFlags)0u,                       // VkAttachmentDescriptionFlags         flags;
196                         imageRSInfo.format,                                                     // VkFormat                                                     format;
197                         imageRSInfo.samples,                                            // VkSampleCountFlagBits                        samples;
198                         VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                           loadOp;
199                         VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                          storeOp;
200                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                           stencilLoadOp;
201                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                          stencilStoreOp;
202                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                        initialLayout;
203                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout                                        finalLayout;
204                 };
205
206                 attachments[1] = attachmentRSDesc;
207
208                 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
209                 {
210                         attachments[firstSubpassAttachmentsCount + sampleNdx] = attachmentRSDesc;
211                 }
212         }
213
214         const VkAttachmentReference attachmentMSColorRef =
215         {
216                 0u,                                                                                     // deUint32                     attachment;
217                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
218         };
219
220         const VkAttachmentReference attachmentMSInputRef =
221         {
222                 0u,                                                                                     // deUint32                     attachment;
223                 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL        // VkImageLayout        layout;
224         };
225
226         const VkAttachmentReference attachmentRSColorRef =
227         {
228                 1u,                                                                                     // deUint32                     attachment;
229                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
230         };
231
232         std::vector<VkAttachmentReference> perSampleAttachmentRef(numSamples);
233
234         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
235         {
236                 const VkAttachmentReference attachmentRef =
237                 {
238                         firstSubpassAttachmentsCount + sampleNdx,       // deUint32                     attachment;
239                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
240                 };
241
242                 perSampleAttachmentRef[sampleNdx] = attachmentRef;
243         }
244
245         std::vector<deUint32> preserveAttachments(1u + numSamples);
246
247         for (deUint32 attachNdx = 0u; attachNdx < 1u + numSamples; ++attachNdx)
248         {
249                 preserveAttachments[attachNdx] = 1u + attachNdx;
250         }
251
252         std::vector<VkSubpassDescription> subpasses(1u + numSamples);
253         std::vector<VkSubpassDependency>  subpassDependencies(numSamples);
254
255         const VkSubpassDescription firstSubpassDesc =
256         {
257                 (VkSubpassDescriptionFlags)0u,          // VkSubpassDescriptionFlags            flags;
258                 VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                          pipelineBindPoint;
259                 0u,                                                                     // deUint32                                                     inputAttachmentCount;
260                 DE_NULL,                                                        // const VkAttachmentReference*         pInputAttachments;
261                 1u,                                                                     // deUint32                                                     colorAttachmentCount;
262                 &attachmentMSColorRef,                          // const VkAttachmentReference*         pColorAttachments;
263                 &attachmentRSColorRef,                          // const VkAttachmentReference*         pResolveAttachments;
264                 DE_NULL,                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
265                 0u,                                                                     // deUint32                                                     preserveAttachmentCount;
266                 DE_NULL                                                         // const deUint32*                                      pPreserveAttachments;
267         };
268
269         subpasses[0] = firstSubpassDesc;
270
271         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
272         {
273                 const VkSubpassDescription subpassDesc =
274                 {
275                         (VkSubpassDescriptionFlags)0u,                  // VkSubpassDescriptionFlags            flags;
276                         VK_PIPELINE_BIND_POINT_GRAPHICS,                // VkPipelineBindPoint                          pipelineBindPoint;
277                         1u,                                                                             // deUint32                                                     inputAttachmentCount;
278                         &attachmentMSInputRef,                                  // const VkAttachmentReference*         pInputAttachments;
279                         1u,                                                                             // deUint32                                                     colorAttachmentCount;
280                         &perSampleAttachmentRef[sampleNdx],             // const VkAttachmentReference*         pColorAttachments;
281                         DE_NULL,                                                                // const VkAttachmentReference*         pResolveAttachments;
282                         DE_NULL,                                                                // const VkAttachmentReference*         pDepthStencilAttachment;
283                         1u + sampleNdx,                                                 // deUint32                                                     preserveAttachmentCount;
284                         dataPointer(preserveAttachments)                // const deUint32*                                      pPreserveAttachments;
285                 };
286
287                 subpasses[1u + sampleNdx] = subpassDesc;
288
289                 const VkSubpassDependency subpassDependency =
290                 {
291                         0u,                                                                                             // uint32_t                srcSubpass;
292                         1u + sampleNdx,                                                                 // 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                         0u,                                                                                             // VkDependencyFlags       dependencyFlags;
298                 };
299
300                 subpassDependencies[sampleNdx] = subpassDependency;
301         }
302
303         const VkRenderPassCreateInfo renderPassInfo =
304         {
305                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
306                 DE_NULL,                                                                                        // const void*                                          pNext;
307                 (VkRenderPassCreateFlags)0u,                                            // VkRenderPassCreateFlags                      flags;
308                 static_cast<deUint32>(attachments.size()),                      // deUint32                                                     attachmentCount;
309                 dataPointer(attachments),                                                       // const VkAttachmentDescription*       pAttachments;
310                 static_cast<deUint32>(subpasses.size()),                        // deUint32                                                     subpassCount;
311                 dataPointer(subpasses),                                                         // const VkSubpassDescription*          pSubpasses;
312                 static_cast<deUint32>(subpassDependencies.size()),      // deUint32                                                     dependencyCount;
313                 dataPointer(subpassDependencies)                                        // const VkSubpassDependency*           pDependencies;
314         };
315
316         const Unique<VkRenderPass> renderPass(createRenderPass(deviceInterface, device, &renderPassInfo));
317
318         const VkImageSubresourceRange fullImageRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageMSInfo.mipLevels, 0u, imageMSInfo.arrayLayers);
319
320         // Create color attachments image views
321         typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
322         std::vector<VkImageViewSp>      imageViewsShPtrs(firstSubpassAttachmentsCount + numSamples);
323         std::vector<VkImageView>        imageViews(firstSubpassAttachmentsCount + numSamples);
324
325         imageViewsShPtrs[0] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imageMS, mapImageViewType(m_imageType), imageMSInfo.format, fullImageRange));
326         imageViewsShPtrs[1] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imageRS, mapImageViewType(m_imageType), imageRSInfo.format, fullImageRange));
327
328         imageViews[0] = **imageViewsShPtrs[0];
329         imageViews[1] = **imageViewsShPtrs[1];
330
331         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
332         {
333                 imageViewsShPtrs[firstSubpassAttachmentsCount + sampleNdx] = makeVkSharedPtr(makeImageView(deviceInterface, device, **imagesPerSampleVec[sampleNdx], mapImageViewType(m_imageType), imageRSInfo.format, fullImageRange));
334                 imageViews[firstSubpassAttachmentsCount + sampleNdx] = **imageViewsShPtrs[firstSubpassAttachmentsCount + sampleNdx];
335         }
336
337         // Create framebuffer
338         const VkFramebufferCreateInfo framebufferInfo =
339         {
340                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                                                         sType;
341                 DE_NULL,                                                                        // const void*                                 pNext;
342                 (VkFramebufferCreateFlags)0u,                           // VkFramebufferCreateFlags                    flags;
343                 *renderPass,                                                            // VkRenderPass                                renderPass;
344                 static_cast<deUint32>(imageViews.size()),       // uint32_t                                    attachmentCount;
345                 dataPointer(imageViews),                                        // const VkImageView*                          pAttachments;
346                 imageMSInfo.extent.width,                                       // uint32_t                                    width;
347                 imageMSInfo.extent.height,                                      // uint32_t                                    height;
348                 imageMSInfo.arrayLayers,                                        // uint32_t                                    layers;
349         };
350
351         const Unique<VkFramebuffer> framebuffer(createFramebuffer(deviceInterface, device, &framebufferInfo));
352
353         const VkDescriptorSetLayout* descriptorSetLayoutMSPass = createMSPassDescSetLayout(m_imageMSParams);
354
355         // Create pipeline layout
356         const VkPipelineLayoutCreateInfo pipelineLayoutMSPassParams =
357         {
358                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,  // VkStructureType                                      sType;
359                 DE_NULL,                                                                                // const void*                                          pNext;
360                 (VkPipelineLayoutCreateFlags)0u,                                // VkPipelineLayoutCreateFlags          flags;
361                 descriptorSetLayoutMSPass ? 1u : 0u,                    // deUint32                                                     setLayoutCount;
362                 descriptorSetLayoutMSPass,                                              // const VkDescriptorSetLayout*         pSetLayouts;
363                 0u,                                                                                             // deUint32                                                     pushConstantRangeCount;
364                 DE_NULL,                                                                                // const VkPushConstantRange*           pPushConstantRanges;
365         };
366
367         const Unique<VkPipelineLayout> pipelineLayoutMSPass(createPipelineLayout(deviceInterface, device, &pipelineLayoutMSPassParams));
368
369         // Create vertex attributes data
370         const VertexDataDesc vertexDataDesc = getVertexDataDescripton();
371
372         de::SharedPtr<Buffer> vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(vertexDataDesc.dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
373         const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
374
375         uploadVertexData(vertexBufferAllocation, vertexDataDesc);
376
377         flushMappedMemoryRange(deviceInterface, device, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), VK_WHOLE_SIZE);
378
379         const VkVertexInputBindingDescription vertexBinding =
380         {
381                 0u,                                                     // deUint32                             binding;
382                 vertexDataDesc.dataStride,      // deUint32                             stride;
383                 VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputRate    inputRate;
384         };
385
386         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
387         {
388                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,                      // VkStructureType                             sType;
389                 DE_NULL,                                                                                                                        // const void*                                 pNext;
390                 (VkPipelineVertexInputStateCreateFlags)0u,                                                      // VkPipelineVertexInputStateCreateFlags       flags;
391                 1u,                                                                                                                                     // uint32_t                                    vertexBindingDescriptionCount;
392                 &vertexBinding,                                                                                                         // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
393                 static_cast<deUint32>(vertexDataDesc.vertexAttribDescVec.size()),       // uint32_t                                    vertexAttributeDescriptionCount;
394                 dataPointer(vertexDataDesc.vertexAttribDescVec),                                        // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
395         };
396
397         const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
398         {
399                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
400                 DE_NULL,                                                                                                                // const void*                                 pNext;
401                 (VkPipelineInputAssemblyStateCreateFlags)0u,                                    // VkPipelineInputAssemblyStateCreateFlags     flags;
402                 vertexDataDesc.primitiveTopology,                                                               // VkPrimitiveTopology                         topology;
403                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
404         };
405
406         const VkViewport viewport =
407         {
408                 0.0f, 0.0f,
409                 static_cast<float>(imageMSInfo.extent.width), static_cast<float>(imageMSInfo.extent.height),
410                 0.0f, 1.0f
411         };
412
413         const VkRect2D scissor =
414         {
415                 makeOffset2D(0, 0),
416                 makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
417         };
418
419         const VkPipelineViewportStateCreateInfo viewportStateInfo =
420         {
421                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                             sType;
422                 DE_NULL,                                                                                                                // const void*                                 pNext;
423                 (VkPipelineViewportStateCreateFlags)0u,                                                 // VkPipelineViewportStateCreateFlags          flags;
424                 1u,                                                                                                                             // uint32_t                                    viewportCount;
425                 &viewport,                                                                                                              // const VkViewport*                           pViewports;
426                 1u,                                                                                                                             // uint32_t                                    scissorCount;
427                 &scissor,                                                                                                               // const VkRect2D*                             pScissors;
428         };
429
430         const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
431         {
432                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
433                 DE_NULL,                                                                                                                // const void*                              pNext;
434                 (VkPipelineRasterizationStateCreateFlags)0u,                                    // VkPipelineRasterizationStateCreateFlags  flags;
435                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
436                 VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
437                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
438                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
439                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
440                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
441                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
442                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
443                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
444                 1.0f,                                                                                                                   // float                                                                        lineWidth;
445         };
446
447         const VkPipelineMultisampleStateCreateInfo multisampleStateInfo = getMSStateCreateInfo(m_imageMSParams);
448
449         const VkStencilOpState stencilOpState = makeStencilOpState
450         (
451                 VK_STENCIL_OP_KEEP,             // stencil fail
452                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
453                 VK_STENCIL_OP_KEEP,             // depth only fail
454                 VK_COMPARE_OP_ALWAYS,   // compare op
455                 0u,                                             // compare mask
456                 0u,                                             // write mask
457                 0u                                              // reference
458         );
459
460         const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo =
461         {
462                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
463                 DE_NULL,                                                                                                                // const void*                                                          pNext;
464                 (VkPipelineDepthStencilStateCreateFlags)0u,                                             // VkPipelineDepthStencilStateCreateFlags       flags;
465                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthTestEnable;
466                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthWriteEnable;
467                 VK_COMPARE_OP_LESS,                                                                                             // VkCompareOp                                                          depthCompareOp;
468                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBoundsTestEnable;
469                 VK_FALSE,                                                                                                               // VkBool32                                                                     stencilTestEnable;
470                 stencilOpState,                                                                                                 // VkStencilOpState                                                     front;
471                 stencilOpState,                                                                                                 // VkStencilOpState                                                     back;
472                 0.0f,                                                                                                                   // float                                                                        minDepthBounds;
473                 1.0f,                                                                                                                   // float                                                                        maxDepthBounds;
474         };
475
476         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
477
478         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
479         {
480                 VK_FALSE,                                                                                                               // VkBool32                                     blendEnable;
481                 VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor                        srcColorBlendFactor;
482                 VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor                        dstColorBlendFactor;
483                 VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            colorBlendOp;
484                 VK_BLEND_FACTOR_ONE,                                                                                    // VkBlendFactor                        srcAlphaBlendFactor;
485                 VK_BLEND_FACTOR_ZERO,                                                                                   // VkBlendFactor                        dstAlphaBlendFactor;
486                 VK_BLEND_OP_ADD,                                                                                                // VkBlendOp                            alphaBlendOp;
487                 colorComponentsAll,                                                                                             // VkColorComponentFlags        colorWriteMask;
488         };
489
490         const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
491         {
492                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
493                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
494                 (VkPipelineColorBlendStateCreateFlags)0u,                                               // VkPipelineColorBlendStateCreateFlags                 flags;
495                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
496                 VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
497                 1u,                                                                                                                             // deUint32                                                                             attachmentCount;
498                 &colorBlendAttachmentState,                                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
499                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                             // float                                                                                blendConstants[4];
500         };
501
502         // Create graphics pipeline for multisample pass
503         const Unique<VkShaderModule> vsMSPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0u));
504
505         const VkPipelineShaderStageCreateInfo vsMSPassShaderStageInfo =
506         {
507                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                              sType;
508                 DE_NULL,                                                                                                                // const void*                                                  pNext;
509                 (VkPipelineShaderStageCreateFlags)0u,                                                   // VkPipelineShaderStageCreateFlags             flags;
510                 VK_SHADER_STAGE_VERTEX_BIT,                                                                             // VkShaderStageFlagBits                                stage;
511                 *vsMSPassModule,                                                                                                // VkShaderModule                                               module;
512                 "main",                                                                                                                 // const char*                                                  pName;
513                 DE_NULL,                                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
514         };
515
516         const Unique<VkShaderModule> fsMSPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0u));
517
518         const VkPipelineShaderStageCreateInfo fsMSPassShaderStageInfo =
519         {
520                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                              sType;
521                 DE_NULL,                                                                                                                // const void*                                                  pNext;
522                 (VkPipelineShaderStageCreateFlags)0u,                                                   // VkPipelineShaderStageCreateFlags             flags;
523                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                                   // VkShaderStageFlagBits                                stage;
524                 *fsMSPassModule,                                                                                                // VkShaderModule                                               module;
525                 "main",                                                                                                                 // const char*                                                  pName;
526                 DE_NULL,                                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
527         };
528
529         const VkPipelineShaderStageCreateInfo shaderStageInfosMSPass[] = { vsMSPassShaderStageInfo, fsMSPassShaderStageInfo };
530
531         const VkGraphicsPipelineCreateInfo graphicsPipelineInfoMSPass =
532         {
533                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                // VkStructureType                                                                      sType;
534                 DE_NULL,                                                                                                                // const void*                                                                          pNext;
535                 (VkPipelineCreateFlags)0u,                                                                              // VkPipelineCreateFlags                                                        flags;
536                 2u,                                                                                                                             // deUint32                                                                                     stageCount;
537                 shaderStageInfosMSPass,                                                                                 // const VkPipelineShaderStageCreateInfo*                       pStages;
538                 &vertexInputStateInfo,                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
539                 &inputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
540                 DE_NULL,                                                                                                                // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
541                 &viewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
542                 &rasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
543                 &multisampleStateInfo,                                                                                  // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
544                 &depthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
545                 &colorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
546                 DE_NULL,                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
547                 *pipelineLayoutMSPass,                                                                                  // VkPipelineLayout                                                                     layout;
548                 *renderPass,                                                                                                    // VkRenderPass                                                                         renderPass;
549                 0u,                                                                                                                             // deUint32                                                                                     subpass;
550                 DE_NULL,                                                                                                                // VkPipeline                                                                           basePipelineHandle;
551                 0u,                                                                                                                             // deInt32                                                                                      basePipelineIndex;
552         };
553
554         const Unique<VkPipeline> graphicsPipelineMSPass(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfoMSPass));
555
556         typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
557         std::vector<VkPipelineSp> graphicsPipelinesPerSampleFetch(numSamples);
558
559         // Create descriptor set layout
560         const Unique<VkDescriptorSetLayout> descriptorSetLayout(
561                 DescriptorSetLayoutBuilder()
562                 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
563                 .addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, VK_SHADER_STAGE_FRAGMENT_BIT)
564                 .build(deviceInterface, device));
565
566         const Unique<VkPipelineLayout> pipelineLayoutPerSampleFetchPass(makePipelineLayout(deviceInterface, device, *descriptorSetLayout));
567
568         const deUint32 bufferPerSampleFetchPassSize = 4u * (deUint32)sizeof(tcu::Vec4);
569
570         de::SharedPtr<Buffer> vertexBufferPerSampleFetchPass = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, makeBufferCreateInfo(bufferPerSampleFetchPassSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
571
572         // Create graphics pipelines for per sample texel fetch passes
573         {
574                 const Unique<VkShaderModule> vsPerSampleFetchPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("per_sample_fetch_vs"), (VkShaderModuleCreateFlags)0u));
575
576                 const VkPipelineShaderStageCreateInfo vsPerSampleFetchPassShaderStageInfo =
577                 {
578                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                              sType;
579                         DE_NULL,                                                                                                                // const void*                                                  pNext;
580                         (VkPipelineShaderStageCreateFlags)0u,                                                   // VkPipelineShaderStageCreateFlags             flags;
581                         VK_SHADER_STAGE_VERTEX_BIT,                                                                             // VkShaderStageFlagBits                                stage;
582                         *vsPerSampleFetchPassModule,                                                                    // VkShaderModule                                               module;
583                         "main",                                                                                                                 // const char*                                                  pName;
584                         DE_NULL,                                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
585                 };
586
587                 const Unique<VkShaderModule> fsPerSampleFetchPassModule(createShaderModule(deviceInterface, device, m_context.getBinaryCollection().get("per_sample_fetch_fs"), (VkShaderModuleCreateFlags)0u));
588
589                 const VkPipelineShaderStageCreateInfo fsPerSampleFetchPassShaderStageInfo =
590                 {
591                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,                    // VkStructureType                                              sType;
592                         DE_NULL,                                                                                                                // const void*                                                  pNext;
593                         (VkPipelineShaderStageCreateFlags)0u,                                                   // VkPipelineShaderStageCreateFlags             flags;
594                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                                   // VkShaderStageFlagBits                                stage;
595                         *fsPerSampleFetchPassModule,                                                                    // VkShaderModule                                               module;
596                         "main",                                                                                                                 // const char*                                                  pName;
597                         DE_NULL,                                                                                                                // const VkSpecializationInfo*                  pSpecializationInfo;
598                 };
599
600                 const VkPipelineShaderStageCreateInfo shaderStageInfosPerSampleFetchPass[] = { vsPerSampleFetchPassShaderStageInfo, fsPerSampleFetchPassShaderStageInfo };
601
602                 std::vector<tcu::Vec4> vertices;
603
604                 vertices.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
605                 vertices.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
606                 vertices.push_back(tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f));
607                 vertices.push_back(tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f));
608
609                 const Allocation& vertexAllocPerSampleFetchPass = vertexBufferPerSampleFetchPass->getAllocation();
610
611                 deMemcpy(vertexAllocPerSampleFetchPass.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(bufferPerSampleFetchPassSize));
612
613                 flushMappedMemoryRange(deviceInterface, device, vertexAllocPerSampleFetchPass.getMemory(), vertexAllocPerSampleFetchPass.getOffset(), VK_WHOLE_SIZE);
614
615                 const VkVertexInputBindingDescription vertexBindingPerSampleFetchPass =
616                 {
617                         0u,                                                     // deUint32                             binding;
618                         sizeof(tcu::Vec4),                      // deUint32                             stride;
619                         VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputRate    inputRate;
620                 };
621
622                 const VkVertexInputAttributeDescription vertexAttribPositionNdc =
623                 {
624                         0u,                                                                                     // deUint32     location;
625                         0u,                                                                                     // deUint32     binding;
626                         VK_FORMAT_R32G32B32A32_SFLOAT,                          // VkFormat     format;
627                         0u,                                                                                     // deUint32     offset;
628                 };
629
630                 const VkPipelineVertexInputStateCreateInfo vertexInputStatePerSampleFetchPass =
631                 {
632                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,                      // VkStructureType                             sType;
633                         DE_NULL,                                                                                                                        // const void*                                 pNext;
634                         (VkPipelineVertexInputStateCreateFlags)0u,                                                      // VkPipelineVertexInputStateCreateFlags       flags;
635                         1u,                                                                                                                                     // uint32_t                                    vertexBindingDescriptionCount;
636                         &vertexBindingPerSampleFetchPass,                                                                       // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
637                         1u,                                                                                                                                     // uint32_t                                    vertexAttributeDescriptionCount;
638                         &vertexAttribPositionNdc,                                                                                       // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
639                 };
640
641                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStatePerSampleFetchPass =
642                 {
643                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
644                         DE_NULL,                                                                                                                // const void*                                 pNext;
645                         (VkPipelineInputAssemblyStateCreateFlags)0u,                                    // VkPipelineInputAssemblyStateCreateFlags     flags;
646                         VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,                                                           // VkPrimitiveTopology                         topology;
647                         VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
648                 };
649
650                 const VkPipelineMultisampleStateCreateInfo multisampleStatePerSampleFetchPass =
651                 {
652                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
653                         DE_NULL,                                                                                                                // const void*                                                          pNext;
654                         (VkPipelineMultisampleStateCreateFlags)0u,                                              // VkPipelineMultisampleStateCreateFlags        flags;
655                         VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
656                         VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
657                         0.0f,                                                                                                                   // float                                                                        minSampleShading;
658                         DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
659                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
660                         VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToOneEnable;
661                 };
662
663                 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
664                 {
665                         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
666                         {
667                                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                // VkStructureType                                                                      sType;
668                                 DE_NULL,                                                                                                                // const void*                                                                          pNext;
669                                 (VkPipelineCreateFlags)0u,                                                                              // VkPipelineCreateFlags                                                        flags;
670                                 2u,                                                                                                                             // deUint32                                                                                     stageCount;
671                                 shaderStageInfosPerSampleFetchPass,                                                             // const VkPipelineShaderStageCreateInfo*                       pStages;
672                                 &vertexInputStatePerSampleFetchPass,                                                    // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
673                                 &inputAssemblyStatePerSampleFetchPass,                                                  // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
674                                 DE_NULL,                                                                                                                // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
675                                 &viewportStateInfo,                                                                                             // const VkPipelineViewportStateCreateInfo*                     pViewportState;
676                                 &rasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
677                                 &multisampleStatePerSampleFetchPass,                                                    // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
678                                 &depthStencilStateInfo,                                                                                 // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
679                                 &colorBlendStateInfo,                                                                                   // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
680                                 DE_NULL,                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
681                                 *pipelineLayoutPerSampleFetchPass,                                                              // VkPipelineLayout                                                                     layout;
682                                 *renderPass,                                                                                                    // VkRenderPass                                                                         renderPass;
683                                 1u + sampleNdx,                                                                                                 // deUint32                                                                                     subpass;
684                                 DE_NULL,                                                                                                                // VkPipeline                                                                           basePipelineHandle;
685                                 0u,                                                                                                                             // deInt32                                                                                      basePipelineIndex;
686                         };
687
688                         graphicsPipelinesPerSampleFetch[sampleNdx] = makeVkSharedPtr(createGraphicsPipeline(deviceInterface, device, DE_NULL, &graphicsPipelineInfo));
689                 }
690         }
691
692         // Create descriptor pool
693         const Unique<VkDescriptorPool> descriptorPool(
694                 DescriptorPoolBuilder()
695                 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u)
696                 .addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1u)
697                 .build(deviceInterface, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
698
699         // Create descriptor set
700         const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(deviceInterface, device, *descriptorPool, *descriptorSetLayout));
701
702         const VkPhysicalDeviceLimits deviceLimits = getPhysicalDeviceProperties(instance, physicalDevice).limits;
703
704         VkDeviceSize uboOffsetAlignment = sizeof(deInt32) < deviceLimits.minUniformBufferOffsetAlignment ? deviceLimits.minUniformBufferOffsetAlignment : sizeof(deInt32);
705
706         uboOffsetAlignment += (deviceLimits.minUniformBufferOffsetAlignment - uboOffsetAlignment % deviceLimits.minUniformBufferOffsetAlignment) % deviceLimits.minUniformBufferOffsetAlignment;
707
708         const VkBufferCreateInfo        bufferSampleIDInfo = makeBufferCreateInfo(uboOffsetAlignment * numSamples, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
709         const de::UniquePtr<Buffer>     bufferSampleID(new Buffer(deviceInterface, device, allocator, bufferSampleIDInfo, MemoryRequirement::HostVisible));
710
711         std::vector<deUint32> sampleIDsOffsets(numSamples);
712
713         {
714                 deInt8* sampleIDs = new deInt8[uboOffsetAlignment * numSamples];
715
716                 for (deInt32 sampleNdx = 0u; sampleNdx < static_cast<deInt32>(numSamples); ++sampleNdx)
717                 {
718                         sampleIDsOffsets[sampleNdx] = static_cast<deUint32>(sampleNdx * uboOffsetAlignment);
719                         deInt8* samplePtr = sampleIDs + sampleIDsOffsets[sampleNdx];
720
721                         deMemcpy(samplePtr, &sampleNdx, sizeof(deInt32));
722                 }
723
724                 deMemcpy(bufferSampleID->getAllocation().getHostPtr(), sampleIDs, static_cast<deUint32>(uboOffsetAlignment * numSamples));
725
726                 flushMappedMemoryRange(deviceInterface, device, bufferSampleID->getAllocation().getMemory(), bufferSampleID->getAllocation().getOffset(), VK_WHOLE_SIZE);
727
728                 delete[] sampleIDs;
729         }
730
731         {
732                 const VkDescriptorImageInfo      descImageInfo  = makeDescriptorImageInfo(DE_NULL, imageViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
733                 const VkDescriptorBufferInfo descBufferInfo     = makeDescriptorBufferInfo(**bufferSampleID, 0u, sizeof(deInt32));
734
735                 DescriptorSetUpdateBuilder()
736                         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descImageInfo)
737                         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, &descBufferInfo)
738                         .update(deviceInterface, device);
739         }
740
741         // Create command buffer for compute and transfer oparations
742         const Unique<VkCommandPool>       commandPool(createCommandPool(deviceInterface, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
743         const Unique<VkCommandBuffer> commandBuffer(makeCommandBuffer(deviceInterface, device, *commandPool));
744
745         // Start recording commands
746         beginCommandBuffer(deviceInterface, *commandBuffer);
747
748         {
749                 std::vector<VkImageMemoryBarrier> imageOutputAttachmentBarriers(firstSubpassAttachmentsCount + numSamples);
750
751                 imageOutputAttachmentBarriers[0] = makeImageMemoryBarrier
752                 (
753                         0u,
754                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
755                         VK_IMAGE_LAYOUT_UNDEFINED,
756                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
757                         **imageMS,
758                         fullImageRange
759                 );
760
761                 imageOutputAttachmentBarriers[1] = makeImageMemoryBarrier
762                 (
763                         0u,
764                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
765                         VK_IMAGE_LAYOUT_UNDEFINED,
766                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
767                         **imageRS,
768                         fullImageRange
769                 );
770
771                 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
772                 {
773                         imageOutputAttachmentBarriers[firstSubpassAttachmentsCount + sampleNdx] = makeImageMemoryBarrier
774                         (
775                                 0u,
776                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
777                                 VK_IMAGE_LAYOUT_UNDEFINED,
778                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
779                                 **imagesPerSampleVec[sampleNdx],
780                                 fullImageRange
781                         );
782                 }
783
784                 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
785                         static_cast<deUint32>(imageOutputAttachmentBarriers.size()), dataPointer(imageOutputAttachmentBarriers));
786         }
787
788         {
789                 const VkDeviceSize vertexStartOffset = 0u;
790
791                 std::vector<VkClearValue> clearValues(firstSubpassAttachmentsCount + numSamples);
792                 for (deUint32 attachmentNdx = 0u; attachmentNdx < firstSubpassAttachmentsCount + numSamples; ++attachmentNdx)
793                 {
794                         clearValues[attachmentNdx] = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
795                 }
796
797                 const vk::VkRect2D renderArea =
798                 {
799                         makeOffset2D(0u, 0u),
800                         makeExtent2D(imageMSInfo.extent.width, imageMSInfo.extent.height),
801                 };
802
803                 // Begin render pass
804                 const VkRenderPassBeginInfo renderPassBeginInfo =
805                 {
806                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
807                         DE_NULL,                                                                                // const void*             pNext;
808                         *renderPass,                                                                    // VkRenderPass            renderPass;
809                         *framebuffer,                                                                   // VkFramebuffer           framebuffer;
810                         renderArea,                                                                             // VkRect2D                renderArea;
811                         static_cast<deUint32>(clearValues.size()),              // deUint32                clearValueCount;
812                         dataPointer(clearValues),                                               // const VkClearValue*     pClearValues;
813                 };
814
815                 deviceInterface.cmdBeginRenderPass(*commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
816
817                 // Bind graphics pipeline
818                 deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipelineMSPass);
819
820                 const VkDescriptorSet* descriptorSetMSPass = createMSPassDescSet(m_imageMSParams, descriptorSetLayoutMSPass);
821
822                 if (descriptorSetMSPass)
823                 {
824                         // Bind descriptor set
825                         deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutMSPass, 0u, 1u, descriptorSetMSPass, 0u, DE_NULL);
826                 }
827
828                 // Bind vertex buffer
829                 deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexStartOffset);
830
831                 // Perform a draw
832                 deviceInterface.cmdDraw(*commandBuffer, vertexDataDesc.verticesCount, 1u, 0u, 0u);
833
834                 for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
835                 {
836                         deviceInterface.cmdNextSubpass(*commandBuffer, VK_SUBPASS_CONTENTS_INLINE);
837
838                         // Bind graphics pipeline
839                         deviceInterface.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **graphicsPipelinesPerSampleFetch[sampleNdx]);
840
841                         // Bind descriptor set
842                         deviceInterface.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayoutPerSampleFetchPass, 0u, 1u, &descriptorSet.get(), 1u, &sampleIDsOffsets[sampleNdx]);
843
844                         // Bind vertex buffer
845                         deviceInterface.cmdBindVertexBuffers(*commandBuffer, 0u, 1u, &vertexBufferPerSampleFetchPass->get(), &vertexStartOffset);
846
847                         // Perform a draw
848                         deviceInterface.cmdDraw(*commandBuffer, 4u, 1u, 0u, 0u);
849                 }
850
851                 // End render pass
852                 deviceInterface.cmdEndRenderPass(*commandBuffer);
853         }
854
855         {
856                 const VkImageMemoryBarrier imageRSTransferBarrier = makeImageMemoryBarrier
857                 (
858                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
859                         VK_ACCESS_TRANSFER_READ_BIT,
860                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
861                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
862                         **imageRS,
863                         fullImageRange
864                 );
865
866                 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageRSTransferBarrier);
867         }
868
869         // Copy data from imageRS to buffer
870         const deUint32                          imageRSSizeInBytes = getImageSizeInBytes(imageRSInfo.extent, imageRSInfo.arrayLayers, m_imageFormat, imageRSInfo.mipLevels, 1u);
871
872         const VkBufferCreateInfo        bufferRSInfo = makeBufferCreateInfo(imageRSSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
873         const de::UniquePtr<Buffer>     bufferRS(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
874
875         {
876                 const VkBufferImageCopy bufferImageCopy =
877                 {
878                         0u,                                                                                                                                                                             //      VkDeviceSize                            bufferOffset;
879                         0u,                                                                                                                                                                             //      deUint32                                        bufferRowLength;
880                         0u,                                                                                                                                                                             //      deUint32                                        bufferImageHeight;
881                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), //      VkImageSubresourceLayers        imageSubresource;
882                         makeOffset3D(0, 0, 0),                                                                                                                                  //      VkOffset3D                                      imageOffset;
883                         imageRSInfo.extent,                                                                                                                                             //      VkExtent3D                                      imageExtent;
884                 };
885
886                 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, **imageRS, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, bufferRS->get(), 1u, &bufferImageCopy);
887         }
888
889         {
890                 const VkBufferMemoryBarrier bufferRSHostReadBarrier = makeBufferMemoryBarrier
891                 (
892                         VK_ACCESS_TRANSFER_WRITE_BIT,
893                         VK_ACCESS_HOST_READ_BIT,
894                         bufferRS->get(),
895                         0u,
896                         imageRSSizeInBytes
897                 );
898
899                 deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &bufferRSHostReadBarrier, 0u, DE_NULL);
900         }
901
902         // Copy data from per sample images to buffers
903         std::vector<VkImageMemoryBarrier> imagesPerSampleTransferBarriers(numSamples);
904
905         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
906         {
907                 imagesPerSampleTransferBarriers[sampleNdx] = makeImageMemoryBarrier
908                 (
909                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
910                         VK_ACCESS_TRANSFER_READ_BIT,
911                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
912                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
913                         **imagesPerSampleVec[sampleNdx],
914                         fullImageRange
915                 );
916         }
917
918         deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL,
919                 static_cast<deUint32>(imagesPerSampleTransferBarriers.size()), dataPointer(imagesPerSampleTransferBarriers));
920
921         std::vector<de::SharedPtr<Buffer> > buffersPerSample(numSamples);
922
923         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
924         {
925                 buffersPerSample[sampleNdx] = de::SharedPtr<Buffer>(new Buffer(deviceInterface, device, allocator, bufferRSInfo, MemoryRequirement::HostVisible));
926
927                 const VkBufferImageCopy bufferImageCopy =
928                 {
929                         0u,                                                                                                                                                                             //      VkDeviceSize                            bufferOffset;
930                         0u,                                                                                                                                                                             //      deUint32                                        bufferRowLength;
931                         0u,                                                                                                                                                                             //      deUint32                                        bufferImageHeight;
932                         makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, imageRSInfo.arrayLayers), //      VkImageSubresourceLayers        imageSubresource;
933                         makeOffset3D(0, 0, 0),                                                                                                                                  //      VkOffset3D                                      imageOffset;
934                         imageRSInfo.extent,                                                                                                                                             //      VkExtent3D                                      imageExtent;
935                 };
936
937                 deviceInterface.cmdCopyImageToBuffer(*commandBuffer, **imagesPerSampleVec[sampleNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **buffersPerSample[sampleNdx], 1u, &bufferImageCopy);
938         }
939
940         std::vector<VkBufferMemoryBarrier> buffersPerSampleHostReadBarriers(numSamples);
941
942         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
943         {
944                 buffersPerSampleHostReadBarriers[sampleNdx] = makeBufferMemoryBarrier
945                 (
946                         VK_ACCESS_TRANSFER_WRITE_BIT,
947                         VK_ACCESS_HOST_READ_BIT,
948                         **buffersPerSample[sampleNdx],
949                         0u,
950                         imageRSSizeInBytes
951                 );
952         }
953
954         deviceInterface.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL,
955                 static_cast<deUint32>(buffersPerSampleHostReadBarriers.size()), dataPointer(buffersPerSampleHostReadBarriers), 0u, DE_NULL);
956
957         // End recording commands
958         VK_CHECK(deviceInterface.endCommandBuffer(*commandBuffer));
959
960         // Submit commands for execution and wait for completion
961         submitCommandsAndWait(deviceInterface, device, queue, *commandBuffer);
962
963         // Retrieve data from bufferRS to host memory
964         const Allocation& bufferRSAlloc = bufferRS->getAllocation();
965
966         invalidateMappedMemoryRange(deviceInterface, device, bufferRSAlloc.getMemory(), bufferRSAlloc.getOffset(), VK_WHOLE_SIZE);
967
968         const tcu::ConstPixelBufferAccess bufferRSData (m_imageFormat,
969                                                                                                         imageRSInfo.extent.width,
970                                                                                                         imageRSInfo.extent.height,
971                                                                                                         imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
972                                                                                                         bufferRSAlloc.getHostPtr());
973
974         std::stringstream resolveName;
975         resolveName << "Resolve image " << getImageTypeName(m_imageType) << "_" << bufferRSData.getWidth() << "_" << bufferRSData.getHeight() << "_" << bufferRSData.getDepth() << std::endl;
976
977         m_context.getTestContext().getLog()
978                 << tcu::TestLog::Section(resolveName.str(), resolveName.str())
979                 << tcu::LogImage("resolve", "", bufferRSData)
980                 << tcu::TestLog::EndSection;
981
982         std::vector<tcu::ConstPixelBufferAccess> buffersPerSampleData(numSamples);
983
984         // Retrieve data from per sample buffers to host memory
985         for (deUint32 sampleNdx = 0u; sampleNdx < numSamples; ++sampleNdx)
986         {
987                 const Allocation& bufferAlloc = buffersPerSample[sampleNdx]->getAllocation();
988
989                 invalidateMappedMemoryRange(deviceInterface, device, bufferAlloc.getMemory(), bufferAlloc.getOffset(), VK_WHOLE_SIZE);
990
991                 buffersPerSampleData[sampleNdx] = tcu::ConstPixelBufferAccess
992                 (
993                         m_imageFormat,
994                         imageRSInfo.extent.width,
995                         imageRSInfo.extent.height,
996                         imageRSInfo.extent.depth * imageRSInfo.arrayLayers,
997                         bufferAlloc.getHostPtr()
998                 );
999
1000                 std::stringstream sampleName;
1001                 sampleName << "Sample " << sampleNdx << " image" << std::endl;
1002
1003                 m_context.getTestContext().getLog()
1004                         << tcu::TestLog::Section(sampleName.str(), sampleName.str())
1005                         << tcu::LogImage("sample", "", buffersPerSampleData[sampleNdx])
1006                         << tcu::TestLog::EndSection;
1007         }
1008
1009         return verifyImageData(imageMSInfo, imageRSInfo, buffersPerSampleData, bufferRSData);
1010 }
1011
1012 } // multisample
1013 } // pipeline
1014 } // vkt