1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google 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
21  * \brief Tests reading of samples from a previous subpass.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktRenderPassSampleReadTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29 
30 #include "vkDefs.hpp"
31 #include "vkBarrierUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 
42 #include "tcuImageCompare.hpp"
43 #include "tcuResultCollector.hpp"
44 
45 #include "deUniquePtr.hpp"
46 
47 using namespace vk;
48 
49 using tcu::UVec4;
50 using tcu::Vec4;
51 
52 using tcu::ConstPixelBufferAccess;
53 using tcu::PixelBufferAccess;
54 
55 using tcu::TestLog;
56 
57 using std::string;
58 using std::vector;
59 
60 namespace vkt
61 {
62 namespace
63 {
64 using namespace renderpass;
65 
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)66 de::MovePtr<Allocation> createBufferMemory(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
67                                            VkBuffer buffer)
68 {
69     de::MovePtr<Allocation> allocation(
70         allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
71     VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
72     return allocation;
73 }
74 
createImageMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkImage image)75 de::MovePtr<Allocation> createImageMemory(const DeviceInterface &vk, VkDevice device, Allocator &allocator,
76                                           VkImage image)
77 {
78     de::MovePtr<Allocation> allocation(
79         allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
80     VK_CHECK(vk.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
81     return allocation;
82 }
83 
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags flags,VkImageType imageType,VkFormat format,VkExtent3D extent,uint32_t mipLevels,uint32_t arrayLayers,VkSampleCountFlagBits samples,VkImageTiling tiling,VkImageUsageFlags usage,VkSharingMode sharingMode,uint32_t queueFamilyCount,const uint32_t * pQueueFamilyIndices,VkImageLayout initialLayout)84 Move<VkImage> createImage(const DeviceInterface &vk, VkDevice device, VkImageCreateFlags flags, VkImageType imageType,
85                           VkFormat format, VkExtent3D extent, uint32_t mipLevels, uint32_t arrayLayers,
86                           VkSampleCountFlagBits samples, VkImageTiling tiling, VkImageUsageFlags usage,
87                           VkSharingMode sharingMode, uint32_t queueFamilyCount, const uint32_t *pQueueFamilyIndices,
88                           VkImageLayout initialLayout)
89 {
90     const VkImageCreateInfo createInfo = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
91                                           DE_NULL,
92                                           flags,
93                                           imageType,
94                                           format,
95                                           extent,
96                                           mipLevels,
97                                           arrayLayers,
98                                           samples,
99                                           tiling,
100                                           usage,
101                                           sharingMode,
102                                           queueFamilyCount,
103                                           pQueueFamilyIndices,
104                                           initialLayout};
105     return createImage(vk, device, &createInfo);
106 }
107 
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)108 Move<VkImageView> createImageView(const DeviceInterface &vk, VkDevice device, VkImageViewCreateFlags flags,
109                                   VkImage image, VkImageViewType viewType, VkFormat format,
110                                   VkComponentMapping components, VkImageSubresourceRange subresourceRange)
111 {
112     const VkImageViewCreateInfo pCreateInfo = {
113         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, DE_NULL, flags, image, viewType, format, components, subresourceRange,
114     };
115     return createImageView(vk, device, &pCreateInfo);
116 }
117 
createImage(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat,VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,uint32_t width,uint32_t height)118 Move<VkImage> createImage(const InstanceInterface &vki, VkPhysicalDevice physicalDevice, const DeviceInterface &vkd,
119                           VkDevice device, VkFormat vkFormat, VkSampleCountFlagBits sampleCountBit,
120                           VkImageUsageFlags usage, uint32_t width, uint32_t height)
121 {
122     try
123     {
124         const VkImageType imageType(VK_IMAGE_TYPE_2D);
125         const VkImageTiling imageTiling(VK_IMAGE_TILING_OPTIMAL);
126         const VkImageFormatProperties imageFormatProperties(
127             getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
128         const VkExtent3D imageExtent = {width, height, 1u};
129 
130         if (imageFormatProperties.maxExtent.width < imageExtent.width ||
131             imageFormatProperties.maxExtent.height < imageExtent.height ||
132             ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
133         {
134             TCU_THROW(NotSupportedError, "Image type not supported");
135         }
136 
137         return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling,
138                            usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
139     }
140     catch (const vk::Error &error)
141     {
142         if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
143             TCU_THROW(NotSupportedError, "Image format not supported");
144 
145         throw;
146     }
147 }
148 
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)149 Move<VkImageView> createImageView(const DeviceInterface &vkd, VkDevice device, VkImage image, VkFormat format,
150                                   VkImageAspectFlags aspect)
151 {
152     const VkImageSubresourceRange range = {aspect, 0u, 1u, 0u, 1u};
153 
154     return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
155 }
156 
chooseSrcInputImageLayout(const SharedGroupParams groupParams)157 VkImageLayout chooseSrcInputImageLayout(const SharedGroupParams groupParams)
158 {
159 #ifndef CTS_USES_VULKANSC
160     if (groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
161     {
162         // use general layout for local reads for some tests
163         if (groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
164             return VK_IMAGE_LAYOUT_GENERAL;
165         return VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
166     }
167 #else
168     DE_UNREF(groupParams);
169 #endif
170     return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
171 }
172 
getPixelSize(VkFormat vkFormat)173 VkDeviceSize getPixelSize(VkFormat vkFormat)
174 {
175     const tcu::TextureFormat format(mapVkFormat(vkFormat));
176 
177     return format.getPixelSize();
178 }
179 
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,uint32_t width,uint32_t height)180 Move<VkBuffer> createBuffer(const DeviceInterface &vkd, VkDevice device, VkFormat format, uint32_t width,
181                             uint32_t height)
182 {
183     const VkBufferUsageFlags bufferUsage(VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
184     const VkDeviceSize pixelSize(getPixelSize(format));
185     const VkBufferCreateInfo createInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
186                                            DE_NULL,
187                                            0u,
188 
189                                            width * height * pixelSize,
190                                            bufferUsage,
191 
192                                            VK_SHARING_MODE_EXCLUSIVE,
193                                            0u,
194                                            DE_NULL};
195     return createBuffer(vkd, device, &createInfo);
196 }
197 
sampleCountBitFromSampleCount(uint32_t count)198 VkSampleCountFlagBits sampleCountBitFromSampleCount(uint32_t count)
199 {
200     switch (count)
201     {
202     case 1:
203         return VK_SAMPLE_COUNT_1_BIT;
204     case 2:
205         return VK_SAMPLE_COUNT_2_BIT;
206     case 4:
207         return VK_SAMPLE_COUNT_4_BIT;
208     case 8:
209         return VK_SAMPLE_COUNT_8_BIT;
210     case 16:
211         return VK_SAMPLE_COUNT_16_BIT;
212     case 32:
213         return VK_SAMPLE_COUNT_32_BIT;
214     case 64:
215         return VK_SAMPLE_COUNT_64_BIT;
216 
217     default:
218         DE_FATAL("Invalid sample count");
219         return (VkSampleCountFlagBits)(0x1u << count);
220     }
221 }
222 
223 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
224           typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,uint32_t sampleCount,RenderingType renderingType)225 Move<VkRenderPass> createRenderPass(const DeviceInterface &vkd, VkDevice device, VkFormat srcFormat, VkFormat dstFormat,
226                                     uint32_t sampleCount, RenderingType renderingType)
227 {
228     const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(sampleCount));
229     const VkImageAspectFlagBits aspectFlag((renderingType == RENDERING_TYPE_RENDERPASS2) ?
230                                                VK_IMAGE_ASPECT_COLOR_BIT :
231                                                static_cast<VkImageAspectFlagBits>(0u));
232     const AttachmentRef
233         srcAttachmentRef //  VkAttachmentReference                                        ||  VkAttachmentReference2KHR
234         (
235             //  ||  VkStructureType sType;
236             DE_NULL,                                  //   ||  const void* pNext;
237             0u,                                       //  uint32_t attachment; ||  uint32_t attachment;
238             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //  VkImageLayout layout; ||  VkImageLayout layout;
239             0u                                        // ||  VkImageAspectFlags aspectMask;
240         );
241     const AttachmentRef
242         srcAttachmentInputRef //  VkAttachmentReference                                        ||  VkAttachmentReference2KHR
243         (
244             //  ||  VkStructureType sType;
245             DE_NULL,                                  //   ||  const void* pNext;
246             0u,                                       //  uint32_t attachment; ||  uint32_t attachment;
247             VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, //  VkImageLayout layout; ||  VkImageLayout layout;
248             aspectFlag                                // ||  VkImageAspectFlags aspectMask;
249         );
250     const AttachmentRef
251         dstAttachmentRef //  VkAttachmentReference                                        ||  VkAttachmentReference2KHR
252         (
253             //  ||  VkStructureType sType;
254             DE_NULL,                                  //   ||  const void* pNext;
255             1u,                                       //  uint32_t attachment; ||  uint32_t attachment;
256             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //  VkImageLayout layout; ||  VkImageLayout layout;
257             0u                                        // ||  VkImageAspectFlags aspectMask;
258         );
259     const AttachmentRef
260         dstResolveAttachmentRef //  VkAttachmentReference                                        ||  VkAttachmentReference2KHR
261         (
262             //  ||  VkStructureType sType;
263             DE_NULL,                                  //   ||  const void* pNext;
264             2u,                                       //  uint32_t attachment; ||  uint32_t attachment;
265             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //  VkImageLayout layout; ||  VkImageLayout layout;
266             0u                                        // ||  VkImageAspectFlags aspectMask;
267         );
268     const SubpassDep
269         dependency //  VkSubpassDependency                                            ||  VkSubpassDependency2KHR
270         (
271             //  || VkStructureType sType;
272             DE_NULL,                                       //   || const void* pNext;
273             0u,                                            //  uint32_t srcSubpass; || uint32_t srcSubpass;
274             1u,                                            //  uint32_t dstSubpass; || uint32_t dstSubpass;
275             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //  VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
276             VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, //  VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
277             VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //  VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
278             VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,  //  VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
279             VK_DEPENDENCY_BY_REGION_BIT, //  VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
280             0u                           //    || int32_t viewOffset;
281         );
282     const AttachmentDesc
283         srcAttachment //  VkAttachmentDescription                                        ||  VkAttachmentDescription2KHR
284         (
285             //  ||  VkStructureType sType;
286             DE_NULL,   //   ||  const void* pNext;
287             0u,        //  VkAttachmentDescriptionFlags flags; ||  VkAttachmentDescriptionFlags flags;
288             srcFormat, //  VkFormat format; ||  VkFormat format;
289             samples,   //  VkSampleCountFlagBits samples; ||  VkSampleCountFlagBits samples;
290             VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp loadOp; ||  VkAttachmentLoadOp loadOp;
291             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp storeOp; ||  VkAttachmentStoreOp storeOp;
292             VK_ATTACHMENT_LOAD_OP_DONT_CARE, //  VkAttachmentLoadOp stencilLoadOp; ||  VkAttachmentLoadOp stencilLoadOp;
293             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp; ||  VkAttachmentStoreOp stencilStoreOp;
294             VK_IMAGE_LAYOUT_UNDEFINED,        //  VkImageLayout initialLayout; ||  VkImageLayout initialLayout;
295             VK_IMAGE_LAYOUT_GENERAL           //  VkImageLayout finalLayout; ||  VkImageLayout finalLayout;
296         );
297     const AttachmentDesc
298         dstMultisampleAttachment //  VkAttachmentDescription                                        ||  VkAttachmentDescription2KHR
299         (
300             //  ||  VkStructureType sType;
301             DE_NULL,   //   ||  const void* pNext;
302             0u,        //  VkAttachmentDescriptionFlags flags; ||  VkAttachmentDescriptionFlags flags;
303             dstFormat, //  VkFormat format; ||  VkFormat format;
304             samples,   //  VkSampleCountFlagBits samples; ||  VkSampleCountFlagBits samples;
305             VK_ATTACHMENT_LOAD_OP_DONT_CARE,  //  VkAttachmentLoadOp loadOp; ||  VkAttachmentLoadOp loadOp;
306             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp storeOp; ||  VkAttachmentStoreOp storeOp;
307             VK_ATTACHMENT_LOAD_OP_DONT_CARE, //  VkAttachmentLoadOp stencilLoadOp; ||  VkAttachmentLoadOp stencilLoadOp;
308             VK_ATTACHMENT_STORE_OP_DONT_CARE, //  VkAttachmentStoreOp stencilStoreOp; ||  VkAttachmentStoreOp stencilStoreOp;
309             VK_IMAGE_LAYOUT_UNDEFINED,        //  VkImageLayout initialLayout; ||  VkImageLayout initialLayout;
310             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL //  VkImageLayout finalLayout; ||  VkImageLayout finalLayout;
311         );
312     const AttachmentDesc
313         dstResolveAttachment //  VkAttachmentDescription                                        ||  VkAttachmentDescription2KHR
314         (
315             //  ||  VkStructureType sType;
316             DE_NULL,               //   ||  const void* pNext;
317             0u,                    //  VkAttachmentDescriptionFlags flags; ||  VkAttachmentDescriptionFlags flags;
318             dstFormat,             //  VkFormat format; ||  VkFormat format;
319             VK_SAMPLE_COUNT_1_BIT, //  VkSampleCountFlagBits samples; ||  VkSampleCountFlagBits samples;
320             VK_ATTACHMENT_LOAD_OP_DONT_CARE, //  VkAttachmentLoadOp loadOp; ||  VkAttachmentLoadOp loadOp;
321             VK_ATTACHMENT_STORE_OP_STORE,    //  VkAttachmentStoreOp storeOp; ||  VkAttachmentStoreOp storeOp;
322             VK_ATTACHMENT_LOAD_OP_DONT_CARE, //  VkAttachmentLoadOp stencilLoadOp; ||  VkAttachmentLoadOp stencilLoadOp;
323             VK_ATTACHMENT_STORE_OP_STORE, //  VkAttachmentStoreOp stencilStoreOp; ||  VkAttachmentStoreOp stencilStoreOp;
324             VK_IMAGE_LAYOUT_UNDEFINED,    //  VkImageLayout initialLayout; ||  VkImageLayout initialLayout;
325             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL //  VkImageLayout finalLayout; ||  VkImageLayout finalLayout;
326         );
327     const AttachmentDesc attachments[] = {srcAttachment, dstMultisampleAttachment, dstResolveAttachment};
328     const SubpassDesc
329         subpass1 //  VkSubpassDescription                                        ||  VkSubpassDescription2KHR
330         (
331             //  ||  VkStructureType sType;
332             DE_NULL,                      //   ||  const void* pNext;
333             (VkSubpassDescriptionFlags)0, //  VkSubpassDescriptionFlags flags; ||  VkSubpassDescriptionFlags flags;
334             VK_PIPELINE_BIND_POINT_GRAPHICS, //  VkPipelineBindPoint pipelineBindPoint; ||  VkPipelineBindPoint pipelineBindPoint;
335             0u,                              //   ||  uint32_t viewMask;
336             0u,                              //  uint32_t inputAttachmentCount; ||  uint32_t inputAttachmentCount;
337             DE_NULL, //  const VkAttachmentReference* pInputAttachments; ||  const VkAttachmentReference2KHR* pInputAttachments;
338             1u, //  uint32_t colorAttachmentCount; ||  uint32_t colorAttachmentCount;
339             &srcAttachmentRef, //  const VkAttachmentReference* pColorAttachments; ||  const VkAttachmentReference2KHR* pColorAttachments;
340             DE_NULL, //  const VkAttachmentReference* pResolveAttachments; ||  const VkAttachmentReference2KHR* pResolveAttachments;
341             DE_NULL, //  const VkAttachmentReference* pDepthStencilAttachment; ||  const VkAttachmentReference2KHR* pDepthStencilAttachment;
342             0u,     //  uint32_t preserveAttachmentCount; ||  uint32_t preserveAttachmentCount;
343             DE_NULL //  const uint32_t* pPreserveAttachments; ||  const uint32_t* pPreserveAttachments;
344         );
345     const SubpassDesc
346         subpass2 //  VkSubpassDescription                                        ||  VkSubpassDescription2KHR
347         (
348             //  ||  VkStructureType sType;
349             DE_NULL,                      //   ||  const void* pNext;
350             (VkSubpassDescriptionFlags)0, //  VkSubpassDescriptionFlags flags; ||  VkSubpassDescriptionFlags flags;
351             VK_PIPELINE_BIND_POINT_GRAPHICS, //  VkPipelineBindPoint pipelineBindPoint; ||  VkPipelineBindPoint pipelineBindPoint;
352             0u,                              //   ||  uint32_t viewMask;
353             1u,                              //  uint32_t inputAttachmentCount; ||  uint32_t inputAttachmentCount;
354             &srcAttachmentInputRef, //  const VkAttachmentReference* pInputAttachments; ||  const VkAttachmentReference2KHR* pInputAttachments;
355             1u, //  uint32_t colorAttachmentCount; ||  uint32_t colorAttachmentCount;
356             &dstAttachmentRef, //  const VkAttachmentReference* pColorAttachments; ||  const VkAttachmentReference2KHR* pColorAttachments;
357             &dstResolveAttachmentRef, //  const VkAttachmentReference* pResolveAttachments; ||  const VkAttachmentReference2KHR* pResolveAttachments;
358             DE_NULL, //  const VkAttachmentReference* pDepthStencilAttachment; ||  const VkAttachmentReference2KHR* pDepthStencilAttachment;
359             0u,     //  uint32_t preserveAttachmentCount; ||  uint32_t preserveAttachmentCount;
360             DE_NULL //  const uint32_t* pPreserveAttachments; ||  const uint32_t* pPreserveAttachments;
361         );
362     const SubpassDesc subpasses[] = {subpass1, subpass2};
363     const RenderPassCreateInfo
364         renderPassCreator //  VkRenderPassCreateInfo                                        ||  VkRenderPassCreateInfo2KHR
365         (
366             //  VkStructureType sType; ||  VkStructureType sType;
367             DE_NULL,                     //  const void* pNext; ||  const void* pNext;
368             (VkRenderPassCreateFlags)0u, //  VkRenderPassCreateFlags flags; ||  VkRenderPassCreateFlags flags;
369             3u,                          //  uint32_t attachmentCount; ||  uint32_t attachmentCount;
370             attachments, //  const VkAttachmentDescription* pAttachments; ||  const VkAttachmentDescription2KHR* pAttachments;
371             2u,          //  uint32_t subpassCount; ||  uint32_t subpassCount;
372             subpasses,   //  const VkSubpassDescription* pSubpasses; ||  const VkSubpassDescription2KHR* pSubpasses;
373             1u,          //  uint32_t dependencyCount; ||  uint32_t dependencyCount;
374             &dependency, //  const VkSubpassDependency* pDependencies; ||  const VkSubpassDependency2KHR* pDependencies;
375             0u,          //   ||  uint32_t correlatedViewMaskCount;
376             DE_NULL      //  ||  const uint32_t* pCorrelatedViewMasks;
377         );
378 
379     return renderPassCreator.createRenderPass(vkd, device);
380 }
381 
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,uint32_t sampleCount,RenderingType renderingType)382 Move<VkRenderPass> createRenderPass(const DeviceInterface &vkd, VkDevice device, VkFormat srcFormat, VkFormat dstFormat,
383                                     uint32_t sampleCount, RenderingType renderingType)
384 {
385     switch (renderingType)
386     {
387     case RENDERING_TYPE_RENDERPASS_LEGACY:
388         return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1,
389                                 RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType);
390     case RENDERING_TYPE_RENDERPASS2:
391         return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2,
392                                 RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType);
393     case RENDERING_TYPE_DYNAMIC_RENDERING:
394         return Move<VkRenderPass>();
395     default:
396         TCU_THROW(InternalError, "Impossible");
397     }
398 }
399 
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView srcImageView,VkImageView dstMultisampleImageView,VkImageView dstSinglesampleImageView,uint32_t width,uint32_t height)400 Move<VkFramebuffer> createFramebuffer(const DeviceInterface &vkd, VkDevice device, VkRenderPass renderPass,
401                                       VkImageView srcImageView, VkImageView dstMultisampleImageView,
402                                       VkImageView dstSinglesampleImageView, uint32_t width, uint32_t height)
403 {
404     // when RenderPass was not created then we are testing dynamic rendering
405     // and we can't create framebuffer without valid RenderPass object
406     if (!renderPass)
407         return Move<VkFramebuffer>();
408 
409     VkImageView attachments[] = {srcImageView, dstMultisampleImageView, dstSinglesampleImageView};
410 
411     const VkFramebufferCreateInfo createInfo = {VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
412                                                 DE_NULL,
413                                                 0u,
414 
415                                                 renderPass,
416                                                 3u,
417                                                 attachments,
418 
419                                                 width,
420                                                 height,
421                                                 1u};
422 
423     return createFramebuffer(vkd, device, &createInfo);
424 }
425 
createSubpassDescriptorSetLayout(const DeviceInterface & vkd,VkDevice device)426 Move<VkDescriptorSetLayout> createSubpassDescriptorSetLayout(const DeviceInterface &vkd, VkDevice device)
427 {
428     const VkDescriptorSetLayoutBinding bindings[] = {
429         {0u, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL},
430         {1u, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL}};
431     const VkDescriptorSetLayoutCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, DE_NULL,
432                                                         0u,
433 
434                                                         1u, bindings};
435 
436     return createDescriptorSetLayout(vkd, device, &createInfo);
437 }
438 
createSubpassDescriptorPool(const DeviceInterface & vkd,VkDevice device)439 Move<VkDescriptorPool> createSubpassDescriptorPool(const DeviceInterface &vkd, VkDevice device)
440 {
441     const VkDescriptorPoolSize size             = {VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u};
442     const VkDescriptorPoolCreateInfo createInfo = {VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
443                                                    DE_NULL,
444                                                    VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
445 
446                                                    2u,
447                                                    1u,
448                                                    &size};
449 
450     return createDescriptorPool(vkd, device, &createInfo);
451 }
452 
createSubpassDescriptorSet(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkDescriptorPool pool,VkDescriptorSetLayout layout,VkImageView imageView,VkImageLayout imageReadLayout)453 Move<VkDescriptorSet> createSubpassDescriptorSet(const DeviceInterface &vkd, VkDevice device, VkRenderPass renderPass,
454                                                  VkDescriptorPool pool, VkDescriptorSetLayout layout,
455                                                  VkImageView imageView, VkImageLayout imageReadLayout)
456 {
457     DE_UNREF(renderPass);
458 
459     const VkDescriptorSetAllocateInfo allocateInfo{VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, DE_NULL, pool, 1u,
460                                                    &layout};
461     Move<VkDescriptorSet> set(allocateDescriptorSet(vkd, device, &allocateInfo));
462     const VkDescriptorImageInfo imageInfo{(VkSampler)0u, imageView, imageReadLayout};
463     const VkWriteDescriptorSet write{VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
464                                      DE_NULL,
465 
466                                      *set,
467                                      0u,
468                                      0u,
469                                      1u,
470                                      VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
471                                      &imageInfo,
472                                      DE_NULL,
473                                      DE_NULL};
474 
475     vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
476 
477     return set;
478 }
479 
480 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(const DeviceInterface & vk,VkCommandBuffer secCmdBuffer)481 void beginSecondaryCmdBuffer(const DeviceInterface &vk, VkCommandBuffer secCmdBuffer)
482 {
483     VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
484     VkFormat colorAttachmentFormats[]    = {VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT};
485     const VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
486         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
487         DE_NULL,                                                         // const void* pNext;
488         0u,                                                              // VkRenderingFlagsKHR flags;
489         0u,                                                              // uint32_t viewMask;
490         2u,                                                              // uint32_t colorAttachmentCount;
491         colorAttachmentFormats,                                          // const VkFormat* pColorAttachmentFormats;
492         VK_FORMAT_UNDEFINED,                                             // VkFormat depthAttachmentFormat;
493         VK_FORMAT_UNDEFINED,                                             // VkFormat stencilAttachmentFormat;
494         VK_SAMPLE_COUNT_1_BIT,                                           // VkSampleCountFlagBits rasterizationSamples;
495     };
496     const VkCommandBufferInheritanceInfo bufferInheritanceInfo{
497         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
498         &inheritanceRenderingInfo,                         // const void* pNext;
499         DE_NULL,                                           // VkRenderPass renderPass;
500         0u,                                                // uint32_t subpass;
501         DE_NULL,                                           // VkFramebuffer framebuffer;
502         VK_FALSE,                                          // VkBool32 occlusionQueryEnable;
503         (VkQueryControlFlags)0u,                           // VkQueryControlFlags queryFlags;
504         (VkQueryPipelineStatisticFlags)0u                  // VkQueryPipelineStatisticFlags pipelineStatistics;
505     };
506     const VkCommandBufferBeginInfo commandBufBeginParams{
507         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
508         DE_NULL,                                     // const void* pNext;
509         usageFlags,                                  // VkCommandBufferUsageFlags flags;
510         &bufferInheritanceInfo                       // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
511     };
512     VK_CHECK(vk.beginCommandBuffer(secCmdBuffer, &commandBufBeginParams));
513 }
514 #endif // CTS_USES_VULKANSC
515 
516 enum TestMode
517 {
518     TESTMODE_ADD = 0,
519     TESTMODE_SELECT,
520 
521     TESTMODE_LAST
522 };
523 
524 struct TestConfig
525 {
TestConfigvkt::__anon6c5bceb80111::TestConfig526     TestConfig(uint32_t sampleCount_, TestMode testMode_, uint32_t selectedSample_,
527                const SharedGroupParams groupParams_)
528         : sampleCount(sampleCount_)
529         , testMode(testMode_)
530         , selectedSample(selectedSample_)
531         , groupParams(groupParams_)
532     {
533     }
534 
535     uint32_t sampleCount;
536     TestMode testMode;
537     uint32_t selectedSample;
538     const SharedGroupParams groupParams;
539 };
540 
541 class SampleReadTestInstance : public TestInstance
542 {
543 public:
544     SampleReadTestInstance(Context &context, TestConfig config);
545     ~SampleReadTestInstance(void);
546 
547     tcu::TestStatus iterate(void);
548 
549 protected:
550     template <typename RenderpassSubpass>
551     tcu::TestStatus iterateInternal(void);
552     tcu::TestStatus iterateInternalDynamicRendering(void);
553 
554     void createRenderPipeline(void);
555     void createSubpassPipeline(void);
556 
557 #ifndef CTS_USES_VULKANSC
558     void preRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
559     void inbetweenRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
560 #endif // CTS_USES_VULKANSC
561     void drawFirstSubpass(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
562     void drawSecondSubpass(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
563     void postRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
564 
565     void verifyResult(void);
566 
567 private:
568     const SharedGroupParams m_groupParams;
569 
570     const uint32_t m_sampleCount;
571     const uint32_t m_width;
572     const uint32_t m_height;
573     const TestMode m_testMode;
574     const uint32_t m_selectedSample;
575 
576     const Unique<VkImage> m_srcImage;
577     const de::UniquePtr<Allocation> m_srcImageMemory;
578     const Unique<VkImageView> m_srcImageView;
579     const Unique<VkImageView> m_srcInputImageView;
580     const VkImageLayout m_srcInputImageReadLayout;
581 
582     const Unique<VkImage> m_dstMultisampleImage;
583     const de::UniquePtr<Allocation> m_dstMultisampleImageMemory;
584     const Unique<VkImageView> m_dstMultisampleImageView;
585 
586     const Unique<VkImage> m_dstSinglesampleImage;
587     const de::UniquePtr<Allocation> m_dstSinglesampleImageMemory;
588     const Unique<VkImageView> m_dstSinglesampleImageView;
589 
590     const Unique<VkBuffer> m_dstBuffer;
591     const de::UniquePtr<Allocation> m_dstBufferMemory;
592 
593     const Unique<VkRenderPass> m_renderPass;
594     const Unique<VkFramebuffer> m_framebuffer;
595 
596     PipelineLayoutWrapper m_renderPipelineLayout;
597     GraphicsPipelineWrapper m_renderPipeline;
598 
599     const Unique<VkDescriptorSetLayout> m_subpassDescriptorSetLayout;
600     PipelineLayoutWrapper m_subpassPipelineLayout;
601     GraphicsPipelineWrapper m_subpassPipeline;
602     const Unique<VkDescriptorPool> m_subpassDescriptorPool;
603     const Unique<VkDescriptorSet> m_subpassDescriptorSet;
604 
605     const Unique<VkCommandPool> m_commandPool;
606     tcu::ResultCollector m_resultCollector;
607 };
608 
SampleReadTestInstance(Context & context,TestConfig config)609 SampleReadTestInstance::SampleReadTestInstance(Context &context, TestConfig config)
610     : TestInstance(context)
611     , m_groupParams(config.groupParams)
612     , m_sampleCount(config.sampleCount)
613     , m_width(32u)
614     , m_height(32u)
615     , m_testMode(config.testMode)
616     , m_selectedSample(config.selectedSample)
617     , m_srcImage(createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(),
618                              context.getDevice(), VK_FORMAT_R32_UINT, sampleCountBitFromSampleCount(m_sampleCount),
619                              VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, m_width,
620                              m_height))
621     , m_srcImageMemory(createImageMemory(context.getDeviceInterface(), context.getDevice(),
622                                          context.getDefaultAllocator(), *m_srcImage))
623     , m_srcImageView(createImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, VK_FORMAT_R32_UINT,
624                                      VK_IMAGE_ASPECT_COLOR_BIT))
625     , m_srcInputImageView(createImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage,
626                                           VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT))
627     , m_srcInputImageReadLayout(chooseSrcInputImageLayout(config.groupParams))
628     , m_dstMultisampleImage(createImage(context.getInstanceInterface(), context.getPhysicalDevice(),
629                                         context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT,
630                                         sampleCountBitFromSampleCount(m_sampleCount),
631                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, m_width, m_height))
632     , m_dstMultisampleImageMemory(createImageMemory(context.getDeviceInterface(), context.getDevice(),
633                                                     context.getDefaultAllocator(), *m_dstMultisampleImage))
634     , m_dstMultisampleImageView(createImageView(context.getDeviceInterface(), context.getDevice(),
635                                                 *m_dstMultisampleImage, VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT))
636     , m_dstSinglesampleImage(
637           createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(),
638                       context.getDevice(), VK_FORMAT_R32_UINT, VK_SAMPLE_COUNT_1_BIT,
639                       VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, m_width, m_height))
640     , m_dstSinglesampleImageMemory(createImageMemory(context.getDeviceInterface(), context.getDevice(),
641                                                      context.getDefaultAllocator(), *m_dstSinglesampleImage))
642     , m_dstSinglesampleImageView(createImageView(context.getDeviceInterface(), context.getDevice(),
643                                                  *m_dstSinglesampleImage, VK_FORMAT_R32_UINT,
644                                                  VK_IMAGE_ASPECT_COLOR_BIT))
645     , m_dstBuffer(
646           createBuffer(context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT, m_width, m_height))
647     , m_dstBufferMemory(createBufferMemory(context.getDeviceInterface(), context.getDevice(),
648                                            context.getDefaultAllocator(), *m_dstBuffer))
649     , m_renderPass(createRenderPass(context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT,
650                                     VK_FORMAT_R32_UINT, m_sampleCount, m_groupParams->renderingType))
651     , m_framebuffer(createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView,
652                                       *m_dstMultisampleImageView, *m_dstSinglesampleImageView, m_width, m_height))
653     , m_renderPipelineLayout(m_groupParams->pipelineConstructionType, context.getDeviceInterface(), context.getDevice())
654     , m_renderPipeline(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
655                        context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
656     , m_subpassDescriptorSetLayout(createSubpassDescriptorSetLayout(context.getDeviceInterface(), context.getDevice()))
657     , m_subpassPipelineLayout(m_groupParams->pipelineConstructionType, context.getDeviceInterface(),
658                               context.getDevice(), 1u, &*m_subpassDescriptorSetLayout)
659     , m_subpassPipeline(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
660                         context.getDevice(), context.getDeviceExtensions(), m_groupParams->pipelineConstructionType)
661     , m_subpassDescriptorPool(createSubpassDescriptorPool(context.getDeviceInterface(), context.getDevice()))
662     , m_subpassDescriptorSet(createSubpassDescriptorSet(
663           context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_subpassDescriptorPool,
664           *m_subpassDescriptorSetLayout, *m_srcInputImageView, m_srcInputImageReadLayout))
665     , m_commandPool(createCommandPool(context.getDeviceInterface(), context.getDevice(),
666                                       VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
667 {
668     createRenderPipeline();
669     createSubpassPipeline();
670 }
671 
~SampleReadTestInstance(void)672 SampleReadTestInstance::~SampleReadTestInstance(void)
673 {
674 }
675 
iterate(void)676 tcu::TestStatus SampleReadTestInstance::iterate(void)
677 {
678     switch (m_groupParams->renderingType)
679     {
680     case RENDERING_TYPE_RENDERPASS_LEGACY:
681         return iterateInternal<RenderpassSubpass1>();
682     case RENDERING_TYPE_RENDERPASS2:
683         return iterateInternal<RenderpassSubpass2>();
684     case RENDERING_TYPE_DYNAMIC_RENDERING:
685         return iterateInternalDynamicRendering();
686     default:
687         TCU_THROW(InternalError, "Impossible");
688     }
689 }
690 
691 template <typename RenderpassSubpass>
iterateInternal(void)692 tcu::TestStatus SampleReadTestInstance::iterateInternal(void)
693 {
694     const DeviceInterface &vkd(m_context.getDeviceInterface());
695     const VkDevice device(m_context.getDevice());
696     const Unique<VkCommandBuffer> commandBuffer(
697         allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
698     const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
699     const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
700 
701     beginCommandBuffer(vkd, *commandBuffer);
702 
703     {
704         const VkRenderPassBeginInfo beginInfo = {VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
705                                                  DE_NULL,
706 
707                                                  *m_renderPass,
708                                                  *m_framebuffer,
709 
710                                                  {{0u, 0u}, {m_width, m_height}},
711 
712                                                  0u,
713                                                  DE_NULL};
714         RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
715     }
716 
717     drawFirstSubpass(vkd, *commandBuffer);
718 
719     RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
720 
721     drawSecondSubpass(vkd, *commandBuffer);
722 
723     RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
724 
725     postRenderCommands(vkd, *commandBuffer);
726 
727     endCommandBuffer(vkd, *commandBuffer);
728 
729     submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
730 
731     verifyResult();
732 
733     return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
734 }
735 
iterateInternalDynamicRendering()736 tcu::TestStatus SampleReadTestInstance::iterateInternalDynamicRendering()
737 {
738 #ifndef CTS_USES_VULKANSC
739 
740     const DeviceInterface &vk(m_context.getDeviceInterface());
741     const VkDevice device(m_context.getDevice());
742     const Unique<VkCommandBuffer> cmdBuffer(
743         allocateCommandBuffer(vk, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
744     Move<VkCommandBuffer> secCmdBuffer;
745 
746     const VkClearValue clearValue(makeClearValueColor(tcu::Vec4(0.0f)));
747 
748     uint32_t colorAttachmentLocations[]{VK_ATTACHMENT_UNUSED, 0};
749     VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
750     renderingAttachmentLocationInfo.colorAttachmentCount                 = 2u;
751     renderingAttachmentLocationInfo.pColorAttachmentLocations            = colorAttachmentLocations;
752 
753     uint32_t colorAttachmentInputIndices[]{0, VK_ATTACHMENT_UNUSED};
754     VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
755     renderingInputAttachmentIndexInfo.colorAttachmentCount                   = 2u;
756     renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices           = colorAttachmentInputIndices;
757 
758     std::vector<VkRenderingAttachmentInfo> colorAttachments(
759         2u,
760         {
761             VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType            sType
762             DE_NULL,                                     // const void*                pNext
763             *m_srcImageView,                             // VkImageView                imageView
764             m_srcInputImageReadLayout,                   // VkImageLayout            imageLayout
765             VK_RESOLVE_MODE_NONE,                        // VkResolveModeFlagBits    resolveMode
766             DE_NULL,                                     // VkImageView                resolveImageView
767             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,    // VkImageLayout            resolveImageLayout
768             VK_ATTACHMENT_LOAD_OP_DONT_CARE,             // VkAttachmentLoadOp        loadOp
769             VK_ATTACHMENT_STORE_OP_DONT_CARE,            // VkAttachmentStoreOp        storeOp
770             clearValue                                   // VkClearValue                clearValue
771         });
772 
773     colorAttachments[1].imageView        = *m_dstMultisampleImageView;
774     colorAttachments[1].resolveMode      = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
775     colorAttachments[1].resolveImageView = *m_dstSinglesampleImageView;
776 
777     VkRenderingInfo renderingInfo{
778         VK_STRUCTURE_TYPE_RENDERING_INFO,
779         DE_NULL,
780         0,                             // VkRenderingFlagsKHR flags;
781         makeRect2D(m_width, m_height), // VkRect2D renderArea;
782         1u,                            // uint32_t layerCount;
783         0u,                            // uint32_t viewMask;
784         2u,                            // uint32_t colorAttachmentCount;
785         colorAttachments.data(),       // const VkRenderingAttachmentInfoKHR* pColorAttachments;
786         DE_NULL,                       // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
787         DE_NULL,                       // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
788     };
789 
790     if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
791     {
792         secCmdBuffer = allocateCommandBuffer(vk, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
793 
794         // record secondary command buffer
795         beginSecondaryCmdBuffer(vk, *secCmdBuffer);
796         vk.cmdBeginRendering(*secCmdBuffer, &renderingInfo);
797 
798         drawFirstSubpass(vk, *secCmdBuffer);
799         inbetweenRenderCommands(vk, *secCmdBuffer);
800         vk.cmdSetRenderingAttachmentLocationsKHR(*secCmdBuffer, &renderingAttachmentLocationInfo);
801         vk.cmdSetRenderingInputAttachmentIndicesKHR(*secCmdBuffer, &renderingInputAttachmentIndexInfo);
802         drawSecondSubpass(vk, *secCmdBuffer);
803 
804         vk.cmdEndRendering(*secCmdBuffer);
805         endCommandBuffer(vk, *secCmdBuffer);
806 
807         // record primary command buffer
808         beginCommandBuffer(vk, *cmdBuffer);
809         preRenderCommands(vk, *cmdBuffer);
810         vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
811         postRenderCommands(vk, *cmdBuffer);
812         endCommandBuffer(vk, *cmdBuffer);
813     }
814     else
815     {
816         beginCommandBuffer(vk, *cmdBuffer);
817 
818         preRenderCommands(vk, *cmdBuffer);
819 
820         vk.cmdBeginRendering(*cmdBuffer, &renderingInfo);
821         drawFirstSubpass(vk, *cmdBuffer);
822         inbetweenRenderCommands(vk, *cmdBuffer);
823         vk.cmdSetRenderingAttachmentLocationsKHR(*cmdBuffer, &renderingAttachmentLocationInfo);
824         vk.cmdSetRenderingInputAttachmentIndicesKHR(*cmdBuffer, &renderingInputAttachmentIndexInfo);
825         drawSecondSubpass(vk, *cmdBuffer);
826         vk.cmdEndRendering(*cmdBuffer);
827 
828         postRenderCommands(vk, *cmdBuffer);
829 
830         endCommandBuffer(vk, *cmdBuffer);
831     }
832 
833     submitCommandsAndWait(vk, device, m_context.getUniversalQueue(), *cmdBuffer);
834 
835     verifyResult();
836 
837 #endif // CTS_USES_VULKANSC
838 
839     return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
840 }
841 
createRenderPipeline()842 void SampleReadTestInstance::createRenderPipeline()
843 {
844     const DeviceInterface &vk(m_context.getDeviceInterface());
845     const VkDevice device(m_context.getDevice());
846     vk::BinaryCollection &binaryCollection(m_context.getBinaryCollection());
847     const std::vector<VkViewport> viewports{makeViewport(tcu::UVec2(m_width, m_height))};
848     const std::vector<VkRect2D> scissors{makeRect2D(tcu::UVec2(m_width, m_height))};
849     ShaderWrapper vertexShaderModule(vk, device, binaryCollection.get("quad-vert"), 0);
850     ShaderWrapper fragmentShaderModule(vk, device, binaryCollection.get("quad-frag"), 0);
851 
852     PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
853     const VkPipelineVertexInputStateCreateInfo vertexInputState = initVulkanStructure();
854     const VkPipelineMultisampleStateCreateInfo multisampleState{
855         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
856         DE_NULL,
857         (VkPipelineMultisampleStateCreateFlags)0u,
858 
859         sampleCountBitFromSampleCount(m_sampleCount),
860         VK_TRUE,
861         1.0f,
862         DE_NULL,
863         VK_FALSE,
864         VK_FALSE,
865     };
866 
867     VkPipelineColorBlendAttachmentState colorBlendAttachmentState;
868     deMemset(&colorBlendAttachmentState, 0x00, sizeof(VkPipelineColorBlendAttachmentState));
869     colorBlendAttachmentState.colorWriteMask = 0xF;
870 
871     const std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(
872         uint32_t(*m_renderPass == DE_NULL) + 1u, colorBlendAttachmentState);
873     VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = initVulkanStructure();
874     colorBlendStateCreateInfo.attachmentCount                     = uint32_t(colorBlendAttachmentStates.size());
875     colorBlendStateCreateInfo.pAttachments                        = colorBlendAttachmentStates.data();
876 
877 #ifndef CTS_USES_VULKANSC
878     VkFormat colorAttachmentFormats[] = {VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT};
879     VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
880                                                       DE_NULL,
881                                                       0u,
882                                                       2u,
883                                                       colorAttachmentFormats,
884                                                       VK_FORMAT_UNDEFINED,
885                                                       VK_FORMAT_UNDEFINED};
886 
887     if (*m_renderPass == DE_NULL)
888         renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
889 #endif // CTS_USES_VULKANSC
890 
891     m_renderPipeline.setDefaultDepthStencilState()
892         .setDefaultRasterizationState()
893         .setupVertexInputState(&vertexInputState)
894         .setupPreRasterizationShaderState(viewports, scissors, m_renderPipelineLayout, *m_renderPass, 0u,
895                                           vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
896                                           DE_NULL, DE_NULL, renderingCreateInfoWrapper)
897         .setupFragmentShaderState(m_renderPipelineLayout, *m_renderPass, 0u, fragmentShaderModule, 0u,
898                                   &multisampleState)
899         .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfo, &multisampleState)
900         .setMonolithicPipelineLayout(m_renderPipelineLayout)
901         .buildPipeline();
902 }
903 
createSubpassPipeline()904 void SampleReadTestInstance::createSubpassPipeline()
905 {
906     const DeviceInterface &vk(m_context.getDeviceInterface());
907     const VkDevice device(m_context.getDevice());
908     vk::BinaryCollection &binaryCollection(m_context.getBinaryCollection());
909     const std::vector<VkViewport> viewports{makeViewport(tcu::UVec2(m_width, m_height))};
910     const std::vector<VkRect2D> scissors{makeRect2D(tcu::UVec2(m_width, m_height))};
911     ShaderWrapper vertexShaderModule(vk, device, binaryCollection.get("quad-vert"), 0u);
912     ShaderWrapper fragmentShaderModule(vk, device, binaryCollection.get("quad-subpass-frag"), 0u);
913 
914     PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
915     RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfoWrapper;
916     RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
917     const VkPipelineVertexInputStateCreateInfo vertexInputState = initVulkanStructure();
918     const VkPipelineMultisampleStateCreateInfo multisampleState{
919         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
920         DE_NULL,
921         (VkPipelineMultisampleStateCreateFlags)0u,
922 
923         sampleCountBitFromSampleCount(m_sampleCount),
924         VK_FALSE,
925         0.0f,
926         DE_NULL,
927         VK_FALSE,
928         VK_FALSE,
929     };
930 
931     VkPipelineColorBlendAttachmentState colorBlendAttachmentState;
932     deMemset(&colorBlendAttachmentState, 0x00, sizeof(VkPipelineColorBlendAttachmentState));
933     colorBlendAttachmentState.colorWriteMask = 0xF;
934 
935     const std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(
936         uint32_t(*m_renderPass == DE_NULL) + 1u, colorBlendAttachmentState);
937     VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = initVulkanStructure();
938     colorBlendStateCreateInfo.attachmentCount                     = uint32_t(colorBlendAttachmentStates.size());
939     colorBlendStateCreateInfo.pAttachments                        = colorBlendAttachmentStates.data();
940 
941 #ifndef CTS_USES_VULKANSC
942     uint32_t colorAttachmentLocations[]                              = {VK_ATTACHMENT_UNUSED, 0};
943     VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocation = initVulkanStructure();
944     renderingAttachmentLocation.colorAttachmentCount                 = 2u;
945     renderingAttachmentLocation.pColorAttachmentLocations            = colorAttachmentLocations;
946 
947     uint32_t colorAttachmentInputIndices[]{0, VK_ATTACHMENT_UNUSED};
948     VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
949     renderingInputAttachmentIndexInfo.colorAttachmentCount                   = 2u;
950     renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices           = colorAttachmentInputIndices;
951 
952     VkFormat colorAttachmentFormats[]                 = {VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT};
953     VkPipelineRenderingCreateInfo renderingCreateInfo = initVulkanStructure();
954     renderingCreateInfo.colorAttachmentCount          = 2u;
955     renderingCreateInfo.pColorAttachmentFormats       = colorAttachmentFormats;
956 
957     if (*m_renderPass == DE_NULL)
958     {
959         renderingCreateInfoWrapper.ptr           = &renderingCreateInfo;
960         renderingAttachmentLocationInfoWrapper   = &renderingAttachmentLocation;
961         renderingInputAttachmentIndexInfoWrapper = &renderingInputAttachmentIndexInfo;
962     }
963 #endif // CTS_USES_VULKANSC
964 
965     m_subpassPipeline.setDefaultDepthStencilState()
966         .setDefaultRasterizationState()
967         .setupVertexInputState(&vertexInputState)
968         .setupPreRasterizationShaderState(viewports, scissors, m_subpassPipelineLayout, *m_renderPass, 1u,
969                                           vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
970                                           DE_NULL, DE_NULL, renderingCreateInfoWrapper)
971         .setupFragmentShaderState(m_subpassPipelineLayout, *m_renderPass, 1u, fragmentShaderModule, 0u,
972                                   &multisampleState, 0, 0, {}, renderingInputAttachmentIndexInfoWrapper)
973         .setupFragmentOutputState(*m_renderPass, 1u, &colorBlendStateCreateInfo, &multisampleState, 0, {},
974                                   renderingAttachmentLocationInfoWrapper)
975         .setMonolithicPipelineLayout(m_subpassPipelineLayout)
976         .buildPipeline();
977 }
978 
979 #ifndef CTS_USES_VULKANSC
preRenderCommands(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)980 void SampleReadTestInstance::preRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
981 {
982     const VkImageSubresourceRange subresourceRange(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1));
983     VkImageMemoryBarrier imageBarriers[]{
984         makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
985                                m_srcInputImageReadLayout, *m_srcImage, subresourceRange),
986         makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
987                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *m_dstMultisampleImage, subresourceRange),
988         makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
989                                VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, *m_dstSinglesampleImage, subresourceRange),
990     };
991 
992     vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
993                           0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageBarriers);
994 }
995 
inbetweenRenderCommands(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)996 void SampleReadTestInstance::inbetweenRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
997 {
998     const VkImageSubresourceRange subresourceRange(makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1));
999     VkImageMemoryBarrier imageBarrier(
1000         makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1001                                m_srcInputImageReadLayout, m_srcInputImageReadLayout, *m_srcImage, subresourceRange));
1002 
1003     vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1004                           VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 0u, DE_NULL, 0u, DE_NULL,
1005                           1u, &imageBarrier);
1006 }
1007 #endif // CTS_USES_VULKANSC
1008 
drawFirstSubpass(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)1009 void SampleReadTestInstance::drawFirstSubpass(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
1010 {
1011     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_renderPipeline.getPipeline());
1012     vk.cmdDraw(cmdBuffer, 6u, 1u, 0u, 0u);
1013 }
1014 
drawSecondSubpass(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)1015 void SampleReadTestInstance::drawSecondSubpass(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
1016 {
1017     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_subpassPipeline.getPipeline());
1018     vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpassPipelineLayout, 0u, 1u,
1019                              &*m_subpassDescriptorSet, 0u, DE_NULL);
1020     vk.cmdDraw(cmdBuffer, 6u, 1u, 0u, 0u);
1021 }
1022 
postRenderCommands(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)1023 void SampleReadTestInstance::postRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
1024 {
1025     auto srcStageMask = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1026     if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1027         srcStageMask = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1028 
1029     copyImageToBuffer(vk, cmdBuffer, *m_dstSinglesampleImage, *m_dstBuffer, tcu::IVec2(m_width, m_height),
1030                       VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, srcStageMask);
1031 }
1032 
verifyResult()1033 void SampleReadTestInstance::verifyResult()
1034 {
1035     const DeviceInterface &vk(m_context.getDeviceInterface());
1036     const VkDevice device(m_context.getDevice());
1037 
1038     invalidateAlloc(vk, device, *m_dstBufferMemory);
1039 
1040     const tcu::TextureFormat format(mapVkFormat(VK_FORMAT_R32_UINT));
1041     const void *const ptr(m_dstBufferMemory->getHostPtr());
1042     const tcu::ConstPixelBufferAccess access(format, m_width, m_height, 1, ptr);
1043     tcu::TextureLevel reference(format, m_width, m_height);
1044 
1045     for (uint32_t y = 0; y < m_height; y++)
1046         for (uint32_t x = 0; x < m_width; x++)
1047         {
1048             uint32_t bits;
1049 
1050             if (m_testMode == TESTMODE_ADD)
1051                 bits = m_sampleCount == 32 ? 0xffffffff : (1u << m_sampleCount) - 1;
1052             else
1053                 bits = 1u << m_selectedSample;
1054 
1055             const UVec4 color(bits, 0, 0, 0xffffffff);
1056 
1057             reference.getAccess().setPixel(color, x, y);
1058         }
1059 
1060     if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u),
1061                                   tcu::COMPARE_LOG_ON_ERROR))
1062         m_resultCollector.fail("Compare failed.");
1063 }
1064 
1065 struct Programs
1066 {
initvkt::__anon6c5bceb80111::Programs1067     void init(vk::SourceCollections &dst, TestConfig config) const
1068     {
1069         std::ostringstream fragmentShader;
1070         std::ostringstream subpassShader;
1071 
1072         dst.glslSources.add("quad-vert") << glu::VertexSource(
1073             "#version 450\n"
1074             "out gl_PerVertex {\n"
1075             "\tvec4 gl_Position;\n"
1076             "};\n"
1077             "highp float;\n"
1078             "void main (void)\n"
1079             "{\n"
1080             "    gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1081             "                       ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1082             "}\n");
1083 
1084         fragmentShader << "#version 450\n"
1085                           "layout(location = 0) out highp uvec4 o_color;\n"
1086                           "void main (void)\n"
1087                           "{\n"
1088                           "    o_color = uvec4(1u << gl_SampleID, 0, 0, 0);\n"
1089                           "}\n";
1090 
1091         dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1092 
1093         subpassShader
1094             << "#version 450\n"
1095                "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_color;\n"
1096                "layout(location = 0) out highp uvec4 o_color;\n"
1097                "void main (void)\n"
1098                "{\n"
1099                "    o_color = uvec4(0);\n";
1100 
1101         if (config.testMode == TESTMODE_ADD)
1102         {
1103             subpassShader << "    for (int i = 0; i < " << config.sampleCount << "; i++)\n"
1104                           << "        o_color.r += subpassLoad(i_color, i).r;\n";
1105         }
1106         else
1107         {
1108             subpassShader << "    o_color.r = subpassLoad(i_color, " << de::toString(config.selectedSample) << ").r;\n";
1109         }
1110 
1111         subpassShader << "}\n";
1112 
1113         dst.glslSources.add("quad-subpass-frag") << glu::FragmentSource(subpassShader.str());
1114     }
1115 };
1116 
checkSupport(vkt::Context & context,TestConfig config)1117 void checkSupport(vkt::Context &context, TestConfig config)
1118 {
1119     checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(),
1120                                           config.groupParams->pipelineConstructionType);
1121     context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING);
1122 
1123     if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
1124         context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
1125     else if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1126         context.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
1127 }
1128 
initTests(tcu::TestCaseGroup * group,const SharedGroupParams groupParams)1129 void initTests(tcu::TestCaseGroup *group, const SharedGroupParams groupParams)
1130 {
1131     const uint32_t sampleCounts[] = {2u, 4u, 8u, 16u, 32u};
1132     tcu::TestContext &testCtx(group->getTestContext());
1133 
1134     for (uint32_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1135     {
1136         // limit number of repeated tests for non monolithic pipelines
1137         if ((groupParams->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) && (sampleCountNdx > 1))
1138             continue;
1139 
1140         const uint32_t sampleCount(sampleCounts[sampleCountNdx]);
1141         {
1142             const TestConfig testConfig(sampleCount, TESTMODE_ADD, 0, groupParams);
1143             const std::string testName("numsamples_" + de::toString(sampleCount) + "_add");
1144 
1145             group->addChild(new InstanceFactory1WithSupport<SampleReadTestInstance, TestConfig,
1146                                                             FunctionSupport1<TestConfig>, Programs>(
1147                 testCtx, testName.c_str(), testConfig,
1148                 typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));
1149         }
1150 
1151         for (uint32_t sample = 0; sample < sampleCount; sample++)
1152         {
1153             const TestConfig testConfig(sampleCount, TESTMODE_SELECT, sample, groupParams);
1154             const std::string testName("numsamples_" + de::toString(sampleCount) + "_selected_sample_" +
1155                                        de::toString(sample));
1156 
1157             group->addChild(new InstanceFactory1WithSupport<SampleReadTestInstance, TestConfig,
1158                                                             FunctionSupport1<TestConfig>, Programs>(
1159                 testCtx, testName.c_str(), testConfig,
1160                 typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));
1161         }
1162     }
1163 }
1164 
1165 } // namespace
1166 
createRenderPassSampleReadTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1167 tcu::TestCaseGroup *createRenderPassSampleReadTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
1168 {
1169     return createTestGroup(testCtx, "sampleread", initTests, groupParams);
1170 }
1171 
1172 } // namespace vkt
1173