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