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 "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkRef.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40
41 #include "tcuImageCompare.hpp"
42 #include "tcuResultCollector.hpp"
43
44 #include "deUniquePtr.hpp"
45
46 using namespace vk;
47
48 using tcu::UVec4;
49 using tcu::Vec4;
50
51 using tcu::ConstPixelBufferAccess;
52 using tcu::PixelBufferAccess;
53
54 using tcu::TestLog;
55
56 using std::string;
57 using std::vector;
58
59 namespace vkt
60 {
61 namespace
62 {
63 using namespace renderpass;
64
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)65 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
66 VkDevice device,
67 Allocator& allocator,
68 VkBuffer buffer)
69 {
70 de::MovePtr<Allocation> allocation (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,
76 VkDevice device,
77 Allocator& allocator,
78 VkImage image)
79 {
80 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
81 VK_CHECK(vk.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
82 return allocation;
83 }
84
createImage(const DeviceInterface & vk,VkDevice device,VkImageCreateFlags flags,VkImageType imageType,VkFormat format,VkExtent3D extent,deUint32 mipLevels,deUint32 arrayLayers,VkSampleCountFlagBits samples,VkImageTiling tiling,VkImageUsageFlags usage,VkSharingMode sharingMode,deUint32 queueFamilyCount,const deUint32 * pQueueFamilyIndices,VkImageLayout initialLayout)85 Move<VkImage> createImage (const DeviceInterface& vk,
86 VkDevice device,
87 VkImageCreateFlags flags,
88 VkImageType imageType,
89 VkFormat format,
90 VkExtent3D extent,
91 deUint32 mipLevels,
92 deUint32 arrayLayers,
93 VkSampleCountFlagBits samples,
94 VkImageTiling tiling,
95 VkImageUsageFlags usage,
96 VkSharingMode sharingMode,
97 deUint32 queueFamilyCount,
98 const deUint32* pQueueFamilyIndices,
99 VkImageLayout initialLayout)
100 {
101 const VkImageCreateInfo createInfo =
102 {
103 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
104 DE_NULL,
105 flags,
106 imageType,
107 format,
108 extent,
109 mipLevels,
110 arrayLayers,
111 samples,
112 tiling,
113 usage,
114 sharingMode,
115 queueFamilyCount,
116 pQueueFamilyIndices,
117 initialLayout
118 };
119 return createImage(vk, device, &createInfo);
120 }
121
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)122 Move<VkImageView> createImageView (const DeviceInterface& vk,
123 VkDevice device,
124 VkImageViewCreateFlags flags,
125 VkImage image,
126 VkImageViewType viewType,
127 VkFormat format,
128 VkComponentMapping components,
129 VkImageSubresourceRange subresourceRange)
130 {
131 const VkImageViewCreateInfo pCreateInfo =
132 {
133 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
134 DE_NULL,
135 flags,
136 image,
137 viewType,
138 format,
139 components,
140 subresourceRange,
141 };
142 return createImageView(vk, device, &pCreateInfo);
143 }
144
createImage(const InstanceInterface & vki,VkPhysicalDevice physicalDevice,const DeviceInterface & vkd,VkDevice device,VkFormat vkFormat,VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,deUint32 width,deUint32 height)145 Move<VkImage> createImage (const InstanceInterface& vki,
146 VkPhysicalDevice physicalDevice,
147 const DeviceInterface& vkd,
148 VkDevice device,
149 VkFormat vkFormat,
150 VkSampleCountFlagBits sampleCountBit,
151 VkImageUsageFlags usage,
152 deUint32 width,
153 deUint32 height)
154 {
155 try
156 {
157 const VkImageType imageType (VK_IMAGE_TYPE_2D);
158 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
159 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
160 const VkExtent3D imageExtent =
161 {
162 width,
163 height,
164 1u
165 };
166
167 if (imageFormatProperties.maxExtent.width < imageExtent.width
168 || imageFormatProperties.maxExtent.height < imageExtent.height
169 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
170 {
171 TCU_THROW(NotSupportedError, "Image type not supported");
172 }
173
174 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
175 }
176 catch (const vk::Error& error)
177 {
178 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
179 TCU_THROW(NotSupportedError, "Image format not supported");
180
181 throw;
182 }
183 }
184
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)185 Move<VkImageView> createImageView (const DeviceInterface& vkd,
186 VkDevice device,
187 VkImage image,
188 VkFormat format,
189 VkImageAspectFlags aspect)
190 {
191 const VkImageSubresourceRange range =
192 {
193 aspect,
194 0u,
195 1u,
196 0u,
197 1u
198 };
199
200 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
201 }
202
getPixelSize(VkFormat vkFormat)203 VkDeviceSize getPixelSize (VkFormat vkFormat)
204 {
205 const tcu::TextureFormat format (mapVkFormat(vkFormat));
206
207 return format.getPixelSize();
208 }
209
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)210 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
211 VkDevice device,
212 VkFormat format,
213 deUint32 width,
214 deUint32 height)
215 {
216 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
217 const VkDeviceSize pixelSize (getPixelSize(format));
218 const VkBufferCreateInfo createInfo =
219 {
220 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
221 DE_NULL,
222 0u,
223
224 width * height * pixelSize,
225 bufferUsage,
226
227 VK_SHARING_MODE_EXCLUSIVE,
228 0u,
229 DE_NULL
230 };
231 return createBuffer(vkd, device, &createInfo);
232 }
233
sampleCountBitFromSampleCount(deUint32 count)234 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
235 {
236 switch (count)
237 {
238 case 1: return VK_SAMPLE_COUNT_1_BIT;
239 case 2: return VK_SAMPLE_COUNT_2_BIT;
240 case 4: return VK_SAMPLE_COUNT_4_BIT;
241 case 8: return VK_SAMPLE_COUNT_8_BIT;
242 case 16: return VK_SAMPLE_COUNT_16_BIT;
243 case 32: return VK_SAMPLE_COUNT_32_BIT;
244 case 64: return VK_SAMPLE_COUNT_64_BIT;
245
246 default:
247 DE_FATAL("Invalid sample count");
248 return (VkSampleCountFlagBits)(0x1u << count);
249 }
250 }
251
252 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,deUint32 sampleCount,RenderingType renderingType)253 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
254 VkDevice device,
255 VkFormat srcFormat,
256 VkFormat dstFormat,
257 deUint32 sampleCount,
258 RenderingType renderingType)
259 {
260 const VkSampleCountFlagBits samples (sampleCountBitFromSampleCount(sampleCount));
261 const VkImageAspectFlagBits aspectFlag ((renderingType == RENDERING_TYPE_RENDERPASS2) ? VK_IMAGE_ASPECT_COLOR_BIT :
262 static_cast<VkImageAspectFlagBits>(0u));
263 const AttachmentRef srcAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
264 (
265 // || VkStructureType sType;
266 DE_NULL, // || const void* pNext;
267 0u, // deUint32 attachment; || deUint32 attachment;
268 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
269 0u // || VkImageAspectFlags aspectMask;
270 );
271 const AttachmentRef srcAttachmentInputRef // VkAttachmentReference || VkAttachmentReference2KHR
272 (
273 // || VkStructureType sType;
274 DE_NULL, // || const void* pNext;
275 0u, // deUint32 attachment; || deUint32 attachment;
276 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
277 aspectFlag // || VkImageAspectFlags aspectMask;
278 );
279 const AttachmentRef dstAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
280 (
281 // || VkStructureType sType;
282 DE_NULL, // || const void* pNext;
283 1u, // deUint32 attachment; || deUint32 attachment;
284 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
285 0u // || VkImageAspectFlags aspectMask;
286 );
287 const AttachmentRef dstResolveAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
288 (
289 // || VkStructureType sType;
290 DE_NULL, // || const void* pNext;
291 2u, // deUint32 attachment; || deUint32 attachment;
292 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
293 0u // || VkImageAspectFlags aspectMask;
294 );
295 const SubpassDep dependency // VkSubpassDependency || VkSubpassDependency2KHR
296 (
297 // || VkStructureType sType;
298 DE_NULL, // || const void* pNext;
299 0u, // deUint32 srcSubpass; || deUint32 srcSubpass;
300 1u, // deUint32 dstSubpass; || deUint32 dstSubpass;
301 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
302 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
303 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
304 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
305 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
306 0u // || deInt32 viewOffset;
307 );
308 const AttachmentDesc srcAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
309 (
310 // || VkStructureType sType;
311 DE_NULL, // || const void* pNext;
312 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
313 srcFormat, // VkFormat format; || VkFormat format;
314 samples, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
315 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
316 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
317 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
318 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
319 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
320 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
321 );
322 const AttachmentDesc dstMultisampleAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
323 (
324 // || VkStructureType sType;
325 DE_NULL, // || const void* pNext;
326 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
327 dstFormat, // VkFormat format; || VkFormat format;
328 samples, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
329 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
330 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
331 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
332 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
333 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
334 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
335 );
336 const AttachmentDesc dstResolveAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
337 (
338 // || VkStructureType sType;
339 DE_NULL, // || const void* pNext;
340 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
341 dstFormat, // VkFormat format; || VkFormat format;
342 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
343 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
344 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
345 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
346 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
347 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
348 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
349 );
350 const AttachmentDesc attachments[] =
351 {
352 srcAttachment,
353 dstMultisampleAttachment,
354 dstResolveAttachment
355 };
356 const SubpassDesc subpass1 // VkSubpassDescription || VkSubpassDescription2KHR
357 (
358 // || VkStructureType sType;
359 DE_NULL, // || const void* pNext;
360 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
361 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
362 0u, // || deUint32 viewMask;
363 0u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
364 DE_NULL, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
365 1u, // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
366 &srcAttachmentRef, // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
367 DE_NULL, // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
368 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
369 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
370 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
371 );
372 const SubpassDesc subpass2 // VkSubpassDescription || VkSubpassDescription2KHR
373 (
374 // || VkStructureType sType;
375 DE_NULL, // || const void* pNext;
376 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
377 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
378 0u, // || deUint32 viewMask;
379 1u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
380 &srcAttachmentInputRef, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
381 1u, // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
382 &dstAttachmentRef, // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
383 &dstResolveAttachmentRef, // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
384 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
385 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
386 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
387 );
388 const SubpassDesc subpasses[] =
389 {
390 subpass1,
391 subpass2
392 };
393 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
394 (
395 // VkStructureType sType; || VkStructureType sType;
396 DE_NULL, // const void* pNext; || const void* pNext;
397 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
398 3u, // deUint32 attachmentCount; || deUint32 attachmentCount;
399 attachments, // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
400 2u, // deUint32 subpassCount; || deUint32 subpassCount;
401 subpasses, // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
402 1u, // deUint32 dependencyCount; || deUint32 dependencyCount;
403 &dependency, // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
404 0u, // || deUint32 correlatedViewMaskCount;
405 DE_NULL // || const deUint32* pCorrelatedViewMasks;
406 );
407
408 return renderPassCreator.createRenderPass(vkd, device);
409 }
410
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat srcFormat,VkFormat dstFormat,deUint32 sampleCount,RenderingType renderingType)411 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
412 VkDevice device,
413 VkFormat srcFormat,
414 VkFormat dstFormat,
415 deUint32 sampleCount,
416 RenderingType renderingType)
417 {
418 switch (renderingType)
419 {
420 case RENDERING_TYPE_RENDERPASS_LEGACY:
421 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType);
422 case RENDERING_TYPE_RENDERPASS2:
423 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType);
424 default:
425 TCU_THROW(InternalError, "Impossible");
426 }
427 }
428
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView srcImageView,VkImageView dstMultisampleImageView,VkImageView dstSinglesampleImageView,deUint32 width,deUint32 height)429 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
430 VkDevice device,
431 VkRenderPass renderPass,
432 VkImageView srcImageView,
433 VkImageView dstMultisampleImageView,
434 VkImageView dstSinglesampleImageView,
435 deUint32 width,
436 deUint32 height)
437 {
438 VkImageView attachments[] =
439 {
440 srcImageView,
441 dstMultisampleImageView,
442 dstSinglesampleImageView
443 };
444
445 const VkFramebufferCreateInfo createInfo =
446 {
447 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
448 DE_NULL,
449 0u,
450
451 renderPass,
452 3u,
453 attachments,
454
455 width,
456 height,
457 1u
458 };
459
460 return createFramebuffer(vkd, device, &createInfo);
461 }
462
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)463 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
464 VkDevice device)
465 {
466 const VkPipelineLayoutCreateInfo createInfo =
467 {
468 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
469 DE_NULL,
470 (vk::VkPipelineLayoutCreateFlags)0,
471
472 0u,
473 DE_NULL,
474
475 0u,
476 DE_NULL
477 };
478
479 return createPipelineLayout(vkd, device, &createInfo);
480 }
481
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::BinaryCollection & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)482 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
483 VkDevice device,
484 VkRenderPass renderPass,
485 VkPipelineLayout pipelineLayout,
486 const vk::BinaryCollection& binaryCollection,
487 deUint32 width,
488 deUint32 height,
489 deUint32 sampleCount)
490 {
491 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
492 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
493 const VkPipelineVertexInputStateCreateInfo vertexInputState =
494 {
495 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
496 DE_NULL,
497 (VkPipelineVertexInputStateCreateFlags)0u,
498
499 0u,
500 DE_NULL,
501
502 0u,
503 DE_NULL
504 };
505 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
506 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
507
508 const VkPipelineMultisampleStateCreateInfo multisampleState =
509 {
510 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
511 DE_NULL,
512 (VkPipelineMultisampleStateCreateFlags)0u,
513
514 sampleCountBitFromSampleCount(sampleCount),
515 VK_TRUE,
516 1.0f,
517 DE_NULL,
518 VK_FALSE,
519 VK_FALSE,
520 };
521
522 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
523 device, // const VkDevice device
524 pipelineLayout, // const VkPipelineLayout pipelineLayout
525 *vertexShaderModule, // const VkShaderModule vertexShaderModule
526 DE_NULL, // const VkShaderModule tessellationControlShaderModule
527 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
528 DE_NULL, // const VkShaderModule geometryShaderModule
529 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
530 renderPass, // const VkRenderPass renderPass
531 viewports, // const std::vector<VkViewport>& viewports
532 scissors, // const std::vector<VkRect2D>& scissors
533 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
534 0u, // const deUint32 subpass
535 0u, // const deUint32 patchControlPoints
536 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
537 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
538 &multisampleState); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
539 }
540
createSubpassDescriptorSetLayout(const DeviceInterface & vkd,VkDevice device)541 Move<VkDescriptorSetLayout> createSubpassDescriptorSetLayout (const DeviceInterface& vkd,
542 VkDevice device)
543 {
544 const VkDescriptorSetLayoutBinding bindings[] =
545 {
546 {
547 0u,
548 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
549 1u,
550 VK_SHADER_STAGE_FRAGMENT_BIT,
551 DE_NULL
552 },
553 {
554 1u,
555 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
556 1u,
557 VK_SHADER_STAGE_FRAGMENT_BIT,
558 DE_NULL
559 }
560 };
561 const VkDescriptorSetLayoutCreateInfo createInfo =
562 {
563 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
564 DE_NULL,
565 0u,
566
567 1u,
568 bindings
569 };
570
571 return createDescriptorSetLayout(vkd, device, &createInfo);
572 }
573
createSubpassPipelineLayout(const DeviceInterface & vkd,VkDevice device,VkDescriptorSetLayout descriptorSetLayout)574 Move<VkPipelineLayout> createSubpassPipelineLayout (const DeviceInterface& vkd,
575 VkDevice device,
576 VkDescriptorSetLayout descriptorSetLayout)
577 {
578 const VkPipelineLayoutCreateInfo createInfo =
579 {
580 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
581 DE_NULL,
582 (vk::VkPipelineLayoutCreateFlags)0,
583
584 1u,
585 &descriptorSetLayout,
586
587 0u,
588 DE_NULL
589 };
590
591 return createPipelineLayout(vkd, device, &createInfo);
592 }
593
createSubpassPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const vk::BinaryCollection & binaryCollection,deUint32 width,deUint32 height,deUint32 sampleCount)594 Move<VkPipeline> createSubpassPipeline (const DeviceInterface& vkd,
595 VkDevice device,
596 VkRenderPass renderPass,
597 VkPipelineLayout pipelineLayout,
598 const vk::BinaryCollection& binaryCollection,
599 deUint32 width,
600 deUint32 height,
601 deUint32 sampleCount)
602 {
603 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
604 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-subpass-frag"), 0u));
605
606 const VkPipelineVertexInputStateCreateInfo vertexInputState =
607 {
608 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
609 DE_NULL,
610 (VkPipelineVertexInputStateCreateFlags)0u,
611
612 0u,
613 DE_NULL,
614
615 0u,
616 DE_NULL
617 };
618
619 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
620 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
621
622 const VkPipelineMultisampleStateCreateInfo multisampleState =
623 {
624 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
625 DE_NULL,
626 (VkPipelineMultisampleStateCreateFlags)0u,
627
628 sampleCountBitFromSampleCount(sampleCount),
629 VK_FALSE,
630 0.0f,
631 DE_NULL,
632 VK_FALSE,
633 VK_FALSE,
634 };
635
636 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
637 device, // const VkDevice device
638 pipelineLayout, // const VkPipelineLayout pipelineLayout
639 *vertexShaderModule, // const VkShaderModule vertexShaderModule
640 DE_NULL, // const VkShaderModule tessellationControlShaderModule
641 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
642 DE_NULL, // const VkShaderModule geometryShaderModule
643 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
644 renderPass, // const VkRenderPass renderPass
645 viewports, // const std::vector<VkViewport>& viewports
646 scissors, // const std::vector<VkRect2D>& scissors
647 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
648 1u, // const deUint32 subpass
649 0u, // const deUint32 patchControlPoints
650 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
651 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
652 &multisampleState); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
653 }
654
createSubpassDescriptorPool(const DeviceInterface & vkd,VkDevice device)655 Move<VkDescriptorPool> createSubpassDescriptorPool (const DeviceInterface& vkd,
656 VkDevice device)
657 {
658 const VkDescriptorPoolSize size =
659 {
660 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
661 };
662 const VkDescriptorPoolCreateInfo createInfo =
663 {
664 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
665 DE_NULL,
666 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
667
668 2u,
669 1u,
670 &size
671 };
672
673 return createDescriptorPool(vkd, device, &createInfo);
674 }
675
createSubpassDescriptorSet(const DeviceInterface & vkd,VkDevice device,VkDescriptorPool pool,VkDescriptorSetLayout layout,VkImageView imageView)676 Move<VkDescriptorSet> createSubpassDescriptorSet (const DeviceInterface& vkd,
677 VkDevice device,
678 VkDescriptorPool pool,
679 VkDescriptorSetLayout layout,
680 VkImageView imageView)
681 {
682 const VkDescriptorSetAllocateInfo allocateInfo =
683 {
684 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
685 DE_NULL,
686
687 pool,
688 1u,
689 &layout
690 };
691 Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));
692
693 {
694 const VkDescriptorImageInfo imageInfo =
695 {
696 (VkSampler)0u,
697 imageView,
698 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
699 };
700 const VkWriteDescriptorSet write =
701 {
702 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
703 DE_NULL,
704
705 *set,
706 0u,
707 0u,
708 1u,
709 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
710 &imageInfo,
711 DE_NULL,
712 DE_NULL
713 };
714
715 vkd.updateDescriptorSets(device, 1u, &write, 0u, DE_NULL);
716 }
717 return set;
718 }
719
720 enum TestMode
721 {
722 TESTMODE_ADD = 0,
723 TESTMODE_SELECT,
724
725 TESTMODE_LAST
726 };
727
728 struct TestConfig
729 {
TestConfigvkt::__anonfd259d420111::TestConfig730 TestConfig (deUint32 sampleCount_, TestMode testMode_, deUint32 selectedSample_, RenderingType renderingType_)
731 : sampleCount (sampleCount_)
732 , testMode (testMode_)
733 , selectedSample (selectedSample_)
734 , renderingType (renderingType_)
735 {
736 }
737
738 deUint32 sampleCount;
739 TestMode testMode;
740 deUint32 selectedSample;
741 RenderingType renderingType;
742 };
743
744 class SampleReadTestInstance : public TestInstance
745 {
746 public:
747 SampleReadTestInstance (Context& context, TestConfig config);
748 ~SampleReadTestInstance (void);
749
750 tcu::TestStatus iterate (void);
751
752 template<typename RenderpassSubpass>
753 tcu::TestStatus iterateInternal (void);
754
755 private:
756 const bool m_extensionSupported;
757 const RenderingType m_renderingType;
758
759 const deUint32 m_sampleCount;
760 const deUint32 m_width;
761 const deUint32 m_height;
762 const TestMode m_testMode;
763 const deUint32 m_selectedSample;
764
765 const Unique<VkImage> m_srcImage;
766 const de::UniquePtr<Allocation> m_srcImageMemory;
767 const Unique<VkImageView> m_srcImageView;
768 const Unique<VkImageView> m_srcInputImageView;
769
770 const Unique<VkImage> m_dstMultisampleImage;
771 const de::UniquePtr<Allocation> m_dstMultisampleImageMemory;
772 const Unique<VkImageView> m_dstMultisampleImageView;
773
774 const Unique<VkImage> m_dstSinglesampleImage;
775 const de::UniquePtr<Allocation> m_dstSinglesampleImageMemory;
776 const Unique<VkImageView> m_dstSinglesampleImageView;
777
778 const Unique<VkBuffer> m_dstBuffer;
779 const de::UniquePtr<Allocation> m_dstBufferMemory;
780
781 const Unique<VkRenderPass> m_renderPass;
782 const Unique<VkFramebuffer> m_framebuffer;
783
784 const Unique<VkPipelineLayout> m_renderPipelineLayout;
785 const Unique<VkPipeline> m_renderPipeline;
786
787 const Unique<VkDescriptorSetLayout> m_subpassDescriptorSetLayout;
788 const Unique<VkPipelineLayout> m_subpassPipelineLayout;
789 const Unique<VkPipeline> m_subpassPipeline;
790 const Unique<VkDescriptorPool> m_subpassDescriptorPool;
791 const Unique<VkDescriptorSet> m_subpassDescriptorSet;
792
793 const Unique<VkCommandPool> m_commandPool;
794 tcu::ResultCollector m_resultCollector;
795 };
796
SampleReadTestInstance(Context & context,TestConfig config)797 SampleReadTestInstance::SampleReadTestInstance (Context& context, TestConfig config)
798 : TestInstance (context)
799 , m_extensionSupported (context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING) &&
800 ((config.renderingType != RENDERING_TYPE_RENDERPASS2) || context.requireDeviceFunctionality("VK_KHR_create_renderpass2")))
801 , m_renderingType (config.renderingType)
802 , m_sampleCount (config.sampleCount)
803 , m_width (32u)
804 , m_height (32u)
805 , m_testMode (config.testMode)
806 , m_selectedSample (config.selectedSample)
807 , m_srcImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT, sampleCountBitFromSampleCount(m_sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, m_width, m_height))
808 , m_srcImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
809 , m_srcImageView (createImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT))
810 , m_srcInputImageView (createImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT))
811 , m_dstMultisampleImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT, sampleCountBitFromSampleCount(m_sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, m_width, m_height))
812 , m_dstMultisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstMultisampleImage))
813 , m_dstMultisampleImageView (createImageView(context.getDeviceInterface(), context.getDevice(), *m_dstMultisampleImage, VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT))
814 , m_dstSinglesampleImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, m_width, m_height))
815 , m_dstSinglesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstSinglesampleImage))
816 , m_dstSinglesampleImageView (createImageView(context.getDeviceInterface(), context.getDevice(), *m_dstSinglesampleImage, VK_FORMAT_R32_UINT, VK_IMAGE_ASPECT_COLOR_BIT))
817 , m_dstBuffer (createBuffer(context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT, m_width, m_height))
818 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
819 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), VK_FORMAT_R32_UINT, VK_FORMAT_R32_UINT, m_sampleCount, config.renderingType))
820 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, *m_dstMultisampleImageView, *m_dstSinglesampleImageView, m_width, m_height))
821 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
822 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
823 , m_subpassDescriptorSetLayout (createSubpassDescriptorSetLayout(context.getDeviceInterface(), context.getDevice()))
824 , m_subpassPipelineLayout (createSubpassPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_subpassDescriptorSetLayout))
825 , m_subpassPipeline (createSubpassPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_subpassPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
826 , m_subpassDescriptorPool (createSubpassDescriptorPool(context.getDeviceInterface(), context.getDevice()))
827 , m_subpassDescriptorSet (createSubpassDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_subpassDescriptorPool, *m_subpassDescriptorSetLayout, *m_srcInputImageView))
828 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
829 {
830 }
831
~SampleReadTestInstance(void)832 SampleReadTestInstance::~SampleReadTestInstance (void)
833 {
834 }
835
iterate(void)836 tcu::TestStatus SampleReadTestInstance::iterate (void)
837 {
838 switch (m_renderingType)
839 {
840 case RENDERING_TYPE_RENDERPASS_LEGACY:
841 return iterateInternal<RenderpassSubpass1>();
842 case RENDERING_TYPE_RENDERPASS2:
843 return iterateInternal<RenderpassSubpass2>();
844 default:
845 TCU_THROW(InternalError, "Impossible");
846 }
847 }
848
849 template<typename RenderpassSubpass>
iterateInternal(void)850 tcu::TestStatus SampleReadTestInstance::iterateInternal (void)
851 {
852 const DeviceInterface& vkd (m_context.getDeviceInterface());
853 const VkDevice device (m_context.getDevice());
854 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
855 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
856 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
857
858 beginCommandBuffer(vkd, *commandBuffer);
859
860 {
861 const VkRenderPassBeginInfo beginInfo =
862 {
863 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
864 DE_NULL,
865
866 *m_renderPass,
867 *m_framebuffer,
868
869 {
870 { 0u, 0u },
871 { m_width, m_height }
872 },
873
874 0u,
875 DE_NULL
876 };
877 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
878 }
879
880 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
881
882 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
883
884 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
885
886 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpassPipeline);
887 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpassPipelineLayout, 0u, 1u, &*m_subpassDescriptorSet, 0u, DE_NULL);
888 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
889
890 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
891
892 copyImageToBuffer(vkd, *commandBuffer, *m_dstSinglesampleImage, *m_dstBuffer, tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
893
894 endCommandBuffer(vkd, *commandBuffer);
895
896 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
897
898 {
899 invalidateAlloc(vkd, device, *m_dstBufferMemory);
900
901 const tcu::TextureFormat format (mapVkFormat(VK_FORMAT_R32_UINT));
902 const void* const ptr (m_dstBufferMemory->getHostPtr());
903 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
904 tcu::TextureLevel reference (format, m_width, m_height);
905
906 for (deUint32 y = 0; y < m_height; y++)
907 for (deUint32 x = 0; x < m_width; x++)
908 {
909 deUint32 bits;
910
911 if (m_testMode == TESTMODE_ADD)
912 bits = m_sampleCount == 32 ? 0xffffffff : (1u << m_sampleCount) - 1;
913 else
914 bits = 1u << m_selectedSample;
915
916 const UVec4 color (bits, 0, 0, 0xffffffff);
917
918 reference.getAccess().setPixel(color, x, y);
919 }
920
921 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
922 m_resultCollector.fail("Compare failed.");
923 }
924
925 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
926 }
927
928 struct Programs
929 {
initvkt::__anonfd259d420111::Programs930 void init (vk::SourceCollections& dst, TestConfig config) const
931 {
932 std::ostringstream fragmentShader;
933 std::ostringstream subpassShader;
934
935 dst.glslSources.add("quad-vert") << glu::VertexSource(
936 "#version 450\n"
937 "out gl_PerVertex {\n"
938 "\tvec4 gl_Position;\n"
939 "};\n"
940 "highp float;\n"
941 "void main (void)\n"
942 "{\n"
943 " gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
944 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
945 "}\n");
946
947 fragmentShader <<
948 "#version 450\n"
949 "layout(location = 0) out highp uvec4 o_color;\n"
950 "void main (void)\n"
951 "{\n"
952 " o_color = uvec4(1u << gl_SampleID, 0, 0, 0);\n"
953 "}\n";
954
955 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
956
957 subpassShader <<
958 "#version 450\n"
959 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_color;\n"
960 "layout(location = 0) out highp uvec4 o_color;\n"
961 "void main (void)\n"
962 "{\n"
963 " o_color = uvec4(0);\n";
964
965 if (config.testMode == TESTMODE_ADD)
966 {
967 subpassShader <<
968 " for (int i = 0; i < " << config.sampleCount << "; i++)\n" <<
969 " o_color.r += subpassLoad(i_color, i).r;\n";
970 }
971 else
972 {
973 subpassShader <<
974 " o_color.r = subpassLoad(i_color, " << de::toString(config.selectedSample) << ").r;\n";
975 }
976
977 subpassShader << "}\n";
978
979 dst.glslSources.add("quad-subpass-frag") << glu::FragmentSource(subpassShader.str());
980 }
981 };
982
initTests(tcu::TestCaseGroup * group,RenderingType renderingType)983 void initTests (tcu::TestCaseGroup* group, RenderingType renderingType)
984 {
985 const deUint32 sampleCounts[] = { 2u, 4u, 8u, 16u, 32u };
986 tcu::TestContext& testCtx (group->getTestContext());
987
988 for (deUint32 sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
989 {
990 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
991 {
992 const TestConfig testConfig (sampleCount, TESTMODE_ADD, 0, renderingType);
993 const std::string testName ("numsamples_" + de::toString(sampleCount) + "_add");
994
995 group->addChild(new InstanceFactory1<SampleReadTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
996 }
997
998 for (deUint32 sample = 0; sample < sampleCount; sample++)
999 {
1000 const TestConfig testConfig (sampleCount, TESTMODE_SELECT, sample, renderingType);
1001 const std::string testName ("numsamples_" + de::toString(sampleCount) + "_selected_sample_" + de::toString(sample));
1002
1003 group->addChild(new InstanceFactory1<SampleReadTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
1004 }
1005 }
1006 }
1007
1008 } // anonymous
1009
createRenderPassSampleReadTests(tcu::TestContext & testCtx)1010 tcu::TestCaseGroup* createRenderPassSampleReadTests (tcu::TestContext& testCtx)
1011 {
1012 return createTestGroup(testCtx, "sampleread", "Sample reading tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
1013 }
1014
createRenderPass2SampleReadTests(tcu::TestContext & testCtx)1015 tcu::TestCaseGroup* createRenderPass2SampleReadTests (tcu::TestContext& testCtx)
1016 {
1017 return createTestGroup(testCtx, "sampleread", "Sample reading tests", initTests, RENDERING_TYPE_RENDERPASS2);
1018 }
1019
1020 } // vkt
1021