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 for render pass multisample resolve
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassMultisampleResolveTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29
30 #include "vkDefs.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42
43 #include "tcuFloat.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuMaybe.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorUtil.hpp"
51 #include "tcuStringTemplate.hpp"
52
53 #include "deUniquePtr.hpp"
54 #include "deSharedPtr.hpp"
55
56 using namespace vk;
57
58 using tcu::BVec4;
59 using tcu::IVec2;
60 using tcu::IVec4;
61 using tcu::UVec2;
62 using tcu::UVec4;
63 using tcu::Vec2;
64 using tcu::Vec3;
65 using tcu::Vec4;
66
67 using tcu::ConstPixelBufferAccess;
68 using tcu::PixelBufferAccess;
69 using tcu::TestLog;
70
71 using std::vector;
72
73 typedef de::SharedPtr<Allocation> AllocationSp;
74 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
75 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
76 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
77 typedef de::SharedPtr<vk::Unique<VkSampler> > VkSamplerSp;
78 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
79 typedef de::SharedPtr<vk::Unique<VkDescriptorSetLayout> > VkDescriptorSetLayoutSp;
80 typedef de::SharedPtr<vk::Unique<VkDescriptorPool> > VkDescriptorPoolSp;
81 typedef de::SharedPtr<vk::Unique<VkDescriptorSet> > VkDescriptorSetSp;
82
83 namespace vkt
84 {
85 namespace
86 {
87
88 using namespace renderpass;
89
90 template<typename T>
safeSharedPtr(T * ptr)91 de::SharedPtr<T> safeSharedPtr (T* ptr)
92 {
93 try
94 {
95 return de::SharedPtr<T>(ptr);
96 }
97 catch (...)
98 {
99 delete ptr;
100 throw;
101 }
102 }
103
104 enum TestType
105 {
106 RESOLVE = 0,
107 MAX_ATTACHMENTS,
108 COMPATIBILITY
109 };
110
111 struct TestConfig
112 {
113 TestType testType;
114 VkFormat format;
115 deUint32 sampleCount;
116 deUint32 layerCount;
117 deUint32 baseLayer;
118 deUint32 attachmentCount;
119 deUint32 width;
120 deUint32 height;
121 const SharedGroupParams groupParams;
122 };
123
124 struct TestConfig2 : TestConfig
125 {
TestConfig2vkt::__anonc87134f00111::TestConfig2126 TestConfig2(const TestConfig& src, deUint32 level)
127 : TestConfig (src)
128 , resolveLevel (level)
129 {
130 }
131 deUint32 resolveLevel;
132 };
133
134 // Render pass traits that groups render pass related types together and by that help
135 // to reduce number of template parrameters passed to number of functions in those tests
136 struct RenderPass1Trait
137 {
138 typedef AttachmentDescription1 AttDesc;
139 typedef AttachmentReference1 AttRef;
140 typedef SubpassDescription1 SubpassDesc;
141 typedef SubpassDependency1 SubpassDep;
142 typedef RenderPassCreateInfo1 RenderPassCreateInfo;
143 };
144 struct RenderPass2Trait
145 {
146 typedef AttachmentDescription2 AttDesc;
147 typedef AttachmentReference2 AttRef;
148 typedef SubpassDescription2 SubpassDesc;
149 typedef SubpassDependency2 SubpassDep;
150 typedef RenderPassCreateInfo2 RenderPassCreateInfo;
151 };
152
153 class MultisampleRenderPassTestBase : public TestInstance
154 {
155 public:
156 MultisampleRenderPassTestBase (Context& context, TestConfig config);
157 ~MultisampleRenderPassTestBase (void);
158
159 protected:
160
161 Move<VkImage> createImage (VkSampleCountFlagBits sampleCountBit,
162 VkImageUsageFlags usage) const;
163 Move<VkImage> createImage (VkSampleCountFlagBits sampleCountBit,
164 VkImageUsageFlags usage,
165 deUint32 width,
166 deUint32 height,
167 deUint32 mipLevels) const;
168 vector<VkImageSp> createImages (VkSampleCountFlagBits sampleCountBit,
169 VkImageUsageFlags usage) const;
170 vector<VkImageSp> createImages (VkSampleCountFlagBits sampleCountBit,
171 VkImageUsageFlags usage,
172 deUint32 width,
173 deUint32 height,
174 deUint32 mipLevels) const;
175 vector<AllocationSp> createImageMemory (const vector<VkImageSp>& images) const;
176 vector<VkImageViewSp> createImageViews (const vector<VkImageSp>& images,
177 deUint32 mipLevel = 0,
178 deUint32 baseLayers = 0) const;
179
180 vector<VkBufferSp> createBuffers () const;
181 vector<VkBufferSp> createBuffers (deUint32 width,
182 deUint32 height,
183 deUint32 mipLevels) const;
184 vector<AllocationSp> createBufferMemory (const vector<VkBufferSp>& buffers) const;
185
186 Move<VkFramebuffer> createFramebuffer (const std::vector<VkImageViewSp> multisampleImageViews,
187 const std::vector<VkImageViewSp> singlesampleImageViews,
188 VkRenderPass renderPass) const;
189
190 void clearAttachments (VkCommandBuffer commandBuffer) const;
191 VkDeviceSize getPixelSize () const;
192 tcu::Vec4 getFormatThreshold () const;
193 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) const;
194 void logImage (const std::string& name,
195 const tcu::ConstPixelBufferAccess& image) const;
196 uint32_t totalLayers () const;
197
198 protected:
199
200 const bool m_testCompatibility;
201 const SharedGroupParams m_groupParams;
202
203 const VkFormat m_format;
204 const VkSampleCountFlagBits m_sampleCount;
205 const deUint32 m_layerCount;
206 const deUint32 m_baseLayer;
207 const deUint32 m_attachmentsCount;
208 const deUint32 m_width;
209 const deUint32 m_height;
210 };
211
MultisampleRenderPassTestBase(Context & context,TestConfig config)212 MultisampleRenderPassTestBase::MultisampleRenderPassTestBase (Context& context, TestConfig config)
213 : TestInstance (context)
214 , m_testCompatibility (config.testType == COMPATIBILITY)
215 , m_groupParams (config.groupParams)
216 , m_format (config.format)
217 , m_sampleCount (sampleCountBitFromSampleCount(config.sampleCount))
218 , m_layerCount (config.layerCount)
219 , m_baseLayer (config.baseLayer)
220 , m_attachmentsCount (config.attachmentCount)
221 , m_width (config.width)
222 , m_height (config.height)
223 {
224 }
225
~MultisampleRenderPassTestBase()226 MultisampleRenderPassTestBase::~MultisampleRenderPassTestBase ()
227 {
228 }
229
createImage(VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage) const230 Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
231 {
232 return createImage(sampleCountBit, usage, m_width, m_height, 1u);
233 }
234
createImage(VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,deUint32 width,deUint32 height,deUint32 mipLevels) const235 Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits sampleCountBit,
236 VkImageUsageFlags usage,
237 deUint32 width,
238 deUint32 height,
239 deUint32 mipLevels) const
240 {
241 const InstanceInterface& vki = m_context.getInstanceInterface();
242 const DeviceInterface& vkd = m_context.getDeviceInterface();
243 VkDevice device = m_context.getDevice();
244 VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
245 const tcu::TextureFormat format (mapVkFormat(m_format));
246 const VkImageType imageType (VK_IMAGE_TYPE_2D);
247 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
248 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, m_format));
249 const VkExtent3D imageExtent =
250 {
251 width,
252 height,
253 1u
254 };
255
256 try
257 {
258 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, imageType, imageTiling, usage, 0u));
259 const auto isDSFormat = (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
260
261 if (isDSFormat && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
262 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
263
264 if (!isDSFormat && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
265 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
266
267 if (imageFormatProperties.maxExtent.width < imageExtent.width
268 || imageFormatProperties.maxExtent.height < imageExtent.height
269 || ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
270 || imageFormatProperties.maxArrayLayers < m_layerCount)
271 {
272 TCU_THROW(NotSupportedError, "Image type not supported");
273 }
274
275 const VkImageCreateInfo pCreateInfo =
276 {
277 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
278 DE_NULL,
279 0u,
280 imageType,
281 m_format,
282 imageExtent,
283 mipLevels,
284 totalLayers(),
285 sampleCountBit,
286 imageTiling,
287 usage,
288 VK_SHARING_MODE_EXCLUSIVE,
289 0u,
290 DE_NULL,
291 VK_IMAGE_LAYOUT_UNDEFINED
292 };
293
294 return ::createImage(vkd, device, &pCreateInfo);
295 }
296 catch (const vk::Error& error)
297 {
298 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
299 TCU_THROW(NotSupportedError, "Image format not supported");
300
301 throw;
302 }
303 }
304
createImages(VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage) const305 vector<VkImageSp> MultisampleRenderPassTestBase::createImages (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
306 {
307 std::vector<VkImageSp> images (m_attachmentsCount);
308 for (size_t imageNdx = 0; imageNdx < m_attachmentsCount; imageNdx++)
309 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(sampleCountBit, usage)));
310 return images;
311 }
312
createImages(VkSampleCountFlagBits sampleCountBit,VkImageUsageFlags usage,deUint32 width,deUint32 height,deUint32 mipLevels) const313 vector<VkImageSp> MultisampleRenderPassTestBase::createImages (VkSampleCountFlagBits sampleCountBit,
314 VkImageUsageFlags usage,
315 deUint32 width,
316 deUint32 height,
317 deUint32 mipLevels) const
318 {
319 std::vector<VkImageSp> images (m_attachmentsCount);
320 for (size_t imageNdx = 0; imageNdx < m_attachmentsCount; imageNdx++)
321 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(sampleCountBit, usage, width, height, mipLevels)));
322 return images;
323 }
324
createImageMemory(const vector<VkImageSp> & images) const325 vector<AllocationSp> MultisampleRenderPassTestBase::createImageMemory (const vector<VkImageSp>& images) const
326 {
327 const DeviceInterface& vkd = m_context.getDeviceInterface();
328 VkDevice device = m_context.getDevice();
329 Allocator& allocator = m_context.getDefaultAllocator();
330 std::vector<AllocationSp> memory (images.size());
331
332 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
333 {
334 VkImage image = **images[memoryNdx];
335 VkMemoryRequirements requirements = getImageMemoryRequirements(vkd, device, image);
336
337 de::MovePtr<Allocation> allocation (allocator.allocate(requirements, MemoryRequirement::Any));
338 VK_CHECK(vkd.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
339 memory[memoryNdx] = safeSharedPtr(allocation.release());
340 }
341 return memory;
342 }
343
createImageViews(const vector<VkImageSp> & images,deUint32 mipLevel,deUint32 baseLayer) const344 vector<VkImageViewSp> MultisampleRenderPassTestBase::createImageViews (const vector<VkImageSp>& images, deUint32 mipLevel, deUint32 baseLayer) const
345 {
346 const DeviceInterface& vkd = m_context.getDeviceInterface();
347 VkDevice device = m_context.getDevice();
348 std::vector<VkImageViewSp> views (images.size());
349 const VkImageSubresourceRange range =
350 {
351 VK_IMAGE_ASPECT_COLOR_BIT,
352 mipLevel,
353 1u,
354 baseLayer,
355 m_layerCount
356 };
357
358 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
359 {
360 const VkImageViewCreateInfo pCreateInfo =
361 {
362 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
363 DE_NULL,
364 0u,
365 **images[imageNdx],
366 VK_IMAGE_VIEW_TYPE_2D_ARRAY,
367 m_format,
368 makeComponentMappingRGBA(),
369 range,
370 };
371 views[imageNdx] = safeSharedPtr(new Unique<VkImageView>(createImageView(vkd, device, &pCreateInfo)));
372 }
373
374 return views;
375 }
376
createBuffers() const377 vector<VkBufferSp> MultisampleRenderPassTestBase::createBuffers () const
378 {
379 return createBuffers(m_width, m_height, 1u);
380 }
381
createBuffers(deUint32 width,deUint32 height,deUint32 mipLevels) const382 vector<VkBufferSp> MultisampleRenderPassTestBase::createBuffers (deUint32 width, deUint32 height, deUint32 mipLevels) const
383 {
384 DE_ASSERT(mipLevels);
385
386 VkDeviceSize size = 0;
387 for (deUint32 level = 0; level < mipLevels; ++level)
388 {
389 DE_ASSERT(width && height);
390
391 size += (width * height);
392 height /= 2;
393 width /=2;
394 }
395
396 const DeviceInterface& vkd = m_context.getDeviceInterface();
397 VkDevice device = m_context.getDevice();
398 std::vector<VkBufferSp> buffers (m_attachmentsCount);
399 const VkDeviceSize pixelSize (getPixelSize());
400 const VkBufferCreateInfo createInfo =
401 {
402 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
403 DE_NULL,
404 0u,
405
406 size * totalLayers() * pixelSize,
407 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
408
409 VK_SHARING_MODE_EXCLUSIVE,
410 0u,
411 DE_NULL
412 };
413
414 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
415 buffers[bufferNdx] = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vkd, device, &createInfo)));
416
417 return buffers;
418 }
419
createBufferMemory(const vector<VkBufferSp> & buffers) const420 vector<AllocationSp> MultisampleRenderPassTestBase::createBufferMemory (const vector<VkBufferSp>& buffers) const
421 {
422 const DeviceInterface& vkd = m_context.getDeviceInterface();
423 VkDevice device = m_context.getDevice();
424 Allocator& allocator = m_context.getDefaultAllocator();
425 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
426
427 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
428 {
429 VkBuffer buffer = **buffers[memoryNdx];
430 VkMemoryRequirements requirements = getBufferMemoryRequirements(vkd, device, buffer);
431 de::MovePtr<Allocation> allocation (allocator.allocate(requirements, MemoryRequirement::HostVisible));
432
433 VK_CHECK(vkd.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
434 memory[memoryNdx] = safeSharedPtr(allocation.release());
435 }
436 return memory;
437 }
438
createFramebuffer(const std::vector<VkImageViewSp> multisampleImageViews,const std::vector<VkImageViewSp> singlesampleImageViews,VkRenderPass renderPass) const439 Move<VkFramebuffer> MultisampleRenderPassTestBase::createFramebuffer (const std::vector<VkImageViewSp> multisampleImageViews,
440 const std::vector<VkImageViewSp> singlesampleImageViews,
441 VkRenderPass renderPass) const
442 {
443 // when RenderPass was not created then we are testing dynamic rendering
444 // and we can't create framebuffer without valid RenderPass object
445 if (!renderPass)
446 return Move<VkFramebuffer>();
447
448 const DeviceInterface& vkd = m_context.getDeviceInterface();
449 VkDevice device = m_context.getDevice();
450
451 std::vector<VkImageView> attachments;
452 attachments.reserve(multisampleImageViews.size() + singlesampleImageViews.size());
453
454 DE_ASSERT(multisampleImageViews.size() == singlesampleImageViews.size());
455
456 for (size_t ndx = 0; ndx < multisampleImageViews.size(); ndx++)
457 {
458 attachments.push_back(**multisampleImageViews[ndx]);
459 attachments.push_back(**singlesampleImageViews[ndx]);
460 }
461
462 const VkFramebufferCreateInfo createInfo =
463 {
464 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
465 DE_NULL,
466 0u,
467
468 renderPass,
469 (deUint32)attachments.size(),
470 &attachments[0],
471
472 m_width,
473 m_height,
474 m_layerCount
475 };
476
477 return ::createFramebuffer(vkd, device, &createInfo);
478 }
479
clearAttachments(VkCommandBuffer commandBuffer) const480 void MultisampleRenderPassTestBase::clearAttachments (VkCommandBuffer commandBuffer) const
481 {
482 const DeviceInterface& vkd = m_context.getDeviceInterface();
483 const tcu::TextureFormat format (mapVkFormat(m_format));
484 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
485 VkClearValue value;
486
487 // Clear everything to black
488 switch (channelClass)
489 {
490 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
491 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
492 break;
493
494 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
495 value = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
496 break;
497
498 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
499 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
500 break;
501
502 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
503 value = makeClearValueColorI32(-128, -128, -128, -128);
504 break;
505
506 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
507 value = makeClearValueColorU32(0u, 0u, 0u, 0u);
508 break;
509
510 default:
511 DE_FATAL("Unknown channel class");
512 }
513 std::vector<VkClearAttachment> colors(m_attachmentsCount);
514 for (deUint32 attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
515 {
516 colors[attachmentNdx].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
517 colors[attachmentNdx].colorAttachment = attachmentNdx;
518 colors[attachmentNdx].clearValue = value;
519 }
520 const VkClearRect rect =
521 {
522 {
523 { 0u, 0u },
524 { m_width, m_height }
525 },
526 0u,
527 m_layerCount,
528 };
529 vkd.cmdClearAttachments(commandBuffer, deUint32(colors.size()), &colors[0], 1u, &rect);
530 }
531
getPixelSize() const532 VkDeviceSize MultisampleRenderPassTestBase::getPixelSize () const
533 {
534 const tcu::TextureFormat format(mapVkFormat(m_format));
535 return format.getPixelSize();
536 }
537
getFormatThreshold() const538 tcu::Vec4 MultisampleRenderPassTestBase::getFormatThreshold () const
539 {
540 const tcu::TextureFormat tcuFormat (mapVkFormat(m_format));
541 const bool isAlphaOnly = isAlphaOnlyFormat(m_format);
542 const deUint32 componentCount (isAlphaOnly ? 4u : tcu::getNumUsedChannels(tcuFormat.order));
543
544 if (isSnormFormat(m_format))
545 {
546 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffSnorm(m_format, 0) : 0.0f,
547 (componentCount >= 2) ? 1.5f * getRepresentableDiffSnorm(m_format, 1) : 0.0f,
548 (componentCount >= 3) ? 1.5f * getRepresentableDiffSnorm(m_format, 2) : 0.0f,
549 (componentCount == 4) ? 1.5f * getRepresentableDiffSnorm(m_format, 3) : 0.0f);
550 }
551 else if (isUnormFormat(m_format))
552 {
553 return Vec4((componentCount >= 1 && !isAlphaOnly) ? 1.5f * getRepresentableDiffUnorm(m_format, 0) : 0.0f,
554 (componentCount >= 2 && !isAlphaOnly) ? 1.5f * getRepresentableDiffUnorm(m_format, 1) : 0.0f,
555 (componentCount >= 3 && !isAlphaOnly) ? 1.5f * getRepresentableDiffUnorm(m_format, 2) : 0.0f,
556 (componentCount == 4) ? 1.5f * getRepresentableDiffUnorm(m_format, 3) : 0.0f);
557 }
558 else if (isFloatFormat(m_format))
559 {
560 return (tcuFormat.type == tcu::TextureFormat::HALF_FLOAT) ? tcu::Vec4(0.005f) : Vec4(0.00001f);
561 }
562 else
563 return Vec4(0.001f);
564 }
565
sampleCountBitFromSampleCount(deUint32 count) const566 VkSampleCountFlagBits MultisampleRenderPassTestBase::sampleCountBitFromSampleCount (deUint32 count) const
567 {
568 switch (count)
569 {
570 case 1: return VK_SAMPLE_COUNT_1_BIT;
571 case 2: return VK_SAMPLE_COUNT_2_BIT;
572 case 4: return VK_SAMPLE_COUNT_4_BIT;
573 case 8: return VK_SAMPLE_COUNT_8_BIT;
574 case 16: return VK_SAMPLE_COUNT_16_BIT;
575 case 32: return VK_SAMPLE_COUNT_32_BIT;
576 case 64: return VK_SAMPLE_COUNT_64_BIT;
577
578 default:
579 DE_FATAL("Invalid sample count");
580 return (VkSampleCountFlagBits)0x0;
581 }
582 }
583
logImage(const std::string & name,const tcu::ConstPixelBufferAccess & image) const584 void MultisampleRenderPassTestBase::logImage (const std::string& name, const tcu::ConstPixelBufferAccess& image) const
585 {
586 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), image);
587
588 const auto totalLayerCount = totalLayers();
589 for (deUint32 layerNdx = m_baseLayer; layerNdx < totalLayerCount; ++layerNdx)
590 {
591 const std::string layerName (name + " Layer:" + de::toString(layerNdx));
592 tcu::ConstPixelBufferAccess layerImage (image.getFormat(), m_width, m_height, 1, image.getPixelPtr(0, 0, layerNdx));
593
594 m_context.getTestContext().getLog() << tcu::LogImage(layerName.c_str(), layerName.c_str(), layerImage);
595 }
596 }
597
totalLayers() const598 uint32_t MultisampleRenderPassTestBase::totalLayers () const
599 {
600 return (m_layerCount + m_baseLayer);
601 }
602
603 class MultisampleRenderPassTestInstance : public MultisampleRenderPassTestBase
604 {
605 public:
606 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
607 ~MultisampleRenderPassTestInstance (void);
608
609 tcu::TestStatus iterate (void);
610
611 private:
612
613 void drawCommands (VkCommandBuffer cmdBuffer, VkPipeline pipeline, VkPipelineLayout pipelineLayout) const;
614
615 template<typename RenderpassSubpass>
616 void submit (void);
617 void submitDynamicRendering (void);
618 void submitSwitch (const SharedGroupParams groupParams);
619 void verify (void);
620
621 template<typename RenderPassTrait>
622 Move<VkRenderPass> createRenderPass (bool usedResolveAttachment);
623 Move<VkRenderPass> createRenderPassSwitch (bool usedResolveAttachment);
624 Move<VkRenderPass> createRenderPassCompatible (void);
625 Move<VkPipelineLayout> createRenderPipelineLayout (void);
626 Move<VkPipeline> createRenderPipeline (void);
627
628 #ifndef CTS_USES_VULKANSC
629 void beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
630 #endif // CTS_USES_VULKANSC
631
632 private:
633
634 const std::vector<VkImageSp> m_multisampleImages;
635 const std::vector<AllocationSp> m_multisampleImageMemory;
636 const std::vector<VkImageViewSp> m_multisampleImageViews;
637
638 const std::vector<VkImageSp> m_singlesampleImages;
639 const std::vector<AllocationSp> m_singlesampleImageMemory;
640 const std::vector<VkImageViewSp> m_singlesampleImageViews;
641
642 const Unique<VkRenderPass> m_renderPass;
643 const Unique<VkRenderPass> m_renderPassCompatible;
644 const Unique<VkFramebuffer> m_framebuffer;
645
646 const Unique<VkPipelineLayout> m_renderPipelineLayout;
647 const Unique<VkPipeline> m_renderPipeline;
648
649 const std::vector<VkBufferSp> m_buffers;
650 const std::vector<AllocationSp> m_bufferMemory;
651
652 const Unique<VkCommandPool> m_commandPool;
653 tcu::TextureLevel m_sum;
654 tcu::TextureLevel m_sumSrgb;
655 deUint32 m_sampleMask;
656 tcu::ResultCollector m_resultCollector;
657
658 protected:
659 MultisampleRenderPassTestInstance (Context& context, TestConfig config, deUint32 renderLevel);
660
661 const deUint32 m_renderLevel;
662 };
663
MultisampleRenderPassTestInstance(Context & context,TestConfig config)664 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
665 : MultisampleRenderPassTestInstance (context, config, /*defaulf render level*/0u)
666 {
667 }
668
MultisampleRenderPassTestInstance(Context & context,TestConfig config,deUint32 renderLevel)669 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config, deUint32 renderLevel)
670 : MultisampleRenderPassTestBase(context, config)
671
672 , m_multisampleImages (createImages(m_sampleCount, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
673 , m_multisampleImageMemory (createImageMemory(m_multisampleImages))
674 , m_multisampleImageViews (createImageViews(m_multisampleImages))
675
676 , m_singlesampleImages (createImages(VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, (1u << renderLevel)*m_width, (1u << renderLevel)*m_height, renderLevel+1 ))
677 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImages))
678 , m_singlesampleImageViews (createImageViews(m_singlesampleImages, renderLevel, m_baseLayer))
679
680 // The "normal" render pass has an unused resolve attachment when testing compatibility.
681 , m_renderPass (createRenderPassSwitch(!m_testCompatibility))
682 , m_renderPassCompatible (createRenderPassCompatible())
683 , m_framebuffer (createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))
684
685 , m_renderPipelineLayout (createRenderPipelineLayout())
686 , m_renderPipeline (createRenderPipeline())
687
688 , m_buffers (createBuffers((1u << renderLevel)*m_width, (1u << renderLevel)*m_height, renderLevel+1 ))
689 , m_bufferMemory (createBufferMemory(m_buffers))
690
691 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
692 , m_sum (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, totalLayers())
693 , m_sumSrgb (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, totalLayers())
694 , m_sampleMask (0x0u)
695
696 , m_renderLevel (renderLevel)
697 {
698 tcu::clear(m_sum.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
699 tcu::clear(m_sumSrgb.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
700 }
701
~MultisampleRenderPassTestInstance(void)702 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
703 {
704 }
705
drawCommands(VkCommandBuffer cmdBuffer,VkPipeline pipeline,VkPipelineLayout pipelineLayout) const706 void MultisampleRenderPassTestInstance::drawCommands(VkCommandBuffer cmdBuffer, VkPipeline pipeline, VkPipelineLayout pipelineLayout) const
707 {
708 const DeviceInterface& vkd = m_context.getDeviceInterface();
709
710 // Clear everything to black
711 clearAttachments(cmdBuffer);
712
713 // Render black samples
714 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
715 vkd.cmdPushConstants(cmdBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(m_sampleMask), &m_sampleMask);
716 vkd.cmdDraw(cmdBuffer, 6u, 1u, 0u, 0u);
717 }
718
719 template<typename RenderpassSubpass>
submit(void)720 void MultisampleRenderPassTestInstance::submit (void)
721 {
722 const DeviceInterface& vkd (m_context.getDeviceInterface());
723 const VkDevice device (m_context.getDevice());
724 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
725
726 beginCommandBuffer(vkd, *commandBuffer);
727
728 // Memory barriers between previous copies and rendering
729 {
730 std::vector<VkImageMemoryBarrier> barriers;
731
732 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
733 {
734 const VkImageMemoryBarrier barrier =
735 {
736 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
737 DE_NULL,
738
739 VK_ACCESS_TRANSFER_READ_BIT,
740 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
741
742 VK_IMAGE_LAYOUT_UNDEFINED,
743 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
744
745 VK_QUEUE_FAMILY_IGNORED,
746 VK_QUEUE_FAMILY_IGNORED,
747
748 **m_singlesampleImages[dstNdx],
749 {
750 VK_IMAGE_ASPECT_COLOR_BIT,
751 m_renderLevel,
752 1u,
753 m_baseLayer,
754 m_layerCount
755 }
756 };
757
758 barriers.push_back(barrier);
759 }
760
761 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
762 }
763
764 VkRect2D renderArea = makeRect2D(m_width, m_height);
765 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
766 const VkRenderPassBeginInfo beginInfo =
767 {
768 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
769 DE_NULL,
770
771 m_testCompatibility ? *m_renderPassCompatible : *m_renderPass,
772 *m_framebuffer,
773 renderArea,
774
775 0u,
776 DE_NULL
777 };
778 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
779
780 drawCommands(*commandBuffer, *m_renderPipeline, *m_renderPipelineLayout);
781
782 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
783 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
784
785 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
786 {
787 // assume that buffer(s) have enough memory to store desired amount of mipmaps
788 copyImageToBuffer(vkd, *commandBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx],
789 m_format, tcu::IVec2((1u << m_renderLevel)*m_width, (1u << m_renderLevel)*m_height), m_renderLevel,
790 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, totalLayers());
791 }
792
793 endCommandBuffer(vkd, *commandBuffer);
794
795 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
796
797 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
798 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
799 }
800
submitDynamicRendering(void)801 void MultisampleRenderPassTestInstance::submitDynamicRendering (void)
802 {
803 #ifndef CTS_USES_VULKANSC
804
805 const DeviceInterface& vkd (m_context.getDeviceInterface());
806 const VkDevice device (m_context.getDevice());
807 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
808 Move<VkCommandBuffer> secCmdBuffer;
809
810 // Memory barriers between previous copies and rendering
811 std::vector<VkImageMemoryBarrier> singlesampleImageBarriers(m_singlesampleImages.size(),
812 {
813 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
814 DE_NULL,
815
816 VK_ACCESS_TRANSFER_READ_BIT,
817 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
818
819 VK_IMAGE_LAYOUT_UNDEFINED,
820 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
821
822 VK_QUEUE_FAMILY_IGNORED,
823 VK_QUEUE_FAMILY_IGNORED,
824
825 DE_NULL,
826 {
827 VK_IMAGE_ASPECT_COLOR_BIT,
828 m_renderLevel,
829 1u,
830 0u,
831 totalLayers()
832 }
833 });
834 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
835 singlesampleImageBarriers[dstNdx].image = **m_singlesampleImages[dstNdx];
836
837 // Memory barriers to set multisample image layout to COLOR_ATTACHMENT_OPTIMAL
838 std::vector<VkImageMemoryBarrier> multisampleImageBarriers(m_multisampleImages.size(),
839 {
840 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
841 DE_NULL,
842
843 0,
844 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
845
846 VK_IMAGE_LAYOUT_UNDEFINED,
847 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
848
849 VK_QUEUE_FAMILY_IGNORED,
850 VK_QUEUE_FAMILY_IGNORED,
851
852 DE_NULL,
853 {
854 VK_IMAGE_ASPECT_COLOR_BIT,
855 0u,
856 1u,
857 0u,
858 m_layerCount
859 }
860 });
861 for (size_t dstNdx = 0; dstNdx < m_multisampleImages.size(); dstNdx++)
862 multisampleImageBarriers[dstNdx].image = **m_multisampleImages[dstNdx];
863
864 VkRect2D renderArea = makeRect2D(m_width, m_height);
865 const VkClearValue clearValue = makeClearValueColor( { 0.0f, 0.0f, 0.0f, 1.0f } );
866 std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachments(m_attachmentsCount,
867 {
868 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
869 DE_NULL, // const void* pNext;
870 DE_NULL, // VkImageView imageView;
871 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
872 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
873 DE_NULL, // VkImageView resolveImageView;
874 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout resolveImageLayout;
875 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
876 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
877 clearValue // VkClearValue clearValue;
878 });
879
880 for (deUint32 i = 0; i < m_attachmentsCount; ++i)
881 {
882 colorAttachments[i].imageView = **m_multisampleImageViews[i];
883 colorAttachments[i].resolveImageView = **m_singlesampleImageViews[i];
884 if (isIntFormat(m_format) || isUintFormat(m_format))
885 colorAttachments[i].resolveMode = vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
886 else
887 colorAttachments[i].resolveMode = vk::VK_RESOLVE_MODE_AVERAGE_BIT;
888 }
889
890 vk::VkRenderingInfoKHR renderingInfo
891 {
892 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
893 DE_NULL,
894 0, // VkRenderingFlagsKHR flags;
895 renderArea, // VkRect2D renderArea;
896 m_layerCount, // deUint32 layerCount;
897 0u, // deUint32 viewMask;
898 m_attachmentsCount, // deUint32 colorAttachmentCount;
899 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
900 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
901 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
902 };
903
904 if (m_groupParams->useSecondaryCmdBuffer)
905 {
906 secCmdBuffer = allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
907
908 // record secondary command buffer
909 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
910 {
911 beginSecondaryCmdBuffer(*secCmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
912 vkd.cmdBeginRendering(*secCmdBuffer, &renderingInfo);
913 }
914 else
915 beginSecondaryCmdBuffer(*secCmdBuffer);
916
917 drawCommands(*secCmdBuffer, *m_renderPipeline, *m_renderPipelineLayout);
918
919 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
920 vkd.cmdEndRendering(*secCmdBuffer);
921
922 endCommandBuffer(vkd, *secCmdBuffer);
923
924 // record primary command buffer
925 beginCommandBuffer(vkd, *cmdBuffer);
926
927 vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)singlesampleImageBarriers.size(), &singlesampleImageBarriers[0]);
928 vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)multisampleImageBarriers.size(), &multisampleImageBarriers[0]);
929
930 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
931 {
932 renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
933 vkd.cmdBeginRendering(*cmdBuffer, &renderingInfo);
934 }
935 vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
936
937 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
938 vkd.cmdEndRendering(*cmdBuffer);
939 }
940 else
941 {
942 beginCommandBuffer(vkd, *cmdBuffer);
943
944 vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)singlesampleImageBarriers.size(), &singlesampleImageBarriers[0]);
945 vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)multisampleImageBarriers.size(), &multisampleImageBarriers[0]);
946
947 vkd.cmdBeginRendering(*cmdBuffer, &renderingInfo);
948 drawCommands(*cmdBuffer, *m_renderPipeline, *m_renderPipelineLayout);
949 vkd.cmdEndRendering(*cmdBuffer);
950 }
951
952 // Memory barriers to set single-sample image layout to TRANSFER_SRC_OPTIMAL
953 {
954 std::vector<VkImageMemoryBarrier> barriers;
955
956 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
957 {
958 const VkImageMemoryBarrier barrier =
959 {
960 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
961 DE_NULL,
962
963 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
964 VK_ACCESS_TRANSFER_READ_BIT,
965
966 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
967 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
968
969 VK_QUEUE_FAMILY_IGNORED,
970 VK_QUEUE_FAMILY_IGNORED,
971
972 **m_singlesampleImages[dstNdx],
973 {
974 VK_IMAGE_ASPECT_COLOR_BIT,
975 m_renderLevel,
976 1u,
977 0u,
978 totalLayers()
979 }
980 };
981
982 barriers.push_back(barrier);
983 }
984
985 vkd.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
986 }
987
988 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
989 {
990 // assume that buffer(s) have enough memory to store desired amount of mipmaps
991 copyImageToBuffer(vkd, *cmdBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx],
992 m_format, tcu::IVec2((1u << m_renderLevel)*m_width, (1u << m_renderLevel)*m_height), m_renderLevel,
993 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, totalLayers());
994 }
995
996 endCommandBuffer(vkd, *cmdBuffer);
997
998 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
999
1000 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
1001 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
1002
1003 #endif // CTS_USES_VULKANSC
1004 }
1005
submitSwitch(const SharedGroupParams groupParams)1006 void MultisampleRenderPassTestInstance::submitSwitch (const SharedGroupParams groupParams)
1007 {
1008 switch (groupParams->renderingType)
1009 {
1010 case RENDERING_TYPE_RENDERPASS_LEGACY:
1011 submit<RenderpassSubpass1>();
1012 break;
1013 case RENDERING_TYPE_RENDERPASS2:
1014 submit<RenderpassSubpass2>();
1015 break;
1016 case RENDERING_TYPE_DYNAMIC_RENDERING:
1017 submitDynamicRendering();
1018 break;
1019 default:
1020 TCU_THROW(InternalError, "Impossible");
1021 }
1022 }
1023
verify(void)1024 void MultisampleRenderPassTestInstance::verify (void)
1025 {
1026 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1027 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1028 const tcu::TextureFormat format (mapVkFormat(m_format));
1029 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1030
1031 deUint32 offset (0u);
1032 deUint32 width ((1u << m_renderLevel) * m_width);
1033 deUint32 height ((1u << m_renderLevel) * m_height);
1034 deUint32 pixelSize (static_cast<deUint32>(getPixelSize()));
1035 for (deUint32 level = 0; level < m_renderLevel; ++level)
1036 {
1037 offset += (width * height * pixelSize);
1038 height /= 2;
1039 width /= 2;
1040 }
1041
1042 std::vector<tcu::ConstPixelBufferAccess> accesses;
1043 for (deUint32 attachmentIdx = 0; attachmentIdx < m_attachmentsCount; ++attachmentIdx)
1044 {
1045 void* const ptr = static_cast<deUint8*>(m_bufferMemory[attachmentIdx]->getHostPtr()) + offset;
1046 accesses.push_back(tcu::ConstPixelBufferAccess(format, m_width, m_height, totalLayers(), ptr));
1047 }
1048
1049 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, totalLayers());
1050 tcu::TestLog& log (m_context.getTestContext().getLog());
1051
1052 switch (channelClass)
1053 {
1054 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1055 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1056 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1057 {
1058 const bool isAlphaOnly = isAlphaOnlyFormat(m_format);
1059 const int componentCount (isAlphaOnly ? 4 : tcu::getNumUsedChannels(format.order));
1060 bool isOk = true;
1061 float clearValue;
1062 float renderValue;
1063
1064 switch (channelClass)
1065 {
1066 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1067 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1068 clearValue = -1.0f;
1069 renderValue = 1.0f;
1070 break;
1071
1072 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1073 clearValue = 0.0f;
1074 renderValue = 1.0f;
1075 break;
1076
1077 default:
1078 clearValue = 0.0f;
1079 renderValue = 0.0f;
1080 DE_FATAL("Unknown channel class");
1081 }
1082
1083 for (deUint32 z = m_baseLayer; z < totalLayers(); z++)
1084 for (deUint32 y = 0; y < m_height; y++)
1085 for (deUint32 x = 0; x < m_width; x++)
1086 {
1087 // Color has to be black if no samples were covered, white if all samples were covered or same in every attachment
1088 const Vec4 firstColor (accesses[0].getPixel(x, y, z));
1089 const Vec4 refColor (m_sampleMask == 0x0u
1090 ? Vec4((isAlphaOnly ? 0.0f : clearValue),
1091 componentCount > 1 && !isAlphaOnly ? clearValue : 0.0f,
1092 componentCount > 2 && !isAlphaOnly ? clearValue : 0.0f,
1093 componentCount > 3 ? clearValue : 1.0f)
1094 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1095 ? Vec4((isAlphaOnly ? 0.0f : renderValue),
1096 componentCount > 1 && !isAlphaOnly ? renderValue : 0.0f,
1097 componentCount > 2 && !isAlphaOnly ? renderValue : 0.0f,
1098 componentCount > 3 ? renderValue : 1.0f)
1099 : firstColor);
1100
1101 errorMask.getAccess().setPixel(okColor, x, y, z);
1102
1103 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1104 {
1105 const Vec4 color (accesses[attachmentNdx].getPixel(x, y, z));
1106
1107 if (refColor != color)
1108 {
1109 isOk = false;
1110 errorMask.getAccess().setPixel(errorColor, x, y, z);
1111 break;
1112 }
1113 }
1114
1115 {
1116 const Vec4 old = m_sum.getAccess().getPixel(x, y, z);
1117 m_sum.getAccess().setPixel(old + (tcu::isSRGB(format) ? tcu::sRGBToLinear(firstColor) : firstColor), x, y, z);
1118
1119 const Vec4 oldSrgb = m_sumSrgb.getAccess().getPixel(x, y, z);
1120 m_sumSrgb.getAccess().setPixel(oldSrgb + firstColor, x, y, z);
1121 }
1122 }
1123
1124 if (!isOk)
1125 {
1126 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1127 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1128
1129 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1130 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1131
1132 logImage("ErrorMask", errorMask.getAccess());
1133
1134 if (m_sampleMask == 0x0u)
1135 {
1136 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1137 m_resultCollector.fail("Empty sample mask didn't produce correct pixel values");
1138 }
1139 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1140 {
1141 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1142 m_resultCollector.fail("Full sample mask didn't produce correct pixel values");
1143 }
1144 else
1145 {
1146 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve is inconsistent between attachments" << tcu::TestLog::EndMessage;
1147 m_resultCollector.fail("Resolve is inconsistent between attachments");
1148 }
1149 }
1150 break;
1151 }
1152
1153 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1154 {
1155 const int componentCount (tcu::getNumUsedChannels(format.order));
1156 const UVec4 bitDepth (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1157 const UVec4 renderValue (tcu::select((UVec4(1u) << tcu::min(UVec4(8u), bitDepth)) - UVec4(1u),
1158 UVec4(0u, 0u, 0u, 1u),
1159 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1160 const UVec4 clearValue (tcu::select(UVec4(0u),
1161 UVec4(0u, 0u, 0u, 1u),
1162 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1163 bool unexpectedValues = false;
1164 bool inconsistentComponents = false;
1165 bool inconsistentAttachments = false;
1166
1167 for (deUint32 z = m_baseLayer; z < totalLayers(); z++)
1168 for (deUint32 y = 0; y < m_height; y++)
1169 for (deUint32 x = 0; x < m_width; x++)
1170 {
1171 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1172 const UVec4 refColor (m_sampleMask == 0x0u
1173 ? clearValue
1174 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1175 ? renderValue
1176 : accesses[0].getPixelUint(x, y, z));
1177 bool isOk = true;
1178
1179 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1180 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1181 {
1182 // Each component must be resolved same way
1183 const BVec4 isRenderValue (refColor == renderValue);
1184 const BVec4 isClearValue (refColor == clearValue);
1185 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1186 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1187
1188 unexpectedValues |= unexpectedValue;
1189 inconsistentComponents |= inconsistentComponent;
1190
1191 if (unexpectedValue || inconsistentComponent)
1192 isOk = false;
1193 }
1194
1195 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1196 {
1197 const UVec4 color (accesses[attachmentNdx].getPixelUint(x, y, z));
1198
1199 if (refColor != color)
1200 {
1201 isOk = false;
1202 inconsistentAttachments = true;
1203 break;
1204 }
1205 }
1206
1207 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1208 }
1209
1210 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1211 {
1212 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1213 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1214
1215 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1216 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1217
1218 logImage("ErrorMask", errorMask.getAccess());
1219
1220 if (m_sampleMask == 0x0u)
1221 {
1222 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1223 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1224 }
1225 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1226 {
1227 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1228 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1229 }
1230 else
1231 {
1232 if (unexpectedValues)
1233 {
1234 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1235 m_resultCollector.fail("Resolve produced unexpected values");
1236 }
1237
1238 if (inconsistentComponents)
1239 {
1240 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1241 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1242 }
1243
1244 if (inconsistentAttachments)
1245 {
1246 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1247 m_resultCollector.fail("Different attachments were resolved to different values.");
1248 }
1249 }
1250 }
1251 break;
1252 }
1253
1254 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1255 {
1256 const int componentCount (tcu::getNumUsedChannels(format.order));
1257 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
1258 const IVec4 renderValue (tcu::select((IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))) - IVec4(1),
1259 IVec4(0, 0, 0, 1),
1260 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1261 const IVec4 clearValue (tcu::select(-(IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))),
1262 IVec4(0, 0, 0, 1),
1263 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1264 bool unexpectedValues = false;
1265 bool inconsistentComponents = false;
1266 bool inconsistentAttachments = false;
1267
1268 for (deUint32 z = m_baseLayer; z < totalLayers(); z++)
1269 for (deUint32 y = 0; y < m_height; y++)
1270 for (deUint32 x = 0; x < m_width; x++)
1271 {
1272 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1273 const IVec4 refColor (m_sampleMask == 0x0u
1274 ? clearValue
1275 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1276 ? renderValue
1277 : accesses[0].getPixelInt(x, y, z));
1278 bool isOk = true;
1279
1280 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1281 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1282 {
1283 // Each component must be resolved same way
1284 const BVec4 isRenderValue (refColor == renderValue);
1285 const BVec4 isClearValue (refColor == clearValue);
1286 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1287 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1288
1289 unexpectedValues |= unexpectedValue;
1290 inconsistentComponents |= inconsistentComponent;
1291
1292 if (unexpectedValue || inconsistentComponent)
1293 isOk = false;
1294 }
1295
1296 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1297 {
1298 const IVec4 color (accesses[attachmentNdx].getPixelInt(x, y, z));
1299
1300 if (refColor != color)
1301 {
1302 isOk = false;
1303 inconsistentAttachments = true;
1304 break;
1305 }
1306 }
1307
1308 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1309 }
1310
1311 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1312 {
1313 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1314 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1315
1316 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1317 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1318
1319 logImage("ErrorMask", errorMask.getAccess());
1320
1321 if (m_sampleMask == 0x0u)
1322 {
1323 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1324 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1325 }
1326 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1327 {
1328 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1329 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1330 }
1331 else
1332 {
1333 if (unexpectedValues)
1334 {
1335 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1336 m_resultCollector.fail("Resolve produced unexpected values");
1337 }
1338
1339 if (inconsistentComponents)
1340 {
1341 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1342 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1343 }
1344
1345 if (inconsistentAttachments)
1346 {
1347 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1348 m_resultCollector.fail("Different attachments were resolved to different values.");
1349 }
1350 }
1351 }
1352 break;
1353 }
1354
1355 default:
1356 DE_FATAL("Unknown channel class");
1357 }
1358 }
1359
iterate(void)1360 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1361 {
1362 if (m_sampleMask == 0u)
1363 {
1364 const tcu::TextureFormat format (mapVkFormat(m_format));
1365 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1366 tcu::TestLog& log (m_context.getTestContext().getLog());
1367
1368 switch (channelClass)
1369 {
1370 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1371 log << TestLog::Message << "Clearing target to zero and rendering 255 pixels with every possible sample mask" << TestLog::EndMessage;
1372 break;
1373
1374 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1375 log << TestLog::Message << "Clearing target to -128 and rendering 127 pixels with every possible sample mask" << TestLog::EndMessage;
1376 break;
1377
1378 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1379 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1380 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1381 log << TestLog::Message << "Clearing target to black and rendering white pixels with every possible sample mask" << TestLog::EndMessage;
1382 break;
1383
1384 default:
1385 DE_FATAL("Unknown channel class");
1386 }
1387 }
1388
1389 submitSwitch(m_groupParams);
1390 verify();
1391
1392 if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1393 {
1394 const tcu::TextureFormat format (mapVkFormat(m_format));
1395 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1396 const Vec4 threshold (getFormatThreshold());
1397 tcu::TestLog& log (m_context.getTestContext().getLog());
1398
1399 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
1400 || channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
1401 || channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1402 {
1403 const bool isAlphaOnly = isAlphaOnlyFormat(m_format);
1404 const int componentCount (isAlphaOnly ? 4 : tcu::getNumUsedChannels(format.order));
1405 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1406 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1407 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, totalLayers());
1408 bool isOk = true;
1409 Vec4 maxDiff (0.0f);
1410 Vec4 expectedAverage;
1411
1412 switch (channelClass)
1413 {
1414 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1415 {
1416 expectedAverage = Vec4((isAlphaOnly ? 0.0f : 0.5f), componentCount > 1 && !isAlphaOnly ? 0.5f : 0.0f, componentCount > 2 && !isAlphaOnly ? 0.5f : 0.0f, componentCount > 3 ? 0.5f : 1.0f);
1417 break;
1418 }
1419
1420 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1421 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1422 {
1423 expectedAverage = Vec4(0.0f, 0.0f, 0.0f, componentCount > 3 ? 0.0f : 1.0f);
1424 break;
1425 }
1426
1427 default:
1428 DE_FATAL("Unknown channel class");
1429 }
1430
1431 for (deUint32 z = m_baseLayer; z < totalLayers(); z++)
1432 for (deUint32 y = 0; y < m_height; y++)
1433 for (deUint32 x = 0; x < m_width; x++)
1434 {
1435 const Vec4 sum (m_sum.getAccess().getPixel(x, y, z));
1436 const Vec4 average (sum / Vec4((float)(0x1u << m_sampleCount)));
1437 const Vec4 diff (tcu::abs(average - expectedAverage));
1438
1439 m_sum.getAccess().setPixel(average, x, y, z);
1440 errorMask.getAccess().setPixel(okColor, x, y, z);
1441
1442 bool failThreshold;
1443
1444 if (!tcu::isSRGB(format))
1445 {
1446 failThreshold = (diff[0] > threshold.x()
1447 || diff[1] > threshold.y()
1448 || diff[2] > threshold.z()
1449 || diff[3] > threshold.w());
1450 }
1451 else
1452 {
1453 const Vec4 sumSrgb(m_sumSrgb.getAccess().getPixel(x, y, z));
1454 const Vec4 averageSrgb(sumSrgb / Vec4((float)(0x1u << m_sampleCount)));
1455 const Vec4 diffSrgb(tcu::abs(averageSrgb - expectedAverage));
1456
1457 m_sumSrgb.getAccess().setPixel(averageSrgb, x, y, z);
1458
1459 // Spec doesn't restrict implementation to downsample in linear color space. So, comparing both non linear and
1460 // linear diff's in case of srgb formats.
1461 failThreshold = ((diff[0] > threshold.x()
1462 || diff[1] > threshold.y()
1463 || diff[2] > threshold.z()
1464 || diff[3] > threshold.w()) &&
1465 (diffSrgb[0] > threshold.x()
1466 || diffSrgb[1] > threshold.y()
1467 || diffSrgb[2] > threshold.z()
1468 || diffSrgb[3] > threshold.w()));
1469
1470 }
1471
1472 if (failThreshold)
1473 {
1474 isOk = false;
1475 maxDiff = tcu::max(maxDiff, diff);
1476 errorMask.getAccess().setPixel(errorColor, x, y, z);
1477 }
1478 }
1479
1480 log << TestLog::Image("Average resolved values in attachment 0", "Average resolved values in attachment 0", m_sum);
1481
1482 if (!isOk)
1483 {
1484 std::stringstream message;
1485
1486 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1487
1488 message << "Average resolved values differ from expected average values by more than ";
1489
1490 switch (componentCount)
1491 {
1492 case 1:
1493 message << threshold.x();
1494 break;
1495 case 2:
1496 message << "vec2" << Vec2(threshold.x(), threshold.y());
1497 break;
1498 case 3:
1499 message << "vec3" << Vec3(threshold.x(), threshold.y(), threshold.z());
1500 break;
1501 default:
1502 message << "vec4" << threshold;
1503 }
1504
1505 message << ". Max diff " << maxDiff;
1506 log << TestLog::Message << message.str() << TestLog::EndMessage;
1507
1508 m_resultCollector.fail("Average resolved values differ from expected average values");
1509 }
1510 }
1511
1512 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1513 }
1514 else
1515 {
1516 m_sampleMask++;
1517 return tcu::TestStatus::incomplete();
1518 }
1519 }
1520
1521 template<typename RenderPassTrait>
createRenderPass(bool usedResolveAttachment)1522 Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPass (bool usedResolveAttachment)
1523 {
1524 // make name for RenderPass1Trait or RenderPass2Trait shorter
1525 typedef RenderPassTrait RPT;
1526 typedef typename RPT::AttDesc AttDesc;
1527 typedef typename RPT::AttRef AttRef;
1528 typedef typename RPT::SubpassDesc SubpassDesc;
1529 typedef typename RPT::RenderPassCreateInfo RenderPassCreateInfo;
1530
1531 const DeviceInterface& vkd = m_context.getDeviceInterface();
1532 VkDevice device = m_context.getDevice();
1533 std::vector<AttDesc> attachments;
1534 std::vector<AttRef> colorAttachmentRefs;
1535 std::vector<AttRef> resolveAttachmentRefs;
1536
1537 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1538 {
1539 {
1540 const AttDesc multisampleAttachment
1541 (
1542 // sType
1543 DE_NULL, // pNext
1544 0u, // flags
1545 m_format, // format
1546 m_sampleCount, // samples
1547 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
1548 VK_ATTACHMENT_STORE_OP_DONT_CARE, // storeOp
1549 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
1550 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
1551 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
1552 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // finalLayout
1553 );
1554 const AttRef attachmentRef
1555 (
1556 // sType
1557 DE_NULL, // pNext
1558 (deUint32)attachments.size(), // attachment
1559 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
1560 0u // aspectMask
1561 );
1562 colorAttachmentRefs.push_back(attachmentRef);
1563 attachments.push_back(multisampleAttachment);
1564 }
1565 {
1566 const AttDesc singlesampleAttachment
1567 (
1568 // sType
1569 DE_NULL, // pNext
1570 0u, // flags
1571 m_format, // format
1572 VK_SAMPLE_COUNT_1_BIT, // samples
1573 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
1574 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
1575 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
1576 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
1577 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
1578 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // finalLayout
1579 );
1580 const auto attachmentId = (usedResolveAttachment ? static_cast<deUint32>(attachments.size()) : VK_ATTACHMENT_UNUSED);
1581 const AttRef attachmentRef
1582 (
1583 // sType
1584 DE_NULL, // pNext
1585 attachmentId, // attachment
1586 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
1587 0u // aspectMask
1588 );
1589 resolveAttachmentRefs.push_back(attachmentRef);
1590 attachments.push_back(singlesampleAttachment);
1591 }
1592 }
1593
1594 DE_ASSERT(colorAttachmentRefs.size() == resolveAttachmentRefs.size());
1595 DE_ASSERT(attachments.size() == colorAttachmentRefs.size() + resolveAttachmentRefs.size());
1596
1597 const SubpassDesc subpass
1598 (
1599 // sType
1600 DE_NULL, // pNext
1601 (VkSubpassDescriptionFlags)0, // flags
1602 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1603 0u, // viewMask
1604 0u, // inputAttachmentCount
1605 DE_NULL, // pInputAttachments
1606 (deUint32)colorAttachmentRefs.size(), // colorAttachmentCount
1607 &colorAttachmentRefs[0], // pColorAttachments
1608 &resolveAttachmentRefs[0], // pResolveAttachments
1609 DE_NULL, // pDepthStencilAttachment
1610 0u, // preserveAttachmentCount
1611 DE_NULL // pPreserveAttachments
1612 );
1613 const RenderPassCreateInfo renderPassCreator
1614 (
1615 // sType
1616 DE_NULL, // pNext
1617 (VkRenderPassCreateFlags)0u, // flags
1618 (deUint32)attachments.size(), // attachmentCount
1619 &attachments[0], // pAttachments
1620 1u, // subpassCount
1621 &subpass, // pSubpasses
1622 0u, // dependencyCount
1623 DE_NULL, // pDependencies
1624 0u, // correlatedViewMaskCount
1625 DE_NULL // pCorrelatedViewMasks
1626 );
1627
1628 return renderPassCreator.createRenderPass(vkd, device);
1629 }
1630
createRenderPassSwitch(bool usedResolveAttachment)1631 Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPassSwitch (bool usedResolveAttachment)
1632 {
1633 switch (m_groupParams->renderingType)
1634 {
1635 case RENDERING_TYPE_RENDERPASS_LEGACY:
1636 return createRenderPass<RenderPass1Trait>(usedResolveAttachment);
1637 case RENDERING_TYPE_RENDERPASS2:
1638 return createRenderPass<RenderPass2Trait>(usedResolveAttachment);
1639 case RENDERING_TYPE_DYNAMIC_RENDERING:
1640 return Move<VkRenderPass>();
1641 default:
1642 TCU_THROW(InternalError, "Impossible");
1643 }
1644 }
1645
createRenderPassCompatible(void)1646 Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPassCompatible (void)
1647 {
1648 if (m_testCompatibility)
1649 {
1650 // The compatible render pass is always created with a used resolve attachment.
1651 return createRenderPassSwitch(true);
1652 }
1653 else
1654 {
1655 return {};
1656 }
1657 }
1658
createRenderPipelineLayout(void)1659 Move<VkPipelineLayout> MultisampleRenderPassTestInstance::createRenderPipelineLayout (void)
1660 {
1661 const DeviceInterface& vkd = m_context.getDeviceInterface();
1662 VkDevice device = m_context.getDevice();
1663
1664 const VkPushConstantRange pushConstant =
1665 {
1666 VK_SHADER_STAGE_FRAGMENT_BIT,
1667 0u,
1668 4u
1669 };
1670 const VkPipelineLayoutCreateInfo createInfo =
1671 {
1672 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1673 DE_NULL,
1674 (vk::VkPipelineLayoutCreateFlags)0,
1675
1676 0u,
1677 DE_NULL,
1678
1679 1u,
1680 &pushConstant
1681 };
1682
1683 return createPipelineLayout(vkd, device, &createInfo);
1684 }
1685
createRenderPipeline(void)1686 Move<VkPipeline> MultisampleRenderPassTestInstance::createRenderPipeline (void)
1687 {
1688 const DeviceInterface& vkd = m_context.getDeviceInterface();
1689 VkDevice device = m_context.getDevice();
1690 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
1691 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
1692 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
1693 const Move<VkShaderModule> geometryShaderModule (m_layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
1694 // Disable blending
1695 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1696 {
1697 VK_FALSE,
1698 VK_BLEND_FACTOR_SRC_ALPHA,
1699 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1700 VK_BLEND_OP_ADD,
1701 VK_BLEND_FACTOR_ONE,
1702 VK_BLEND_FACTOR_ONE,
1703 VK_BLEND_OP_ADD,
1704 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1705 };
1706 std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates(m_attachmentsCount, attachmentBlendState);
1707 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1708 {
1709 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1710 DE_NULL,
1711 (VkPipelineVertexInputStateCreateFlags)0u,
1712
1713 0u,
1714 DE_NULL,
1715
1716 0u,
1717 DE_NULL
1718 };
1719 const tcu::UVec2 renderArea (m_width, m_height);
1720 const std::vector<VkViewport> viewports (1, makeViewport(renderArea));
1721 const std::vector<VkRect2D> scissors (1, makeRect2D(renderArea));
1722
1723 const VkPipelineMultisampleStateCreateInfo multisampleState =
1724 {
1725 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1726 DE_NULL,
1727 (VkPipelineMultisampleStateCreateFlags)0u,
1728
1729 sampleCountBitFromSampleCount(m_sampleCount),
1730 VK_FALSE,
1731 0.0f,
1732 DE_NULL,
1733 VK_FALSE,
1734 VK_FALSE,
1735 };
1736 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1737 {
1738 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1739 DE_NULL,
1740 (VkPipelineDepthStencilStateCreateFlags)0u,
1741
1742 VK_FALSE,
1743 VK_TRUE,
1744 VK_COMPARE_OP_ALWAYS,
1745 VK_FALSE,
1746 VK_TRUE,
1747 {
1748 VK_STENCIL_OP_KEEP,
1749 VK_STENCIL_OP_INCREMENT_AND_WRAP,
1750 VK_STENCIL_OP_KEEP,
1751 VK_COMPARE_OP_ALWAYS,
1752 ~0u,
1753 ~0u,
1754 0xFFu / (m_sampleCount + 1)
1755 },
1756 {
1757 VK_STENCIL_OP_KEEP,
1758 VK_STENCIL_OP_INCREMENT_AND_WRAP,
1759 VK_STENCIL_OP_KEEP,
1760 VK_COMPARE_OP_ALWAYS,
1761 ~0u,
1762 ~0u,
1763 0xFFu / (m_sampleCount + 1)
1764 },
1765
1766 0.0f,
1767 1.0f
1768 };
1769 const VkPipelineColorBlendStateCreateInfo blendState =
1770 {
1771 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1772 DE_NULL,
1773 (VkPipelineColorBlendStateCreateFlags)0u,
1774
1775 VK_FALSE,
1776 VK_LOGIC_OP_COPY,
1777 deUint32(attachmentBlendStates.size()),
1778 &attachmentBlendStates[0],
1779 { 0.0f, 0.0f, 0.0f, 0.0f }
1780 };
1781
1782 void* pNext = DE_NULL;
1783
1784 #ifndef CTS_USES_VULKANSC
1785 std::vector<VkFormat> attachmentFormats(m_attachmentsCount, m_format);
1786 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
1787 {
1788 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1789 DE_NULL,
1790 0u,
1791 m_attachmentsCount,
1792 attachmentFormats.data(),
1793 VK_FORMAT_UNDEFINED,
1794 VK_FORMAT_UNDEFINED
1795 };
1796 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1797 pNext = &renderingCreateInfo;
1798 #endif // CTS_USES_VULKANSC
1799
1800 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
1801 device, // const VkDevice device
1802 *m_renderPipelineLayout, // const VkPipelineLayout pipelineLayout
1803 *vertexShaderModule, // const VkShaderModule vertexShaderModule
1804 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1805 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1806 m_layerCount != 1 ? *geometryShaderModule : DE_NULL,// const VkShaderModule geometryShaderModule
1807 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1808 *m_renderPass, // const VkRenderPass renderPass
1809 viewports, // const std::vector<VkViewport>& viewports
1810 scissors, // const std::vector<VkRect2D>& scissors
1811 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1812 0u, // const deUint32 subpass
1813 0u, // const deUint32 patchControlPoints
1814 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1815 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1816 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1817 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
1818 &blendState, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
1819 DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
1820 pNext); // const void* pNext
1821 }
1822
1823 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer,VkRenderingFlagsKHR renderingFlags) const1824 void MultisampleRenderPassTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
1825 {
1826 const DeviceInterface& vkd = m_context.getDeviceInterface();
1827 std::vector<VkFormat> formats(m_attachmentsCount, m_format);
1828
1829 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
1830 {
1831 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
1832 DE_NULL, // const void* pNext;
1833 renderingFlags, // VkRenderingFlagsKHR flags;
1834 0u, // uint32_t viewMask;
1835 m_attachmentsCount, // uint32_t colorAttachmentCount;
1836 formats.data(), // const VkFormat* pColorAttachmentFormats;
1837 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
1838 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
1839 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
1840 };
1841
1842 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
1843 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1844 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1845 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1846
1847 const VkCommandBufferBeginInfo commandBufBeginParams
1848 {
1849 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1850 DE_NULL, // const void* pNext;
1851 usageFlags, // VkCommandBufferUsageFlags flags;
1852 &bufferInheritanceInfo
1853 };
1854
1855 VK_CHECK(vkd.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
1856 }
1857 #endif // CTS_USES_VULKANSC
1858
1859 class MaxAttachmenstsRenderPassTestInstance : public MultisampleRenderPassTestBase
1860 {
1861 public:
1862 MaxAttachmenstsRenderPassTestInstance (Context& context, TestConfig config);
1863 ~MaxAttachmenstsRenderPassTestInstance (void);
1864
1865 tcu::TestStatus iterate (void);
1866
1867 private:
1868
1869 template<typename RenderpassSubpass>
1870 void submit (void);
1871 void submitSwitch (RenderingType renderingType);
1872 void verify (void);
1873
1874 Move<VkDescriptorSetLayout> createDescriptorSetLayout (void);
1875 Move<VkDescriptorPool> createDescriptorPool (void);
1876 Move<VkDescriptorSet> createDescriptorSet (void);
1877
1878 template<typename RenderPassTrait>
1879 Move<VkRenderPass> createRenderPass (void);
1880 Move<VkRenderPass> createRenderPassSwitch (const RenderingType renderingType);
1881 Move<VkPipelineLayout> createRenderPipelineLayout (bool secondSubpass);
1882 Move<VkPipeline> createRenderPipeline (bool secondSubpass);
1883
1884 private:
1885
1886 const std::vector<VkImageSp> m_multisampleImages;
1887 const std::vector<AllocationSp> m_multisampleImageMemory;
1888 const std::vector<VkImageViewSp> m_multisampleImageViews;
1889
1890 const std::vector<VkImageSp> m_singlesampleImages;
1891 const std::vector<AllocationSp> m_singlesampleImageMemory;
1892 const std::vector<VkImageViewSp> m_singlesampleImageViews;
1893
1894 const Unique<VkDescriptorSetLayout> m_descriptorSetLayout;
1895 const Unique<VkDescriptorPool> m_descriptorPool;
1896 const Unique<VkDescriptorSet> m_descriptorSet;
1897
1898 const Unique<VkRenderPass> m_renderPass;
1899 const Unique<VkFramebuffer> m_framebuffer;
1900
1901 const Unique<VkPipelineLayout> m_pipelineLayoutPass0;
1902 const Unique<VkPipeline> m_pipelinePass0;
1903 const Unique<VkPipelineLayout> m_pipelineLayoutPass1;
1904 const Unique<VkPipeline> m_pipelinePass1;
1905
1906 const std::vector<VkBufferSp> m_buffers;
1907 const std::vector<AllocationSp> m_bufferMemory;
1908
1909 const Unique<VkCommandPool> m_commandPool;
1910 tcu::ResultCollector m_resultCollector;
1911 };
1912
MaxAttachmenstsRenderPassTestInstance(Context & context,TestConfig config)1913 MaxAttachmenstsRenderPassTestInstance::MaxAttachmenstsRenderPassTestInstance (Context& context, TestConfig config)
1914 : MultisampleRenderPassTestBase(context, config)
1915
1916 , m_multisampleImages (createImages(m_sampleCount, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
1917 , m_multisampleImageMemory (createImageMemory(m_multisampleImages))
1918 , m_multisampleImageViews (createImageViews(m_multisampleImages))
1919
1920 , m_singlesampleImages (createImages(VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
1921 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImages))
1922 , m_singlesampleImageViews (createImageViews(m_singlesampleImages, m_baseLayer))
1923
1924 , m_descriptorSetLayout (createDescriptorSetLayout())
1925 , m_descriptorPool (createDescriptorPool())
1926 , m_descriptorSet (createDescriptorSet())
1927
1928 , m_renderPass (createRenderPassSwitch(config.groupParams->renderingType))
1929 , m_framebuffer (createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))
1930
1931 , m_pipelineLayoutPass0 (createRenderPipelineLayout(0))
1932 , m_pipelinePass0 (createRenderPipeline(0))
1933 , m_pipelineLayoutPass1 (createRenderPipelineLayout(1))
1934 , m_pipelinePass1 (createRenderPipeline(1))
1935
1936 , m_buffers (createBuffers())
1937 , m_bufferMemory (createBufferMemory(m_buffers))
1938
1939 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1940 {
1941 }
1942
~MaxAttachmenstsRenderPassTestInstance(void)1943 MaxAttachmenstsRenderPassTestInstance::~MaxAttachmenstsRenderPassTestInstance (void)
1944 {
1945 }
1946
1947 template<typename RenderpassSubpass>
submit(void)1948 void MaxAttachmenstsRenderPassTestInstance::submit (void)
1949 {
1950 const DeviceInterface& vkd (m_context.getDeviceInterface());
1951 const VkDevice device (m_context.getDevice());
1952 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1953 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1954 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
1955
1956 beginCommandBuffer(vkd, *commandBuffer);
1957
1958 // Memory barriers between previous copies and rendering
1959 {
1960 std::vector<VkImageMemoryBarrier> barriers;
1961
1962 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
1963 {
1964 const VkImageMemoryBarrier barrier =
1965 {
1966 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1967 DE_NULL,
1968
1969 VK_ACCESS_TRANSFER_READ_BIT,
1970 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1971
1972 VK_IMAGE_LAYOUT_UNDEFINED,
1973 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1974
1975 VK_QUEUE_FAMILY_IGNORED,
1976 VK_QUEUE_FAMILY_IGNORED,
1977
1978 **m_singlesampleImages[dstNdx],
1979 {
1980 VK_IMAGE_ASPECT_COLOR_BIT,
1981 0u,
1982 1u,
1983 m_baseLayer,
1984 m_layerCount
1985 }
1986 };
1987
1988 barriers.push_back(barrier);
1989 }
1990
1991 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
1992 }
1993
1994 {
1995 const VkRenderPassBeginInfo beginInfo =
1996 {
1997 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1998 DE_NULL,
1999
2000 *m_renderPass,
2001 *m_framebuffer,
2002
2003 {
2004 { 0u, 0u },
2005 { m_width, m_height }
2006 },
2007
2008 0u,
2009 DE_NULL
2010 };
2011 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2012 }
2013
2014 // Clear everything to black
2015 clearAttachments(*commandBuffer);
2016
2017 // First subpass - render black samples
2018 {
2019 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelinePass0);
2020 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
2021 }
2022
2023 // Second subpasss - merge attachments
2024 {
2025 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
2026 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelinePass1);
2027 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutPass1, 0, 1u, &*m_descriptorSet, 0, NULL);
2028 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
2029 }
2030
2031 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2032
2033 // Memory barriers between rendering and copies
2034 {
2035 std::vector<VkImageMemoryBarrier> barriers;
2036
2037 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
2038 {
2039 const VkImageMemoryBarrier barrier =
2040 {
2041 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2042 DE_NULL,
2043
2044 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2045 VK_ACCESS_TRANSFER_READ_BIT,
2046
2047 VK_IMAGE_LAYOUT_GENERAL,
2048 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2049
2050 VK_QUEUE_FAMILY_IGNORED,
2051 VK_QUEUE_FAMILY_IGNORED,
2052
2053 **m_singlesampleImages[dstNdx],
2054 {
2055 VK_IMAGE_ASPECT_COLOR_BIT,
2056 0u,
2057 1u,
2058 m_baseLayer,
2059 m_layerCount
2060 }
2061 };
2062
2063 barriers.push_back(barrier);
2064 }
2065
2066 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0]);
2067 }
2068
2069 // Copy image memory to buffers
2070 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
2071 {
2072 const VkBufferImageCopy region =
2073 {
2074 0u,
2075 0u,
2076 0u,
2077 {
2078 VK_IMAGE_ASPECT_COLOR_BIT,
2079 0u,
2080 0u,
2081 m_layerCount,
2082 },
2083 { 0u, 0u, 0u },
2084 { m_width, m_height, 1u }
2085 };
2086
2087 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImages[dstNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffers[dstNdx], 1u, ®ion);
2088 }
2089
2090 // Memory barriers between copies and host access
2091 {
2092 std::vector<VkBufferMemoryBarrier> barriers;
2093
2094 for (size_t dstNdx = 0; dstNdx < m_buffers.size(); dstNdx++)
2095 {
2096 const VkBufferMemoryBarrier barrier =
2097 {
2098 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2099 DE_NULL,
2100
2101 VK_ACCESS_TRANSFER_WRITE_BIT,
2102 VK_ACCESS_HOST_READ_BIT,
2103
2104 VK_QUEUE_FAMILY_IGNORED,
2105 VK_QUEUE_FAMILY_IGNORED,
2106
2107 **m_buffers[dstNdx],
2108 0u,
2109 VK_WHOLE_SIZE
2110 };
2111
2112 barriers.push_back(barrier);
2113 }
2114
2115 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0], 0u, DE_NULL);
2116 }
2117
2118 endCommandBuffer(vkd, *commandBuffer);
2119
2120 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
2121
2122 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
2123 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
2124 }
2125
submitSwitch(RenderingType renderingType)2126 void MaxAttachmenstsRenderPassTestInstance::submitSwitch (RenderingType renderingType)
2127 {
2128 switch (renderingType)
2129 {
2130 case RENDERING_TYPE_RENDERPASS_LEGACY:
2131 submit<RenderpassSubpass1>();
2132 break;
2133 case RENDERING_TYPE_RENDERPASS2:
2134 submit<RenderpassSubpass2>();
2135 break;
2136 default:
2137 TCU_THROW(InternalError, "Impossible");
2138 }
2139 }
2140
2141 template <typename VecType>
isValueAboveThreshold1(const VecType & vale,const VecType & threshold)2142 bool isValueAboveThreshold1 (const VecType& vale, const VecType& threshold)
2143 {
2144 return (vale[0] > threshold[0]);
2145 }
2146
2147 template <typename VecType>
isValueAboveThreshold2(const VecType & vale,const VecType & threshold)2148 bool isValueAboveThreshold2 (const VecType& vale, const VecType& threshold)
2149 {
2150 return (vale[0] > threshold[0]) || (vale[1] > threshold[1]);
2151 }
2152
2153 template <typename VecType>
isValueAboveThreshold3(const VecType & vale,const VecType & threshold)2154 bool isValueAboveThreshold3 (const VecType& vale, const VecType& threshold)
2155 {
2156 return (vale[0] > threshold[0]) || (vale[1] > threshold[1]) || (vale[2] > threshold[2]);
2157 }
2158
2159 template <typename VecType>
isValueAboveThreshold4(const VecType & vale,const VecType & threshold)2160 bool isValueAboveThreshold4 (const VecType& vale, const VecType& threshold)
2161 {
2162 return (vale[0] > threshold[0]) || (vale[1] > threshold[1]) || (vale[2] > threshold[2]) || (vale[3] > threshold[3]);
2163 }
2164
verify(void)2165 void MaxAttachmenstsRenderPassTestInstance::verify (void)
2166 {
2167 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
2168 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
2169 const tcu::TextureFormat format (mapVkFormat(m_format));
2170 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
2171 const int componentCount (tcu::getNumUsedChannels(format.order));
2172 const int outputsCount = m_attachmentsCount / 2;
2173
2174 DE_ASSERT((componentCount >= 0) && (componentCount < 5));
2175
2176 std::vector<tcu::ConstPixelBufferAccess> accesses;
2177 for (int outputNdx = 0; outputNdx < outputsCount; ++outputNdx)
2178 {
2179 void* const ptr = m_bufferMemory[outputNdx]->getHostPtr();
2180 accesses.push_back(tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptr));
2181 }
2182
2183 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, outputsCount);
2184 tcu::TestLog& log (m_context.getTestContext().getLog());
2185 bool isOk = true;
2186
2187 switch (channelClass)
2188 {
2189 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2190 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2191 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2192 {
2193 const Vec4 refColor(0.0f, 0.3f, 0.6f, 0.75f);
2194 const Vec4 threshold(getFormatThreshold());
2195
2196 typedef bool(*ValueAboveThresholdFn)(const Vec4&, const Vec4&);
2197 ValueAboveThresholdFn componentToFnMap[4] =
2198 {
2199 isValueAboveThreshold1<Vec4>,
2200 isValueAboveThreshold2<Vec4>,
2201 isValueAboveThreshold3<Vec4>,
2202 isValueAboveThreshold4<Vec4>
2203 };
2204 ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];
2205 bool isSRGBFormat = tcu::isSRGB(format);
2206
2207 for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
2208 for (int y = 0; y < (int)m_height; y++)
2209 for (int x = 0; x < (int)m_width; x++)
2210 {
2211 Vec4 color = accesses[outputNdx].getPixel(x, y);
2212 if (isSRGBFormat)
2213 color = tcu::sRGBToLinear(color);
2214
2215 const Vec4 diff(tcu::abs(color - refColor));
2216
2217 if (isValueAboveThreshold(diff, threshold))
2218 {
2219 isOk = false;
2220 errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
2221 break;
2222 }
2223 else
2224 errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
2225 }
2226 break;
2227 }
2228
2229 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2230 {
2231 const UVec4 refColor(0, 48, 144, 189);
2232 UVec4 threshold(1, 1, 1, 1);
2233
2234 if (m_format == VK_FORMAT_A2B10G10R10_UINT_PACK32)
2235 threshold[3] = 200;
2236
2237 typedef bool(*ValueAboveThresholdFn)(const UVec4&, const UVec4&);
2238 ValueAboveThresholdFn componentToFnMap[4] =
2239 {
2240 isValueAboveThreshold1<UVec4>,
2241 isValueAboveThreshold2<UVec4>,
2242 isValueAboveThreshold3<UVec4>,
2243 isValueAboveThreshold4<UVec4>
2244 };
2245 ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];
2246
2247 for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
2248 for (int y = 0; y < (int)m_height; y++)
2249 for (int x = 0; x < (int)m_width; x++)
2250 {
2251 const UVec4 color (accesses[outputNdx].getPixelUint(x, y));
2252 const UVec4 diff (std::abs(int(color.x()) - int(refColor.x())),
2253 std::abs(int(color.y()) - int(refColor.y())),
2254 std::abs(int(color.z()) - int(refColor.z())),
2255 std::abs(int(color.w()) - int(refColor.w())));
2256
2257 if (isValueAboveThreshold(diff, threshold))
2258 {
2259 isOk = false;
2260 errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
2261 break;
2262 }
2263 else
2264 errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
2265 }
2266 break;
2267 }
2268
2269 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2270 {
2271 const IVec4 refColor (0, 24, 75, 93);
2272 const IVec4 threshold (1, 1, 1, 1);
2273
2274 typedef bool(*ValueAboveThresholdFn)(const IVec4&, const IVec4&);
2275 ValueAboveThresholdFn componentToFnMap[4] =
2276 {
2277 isValueAboveThreshold1<IVec4>,
2278 isValueAboveThreshold2<IVec4>,
2279 isValueAboveThreshold3<IVec4>,
2280 isValueAboveThreshold4<IVec4>
2281 };
2282 ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];
2283
2284 for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
2285 for (int y = 0; y < (int)m_height; y++)
2286 for (int x = 0; x < (int)m_width; x++)
2287 {
2288 const IVec4 color (accesses[outputNdx].getPixelInt(x, y));
2289 const IVec4 diff (std::abs(color.x() - refColor.x()),
2290 std::abs(color.y() - refColor.y()),
2291 std::abs(color.z() - refColor.z()),
2292 std::abs(color.w() - refColor.w()));
2293
2294 if (isValueAboveThreshold(diff, threshold))
2295 {
2296 isOk = false;
2297 errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
2298 break;
2299 }
2300 else
2301 errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
2302 }
2303 break;
2304 }
2305
2306 default:
2307 DE_FATAL("Unknown channel class");
2308 }
2309
2310 if (!isOk)
2311 {
2312 const std::string sectionName ("MaxAttachmentsVerify");
2313 const tcu::ScopedLogSection section (log, sectionName, sectionName);
2314
2315 logImage("ErrorMask", errorMask.getAccess());
2316 m_resultCollector.fail("Fail");
2317 }
2318 }
2319
iterate(void)2320 tcu::TestStatus MaxAttachmenstsRenderPassTestInstance::iterate(void)
2321 {
2322 submitSwitch(m_groupParams->renderingType);
2323 verify();
2324
2325 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2326 }
2327
createDescriptorSetLayout()2328 Move<VkDescriptorSetLayout> MaxAttachmenstsRenderPassTestInstance::createDescriptorSetLayout()
2329 {
2330 const VkDescriptorSetLayoutBinding bindingTemplate =
2331 {
2332 0, // binding
2333 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // descriptorType
2334 1u, // descriptorCount
2335 VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
2336 DE_NULL // pImmutableSamplers
2337 };
2338
2339 std::vector<VkDescriptorSetLayoutBinding> bindings(m_attachmentsCount, bindingTemplate);
2340 for (deUint32 idx = 0; idx < m_attachmentsCount; ++idx)
2341 bindings[idx].binding = idx;
2342
2343 const VkDescriptorSetLayoutCreateInfo createInfo =
2344 {
2345 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
2346 DE_NULL, // pNext
2347 0u, // flags
2348 m_attachmentsCount, // bindingCount
2349 &bindings[0] // pBindings
2350 };
2351
2352 return ::createDescriptorSetLayout(m_context.getDeviceInterface(), m_context.getDevice(), &createInfo);
2353 }
2354
createDescriptorPool()2355 Move<VkDescriptorPool> MaxAttachmenstsRenderPassTestInstance::createDescriptorPool()
2356 {
2357 const VkDescriptorPoolSize size =
2358 {
2359 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // type
2360 m_attachmentsCount // descriptorCount
2361 };
2362
2363 const VkDescriptorPoolCreateInfo createInfo =
2364 {
2365 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
2366 DE_NULL, // pNext
2367 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // flags
2368 1u, // maxSets
2369 1u, // poolSizeCount
2370 &size // pPoolSizes
2371 };
2372
2373 return ::createDescriptorPool(m_context.getDeviceInterface(), m_context.getDevice(), &createInfo);
2374 }
2375
createDescriptorSet()2376 Move<VkDescriptorSet> MaxAttachmenstsRenderPassTestInstance::createDescriptorSet()
2377 {
2378 const VkDescriptorSetAllocateInfo allocateInfo =
2379 {
2380 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
2381 DE_NULL, // pNext
2382 *m_descriptorPool, // descriptorPool
2383 1u, // descriptorSetCount
2384 &*m_descriptorSetLayout // pSetLayouts
2385 };
2386
2387 const vk::DeviceInterface& vkd = m_context.getDeviceInterface();
2388 vk::VkDevice device = m_context.getDevice();
2389 Move<VkDescriptorSet> descriptorSet = allocateDescriptorSet(vkd, device, &allocateInfo);
2390 vector<VkDescriptorImageInfo> descriptorImageInfo (m_attachmentsCount);
2391 vector<VkWriteDescriptorSet> descriptorWrites (m_attachmentsCount);
2392
2393 for (deUint32 idx = 0; idx < m_attachmentsCount; ++idx)
2394 {
2395 const VkDescriptorImageInfo imageInfo =
2396 {
2397 DE_NULL, // VkSampler sampler
2398 **m_singlesampleImageViews[idx], // VkImageView imageView
2399 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout imageLayout
2400 };
2401 descriptorImageInfo[idx] = imageInfo;
2402
2403 const VkWriteDescriptorSet write =
2404 {
2405 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
2406 DE_NULL, // const void* pNext
2407 *descriptorSet, // VkDescriptorSet dstSet
2408 (deUint32)idx, // uint32_t dstBinding
2409 0u, // uint32_t dstArrayElement
2410 1u, // uint32_t descriptorCount
2411 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
2412 &descriptorImageInfo[idx], // const VkDescriptorImageInfo* pImageInfo
2413 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
2414 DE_NULL // const VkBufferView* pTexelBufferView
2415 };
2416
2417 descriptorWrites[idx] = write;
2418 }
2419
2420 vkd.updateDescriptorSets(device, (deUint32)descriptorWrites.size(), &descriptorWrites[0], 0u, DE_NULL);
2421 return descriptorSet;
2422 }
2423
2424 template<typename RenderPassTrait>
createRenderPass(void)2425 Move<VkRenderPass> MaxAttachmenstsRenderPassTestInstance::createRenderPass(void)
2426 {
2427 // make name for RenderPass1Trait or RenderPass2Trait shorter
2428 typedef RenderPassTrait RPT;
2429
2430 typedef typename RPT::AttDesc AttDesc;
2431 typedef typename RPT::AttRef AttRef;
2432 typedef typename RPT::SubpassDep SubpassDep;
2433 typedef typename RPT::SubpassDesc SubpassDesc;
2434 typedef typename RPT::RenderPassCreateInfo RenderPassCreateInfo;
2435
2436 const DeviceInterface& vkd = m_context.getDeviceInterface();
2437 VkDevice device = m_context.getDevice();
2438 std::vector<AttDesc> attachments;
2439 std::vector<AttRef> sp0colorAttachmentRefs;
2440 std::vector<AttRef> sp0resolveAttachmentRefs;
2441 std::vector<AttRef> sp1inAttachmentRefs;
2442 std::vector<AttRef> sp1colorAttachmentRefs;
2443
2444 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
2445 {
2446 // define first subpass outputs
2447 {
2448 const AttDesc multisampleAttachment
2449 (
2450 DE_NULL, // pNext
2451 0u, // flags
2452 m_format, // format
2453 m_sampleCount, // samples
2454 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
2455 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
2456 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
2457 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
2458 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2459 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // finalLayout
2460 );
2461 const AttRef attachmentRef
2462 (
2463 DE_NULL,
2464 (deUint32)attachments.size(), // attachment
2465 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
2466 0u // aspectMask
2467 );
2468 sp0colorAttachmentRefs.push_back(attachmentRef);
2469 attachments.push_back(multisampleAttachment);
2470 }
2471 // define first subpass resolve attachments
2472 {
2473 const AttDesc singlesampleAttachment
2474 (
2475 DE_NULL, // pNext
2476 0u, // flags
2477 m_format, // format
2478 VK_SAMPLE_COUNT_1_BIT, // samples
2479 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
2480 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
2481 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
2482 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
2483 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2484 VK_IMAGE_LAYOUT_GENERAL // finalLayout
2485 );
2486 const AttRef attachmentRef
2487 (
2488 DE_NULL, // pNext
2489 (deUint32)attachments.size(), // attachment
2490 VK_IMAGE_LAYOUT_GENERAL, // layout
2491 0u // aspectMask
2492 );
2493 sp0resolveAttachmentRefs.push_back(attachmentRef);
2494 attachments.push_back(singlesampleAttachment);
2495 }
2496 // define second subpass inputs
2497 {
2498 const AttRef attachmentRef
2499 (
2500 DE_NULL, // pNext
2501 (deUint32)attachments.size() - 1, // attachment
2502 VK_IMAGE_LAYOUT_GENERAL, // layout
2503 VK_IMAGE_ASPECT_COLOR_BIT // aspectMask
2504 );
2505 sp1inAttachmentRefs.push_back(attachmentRef);
2506 }
2507 // define second subpass outputs - it merges pairs of
2508 // results that were produced by the first subpass
2509 if (attachmentNdx < (m_attachmentsCount / 2))
2510 {
2511 const AttRef colorAttachmentRef
2512 (
2513 DE_NULL, // pNext
2514 (deUint32)attachments.size() - 1, // attachment
2515 VK_IMAGE_LAYOUT_GENERAL, // layout
2516 0u // aspectMask
2517 );
2518 sp1colorAttachmentRefs.push_back(colorAttachmentRef);
2519 }
2520 }
2521
2522 DE_ASSERT(sp0colorAttachmentRefs.size() == sp0resolveAttachmentRefs.size());
2523 DE_ASSERT(attachments.size() == sp0colorAttachmentRefs.size() + sp0resolveAttachmentRefs.size());
2524
2525 {
2526 const SubpassDesc subpass0
2527 (
2528 // sType
2529 DE_NULL, // pNext
2530 (VkSubpassDescriptionFlags)0, // flags
2531 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
2532 0u, // viewMask
2533 0u, // inputAttachmentCount
2534 DE_NULL, // pInputAttachments
2535 (deUint32)sp0colorAttachmentRefs.size(), // colorAttachmentCount
2536 &sp0colorAttachmentRefs[0], // pColorAttachments
2537 &sp0resolveAttachmentRefs[0], // pResolveAttachments
2538 DE_NULL, // pDepthStencilAttachment
2539 0u, // preserveAttachmentCount
2540 DE_NULL // pPreserveAttachments
2541 );
2542 const SubpassDesc subpass1
2543 (
2544 // sType
2545 DE_NULL, // pNext
2546 (VkSubpassDescriptionFlags)0, // flags
2547 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
2548 0u, // viewMask
2549 (deUint32)sp1inAttachmentRefs.size(), // inputAttachmentCount
2550 &sp1inAttachmentRefs[0], // pInputAttachments
2551 (deUint32)sp1colorAttachmentRefs.size(), // colorAttachmentCount
2552 &sp1colorAttachmentRefs[0], // pColorAttachments
2553 DE_NULL, // pResolveAttachments
2554 DE_NULL, // pDepthStencilAttachment
2555 0u, // preserveAttachmentCount
2556 DE_NULL // pPreserveAttachments
2557 );
2558 SubpassDesc subpasses[] =
2559 {
2560 subpass0,
2561 subpass1
2562 };
2563 const SubpassDep subpassDependency
2564 (
2565 DE_NULL, // pNext
2566 0u, // srcSubpass
2567 1u, // dstSubpass
2568 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // srcStageMask
2569 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // dstStageMask
2570 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2571 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2572 0u, // dependencyFlags
2573 0u // viewOffset
2574 );
2575 const RenderPassCreateInfo renderPassCreator
2576 (
2577 // sType
2578 DE_NULL, // pNext
2579 (VkRenderPassCreateFlags)0u, // flags
2580 (deUint32)attachments.size(), // attachmentCount
2581 &attachments[0], // pAttachments
2582 2u, // subpassCount
2583 subpasses, // pSubpasses
2584 1u, // dependencyCount
2585 &subpassDependency, // pDependencies
2586 0u, // correlatedViewMaskCount
2587 DE_NULL // pCorrelatedViewMasks
2588 );
2589
2590 return renderPassCreator.createRenderPass(vkd, device);
2591 }
2592 }
2593
createRenderPassSwitch(const RenderingType renderingType)2594 Move<VkRenderPass> MaxAttachmenstsRenderPassTestInstance::createRenderPassSwitch(const RenderingType renderingType)
2595 {
2596 switch (renderingType)
2597 {
2598 case RENDERING_TYPE_RENDERPASS_LEGACY:
2599 return createRenderPass<RenderPass1Trait>();
2600 case RENDERING_TYPE_RENDERPASS2:
2601 return createRenderPass<RenderPass2Trait>();
2602 default:
2603 TCU_THROW(InternalError, "Impossible");
2604 }
2605 }
2606
createRenderPipelineLayout(bool secondSubpass)2607 Move<VkPipelineLayout> MaxAttachmenstsRenderPassTestInstance::createRenderPipelineLayout(bool secondSubpass)
2608 {
2609 const DeviceInterface& vkd = m_context.getDeviceInterface();
2610 VkDevice device = m_context.getDevice();
2611
2612 const VkPipelineLayoutCreateInfo createInfo =
2613 {
2614 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2615 DE_NULL,
2616 (vk::VkPipelineLayoutCreateFlags)0,
2617
2618 secondSubpass ? 1u : 0u,
2619 secondSubpass ? &*m_descriptorSetLayout : DE_NULL,
2620
2621 0u,
2622 DE_NULL
2623 };
2624
2625 return createPipelineLayout(vkd, device, &createInfo);
2626 }
2627
createRenderPipeline(bool secondSubpass)2628 Move<VkPipeline> MaxAttachmenstsRenderPassTestInstance::createRenderPipeline(bool secondSubpass)
2629 {
2630 const DeviceInterface& vkd = m_context.getDeviceInterface();
2631 VkDevice device = m_context.getDevice();
2632 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
2633 VkSampleCountFlagBits sampleCount = sampleCountBitFromSampleCount(m_sampleCount);
2634 deUint32 blendStatesCount = m_attachmentsCount;
2635 std::string fragShaderNameBase = "quad-frag-sp0-";
2636
2637 if (secondSubpass)
2638 {
2639 sampleCount = VK_SAMPLE_COUNT_1_BIT;
2640 blendStatesCount /= 2;
2641 fragShaderNameBase = "quad-frag-sp1-";
2642 }
2643
2644 std::string fragShaderName = fragShaderNameBase + de::toString(m_attachmentsCount);
2645 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
2646 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get(fragShaderName), 0u));
2647 const Move<VkShaderModule> geometryShaderModule (m_layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
2648
2649 // Disable blending
2650 const VkPipelineColorBlendAttachmentState attachmentBlendState =
2651 {
2652 VK_FALSE,
2653 VK_BLEND_FACTOR_SRC_ALPHA,
2654 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
2655 VK_BLEND_OP_ADD,
2656 VK_BLEND_FACTOR_ONE,
2657 VK_BLEND_FACTOR_ONE,
2658 VK_BLEND_OP_ADD,
2659 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
2660 };
2661 std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates(blendStatesCount, attachmentBlendState);
2662 const VkPipelineVertexInputStateCreateInfo vertexInputState =
2663 {
2664 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
2665 DE_NULL,
2666 (VkPipelineVertexInputStateCreateFlags)0u,
2667
2668 0u,
2669 DE_NULL,
2670
2671 0u,
2672 DE_NULL
2673 };
2674 const tcu::UVec2 renderArea (m_width, m_height);
2675 const std::vector<VkViewport> viewports (1, makeViewport(renderArea));
2676 const std::vector<VkRect2D> scissors (1, makeRect2D(renderArea));
2677
2678 const VkPipelineMultisampleStateCreateInfo multisampleState =
2679 {
2680 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
2681 DE_NULL,
2682 (VkPipelineMultisampleStateCreateFlags)0u,
2683
2684 sampleCount,
2685 VK_FALSE,
2686 0.0f,
2687 DE_NULL,
2688 VK_FALSE,
2689 VK_FALSE,
2690 };
2691 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
2692 {
2693 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
2694 DE_NULL,
2695 (VkPipelineDepthStencilStateCreateFlags)0u,
2696
2697 VK_FALSE,
2698 VK_TRUE,
2699 VK_COMPARE_OP_ALWAYS,
2700 VK_FALSE,
2701 VK_TRUE,
2702 {
2703 VK_STENCIL_OP_KEEP,
2704 VK_STENCIL_OP_INCREMENT_AND_WRAP,
2705 VK_STENCIL_OP_KEEP,
2706 VK_COMPARE_OP_ALWAYS,
2707 ~0u,
2708 ~0u,
2709 0xFFu / (m_sampleCount + 1)
2710 },
2711 {
2712 VK_STENCIL_OP_KEEP,
2713 VK_STENCIL_OP_INCREMENT_AND_WRAP,
2714 VK_STENCIL_OP_KEEP,
2715 VK_COMPARE_OP_ALWAYS,
2716 ~0u,
2717 ~0u,
2718 0xFFu / (m_sampleCount + 1)
2719 },
2720
2721 0.0f,
2722 1.0f
2723 };
2724 const VkPipelineColorBlendStateCreateInfo blendState =
2725 {
2726 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
2727 DE_NULL,
2728 (VkPipelineColorBlendStateCreateFlags)0u,
2729
2730 VK_FALSE,
2731 VK_LOGIC_OP_COPY,
2732 deUint32(attachmentBlendStates.size()),
2733 &attachmentBlendStates[0],
2734 { 0.0f, 0.0f, 0.0f, 0.0f }
2735 };
2736
2737 return makeGraphicsPipeline(vkd, // vk
2738 device, // device
2739 secondSubpass ? *m_pipelineLayoutPass1 : *m_pipelineLayoutPass0, // pipelineLayout
2740 *vertexShaderModule, // vertexShaderModule
2741 DE_NULL, // tessellationControlShaderModule
2742 DE_NULL, // tessellationEvalShaderModule
2743 m_layerCount != 1 ? *geometryShaderModule : DE_NULL, // geometryShaderModule
2744 *fragmentShaderModule, // fragmentShaderModule
2745 *m_renderPass, // renderPass
2746 viewports, // viewports
2747 scissors, // scissors
2748 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
2749 secondSubpass, // subpass
2750 0u, // patchControlPoints
2751 &vertexInputState, // vertexInputStateCreateInfo
2752 DE_NULL, // rasterizationStateCreateInfo
2753 &multisampleState, // multisampleStateCreateInfo
2754 &depthStencilState, // depthStencilStateCreateInfo
2755 &blendState); // colorBlendStateCreateInfo
2756 }
2757
2758 class MultisampleRenderPassResolveLevelTestInstance : public MultisampleRenderPassTestInstance
2759 {
2760 public:
2761 MultisampleRenderPassResolveLevelTestInstance (Context& context, TestConfig2 config);
2762 ~MultisampleRenderPassResolveLevelTestInstance (void) = default;
2763 };
2764
MultisampleRenderPassResolveLevelTestInstance(Context & context,TestConfig2 config)2765 MultisampleRenderPassResolveLevelTestInstance::MultisampleRenderPassResolveLevelTestInstance (Context& context, TestConfig2 config)
2766 : MultisampleRenderPassTestInstance(context, config, config.resolveLevel)
2767 {
2768 }
2769
2770 struct Programs
2771 {
initvkt::__anonc87134f00111::Programs2772 void init(vk::SourceCollections& dst, TestConfig config) const
2773 {
2774 const tcu::TextureFormat format (mapVkFormat(config.format));
2775 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
2776
2777 dst.glslSources.add("quad-vert") << glu::VertexSource(
2778 "#version 450\n"
2779 "out gl_PerVertex {\n"
2780 "\tvec4 gl_Position;\n"
2781 "};\n"
2782 "highp float;\n"
2783 "void main (void) {\n"
2784 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
2785 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
2786 "}\n");
2787
2788 if (config.layerCount > 1)
2789 {
2790 std::ostringstream src;
2791
2792 src << "#version 450\n"
2793 << "highp float;\n"
2794 << "\n"
2795 << "layout(triangles) in;\n"
2796 << "layout(triangle_strip, max_vertices = " << 3 * 2 * config.layerCount << ") out;\n"
2797 << "\n"
2798 << "in gl_PerVertex {\n"
2799 << " vec4 gl_Position;\n"
2800 << "} gl_in[];\n"
2801 << "\n"
2802 << "out gl_PerVertex {\n"
2803 << " vec4 gl_Position;\n"
2804 << "};\n"
2805 << "\n"
2806 << "void main (void) {\n"
2807 << " for (int layerNdx = 0; layerNdx < " << config.layerCount << "; ++layerNdx) {\n"
2808 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
2809 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
2810 << " gl_Layer = layerNdx;\n"
2811 << " EmitVertex();\n"
2812 << " };\n"
2813 << " EndPrimitive();\n"
2814 << " };\n"
2815 << "}\n";
2816
2817 dst.glslSources.add("geom") << glu::GeometrySource(src.str());
2818 }
2819
2820 const tcu::StringTemplate genericLayoutTemplate("layout(location = ${INDEX}) out ${TYPE_PREFIX}vec4 o_color${INDEX};\n");
2821 const tcu::StringTemplate genericBodyTemplate("\to_color${INDEX} = ${TYPE_PREFIX}vec4(${COLOR_VAL});\n");
2822
2823 if (config.testType == RESOLVE || config.testType == COMPATIBILITY)
2824 {
2825 const tcu::StringTemplate fragTemplate("#version 450\n"
2826 "layout(push_constant) uniform PushConstant {\n"
2827 "\thighp uint sampleMask;\n"
2828 "} pushConstants;\n"
2829 "${LAYOUT}"
2830 "void main (void)\n"
2831 "{\n"
2832 "${BODY}"
2833 "}\n");
2834
2835 std::map<std::string, std::string> parameters;
2836 switch (channelClass)
2837 {
2838 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2839 parameters["TYPE_PREFIX"] = "u";
2840 parameters["COLOR_VAL"] = "255";
2841 break;
2842
2843 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2844 parameters["TYPE_PREFIX"] = "i";
2845 parameters["COLOR_VAL"] = "127";
2846 break;
2847
2848 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2849 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2850 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2851 parameters["TYPE_PREFIX"] = "";
2852 parameters["COLOR_VAL"] = "1.0";
2853 break;
2854
2855 default:
2856 DE_FATAL("Unknown channel class");
2857 }
2858
2859 std::string layoutDefinitions = "";
2860 std::string shaderBody = "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n";
2861
2862 for (deUint32 attIdx = 0; attIdx < config.attachmentCount; ++attIdx)
2863 {
2864 parameters["INDEX"] = de::toString(attIdx);
2865 layoutDefinitions += genericLayoutTemplate.specialize(parameters);
2866 shaderBody += genericBodyTemplate.specialize(parameters);
2867 }
2868
2869 parameters["LAYOUT"] = layoutDefinitions;
2870 parameters["BODY"] = shaderBody;
2871 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragTemplate.specialize(parameters));
2872 }
2873 else // MAX_ATTACMENTS
2874 {
2875 const tcu::StringTemplate fragTemplate("#version 450\n"
2876 "${LAYOUT}"
2877 "void main (void)\n"
2878 "{\n"
2879 "${BODY}"
2880 "}\n");
2881
2882 std::map<std::string, std::string> parameters;
2883 switch (channelClass)
2884 {
2885 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2886 parameters["TYPE_PREFIX"] = "u";
2887 parameters["COLOR_VAL"] = "0, 64, 192, 252";
2888 break;
2889
2890 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2891 parameters["TYPE_PREFIX"] = "i";
2892 parameters["COLOR_VAL"] = "0, 32, 100, 124";
2893 break;
2894
2895 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2896 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2897 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2898 parameters["TYPE_PREFIX"] = "";
2899 parameters["COLOR_VAL"] = "0.0, 0.4, 0.8, 1.0";
2900 break;
2901
2902 default:
2903 DE_FATAL("Unknown channel class");
2904 }
2905
2906 // parts of fragment shader for second subpass - Vulkan introduced a new uniform type and syntax to glsl for input attachments
2907 const tcu::StringTemplate subpassLayoutTemplate("layout (input_attachment_index = ${INDEX}, set = 0, binding = ${INDEX}) uniform ${TYPE_PREFIX}subpassInput i_color${INDEX};\n");
2908 const tcu::StringTemplate subpassFBodyTemplate("\to_color${INDEX} = subpassLoad(i_color${INDEX})*0.5 + subpassLoad(i_color${MIX_INDEX})*0.25;\n");
2909 const tcu::StringTemplate subpassIBodyTemplate("\to_color${INDEX} = subpassLoad(i_color${INDEX}) / 2 + subpassLoad(i_color${MIX_INDEX}) / 4;\n");
2910
2911 bool selectIBody = isIntFormat(config.format) || isUintFormat(config.format);
2912 const tcu::StringTemplate& subpassBodyTemplate = selectIBody ? subpassIBodyTemplate : subpassFBodyTemplate;
2913
2914 std::string sp0layoutDefinitions = "";
2915 std::string sp0shaderBody = "";
2916 std::string sp1inLayoutDefinitions = "";
2917 std::string sp1outLayoutDefinitions = "";
2918 std::string sp1shaderBody = "";
2919
2920 deUint32 halfAttachments = config.attachmentCount / 2;
2921 for (deUint32 attIdx = 0; attIdx < config.attachmentCount; ++attIdx)
2922 {
2923 parameters["INDEX"] = de::toString(attIdx);
2924
2925 sp0layoutDefinitions += genericLayoutTemplate.specialize(parameters);
2926 sp0shaderBody += genericBodyTemplate.specialize(parameters);
2927
2928 sp1inLayoutDefinitions += subpassLayoutTemplate.specialize(parameters);
2929 if (attIdx < halfAttachments)
2930 {
2931 // we are combining pairs of input attachments to produce half the number of outputs
2932 parameters["MIX_INDEX"] = de::toString(halfAttachments + attIdx);
2933 sp1outLayoutDefinitions += genericLayoutTemplate.specialize(parameters);
2934 sp1shaderBody += subpassBodyTemplate.specialize(parameters);
2935 }
2936 }
2937
2938 // construct fragment shaders for subpass1 and subpass2; note that there
2939 // is different shader definition depending on number of attachments
2940 std::string nameBase = "quad-frag-sp";
2941 std::string namePostfix = de::toString(config.attachmentCount);
2942 parameters["LAYOUT"] = sp0layoutDefinitions;
2943 parameters["BODY"] = sp0shaderBody;
2944 dst.glslSources.add(nameBase + "0-" + namePostfix) << glu::FragmentSource(fragTemplate.specialize(parameters));
2945 parameters["LAYOUT"] = sp1inLayoutDefinitions + sp1outLayoutDefinitions;
2946 parameters["BODY"] = sp1shaderBody;
2947 dst.glslSources.add(nameBase + "1-" + namePostfix) << glu::FragmentSource(fragTemplate.specialize(parameters));
2948 }
2949 }
2950 };
2951
2952 template<class TestConfigType>
checkSupport(Context & context,TestConfigType config)2953 void checkSupport(Context& context, TestConfigType config)
2954 {
2955 #ifndef CTS_USES_VULKANSC
2956 if (config.format == VK_FORMAT_A8_UNORM_KHR)
2957 context.requireDeviceFunctionality("VK_KHR_maintenance5");
2958 #endif // CTS_USES_VULKANSC
2959
2960 if (config.layerCount > 1)
2961 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2962
2963 if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
2964 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
2965
2966 if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
2967 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
2968
2969 #ifndef CTS_USES_VULKANSC
2970 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
2971 !context.getPortabilitySubsetFeatures().multisampleArrayImage &&
2972 (config.sampleCount != VK_SAMPLE_COUNT_1_BIT) && (config.layerCount != 1))
2973 {
2974 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support image array with multiple samples per texel");
2975 }
2976 #endif // CTS_USES_VULKANSC
2977
2978 const InstanceInterface& vki = context.getInstanceInterface();
2979 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
2980 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
2981
2982 if (config.attachmentCount > properties.limits.maxColorAttachments)
2983 TCU_THROW(NotSupportedError, "Required number of color attachments not supported.");
2984
2985 if (config.testType == MAX_ATTACHMENTS && config.attachmentCount > properties.limits.maxPerStageDescriptorInputAttachments)
2986 TCU_THROW(NotSupportedError, "Required number of per stage descriptor input attachments not supported.");
2987 }
2988
formatToName(VkFormat format)2989 std::string formatToName (VkFormat format)
2990 {
2991 const std::string formatStr = de::toString(format);
2992 const std::string prefix = "VK_FORMAT_";
2993
2994 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2995
2996 return de::toLower(formatStr.substr(prefix.length()));
2997 }
2998
initTests(tcu::TestCaseGroup * group,const SharedGroupParams groupParams)2999 void initTests (tcu::TestCaseGroup* group, const SharedGroupParams groupParams)
3000 {
3001 static const VkFormat formats[] =
3002 {
3003 VK_FORMAT_R5G6B5_UNORM_PACK16,
3004 VK_FORMAT_R8_UNORM,
3005 VK_FORMAT_R8_SNORM,
3006 VK_FORMAT_R8_UINT,
3007 VK_FORMAT_R8_SINT,
3008 #ifndef CTS_USES_VULKANSC
3009 VK_FORMAT_A8_UNORM_KHR,
3010 #endif // CTS_USES_VULKANSC
3011 VK_FORMAT_R8G8_UNORM,
3012 VK_FORMAT_R8G8_SNORM,
3013 VK_FORMAT_R8G8_UINT,
3014 VK_FORMAT_R8G8_SINT,
3015 VK_FORMAT_R8G8B8A8_UNORM,
3016 VK_FORMAT_R8G8B8A8_SNORM,
3017 VK_FORMAT_R8G8B8A8_UINT,
3018 VK_FORMAT_R8G8B8A8_SINT,
3019 VK_FORMAT_R8G8B8A8_SRGB,
3020 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
3021 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
3022 VK_FORMAT_A8B8G8R8_UINT_PACK32,
3023 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3024 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3025 VK_FORMAT_B8G8R8A8_UNORM,
3026 VK_FORMAT_B8G8R8A8_SRGB,
3027 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3028 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3029 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3030 VK_FORMAT_R16_UNORM,
3031 VK_FORMAT_R16_SNORM,
3032 VK_FORMAT_R16_UINT,
3033 VK_FORMAT_R16_SINT,
3034 VK_FORMAT_R16_SFLOAT,
3035 VK_FORMAT_R16G16_UNORM,
3036 VK_FORMAT_R16G16_SNORM,
3037 VK_FORMAT_R16G16_UINT,
3038 VK_FORMAT_R16G16_SINT,
3039 VK_FORMAT_R16G16_SFLOAT,
3040 VK_FORMAT_R16G16B16A16_UNORM,
3041 VK_FORMAT_R16G16B16A16_SNORM,
3042 VK_FORMAT_R16G16B16A16_UINT,
3043 VK_FORMAT_R16G16B16A16_SINT,
3044 VK_FORMAT_R16G16B16A16_SFLOAT,
3045 VK_FORMAT_R32_UINT,
3046 VK_FORMAT_R32_SINT,
3047 VK_FORMAT_R32_SFLOAT,
3048 VK_FORMAT_R32G32_UINT,
3049 VK_FORMAT_R32G32_SINT,
3050 VK_FORMAT_R32G32_SFLOAT,
3051 VK_FORMAT_R32G32B32A32_UINT,
3052 VK_FORMAT_R32G32B32A32_SINT,
3053 VK_FORMAT_R32G32B32A32_SFLOAT,
3054 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
3055 };
3056 const deUint32 sampleCounts[] =
3057 {
3058 2u, 4u, 8u
3059 };
3060 const deUint32 layerCounts[] =
3061 {
3062 1u, 3u, 6u
3063 };
3064 const deUint32 resolveLevels[] =
3065 {
3066 2u, 3u, 4u
3067 };
3068 tcu::TestContext& testCtx (group->getTestContext());
3069
3070 for (size_t layerCountNdx = 0; layerCountNdx < DE_LENGTH_OF_ARRAY(layerCounts); layerCountNdx++)
3071 {
3072 const deUint32 layerCount (layerCounts[layerCountNdx]);
3073 const std::string layerGroupName ("layers_" + de::toString(layerCount));
3074 de::MovePtr<tcu::TestCaseGroup> layerGroup (new tcu::TestCaseGroup(testCtx, layerGroupName.c_str()));
3075
3076 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
3077 {
3078 const VkFormat format (formats[formatNdx]);
3079 const std::string formatName (formatToName(format));
3080 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str()));
3081
3082 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
3083 {
3084 const deUint32 sampleCount(sampleCounts[sampleCountNdx]);
3085
3086 // Skip this test as it is rather slow
3087 if (layerCount == 6 && sampleCount == 8)
3088 continue;
3089
3090 // Reduce number of tests for dynamic rendering cases where secondary command buffer is used
3091 if (groupParams->useSecondaryCmdBuffer && ( (sampleCount > 2u) || (layerCount > 3u) ))
3092 continue;
3093
3094 std::string testName ("samples_" + de::toString(sampleCount));
3095 const TestConfig testConfig
3096 {
3097 RESOLVE,
3098 format,
3099 sampleCount,
3100 layerCount,
3101 0,
3102 4u,
3103 32u,
3104 32u,
3105 groupParams
3106 };
3107
3108 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));
3109
3110 const TestConfig testConfigBaseLayer
3111 {
3112 RESOLVE,
3113 format,
3114 sampleCount,
3115 layerCount,
3116 1,
3117 4u,
3118 32u,
3119 32u,
3120 groupParams
3121 };
3122 std::string testNameBaseLayer ("samples_" + de::toString(sampleCount) + "_baseLayer1");
3123
3124 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testNameBaseLayer.c_str(), testConfigBaseLayer, typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfigBaseLayer)));
3125
3126 for (deUint32 resolveLevel : resolveLevels)
3127 {
3128 const TestConfig2 testConfig2(testConfig, resolveLevel);
3129 std::string resolveLevelTestNameStr(testName + "_resolve_level_" + de::toString(resolveLevel));
3130 const char* resolveLevelTestName = resolveLevelTestNameStr.c_str();
3131
3132 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassResolveLevelTestInstance, TestConfig2, FunctionSupport1<TestConfig2>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, resolveLevelTestName, testConfig2, typename FunctionSupport1<TestConfig2>::Args(checkSupport, testConfig2)));
3133
3134 // Reduce number of tests for dynamic rendering cases where secondary command buffer is used
3135 if (groupParams->useSecondaryCmdBuffer)
3136 break;
3137 }
3138
3139 // MaxAttachmenstsRenderPassTest is ment to test extreme cases where applications might consume all available on-chip
3140 // memory. This is achieved by using maxColorAttachments attachments and two subpasses, but during test creation we
3141 // dont know what is the maximal number of attachments (spirv tools are not available on all platforms) so we cant
3142 // construct shaders during test execution. To be able to test this we need to execute tests for all available
3143 // numbers of attachments despite the fact that we are only interested in the maximal number; test construction code
3144 // assumes that the number of attachments is power of two
3145 if ((groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) && (layerCount == 1))
3146 {
3147 for (deUint32 power = 2; power < 5; ++power)
3148 {
3149 deUint32 attachmentCount = 1 << power;
3150 std::string maxAttName = "max_attachments_" + de::toString(attachmentCount) + "_" + testName;
3151
3152 TestConfig maxAttachmentsTestConfig = testConfig;
3153 maxAttachmentsTestConfig.testType = MAX_ATTACHMENTS;
3154 maxAttachmentsTestConfig.attachmentCount = attachmentCount;
3155
3156 formatGroup->addChild(new InstanceFactory1WithSupport<MaxAttachmenstsRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, maxAttName.c_str(), maxAttachmentsTestConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, maxAttachmentsTestConfig)));
3157 }
3158
3159 {
3160 std::string compatibilityTestName = "compatibility_" + testName;
3161
3162 TestConfig compatibilityTestConfig = testConfig;
3163 compatibilityTestConfig.testType = COMPATIBILITY;
3164 compatibilityTestConfig.attachmentCount = 1;
3165
3166 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, compatibilityTestConfig)));
3167 }
3168 }
3169 }
3170
3171 if (layerCount == 1)
3172 group->addChild(formatGroup.release());
3173 else
3174 layerGroup->addChild(formatGroup.release());
3175 }
3176
3177 if (layerCount != 1)
3178 group->addChild(layerGroup.release());
3179 }
3180 }
3181
3182 } // anonymous
3183
createRenderPassMultisampleResolveTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)3184 tcu::TestCaseGroup* createRenderPassMultisampleResolveTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
3185 {
3186 return createTestGroup(testCtx, "multisample_resolve", initTests, groupParams);
3187 }
3188
createRenderPass2MultisampleResolveTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)3189 tcu::TestCaseGroup* createRenderPass2MultisampleResolveTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
3190 {
3191 return createTestGroup(testCtx, "multisample_resolve", initTests, groupParams);
3192 }
3193
createDynamicRenderingMultisampleResolveTests(tcu::TestContext & testCtx,const renderpass::SharedGroupParams groupParams)3194 tcu::TestCaseGroup* createDynamicRenderingMultisampleResolveTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
3195 {
3196 return createTestGroup(testCtx, "multisample_resolve", initTests, groupParams);
3197 }
3198
3199 } // vkt
3200