1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Tests for render pass multisample resolve
22 *//*--------------------------------------------------------------------*/
24 #include "vktRenderPassMultisampleResolveTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.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"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
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"
53 #include "deUniquePtr.hpp"
54 #include "deSharedPtr.hpp"
67 using tcu::ConstPixelBufferAccess;
68 using tcu::PixelBufferAccess;
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;
88 using namespace renderpass;
91 de::SharedPtr<T> safeSharedPtr (T* ptr)
95 return de::SharedPtr<T>(ptr);
115 deUint32 sampleCount;
117 deUint32 attachmentCount;
120 const SharedGroupParams groupParams;
123 struct TestConfig2 : TestConfig
125 TestConfig2(const TestConfig& src, deUint32 level)
127 , resolveLevel (level)
130 deUint32 resolveLevel;
133 // Render pass traits that groups render pass related types together and by that help
134 // to reduce number of template parrameters passed to number of functions in those tests
135 struct RenderPass1Trait
137 typedef AttachmentDescription1 AttDesc;
138 typedef AttachmentReference1 AttRef;
139 typedef SubpassDescription1 SubpassDesc;
140 typedef SubpassDependency1 SubpassDep;
141 typedef RenderPassCreateInfo1 RenderPassCreateInfo;
143 struct RenderPass2Trait
145 typedef AttachmentDescription2 AttDesc;
146 typedef AttachmentReference2 AttRef;
147 typedef SubpassDescription2 SubpassDesc;
148 typedef SubpassDependency2 SubpassDep;
149 typedef RenderPassCreateInfo2 RenderPassCreateInfo;
152 class MultisampleRenderPassTestBase : public TestInstance
155 MultisampleRenderPassTestBase (Context& context, TestConfig config);
156 ~MultisampleRenderPassTestBase (void);
160 Move<VkImage> createImage (VkSampleCountFlagBits sampleCountBit,
161 VkImageUsageFlags usage) const;
162 Move<VkImage> createImage (VkSampleCountFlagBits sampleCountBit,
163 VkImageUsageFlags usage,
166 deUint32 mipLevels) const;
167 vector<VkImageSp> createImages (VkSampleCountFlagBits sampleCountBit,
168 VkImageUsageFlags usage) const;
169 vector<VkImageSp> createImages (VkSampleCountFlagBits sampleCountBit,
170 VkImageUsageFlags usage,
173 deUint32 mipLevels) const;
174 vector<AllocationSp> createImageMemory (const vector<VkImageSp>& images) const;
175 vector<VkImageViewSp> createImageViews (const vector<VkImageSp>& images,
176 deUint32 mipLevel = 0) const;
178 vector<VkBufferSp> createBuffers () const;
179 vector<VkBufferSp> createBuffers (deUint32 width,
181 deUint32 mipLevels) const;
182 vector<AllocationSp> createBufferMemory (const vector<VkBufferSp>& buffers) const;
184 Move<VkFramebuffer> createFramebuffer (const std::vector<VkImageViewSp> multisampleImageViews,
185 const std::vector<VkImageViewSp> singlesampleImageViews,
186 VkRenderPass renderPass) const;
188 void clearAttachments (VkCommandBuffer commandBuffer) const;
189 VkDeviceSize getPixelSize () const;
190 tcu::Vec4 getFormatThreshold () const;
191 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) const;
192 void logImage (const std::string& name,
193 const tcu::ConstPixelBufferAccess& image) const;
197 const bool m_testCompatibility;
198 const SharedGroupParams m_groupParams;
200 const VkFormat m_format;
201 const VkSampleCountFlagBits m_sampleCount;
202 const deUint32 m_layerCount;
203 const deUint32 m_attachmentsCount;
204 const deUint32 m_width;
205 const deUint32 m_height;
208 MultisampleRenderPassTestBase::MultisampleRenderPassTestBase (Context& context, TestConfig config)
209 : TestInstance (context)
210 , m_testCompatibility (config.testType == COMPATIBILITY)
211 , m_groupParams (config.groupParams)
212 , m_format (config.format)
213 , m_sampleCount (sampleCountBitFromSampleCount(config.sampleCount))
214 , m_layerCount (config.layerCount)
215 , m_attachmentsCount (config.attachmentCount)
216 , m_width (config.width)
217 , m_height (config.height)
221 MultisampleRenderPassTestBase::~MultisampleRenderPassTestBase ()
225 Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
227 return createImage(sampleCountBit, usage, m_width, m_height, 1u);
230 Move<VkImage> MultisampleRenderPassTestBase::createImage (VkSampleCountFlagBits sampleCountBit,
231 VkImageUsageFlags usage,
234 deUint32 mipLevels) const
236 const InstanceInterface& vki = m_context.getInstanceInterface();
237 const DeviceInterface& vkd = m_context.getDeviceInterface();
238 VkDevice device = m_context.getDevice();
239 VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
240 const tcu::TextureFormat format (mapVkFormat(m_format));
241 const VkImageType imageType (VK_IMAGE_TYPE_2D);
242 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
243 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, m_format));
244 const VkExtent3D imageExtent =
253 const VkImageFormatProperties imageFormatProperties(getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, imageType, imageTiling, usage, 0u));
255 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
256 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
257 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
259 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
260 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
261 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
263 if (imageFormatProperties.maxExtent.width < imageExtent.width
264 || imageFormatProperties.maxExtent.height < imageExtent.height
265 || ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
266 || imageFormatProperties.maxArrayLayers < m_layerCount)
268 TCU_THROW(NotSupportedError, "Image type not supported");
271 const VkImageCreateInfo pCreateInfo =
273 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
284 VK_SHARING_MODE_EXCLUSIVE,
287 VK_IMAGE_LAYOUT_UNDEFINED
290 return ::createImage(vkd, device, &pCreateInfo);
292 catch (const vk::Error& error)
294 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
295 TCU_THROW(NotSupportedError, "Image format not supported");
301 vector<VkImageSp> MultisampleRenderPassTestBase::createImages (VkSampleCountFlagBits sampleCountBit, VkImageUsageFlags usage) const
303 std::vector<VkImageSp> images (m_attachmentsCount);
304 for (size_t imageNdx = 0; imageNdx < m_attachmentsCount; imageNdx++)
305 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(sampleCountBit, usage)));
309 vector<VkImageSp> MultisampleRenderPassTestBase::createImages (VkSampleCountFlagBits sampleCountBit,
310 VkImageUsageFlags usage,
313 deUint32 mipLevels) const
315 std::vector<VkImageSp> images (m_attachmentsCount);
316 for (size_t imageNdx = 0; imageNdx < m_attachmentsCount; imageNdx++)
317 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(sampleCountBit, usage, width, height, mipLevels)));
321 vector<AllocationSp> MultisampleRenderPassTestBase::createImageMemory (const vector<VkImageSp>& images) const
323 const DeviceInterface& vkd = m_context.getDeviceInterface();
324 VkDevice device = m_context.getDevice();
325 Allocator& allocator = m_context.getDefaultAllocator();
326 std::vector<AllocationSp> memory (images.size());
328 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
330 VkImage image = **images[memoryNdx];
331 VkMemoryRequirements requirements = getImageMemoryRequirements(vkd, device, image);
333 de::MovePtr<Allocation> allocation (allocator.allocate(requirements, MemoryRequirement::Any));
334 VK_CHECK(vkd.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
335 memory[memoryNdx] = safeSharedPtr(allocation.release());
340 vector<VkImageViewSp> MultisampleRenderPassTestBase::createImageViews (const vector<VkImageSp>& images, deUint32 mipLevel) const
342 const DeviceInterface& vkd = m_context.getDeviceInterface();
343 VkDevice device = m_context.getDevice();
344 std::vector<VkImageViewSp> views (images.size());
345 const VkImageSubresourceRange range =
347 VK_IMAGE_ASPECT_COLOR_BIT,
354 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
356 const VkImageViewCreateInfo pCreateInfo =
358 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
362 VK_IMAGE_VIEW_TYPE_2D_ARRAY,
364 makeComponentMappingRGBA(),
367 views[imageNdx] = safeSharedPtr(new Unique<VkImageView>(createImageView(vkd, device, &pCreateInfo)));
373 vector<VkBufferSp> MultisampleRenderPassTestBase::createBuffers () const
375 return createBuffers(m_width, m_height, 1u);
378 vector<VkBufferSp> MultisampleRenderPassTestBase::createBuffers (deUint32 width, deUint32 height, deUint32 mipLevels) const
380 DE_ASSERT(mipLevels);
382 VkDeviceSize size = 0;
383 for (deUint32 level = 0; level < mipLevels; ++level)
385 DE_ASSERT(width && height);
387 size += (width * height);
392 const DeviceInterface& vkd = m_context.getDeviceInterface();
393 VkDevice device = m_context.getDevice();
394 std::vector<VkBufferSp> buffers (m_attachmentsCount);
395 const VkDeviceSize pixelSize (getPixelSize());
396 const VkBufferCreateInfo createInfo =
398 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
402 size * m_layerCount * pixelSize,
403 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
405 VK_SHARING_MODE_EXCLUSIVE,
410 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
411 buffers[bufferNdx] = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vkd, device, &createInfo)));
416 vector<AllocationSp> MultisampleRenderPassTestBase::createBufferMemory (const vector<VkBufferSp>& buffers) const
418 const DeviceInterface& vkd = m_context.getDeviceInterface();
419 VkDevice device = m_context.getDevice();
420 Allocator& allocator = m_context.getDefaultAllocator();
421 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
423 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
425 VkBuffer buffer = **buffers[memoryNdx];
426 VkMemoryRequirements requirements = getBufferMemoryRequirements(vkd, device, buffer);
427 de::MovePtr<Allocation> allocation (allocator.allocate(requirements, MemoryRequirement::HostVisible));
429 VK_CHECK(vkd.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
430 memory[memoryNdx] = safeSharedPtr(allocation.release());
435 Move<VkFramebuffer> MultisampleRenderPassTestBase::createFramebuffer (const std::vector<VkImageViewSp> multisampleImageViews,
436 const std::vector<VkImageViewSp> singlesampleImageViews,
437 VkRenderPass renderPass) const
439 // when RenderPass was not created then we are testing dynamic rendering
440 // and we can't create framebuffer without valid RenderPass object
442 return Move<VkFramebuffer>();
444 const DeviceInterface& vkd = m_context.getDeviceInterface();
445 VkDevice device = m_context.getDevice();
447 std::vector<VkImageView> attachments;
448 attachments.reserve(multisampleImageViews.size() + singlesampleImageViews.size());
450 DE_ASSERT(multisampleImageViews.size() == singlesampleImageViews.size());
452 for (size_t ndx = 0; ndx < multisampleImageViews.size(); ndx++)
454 attachments.push_back(**multisampleImageViews[ndx]);
455 attachments.push_back(**singlesampleImageViews[ndx]);
458 const VkFramebufferCreateInfo createInfo =
460 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
465 (deUint32)attachments.size(),
473 return ::createFramebuffer(vkd, device, &createInfo);
476 void MultisampleRenderPassTestBase::clearAttachments (VkCommandBuffer commandBuffer) const
478 const DeviceInterface& vkd = m_context.getDeviceInterface();
479 const tcu::TextureFormat format (mapVkFormat(m_format));
480 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
483 // Clear everything to black
484 switch (channelClass)
486 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
487 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
490 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
491 value = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
494 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
495 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
498 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
499 value = makeClearValueColorI32(-128, -128, -128, -128);
502 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
503 value = makeClearValueColorU32(0u, 0u, 0u, 0u);
507 DE_FATAL("Unknown channel class");
509 std::vector<VkClearAttachment> colors(m_attachmentsCount);
510 for (deUint32 attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
512 colors[attachmentNdx].aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
513 colors[attachmentNdx].colorAttachment = attachmentNdx;
514 colors[attachmentNdx].clearValue = value;
516 const VkClearRect rect =
520 { m_width, m_height }
525 vkd.cmdClearAttachments(commandBuffer, deUint32(colors.size()), &colors[0], 1u, &rect);
528 VkDeviceSize MultisampleRenderPassTestBase::getPixelSize () const
530 const tcu::TextureFormat format(mapVkFormat(m_format));
531 return format.getPixelSize();
534 tcu::Vec4 MultisampleRenderPassTestBase::getFormatThreshold () const
536 const tcu::TextureFormat tcuFormat (mapVkFormat(m_format));
537 const deUint32 componentCount (tcu::getNumUsedChannels(tcuFormat.order));
539 if (isSnormFormat(m_format))
541 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffSnorm(m_format, 0) : 0.0f,
542 (componentCount >= 2) ? 1.5f * getRepresentableDiffSnorm(m_format, 1) : 0.0f,
543 (componentCount >= 3) ? 1.5f * getRepresentableDiffSnorm(m_format, 2) : 0.0f,
544 (componentCount == 4) ? 1.5f * getRepresentableDiffSnorm(m_format, 3) : 0.0f);
546 else if (isUnormFormat(m_format))
548 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffUnorm(m_format, 0) : 0.0f,
549 (componentCount >= 2) ? 1.5f * getRepresentableDiffUnorm(m_format, 1) : 0.0f,
550 (componentCount >= 3) ? 1.5f * getRepresentableDiffUnorm(m_format, 2) : 0.0f,
551 (componentCount == 4) ? 1.5f * getRepresentableDiffUnorm(m_format, 3) : 0.0f);
553 else if (isFloatFormat(m_format))
555 return (tcuFormat.type == tcu::TextureFormat::HALF_FLOAT) ? tcu::Vec4(0.005f) : Vec4(0.00001f);
561 VkSampleCountFlagBits MultisampleRenderPassTestBase::sampleCountBitFromSampleCount (deUint32 count) const
565 case 1: return VK_SAMPLE_COUNT_1_BIT;
566 case 2: return VK_SAMPLE_COUNT_2_BIT;
567 case 4: return VK_SAMPLE_COUNT_4_BIT;
568 case 8: return VK_SAMPLE_COUNT_8_BIT;
569 case 16: return VK_SAMPLE_COUNT_16_BIT;
570 case 32: return VK_SAMPLE_COUNT_32_BIT;
571 case 64: return VK_SAMPLE_COUNT_64_BIT;
574 DE_FATAL("Invalid sample count");
575 return (VkSampleCountFlagBits)0x0;
579 void MultisampleRenderPassTestBase::logImage (const std::string& name, const tcu::ConstPixelBufferAccess& image) const
581 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), image);
583 for (deUint32 layerNdx = 0; layerNdx < m_layerCount; ++layerNdx)
585 const std::string layerName (name + " Layer:" + de::toString(layerNdx));
586 tcu::ConstPixelBufferAccess layerImage (image.getFormat(), m_width, m_height, 1, image.getPixelPtr(0, 0, layerNdx));
588 m_context.getTestContext().getLog() << tcu::LogImage(layerName.c_str(), layerName.c_str(), layerImage);
592 class MultisampleRenderPassTestInstance : public MultisampleRenderPassTestBase
595 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
596 ~MultisampleRenderPassTestInstance (void);
598 tcu::TestStatus iterate (void);
602 void drawCommands (VkCommandBuffer cmdBuffer, VkPipeline pipeline, VkPipelineLayout pipelineLayout) const;
604 template<typename RenderpassSubpass>
606 void submitDynamicRendering (void);
607 void submitSwitch (const SharedGroupParams groupParams);
610 template<typename RenderPassTrait>
611 Move<VkRenderPass> createRenderPass (bool usedResolveAttachment);
612 Move<VkRenderPass> createRenderPassSwitch (bool usedResolveAttachment);
613 Move<VkRenderPass> createRenderPassCompatible (void);
614 Move<VkPipelineLayout> createRenderPipelineLayout (void);
615 Move<VkPipeline> createRenderPipeline (void);
617 #ifndef CTS_USES_VULKANSC
618 void beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
619 #endif // CTS_USES_VULKANSC
623 const std::vector<VkImageSp> m_multisampleImages;
624 const std::vector<AllocationSp> m_multisampleImageMemory;
625 const std::vector<VkImageViewSp> m_multisampleImageViews;
627 const std::vector<VkImageSp> m_singlesampleImages;
628 const std::vector<AllocationSp> m_singlesampleImageMemory;
629 const std::vector<VkImageViewSp> m_singlesampleImageViews;
631 const Unique<VkRenderPass> m_renderPass;
632 const Unique<VkRenderPass> m_renderPassCompatible;
633 const Unique<VkFramebuffer> m_framebuffer;
635 const Unique<VkPipelineLayout> m_renderPipelineLayout;
636 const Unique<VkPipeline> m_renderPipeline;
638 const std::vector<VkBufferSp> m_buffers;
639 const std::vector<AllocationSp> m_bufferMemory;
641 const Unique<VkCommandPool> m_commandPool;
642 tcu::TextureLevel m_sum;
643 tcu::TextureLevel m_sumSrgb;
644 deUint32 m_sampleMask;
645 tcu::ResultCollector m_resultCollector;
648 MultisampleRenderPassTestInstance (Context& context, TestConfig config, deUint32 renderLevel);
650 const deUint32 m_renderLevel;
653 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
654 : MultisampleRenderPassTestInstance (context, config, /*defaulf render level*/0u)
658 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config, deUint32 renderLevel)
659 : MultisampleRenderPassTestBase(context, config)
661 , m_multisampleImages (createImages(m_sampleCount, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
662 , m_multisampleImageMemory (createImageMemory(m_multisampleImages))
663 , m_multisampleImageViews (createImageViews(m_multisampleImages))
665 , 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 ))
666 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImages))
667 , m_singlesampleImageViews (createImageViews(m_singlesampleImages, renderLevel))
669 // The "normal" render pass has an unused resolve attachment when testing compatibility.
670 , m_renderPass (createRenderPassSwitch(!m_testCompatibility))
671 , m_renderPassCompatible (createRenderPassCompatible())
672 , m_framebuffer (createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))
674 , m_renderPipelineLayout (createRenderPipelineLayout())
675 , m_renderPipeline (createRenderPipeline())
677 , m_buffers (createBuffers((1u << renderLevel)*m_width, (1u << renderLevel)*m_height, renderLevel+1 ))
678 , m_bufferMemory (createBufferMemory(m_buffers))
680 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
681 , m_sum (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, m_layerCount)
682 , m_sumSrgb (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, m_layerCount)
683 , m_sampleMask (0x0u)
685 , m_renderLevel (renderLevel)
687 tcu::clear(m_sum.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
688 tcu::clear(m_sumSrgb.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
691 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
695 void MultisampleRenderPassTestInstance::drawCommands(VkCommandBuffer cmdBuffer, VkPipeline pipeline, VkPipelineLayout pipelineLayout) const
697 const DeviceInterface& vkd = m_context.getDeviceInterface();
699 // Clear everything to black
700 clearAttachments(cmdBuffer);
702 // Render black samples
703 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
704 vkd.cmdPushConstants(cmdBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(m_sampleMask), &m_sampleMask);
705 vkd.cmdDraw(cmdBuffer, 6u, 1u, 0u, 0u);
708 template<typename RenderpassSubpass>
709 void MultisampleRenderPassTestInstance::submit (void)
711 const DeviceInterface& vkd (m_context.getDeviceInterface());
712 const VkDevice device (m_context.getDevice());
713 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
715 beginCommandBuffer(vkd, *commandBuffer);
717 // Memory barriers between previous copies and rendering
719 std::vector<VkImageMemoryBarrier> barriers;
721 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
723 const VkImageMemoryBarrier barrier =
725 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
728 VK_ACCESS_TRANSFER_READ_BIT,
729 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
731 VK_IMAGE_LAYOUT_UNDEFINED,
732 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
734 VK_QUEUE_FAMILY_IGNORED,
735 VK_QUEUE_FAMILY_IGNORED,
737 **m_singlesampleImages[dstNdx],
739 VK_IMAGE_ASPECT_COLOR_BIT,
747 barriers.push_back(barrier);
750 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]);
753 VkRect2D renderArea = makeRect2D(m_width, m_height);
754 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
755 const VkRenderPassBeginInfo beginInfo =
757 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
760 m_testCompatibility ? *m_renderPassCompatible : *m_renderPass,
767 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
769 drawCommands(*commandBuffer, *m_renderPipeline, *m_renderPipelineLayout);
771 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
772 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
774 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
776 // assume that buffer(s) have enough memory to store desired amount of mipmaps
777 copyImageToBuffer(vkd, *commandBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx],
778 m_format, tcu::IVec2((1u << m_renderLevel)*m_width, (1u << m_renderLevel)*m_height), m_renderLevel,
779 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_layerCount);
782 endCommandBuffer(vkd, *commandBuffer);
784 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
786 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
787 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
790 void MultisampleRenderPassTestInstance::submitDynamicRendering (void)
792 #ifndef CTS_USES_VULKANSC
794 const DeviceInterface& vkd (m_context.getDeviceInterface());
795 const VkDevice device (m_context.getDevice());
796 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
797 Move<VkCommandBuffer> secCmdBuffer;
799 // Memory barriers between previous copies and rendering
800 std::vector<VkImageMemoryBarrier> singlesampleImageBarriers(m_singlesampleImages.size(),
802 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
805 VK_ACCESS_TRANSFER_READ_BIT,
806 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
808 VK_IMAGE_LAYOUT_UNDEFINED,
809 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
811 VK_QUEUE_FAMILY_IGNORED,
812 VK_QUEUE_FAMILY_IGNORED,
816 VK_IMAGE_ASPECT_COLOR_BIT,
823 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
824 singlesampleImageBarriers[dstNdx].image = **m_singlesampleImages[dstNdx];
826 // Memory barriers to set multisample image layout to COLOR_ATTACHMENT_OPTIMAL
827 std::vector<VkImageMemoryBarrier> multisampleImageBarriers(m_multisampleImages.size(),
829 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
833 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
835 VK_IMAGE_LAYOUT_UNDEFINED,
836 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
838 VK_QUEUE_FAMILY_IGNORED,
839 VK_QUEUE_FAMILY_IGNORED,
843 VK_IMAGE_ASPECT_COLOR_BIT,
850 for (size_t dstNdx = 0; dstNdx < m_multisampleImages.size(); dstNdx++)
851 multisampleImageBarriers[dstNdx].image = **m_multisampleImages[dstNdx];
853 VkRect2D renderArea = makeRect2D(m_width, m_height);
854 const VkClearValue clearValue = makeClearValueColor( { 0.0f, 0.0f, 0.0f, 1.0f } );
855 std::vector<vk::VkRenderingAttachmentInfoKHR> colorAttachments(m_attachmentsCount,
857 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
858 DE_NULL, // const void* pNext;
859 DE_NULL, // VkImageView imageView;
860 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
861 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
862 DE_NULL, // VkImageView resolveImageView;
863 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout resolveImageLayout;
864 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
865 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
866 clearValue // VkClearValue clearValue;
869 for (deUint32 i = 0; i < m_attachmentsCount; ++i)
871 colorAttachments[i].imageView = **m_multisampleImageViews[i];
872 colorAttachments[i].resolveImageView = **m_singlesampleImageViews[i];
873 if (isIntFormat(m_format) || isUintFormat(m_format))
874 colorAttachments[i].resolveMode = vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT;
876 colorAttachments[i].resolveMode = vk::VK_RESOLVE_MODE_AVERAGE_BIT;
879 vk::VkRenderingInfoKHR renderingInfo
881 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
883 0, // VkRenderingFlagsKHR flags;
884 renderArea, // VkRect2D renderArea;
885 m_layerCount, // deUint32 layerCount;
886 0u, // deUint32 viewMask;
887 m_attachmentsCount, // deUint32 colorAttachmentCount;
888 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
889 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
890 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
893 if (m_groupParams->useSecondaryCmdBuffer)
895 secCmdBuffer = allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
897 // record secondary command buffer
898 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
900 beginSecondaryCmdBuffer(*secCmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
901 vkd.cmdBeginRendering(*secCmdBuffer, &renderingInfo);
904 beginSecondaryCmdBuffer(*secCmdBuffer);
906 drawCommands(*secCmdBuffer, *m_renderPipeline, *m_renderPipelineLayout);
908 if (m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
909 vkd.cmdEndRendering(*secCmdBuffer);
911 endCommandBuffer(vkd, *secCmdBuffer);
913 // record primary command buffer
914 beginCommandBuffer(vkd, *cmdBuffer);
916 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]);
917 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]);
919 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
921 renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
922 vkd.cmdBeginRendering(*cmdBuffer, &renderingInfo);
924 vkd.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
926 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
927 vkd.cmdEndRendering(*cmdBuffer);
931 beginCommandBuffer(vkd, *cmdBuffer);
933 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]);
934 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]);
936 vkd.cmdBeginRendering(*cmdBuffer, &renderingInfo);
937 drawCommands(*cmdBuffer, *m_renderPipeline, *m_renderPipelineLayout);
938 vkd.cmdEndRendering(*cmdBuffer);
941 // Memory barriers to set single-sample image layout to TRANSFER_SRC_OPTIMAL
943 std::vector<VkImageMemoryBarrier> barriers;
945 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
947 const VkImageMemoryBarrier barrier =
949 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
952 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
953 VK_ACCESS_TRANSFER_READ_BIT,
955 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
956 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
958 VK_QUEUE_FAMILY_IGNORED,
959 VK_QUEUE_FAMILY_IGNORED,
961 **m_singlesampleImages[dstNdx],
963 VK_IMAGE_ASPECT_COLOR_BIT,
971 barriers.push_back(barrier);
974 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]);
977 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
979 // assume that buffer(s) have enough memory to store desired amount of mipmaps
980 copyImageToBuffer(vkd, *cmdBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx],
981 m_format, tcu::IVec2((1u << m_renderLevel)*m_width, (1u << m_renderLevel)*m_height), m_renderLevel,
982 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_layerCount);
985 endCommandBuffer(vkd, *cmdBuffer);
987 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *cmdBuffer);
989 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
990 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
992 #endif // CTS_USES_VULKANSC
995 void MultisampleRenderPassTestInstance::submitSwitch (const SharedGroupParams groupParams)
997 switch (groupParams->renderingType)
999 case RENDERING_TYPE_RENDERPASS_LEGACY:
1000 submit<RenderpassSubpass1>();
1002 case RENDERING_TYPE_RENDERPASS2:
1003 submit<RenderpassSubpass2>();
1005 case RENDERING_TYPE_DYNAMIC_RENDERING:
1006 submitDynamicRendering();
1009 TCU_THROW(InternalError, "Impossible");
1013 void MultisampleRenderPassTestInstance::verify (void)
1015 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1016 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1017 const tcu::TextureFormat format (mapVkFormat(m_format));
1018 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1020 deUint32 offset (0u);
1021 deUint32 width ((1u << m_renderLevel) * m_width);
1022 deUint32 height ((1u << m_renderLevel) * m_height);
1023 deUint32 pixelSize (static_cast<deUint32>(getPixelSize()));
1024 for (deUint32 level = 0; level < m_renderLevel; ++level)
1026 offset += (width * height * pixelSize);
1031 std::vector<tcu::ConstPixelBufferAccess> accesses;
1032 for (deUint32 attachmentIdx = 0; attachmentIdx < m_attachmentsCount; ++attachmentIdx)
1034 void* const ptr = static_cast<deUint8*>(m_bufferMemory[attachmentIdx]->getHostPtr()) + offset;
1035 accesses.push_back(tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptr));
1038 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
1039 tcu::TestLog& log (m_context.getTestContext().getLog());
1041 switch (channelClass)
1043 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1044 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1045 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1047 const int componentCount (tcu::getNumUsedChannels(format.order));
1052 switch (channelClass)
1054 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1055 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1060 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1068 DE_FATAL("Unknown channel class");
1071 for (deUint32 z = 0; z < m_layerCount; z++)
1072 for (deUint32 y = 0; y < m_height; y++)
1073 for (deUint32 x = 0; x < m_width; x++)
1075 // Color has to be black if no samples were covered, white if all samples were covered or same in every attachment
1076 const Vec4 firstColor (accesses[0].getPixel(x, y, z));
1077 const Vec4 refColor (m_sampleMask == 0x0u
1079 componentCount > 1 ? clearValue : 0.0f,
1080 componentCount > 2 ? clearValue : 0.0f,
1081 componentCount > 3 ? clearValue : 1.0f)
1082 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1084 componentCount > 1 ? renderValue : 0.0f,
1085 componentCount > 2 ? renderValue : 0.0f,
1086 componentCount > 3 ? renderValue : 1.0f)
1089 errorMask.getAccess().setPixel(okColor, x, y, z);
1091 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1093 const Vec4 color (accesses[attachmentNdx].getPixel(x, y, z));
1095 if (refColor != color)
1098 errorMask.getAccess().setPixel(errorColor, x, y, z);
1104 const Vec4 old = m_sum.getAccess().getPixel(x, y, z);
1105 m_sum.getAccess().setPixel(old + (tcu::isSRGB(format) ? tcu::sRGBToLinear(firstColor) : firstColor), x, y, z);
1107 const Vec4 oldSrgb = m_sumSrgb.getAccess().getPixel(x, y, z);
1108 m_sumSrgb.getAccess().setPixel(oldSrgb + firstColor, x, y, z);
1114 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1115 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1117 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1118 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1120 logImage("ErrorMask", errorMask.getAccess());
1122 if (m_sampleMask == 0x0u)
1124 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1125 m_resultCollector.fail("Empty sample mask didn't produce correct pixel values");
1127 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1129 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1130 m_resultCollector.fail("Full sample mask didn't produce correct pixel values");
1134 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve is inconsistent between attachments" << tcu::TestLog::EndMessage;
1135 m_resultCollector.fail("Resolve is inconsistent between attachments");
1141 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1143 const int componentCount (tcu::getNumUsedChannels(format.order));
1144 const UVec4 bitDepth (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1145 const UVec4 renderValue (tcu::select((UVec4(1u) << tcu::min(UVec4(8u), bitDepth)) - UVec4(1u),
1146 UVec4(0u, 0u, 0u, 1u),
1147 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1148 const UVec4 clearValue (tcu::select(UVec4(0u),
1149 UVec4(0u, 0u, 0u, 1u),
1150 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1151 bool unexpectedValues = false;
1152 bool inconsistentComponents = false;
1153 bool inconsistentAttachments = false;
1155 for (deUint32 z = 0; z < m_layerCount; z++)
1156 for (deUint32 y = 0; y < m_height; y++)
1157 for (deUint32 x = 0; x < m_width; x++)
1159 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1160 const UVec4 refColor (m_sampleMask == 0x0u
1162 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1164 : accesses[0].getPixelUint(x, y, z));
1167 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1168 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1170 // Each component must be resolved same way
1171 const BVec4 isRenderValue (refColor == renderValue);
1172 const BVec4 isClearValue (refColor == clearValue);
1173 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1174 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1176 unexpectedValues |= unexpectedValue;
1177 inconsistentComponents |= inconsistentComponent;
1179 if (unexpectedValue || inconsistentComponent)
1183 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1185 const UVec4 color (accesses[attachmentNdx].getPixelUint(x, y, z));
1187 if (refColor != color)
1190 inconsistentAttachments = true;
1195 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1198 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1200 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1201 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1203 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1204 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1206 logImage("ErrorMask", errorMask.getAccess());
1208 if (m_sampleMask == 0x0u)
1210 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1211 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1213 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1215 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1216 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1220 if (unexpectedValues)
1222 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1223 m_resultCollector.fail("Resolve produced unexpected values");
1226 if (inconsistentComponents)
1228 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1229 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1232 if (inconsistentAttachments)
1234 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1235 m_resultCollector.fail("Different attachments were resolved to different values.");
1242 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1244 const int componentCount (tcu::getNumUsedChannels(format.order));
1245 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
1246 const IVec4 renderValue (tcu::select((IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))) - IVec4(1),
1248 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1249 const IVec4 clearValue (tcu::select(-(IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))),
1251 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1252 bool unexpectedValues = false;
1253 bool inconsistentComponents = false;
1254 bool inconsistentAttachments = false;
1256 for (deUint32 z = 0; z < m_layerCount; z++)
1257 for (deUint32 y = 0; y < m_height; y++)
1258 for (deUint32 x = 0; x < m_width; x++)
1260 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1261 const IVec4 refColor (m_sampleMask == 0x0u
1263 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1265 : accesses[0].getPixelInt(x, y, z));
1268 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1269 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1271 // Each component must be resolved same way
1272 const BVec4 isRenderValue (refColor == renderValue);
1273 const BVec4 isClearValue (refColor == clearValue);
1274 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1275 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1277 unexpectedValues |= unexpectedValue;
1278 inconsistentComponents |= inconsistentComponent;
1280 if (unexpectedValue || inconsistentComponent)
1284 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1286 const IVec4 color (accesses[attachmentNdx].getPixelInt(x, y, z));
1288 if (refColor != color)
1291 inconsistentAttachments = true;
1296 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1299 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1301 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1302 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1304 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1305 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1307 logImage("ErrorMask", errorMask.getAccess());
1309 if (m_sampleMask == 0x0u)
1311 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1312 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1314 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1316 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1317 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1321 if (unexpectedValues)
1323 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1324 m_resultCollector.fail("Resolve produced unexpected values");
1327 if (inconsistentComponents)
1329 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1330 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1333 if (inconsistentAttachments)
1335 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1336 m_resultCollector.fail("Different attachments were resolved to different values.");
1344 DE_FATAL("Unknown channel class");
1348 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1350 if (m_sampleMask == 0u)
1352 const tcu::TextureFormat format (mapVkFormat(m_format));
1353 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1354 tcu::TestLog& log (m_context.getTestContext().getLog());
1356 switch (channelClass)
1358 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1359 log << TestLog::Message << "Clearing target to zero and rendering 255 pixels with every possible sample mask" << TestLog::EndMessage;
1362 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1363 log << TestLog::Message << "Clearing target to -128 and rendering 127 pixels with every possible sample mask" << TestLog::EndMessage;
1366 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1367 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1368 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1369 log << TestLog::Message << "Clearing target to black and rendering white pixels with every possible sample mask" << TestLog::EndMessage;
1373 DE_FATAL("Unknown channel class");
1377 submitSwitch(m_groupParams);
1380 if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1382 const tcu::TextureFormat format (mapVkFormat(m_format));
1383 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1384 const Vec4 threshold (getFormatThreshold());
1385 tcu::TestLog& log (m_context.getTestContext().getLog());
1387 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
1388 || channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
1389 || channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1391 const int componentCount (tcu::getNumUsedChannels(format.order));
1392 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1393 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1394 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
1396 Vec4 maxDiff (0.0f);
1397 Vec4 expectedAverage;
1399 switch (channelClass)
1401 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1403 expectedAverage = Vec4(0.5f, componentCount > 1 ? 0.5f : 0.0f, componentCount > 2 ? 0.5f : 0.0f, componentCount > 3 ? 0.5f : 1.0f);
1407 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1408 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1410 expectedAverage = Vec4(0.0f, 0.0f, 0.0f, componentCount > 3 ? 0.0f : 1.0f);
1415 DE_FATAL("Unknown channel class");
1418 for (deUint32 z = 0; z < m_layerCount; z++)
1419 for (deUint32 y = 0; y < m_height; y++)
1420 for (deUint32 x = 0; x < m_width; x++)
1422 const Vec4 sum (m_sum.getAccess().getPixel(x, y, z));
1423 const Vec4 average (sum / Vec4((float)(0x1u << m_sampleCount)));
1424 const Vec4 diff (tcu::abs(average - expectedAverage));
1426 m_sum.getAccess().setPixel(average, x, y, z);
1427 errorMask.getAccess().setPixel(okColor, x, y, z);
1431 if (!tcu::isSRGB(format))
1433 failThreshold = (diff[0] > threshold.x()
1434 || diff[1] > threshold.y()
1435 || diff[2] > threshold.z()
1436 || diff[3] > threshold.w());
1440 const Vec4 sumSrgb(m_sumSrgb.getAccess().getPixel(x, y, z));
1441 const Vec4 averageSrgb(sumSrgb / Vec4((float)(0x1u << m_sampleCount)));
1442 const Vec4 diffSrgb(tcu::abs(averageSrgb - expectedAverage));
1444 m_sumSrgb.getAccess().setPixel(averageSrgb, x, y, z);
1446 // Spec doesn't restrict implementation to downsample in linear color space. So, comparing both non linear and
1447 // linear diff's in case of srgb formats.
1448 failThreshold = ((diff[0] > threshold.x()
1449 || diff[1] > threshold.y()
1450 || diff[2] > threshold.z()
1451 || diff[3] > threshold.w()) &&
1452 (diffSrgb[0] > threshold.x()
1453 || diffSrgb[1] > threshold.y()
1454 || diffSrgb[2] > threshold.z()
1455 || diffSrgb[3] > threshold.w()));
1462 maxDiff = tcu::max(maxDiff, diff);
1463 errorMask.getAccess().setPixel(errorColor, x, y, z);
1467 log << TestLog::Image("Average resolved values in attachment 0", "Average resolved values in attachment 0", m_sum);
1471 std::stringstream message;
1473 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1475 message << "Average resolved values differ from expected average values by more than ";
1477 switch (componentCount)
1480 message << threshold.x();
1483 message << "vec2" << Vec2(threshold.x(), threshold.y());
1486 message << "vec3" << Vec3(threshold.x(), threshold.y(), threshold.z());
1489 message << "vec4" << threshold;
1492 message << ". Max diff " << maxDiff;
1493 log << TestLog::Message << message.str() << TestLog::EndMessage;
1495 m_resultCollector.fail("Average resolved values differ from expected average values");
1499 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1504 return tcu::TestStatus::incomplete();
1508 template<typename RenderPassTrait>
1509 Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPass (bool usedResolveAttachment)
1511 // make name for RenderPass1Trait or RenderPass2Trait shorter
1512 typedef RenderPassTrait RPT;
1513 typedef typename RPT::AttDesc AttDesc;
1514 typedef typename RPT::AttRef AttRef;
1515 typedef typename RPT::SubpassDesc SubpassDesc;
1516 typedef typename RPT::RenderPassCreateInfo RenderPassCreateInfo;
1518 const DeviceInterface& vkd = m_context.getDeviceInterface();
1519 VkDevice device = m_context.getDevice();
1520 std::vector<AttDesc> attachments;
1521 std::vector<AttRef> colorAttachmentRefs;
1522 std::vector<AttRef> resolveAttachmentRefs;
1524 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
1527 const AttDesc multisampleAttachment
1533 m_sampleCount, // samples
1534 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
1535 VK_ATTACHMENT_STORE_OP_DONT_CARE, // storeOp
1536 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
1537 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
1538 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
1539 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // finalLayout
1541 const AttRef attachmentRef
1545 (deUint32)attachments.size(), // attachment
1546 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
1549 colorAttachmentRefs.push_back(attachmentRef);
1550 attachments.push_back(multisampleAttachment);
1553 const AttDesc singlesampleAttachment
1559 VK_SAMPLE_COUNT_1_BIT, // samples
1560 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
1561 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
1562 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
1563 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
1564 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
1565 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // finalLayout
1567 const auto attachmentId = (usedResolveAttachment ? static_cast<deUint32>(attachments.size()) : VK_ATTACHMENT_UNUSED);
1568 const AttRef attachmentRef
1572 attachmentId, // attachment
1573 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
1576 resolveAttachmentRefs.push_back(attachmentRef);
1577 attachments.push_back(singlesampleAttachment);
1581 DE_ASSERT(colorAttachmentRefs.size() == resolveAttachmentRefs.size());
1582 DE_ASSERT(attachments.size() == colorAttachmentRefs.size() + resolveAttachmentRefs.size());
1584 const SubpassDesc subpass
1588 (VkSubpassDescriptionFlags)0, // flags
1589 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
1591 0u, // inputAttachmentCount
1592 DE_NULL, // pInputAttachments
1593 (deUint32)colorAttachmentRefs.size(), // colorAttachmentCount
1594 &colorAttachmentRefs[0], // pColorAttachments
1595 &resolveAttachmentRefs[0], // pResolveAttachments
1596 DE_NULL, // pDepthStencilAttachment
1597 0u, // preserveAttachmentCount
1598 DE_NULL // pPreserveAttachments
1600 const RenderPassCreateInfo renderPassCreator
1604 (VkRenderPassCreateFlags)0u, // flags
1605 (deUint32)attachments.size(), // attachmentCount
1606 &attachments[0], // pAttachments
1608 &subpass, // pSubpasses
1609 0u, // dependencyCount
1610 DE_NULL, // pDependencies
1611 0u, // correlatedViewMaskCount
1612 DE_NULL // pCorrelatedViewMasks
1615 return renderPassCreator.createRenderPass(vkd, device);
1618 Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPassSwitch (bool usedResolveAttachment)
1620 switch (m_groupParams->renderingType)
1622 case RENDERING_TYPE_RENDERPASS_LEGACY:
1623 return createRenderPass<RenderPass1Trait>(usedResolveAttachment);
1624 case RENDERING_TYPE_RENDERPASS2:
1625 return createRenderPass<RenderPass2Trait>(usedResolveAttachment);
1626 case RENDERING_TYPE_DYNAMIC_RENDERING:
1627 return Move<VkRenderPass>();
1629 TCU_THROW(InternalError, "Impossible");
1633 Move<VkRenderPass> MultisampleRenderPassTestInstance::createRenderPassCompatible (void)
1635 if (m_testCompatibility)
1637 // The compatible render pass is always created with a used resolve attachment.
1638 return createRenderPassSwitch(true);
1646 Move<VkPipelineLayout> MultisampleRenderPassTestInstance::createRenderPipelineLayout (void)
1648 const DeviceInterface& vkd = m_context.getDeviceInterface();
1649 VkDevice device = m_context.getDevice();
1651 const VkPushConstantRange pushConstant =
1653 VK_SHADER_STAGE_FRAGMENT_BIT,
1657 const VkPipelineLayoutCreateInfo createInfo =
1659 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1661 (vk::VkPipelineLayoutCreateFlags)0,
1670 return createPipelineLayout(vkd, device, &createInfo);
1673 Move<VkPipeline> MultisampleRenderPassTestInstance::createRenderPipeline (void)
1675 const DeviceInterface& vkd = m_context.getDeviceInterface();
1676 VkDevice device = m_context.getDevice();
1677 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
1678 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
1679 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
1680 const Move<VkShaderModule> geometryShaderModule (m_layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
1682 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1685 VK_BLEND_FACTOR_SRC_ALPHA,
1686 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1688 VK_BLEND_FACTOR_ONE,
1689 VK_BLEND_FACTOR_ONE,
1691 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1693 std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates(m_attachmentsCount, attachmentBlendState);
1694 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1696 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1698 (VkPipelineVertexInputStateCreateFlags)0u,
1706 const tcu::UVec2 renderArea (m_width, m_height);
1707 const std::vector<VkViewport> viewports (1, makeViewport(renderArea));
1708 const std::vector<VkRect2D> scissors (1, makeRect2D(renderArea));
1710 const VkPipelineMultisampleStateCreateInfo multisampleState =
1712 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1714 (VkPipelineMultisampleStateCreateFlags)0u,
1716 sampleCountBitFromSampleCount(m_sampleCount),
1723 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1725 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1727 (VkPipelineDepthStencilStateCreateFlags)0u,
1731 VK_COMPARE_OP_ALWAYS,
1736 VK_STENCIL_OP_INCREMENT_AND_WRAP,
1738 VK_COMPARE_OP_ALWAYS,
1741 0xFFu / (m_sampleCount + 1)
1745 VK_STENCIL_OP_INCREMENT_AND_WRAP,
1747 VK_COMPARE_OP_ALWAYS,
1750 0xFFu / (m_sampleCount + 1)
1756 const VkPipelineColorBlendStateCreateInfo blendState =
1758 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1760 (VkPipelineColorBlendStateCreateFlags)0u,
1764 deUint32(attachmentBlendStates.size()),
1765 &attachmentBlendStates[0],
1766 { 0.0f, 0.0f, 0.0f, 0.0f }
1769 void* pNext = DE_NULL;
1771 #ifndef CTS_USES_VULKANSC
1772 std::vector<VkFormat> attachmentFormats(m_attachmentsCount, m_format);
1773 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
1775 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1779 attachmentFormats.data(),
1780 VK_FORMAT_UNDEFINED,
1783 if (m_groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1784 pNext = &renderingCreateInfo;
1785 #endif // CTS_USES_VULKANSC
1787 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
1788 device, // const VkDevice device
1789 *m_renderPipelineLayout, // const VkPipelineLayout pipelineLayout
1790 *vertexShaderModule, // const VkShaderModule vertexShaderModule
1791 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1792 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1793 m_layerCount != 1 ? *geometryShaderModule : DE_NULL,// const VkShaderModule geometryShaderModule
1794 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1795 *m_renderPass, // const VkRenderPass renderPass
1796 viewports, // const std::vector<VkViewport>& viewports
1797 scissors, // const std::vector<VkRect2D>& scissors
1798 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1799 0u, // const deUint32 subpass
1800 0u, // const deUint32 patchControlPoints
1801 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1802 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1803 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1804 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
1805 &blendState, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
1806 DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
1807 pNext); // const void* pNext
1810 #ifndef CTS_USES_VULKANSC
1811 void MultisampleRenderPassTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
1813 const DeviceInterface& vkd = m_context.getDeviceInterface();
1814 std::vector<VkFormat> formats(m_attachmentsCount, m_format);
1816 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
1818 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
1819 DE_NULL, // const void* pNext;
1820 renderingFlags, // VkRenderingFlagsKHR flags;
1821 0u, // uint32_t viewMask;
1822 m_attachmentsCount, // uint32_t colorAttachmentCount;
1823 formats.data(), // const VkFormat* pColorAttachmentFormats;
1824 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
1825 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
1826 m_sampleCount, // VkSampleCountFlagBits rasterizationSamples;
1829 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
1830 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
1831 if (!m_groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1832 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1834 const VkCommandBufferBeginInfo commandBufBeginParams
1836 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1837 DE_NULL, // const void* pNext;
1838 usageFlags, // VkCommandBufferUsageFlags flags;
1839 &bufferInheritanceInfo
1842 VK_CHECK(vkd.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
1844 #endif // CTS_USES_VULKANSC
1846 class MaxAttachmenstsRenderPassTestInstance : public MultisampleRenderPassTestBase
1849 MaxAttachmenstsRenderPassTestInstance (Context& context, TestConfig config);
1850 ~MaxAttachmenstsRenderPassTestInstance (void);
1852 tcu::TestStatus iterate (void);
1856 template<typename RenderpassSubpass>
1858 void submitSwitch (RenderingType renderingType);
1861 Move<VkDescriptorSetLayout> createDescriptorSetLayout (void);
1862 Move<VkDescriptorPool> createDescriptorPool (void);
1863 Move<VkDescriptorSet> createDescriptorSet (void);
1865 template<typename RenderPassTrait>
1866 Move<VkRenderPass> createRenderPass (void);
1867 Move<VkRenderPass> createRenderPassSwitch (const RenderingType renderingType);
1868 Move<VkPipelineLayout> createRenderPipelineLayout (bool secondSubpass);
1869 Move<VkPipeline> createRenderPipeline (bool secondSubpass);
1873 const std::vector<VkImageSp> m_multisampleImages;
1874 const std::vector<AllocationSp> m_multisampleImageMemory;
1875 const std::vector<VkImageViewSp> m_multisampleImageViews;
1877 const std::vector<VkImageSp> m_singlesampleImages;
1878 const std::vector<AllocationSp> m_singlesampleImageMemory;
1879 const std::vector<VkImageViewSp> m_singlesampleImageViews;
1881 const Unique<VkDescriptorSetLayout> m_descriptorSetLayout;
1882 const Unique<VkDescriptorPool> m_descriptorPool;
1883 const Unique<VkDescriptorSet> m_descriptorSet;
1885 const Unique<VkRenderPass> m_renderPass;
1886 const Unique<VkFramebuffer> m_framebuffer;
1888 const Unique<VkPipelineLayout> m_pipelineLayoutPass0;
1889 const Unique<VkPipeline> m_pipelinePass0;
1890 const Unique<VkPipelineLayout> m_pipelineLayoutPass1;
1891 const Unique<VkPipeline> m_pipelinePass1;
1893 const std::vector<VkBufferSp> m_buffers;
1894 const std::vector<AllocationSp> m_bufferMemory;
1896 const Unique<VkCommandPool> m_commandPool;
1897 tcu::ResultCollector m_resultCollector;
1900 MaxAttachmenstsRenderPassTestInstance::MaxAttachmenstsRenderPassTestInstance (Context& context, TestConfig config)
1901 : MultisampleRenderPassTestBase(context, config)
1903 , m_multisampleImages (createImages(m_sampleCount, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT))
1904 , m_multisampleImageMemory (createImageMemory(m_multisampleImages))
1905 , m_multisampleImageViews (createImageViews(m_multisampleImages))
1907 , 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))
1908 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImages))
1909 , m_singlesampleImageViews (createImageViews(m_singlesampleImages))
1911 , m_descriptorSetLayout (createDescriptorSetLayout())
1912 , m_descriptorPool (createDescriptorPool())
1913 , m_descriptorSet (createDescriptorSet())
1915 , m_renderPass (createRenderPassSwitch(config.groupParams->renderingType))
1916 , m_framebuffer (createFramebuffer(m_multisampleImageViews, m_singlesampleImageViews, *m_renderPass))
1918 , m_pipelineLayoutPass0 (createRenderPipelineLayout(0))
1919 , m_pipelinePass0 (createRenderPipeline(0))
1920 , m_pipelineLayoutPass1 (createRenderPipelineLayout(1))
1921 , m_pipelinePass1 (createRenderPipeline(1))
1923 , m_buffers (createBuffers())
1924 , m_bufferMemory (createBufferMemory(m_buffers))
1926 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1930 MaxAttachmenstsRenderPassTestInstance::~MaxAttachmenstsRenderPassTestInstance (void)
1934 template<typename RenderpassSubpass>
1935 void MaxAttachmenstsRenderPassTestInstance::submit (void)
1937 const DeviceInterface& vkd (m_context.getDeviceInterface());
1938 const VkDevice device (m_context.getDevice());
1939 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1940 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1941 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
1943 beginCommandBuffer(vkd, *commandBuffer);
1945 // Memory barriers between previous copies and rendering
1947 std::vector<VkImageMemoryBarrier> barriers;
1949 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
1951 const VkImageMemoryBarrier barrier =
1953 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1956 VK_ACCESS_TRANSFER_READ_BIT,
1957 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1959 VK_IMAGE_LAYOUT_UNDEFINED,
1960 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1962 VK_QUEUE_FAMILY_IGNORED,
1963 VK_QUEUE_FAMILY_IGNORED,
1965 **m_singlesampleImages[dstNdx],
1967 VK_IMAGE_ASPECT_COLOR_BIT,
1975 barriers.push_back(barrier);
1978 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]);
1982 const VkRenderPassBeginInfo beginInfo =
1984 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1992 { m_width, m_height }
1998 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
2001 // Clear everything to black
2002 clearAttachments(*commandBuffer);
2004 // First subpass - render black samples
2006 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelinePass0);
2007 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
2010 // Second subpasss - merge attachments
2012 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
2013 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelinePass1);
2014 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayoutPass1, 0, 1u, &*m_descriptorSet, 0, NULL);
2015 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
2018 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
2020 // Memory barriers between rendering and copies
2022 std::vector<VkImageMemoryBarrier> barriers;
2024 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
2026 const VkImageMemoryBarrier barrier =
2028 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
2031 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
2032 VK_ACCESS_TRANSFER_READ_BIT,
2034 VK_IMAGE_LAYOUT_GENERAL,
2035 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
2037 VK_QUEUE_FAMILY_IGNORED,
2038 VK_QUEUE_FAMILY_IGNORED,
2040 **m_singlesampleImages[dstNdx],
2042 VK_IMAGE_ASPECT_COLOR_BIT,
2050 barriers.push_back(barrier);
2053 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]);
2056 // Copy image memory to buffers
2057 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
2059 const VkBufferImageCopy region =
2065 VK_IMAGE_ASPECT_COLOR_BIT,
2071 { m_width, m_height, 1u }
2074 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImages[dstNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffers[dstNdx], 1u, ®ion);
2077 // Memory barriers between copies and host access
2079 std::vector<VkBufferMemoryBarrier> barriers;
2081 for (size_t dstNdx = 0; dstNdx < m_buffers.size(); dstNdx++)
2083 const VkBufferMemoryBarrier barrier =
2085 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2088 VK_ACCESS_TRANSFER_WRITE_BIT,
2089 VK_ACCESS_HOST_READ_BIT,
2091 VK_QUEUE_FAMILY_IGNORED,
2092 VK_QUEUE_FAMILY_IGNORED,
2094 **m_buffers[dstNdx],
2099 barriers.push_back(barrier);
2102 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);
2105 endCommandBuffer(vkd, *commandBuffer);
2107 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
2109 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
2110 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
2113 void MaxAttachmenstsRenderPassTestInstance::submitSwitch (RenderingType renderingType)
2115 switch (renderingType)
2117 case RENDERING_TYPE_RENDERPASS_LEGACY:
2118 submit<RenderpassSubpass1>();
2120 case RENDERING_TYPE_RENDERPASS2:
2121 submit<RenderpassSubpass2>();
2124 TCU_THROW(InternalError, "Impossible");
2128 template <typename VecType>
2129 bool isValueAboveThreshold1 (const VecType& vale, const VecType& threshold)
2131 return (vale[0] > threshold[0]);
2134 template <typename VecType>
2135 bool isValueAboveThreshold2 (const VecType& vale, const VecType& threshold)
2137 return (vale[0] > threshold[0]) || (vale[1] > threshold[1]);
2140 template <typename VecType>
2141 bool isValueAboveThreshold3 (const VecType& vale, const VecType& threshold)
2143 return (vale[0] > threshold[0]) || (vale[1] > threshold[1]) || (vale[2] > threshold[2]);
2146 template <typename VecType>
2147 bool isValueAboveThreshold4 (const VecType& vale, const VecType& threshold)
2149 return (vale[0] > threshold[0]) || (vale[1] > threshold[1]) || (vale[2] > threshold[2]) || (vale[3] > threshold[3]);
2152 void MaxAttachmenstsRenderPassTestInstance::verify (void)
2154 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
2155 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
2156 const tcu::TextureFormat format (mapVkFormat(m_format));
2157 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
2158 const int componentCount (tcu::getNumUsedChannels(format.order));
2159 const int outputsCount = m_attachmentsCount / 2;
2161 DE_ASSERT((componentCount >= 0) && (componentCount < 5));
2163 std::vector<tcu::ConstPixelBufferAccess> accesses;
2164 for (int outputNdx = 0; outputNdx < outputsCount; ++outputNdx)
2166 void* const ptr = m_bufferMemory[outputNdx]->getHostPtr();
2167 accesses.push_back(tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptr));
2170 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, outputsCount);
2171 tcu::TestLog& log (m_context.getTestContext().getLog());
2174 switch (channelClass)
2176 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2177 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2178 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2180 const Vec4 refColor(0.0f, 0.3f, 0.6f, 0.75f);
2181 const Vec4 threshold(getFormatThreshold());
2183 typedef bool(*ValueAboveThresholdFn)(const Vec4&, const Vec4&);
2184 ValueAboveThresholdFn componentToFnMap[4] =
2186 isValueAboveThreshold1<Vec4>,
2187 isValueAboveThreshold2<Vec4>,
2188 isValueAboveThreshold3<Vec4>,
2189 isValueAboveThreshold4<Vec4>
2191 ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];
2192 bool isSRGBFormat = tcu::isSRGB(format);
2194 for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
2195 for (int y = 0; y < (int)m_height; y++)
2196 for (int x = 0; x < (int)m_width; x++)
2198 Vec4 color = accesses[outputNdx].getPixel(x, y);
2200 color = tcu::sRGBToLinear(color);
2202 const Vec4 diff(tcu::abs(color - refColor));
2204 if (isValueAboveThreshold(diff, threshold))
2207 errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
2211 errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
2216 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2218 const UVec4 refColor(0, 48, 144, 189);
2219 UVec4 threshold(1, 1, 1, 1);
2221 if (m_format == VK_FORMAT_A2B10G10R10_UINT_PACK32)
2224 typedef bool(*ValueAboveThresholdFn)(const UVec4&, const UVec4&);
2225 ValueAboveThresholdFn componentToFnMap[4] =
2227 isValueAboveThreshold1<UVec4>,
2228 isValueAboveThreshold2<UVec4>,
2229 isValueAboveThreshold3<UVec4>,
2230 isValueAboveThreshold4<UVec4>
2232 ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];
2234 for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
2235 for (int y = 0; y < (int)m_height; y++)
2236 for (int x = 0; x < (int)m_width; x++)
2238 const UVec4 color (accesses[outputNdx].getPixelUint(x, y));
2239 const UVec4 diff (std::abs(int(color.x()) - int(refColor.x())),
2240 std::abs(int(color.y()) - int(refColor.y())),
2241 std::abs(int(color.z()) - int(refColor.z())),
2242 std::abs(int(color.w()) - int(refColor.w())));
2244 if (isValueAboveThreshold(diff, threshold))
2247 errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
2251 errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
2256 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2258 const IVec4 refColor (0, 24, 75, 93);
2259 const IVec4 threshold (1, 1, 1, 1);
2261 typedef bool(*ValueAboveThresholdFn)(const IVec4&, const IVec4&);
2262 ValueAboveThresholdFn componentToFnMap[4] =
2264 isValueAboveThreshold1<IVec4>,
2265 isValueAboveThreshold2<IVec4>,
2266 isValueAboveThreshold3<IVec4>,
2267 isValueAboveThreshold4<IVec4>
2269 ValueAboveThresholdFn isValueAboveThreshold = componentToFnMap[componentCount - 1];
2271 for (int outputNdx = 0; outputNdx < outputsCount; outputNdx++)
2272 for (int y = 0; y < (int)m_height; y++)
2273 for (int x = 0; x < (int)m_width; x++)
2275 const IVec4 color (accesses[outputNdx].getPixelInt(x, y));
2276 const IVec4 diff (std::abs(color.x() - refColor.x()),
2277 std::abs(color.y() - refColor.y()),
2278 std::abs(color.z() - refColor.z()),
2279 std::abs(color.w() - refColor.w()));
2281 if (isValueAboveThreshold(diff, threshold))
2284 errorMask.getAccess().setPixel(errorColor, x, y, outputNdx);
2288 errorMask.getAccess().setPixel(okColor, x, y, outputNdx);
2294 DE_FATAL("Unknown channel class");
2299 const std::string sectionName ("MaxAttachmentsVerify");
2300 const tcu::ScopedLogSection section (log, sectionName, sectionName);
2302 logImage("ErrorMask", errorMask.getAccess());
2303 m_resultCollector.fail("Fail");
2307 tcu::TestStatus MaxAttachmenstsRenderPassTestInstance::iterate(void)
2309 submitSwitch(m_groupParams->renderingType);
2312 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
2315 Move<VkDescriptorSetLayout> MaxAttachmenstsRenderPassTestInstance::createDescriptorSetLayout()
2317 const VkDescriptorSetLayoutBinding bindingTemplate =
2320 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // descriptorType
2321 1u, // descriptorCount
2322 VK_SHADER_STAGE_FRAGMENT_BIT, // stageFlags
2323 DE_NULL // pImmutableSamplers
2326 std::vector<VkDescriptorSetLayoutBinding> bindings(m_attachmentsCount, bindingTemplate);
2327 for (deUint32 idx = 0; idx < m_attachmentsCount; ++idx)
2328 bindings[idx].binding = idx;
2330 const VkDescriptorSetLayoutCreateInfo createInfo =
2332 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
2335 m_attachmentsCount, // bindingCount
2336 &bindings[0] // pBindings
2339 return ::createDescriptorSetLayout(m_context.getDeviceInterface(), m_context.getDevice(), &createInfo);
2342 Move<VkDescriptorPool> MaxAttachmenstsRenderPassTestInstance::createDescriptorPool()
2344 const VkDescriptorPoolSize size =
2346 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // type
2347 m_attachmentsCount // descriptorCount
2350 const VkDescriptorPoolCreateInfo createInfo =
2352 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
2354 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // flags
2356 1u, // poolSizeCount
2360 return ::createDescriptorPool(m_context.getDeviceInterface(), m_context.getDevice(), &createInfo);
2363 Move<VkDescriptorSet> MaxAttachmenstsRenderPassTestInstance::createDescriptorSet()
2365 const VkDescriptorSetAllocateInfo allocateInfo =
2367 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
2369 *m_descriptorPool, // descriptorPool
2370 1u, // descriptorSetCount
2371 &*m_descriptorSetLayout // pSetLayouts
2374 const vk::DeviceInterface& vkd = m_context.getDeviceInterface();
2375 vk::VkDevice device = m_context.getDevice();
2376 Move<VkDescriptorSet> descriptorSet = allocateDescriptorSet(vkd, device, &allocateInfo);
2377 vector<VkDescriptorImageInfo> descriptorImageInfo (m_attachmentsCount);
2378 vector<VkWriteDescriptorSet> descriptorWrites (m_attachmentsCount);
2380 for (deUint32 idx = 0; idx < m_attachmentsCount; ++idx)
2382 const VkDescriptorImageInfo imageInfo =
2384 DE_NULL, // VkSampler sampler
2385 **m_singlesampleImageViews[idx], // VkImageView imageView
2386 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout imageLayout
2388 descriptorImageInfo[idx] = imageInfo;
2390 const VkWriteDescriptorSet write =
2392 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
2393 DE_NULL, // const void* pNext
2394 *descriptorSet, // VkDescriptorSet dstSet
2395 (deUint32)idx, // uint32_t dstBinding
2396 0u, // uint32_t dstArrayElement
2397 1u, // uint32_t descriptorCount
2398 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
2399 &descriptorImageInfo[idx], // const VkDescriptorImageInfo* pImageInfo
2400 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
2401 DE_NULL // const VkBufferView* pTexelBufferView
2404 descriptorWrites[idx] = write;
2407 vkd.updateDescriptorSets(device, (deUint32)descriptorWrites.size(), &descriptorWrites[0], 0u, DE_NULL);
2408 return descriptorSet;
2411 template<typename RenderPassTrait>
2412 Move<VkRenderPass> MaxAttachmenstsRenderPassTestInstance::createRenderPass(void)
2414 // make name for RenderPass1Trait or RenderPass2Trait shorter
2415 typedef RenderPassTrait RPT;
2417 typedef typename RPT::AttDesc AttDesc;
2418 typedef typename RPT::AttRef AttRef;
2419 typedef typename RPT::SubpassDep SubpassDep;
2420 typedef typename RPT::SubpassDesc SubpassDesc;
2421 typedef typename RPT::RenderPassCreateInfo RenderPassCreateInfo;
2423 const DeviceInterface& vkd = m_context.getDeviceInterface();
2424 VkDevice device = m_context.getDevice();
2425 std::vector<AttDesc> attachments;
2426 std::vector<AttRef> sp0colorAttachmentRefs;
2427 std::vector<AttRef> sp0resolveAttachmentRefs;
2428 std::vector<AttRef> sp1inAttachmentRefs;
2429 std::vector<AttRef> sp1colorAttachmentRefs;
2431 for (size_t attachmentNdx = 0; attachmentNdx < m_attachmentsCount; attachmentNdx++)
2433 // define first subpass outputs
2435 const AttDesc multisampleAttachment
2440 m_sampleCount, // samples
2441 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
2442 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
2443 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
2444 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
2445 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2446 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // finalLayout
2448 const AttRef attachmentRef
2451 (deUint32)attachments.size(), // attachment
2452 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout
2455 sp0colorAttachmentRefs.push_back(attachmentRef);
2456 attachments.push_back(multisampleAttachment);
2458 // define first subpass resolve attachments
2460 const AttDesc singlesampleAttachment
2465 VK_SAMPLE_COUNT_1_BIT, // samples
2466 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // loadOp
2467 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
2468 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
2469 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
2470 VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2471 VK_IMAGE_LAYOUT_GENERAL // finalLayout
2473 const AttRef attachmentRef
2476 (deUint32)attachments.size(), // attachment
2477 VK_IMAGE_LAYOUT_GENERAL, // layout
2480 sp0resolveAttachmentRefs.push_back(attachmentRef);
2481 attachments.push_back(singlesampleAttachment);
2483 // define second subpass inputs
2485 const AttRef attachmentRef
2488 (deUint32)attachments.size() - 1, // attachment
2489 VK_IMAGE_LAYOUT_GENERAL, // layout
2490 VK_IMAGE_ASPECT_COLOR_BIT // aspectMask
2492 sp1inAttachmentRefs.push_back(attachmentRef);
2494 // define second subpass outputs - it merges pairs of
2495 // results that were produced by the first subpass
2496 if (attachmentNdx < (m_attachmentsCount / 2))
2498 const AttRef colorAttachmentRef
2501 (deUint32)attachments.size() - 1, // attachment
2502 VK_IMAGE_LAYOUT_GENERAL, // layout
2505 sp1colorAttachmentRefs.push_back(colorAttachmentRef);
2509 DE_ASSERT(sp0colorAttachmentRefs.size() == sp0resolveAttachmentRefs.size());
2510 DE_ASSERT(attachments.size() == sp0colorAttachmentRefs.size() + sp0resolveAttachmentRefs.size());
2513 const SubpassDesc subpass0
2517 (VkSubpassDescriptionFlags)0, // flags
2518 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
2520 0u, // inputAttachmentCount
2521 DE_NULL, // pInputAttachments
2522 (deUint32)sp0colorAttachmentRefs.size(), // colorAttachmentCount
2523 &sp0colorAttachmentRefs[0], // pColorAttachments
2524 &sp0resolveAttachmentRefs[0], // pResolveAttachments
2525 DE_NULL, // pDepthStencilAttachment
2526 0u, // preserveAttachmentCount
2527 DE_NULL // pPreserveAttachments
2529 const SubpassDesc subpass1
2533 (VkSubpassDescriptionFlags)0, // flags
2534 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
2536 (deUint32)sp1inAttachmentRefs.size(), // inputAttachmentCount
2537 &sp1inAttachmentRefs[0], // pInputAttachments
2538 (deUint32)sp1colorAttachmentRefs.size(), // colorAttachmentCount
2539 &sp1colorAttachmentRefs[0], // pColorAttachments
2540 DE_NULL, // pResolveAttachments
2541 DE_NULL, // pDepthStencilAttachment
2542 0u, // preserveAttachmentCount
2543 DE_NULL // pPreserveAttachments
2545 SubpassDesc subpasses[] =
2550 const SubpassDep subpassDependency
2555 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // srcStageMask
2556 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // dstStageMask
2557 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
2558 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // dstAccessMask
2559 0u, // dependencyFlags
2562 const RenderPassCreateInfo renderPassCreator
2566 (VkRenderPassCreateFlags)0u, // flags
2567 (deUint32)attachments.size(), // attachmentCount
2568 &attachments[0], // pAttachments
2570 subpasses, // pSubpasses
2571 1u, // dependencyCount
2572 &subpassDependency, // pDependencies
2573 0u, // correlatedViewMaskCount
2574 DE_NULL // pCorrelatedViewMasks
2577 return renderPassCreator.createRenderPass(vkd, device);
2581 Move<VkRenderPass> MaxAttachmenstsRenderPassTestInstance::createRenderPassSwitch(const RenderingType renderingType)
2583 switch (renderingType)
2585 case RENDERING_TYPE_RENDERPASS_LEGACY:
2586 return createRenderPass<RenderPass1Trait>();
2587 case RENDERING_TYPE_RENDERPASS2:
2588 return createRenderPass<RenderPass2Trait>();
2590 TCU_THROW(InternalError, "Impossible");
2594 Move<VkPipelineLayout> MaxAttachmenstsRenderPassTestInstance::createRenderPipelineLayout(bool secondSubpass)
2596 const DeviceInterface& vkd = m_context.getDeviceInterface();
2597 VkDevice device = m_context.getDevice();
2599 const VkPipelineLayoutCreateInfo createInfo =
2601 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2603 (vk::VkPipelineLayoutCreateFlags)0,
2605 secondSubpass ? 1u : 0u,
2606 secondSubpass ? &*m_descriptorSetLayout : DE_NULL,
2612 return createPipelineLayout(vkd, device, &createInfo);
2615 Move<VkPipeline> MaxAttachmenstsRenderPassTestInstance::createRenderPipeline(bool secondSubpass)
2617 const DeviceInterface& vkd = m_context.getDeviceInterface();
2618 VkDevice device = m_context.getDevice();
2619 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
2620 VkSampleCountFlagBits sampleCount = sampleCountBitFromSampleCount(m_sampleCount);
2621 deUint32 blendStatesCount = m_attachmentsCount;
2622 std::string fragShaderNameBase = "quad-frag-sp0-";
2626 sampleCount = VK_SAMPLE_COUNT_1_BIT;
2627 blendStatesCount /= 2;
2628 fragShaderNameBase = "quad-frag-sp1-";
2631 std::string fragShaderName = fragShaderNameBase + de::toString(m_attachmentsCount);
2632 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
2633 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get(fragShaderName), 0u));
2634 const Move<VkShaderModule> geometryShaderModule (m_layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
2637 const VkPipelineColorBlendAttachmentState attachmentBlendState =
2640 VK_BLEND_FACTOR_SRC_ALPHA,
2641 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
2643 VK_BLEND_FACTOR_ONE,
2644 VK_BLEND_FACTOR_ONE,
2646 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
2648 std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates(blendStatesCount, attachmentBlendState);
2649 const VkPipelineVertexInputStateCreateInfo vertexInputState =
2651 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
2653 (VkPipelineVertexInputStateCreateFlags)0u,
2661 const tcu::UVec2 renderArea (m_width, m_height);
2662 const std::vector<VkViewport> viewports (1, makeViewport(renderArea));
2663 const std::vector<VkRect2D> scissors (1, makeRect2D(renderArea));
2665 const VkPipelineMultisampleStateCreateInfo multisampleState =
2667 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
2669 (VkPipelineMultisampleStateCreateFlags)0u,
2678 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
2680 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
2682 (VkPipelineDepthStencilStateCreateFlags)0u,
2686 VK_COMPARE_OP_ALWAYS,
2691 VK_STENCIL_OP_INCREMENT_AND_WRAP,
2693 VK_COMPARE_OP_ALWAYS,
2696 0xFFu / (m_sampleCount + 1)
2700 VK_STENCIL_OP_INCREMENT_AND_WRAP,
2702 VK_COMPARE_OP_ALWAYS,
2705 0xFFu / (m_sampleCount + 1)
2711 const VkPipelineColorBlendStateCreateInfo blendState =
2713 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
2715 (VkPipelineColorBlendStateCreateFlags)0u,
2719 deUint32(attachmentBlendStates.size()),
2720 &attachmentBlendStates[0],
2721 { 0.0f, 0.0f, 0.0f, 0.0f }
2724 return makeGraphicsPipeline(vkd, // vk
2726 secondSubpass ? *m_pipelineLayoutPass1 : *m_pipelineLayoutPass0, // pipelineLayout
2727 *vertexShaderModule, // vertexShaderModule
2728 DE_NULL, // tessellationControlShaderModule
2729 DE_NULL, // tessellationEvalShaderModule
2730 m_layerCount != 1 ? *geometryShaderModule : DE_NULL, // geometryShaderModule
2731 *fragmentShaderModule, // fragmentShaderModule
2732 *m_renderPass, // renderPass
2733 viewports, // viewports
2734 scissors, // scissors
2735 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology
2736 secondSubpass, // subpass
2737 0u, // patchControlPoints
2738 &vertexInputState, // vertexInputStateCreateInfo
2739 DE_NULL, // rasterizationStateCreateInfo
2740 &multisampleState, // multisampleStateCreateInfo
2741 &depthStencilState, // depthStencilStateCreateInfo
2742 &blendState); // colorBlendStateCreateInfo
2745 class MultisampleRenderPassResolveLevelTestInstance : public MultisampleRenderPassTestInstance
2748 MultisampleRenderPassResolveLevelTestInstance (Context& context, TestConfig2 config);
2749 ~MultisampleRenderPassResolveLevelTestInstance (void) = default;
2752 MultisampleRenderPassResolveLevelTestInstance::MultisampleRenderPassResolveLevelTestInstance (Context& context, TestConfig2 config)
2753 : MultisampleRenderPassTestInstance(context, config, config.resolveLevel)
2759 void init(vk::SourceCollections& dst, TestConfig config) const
2761 const tcu::TextureFormat format (mapVkFormat(config.format));
2762 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
2764 dst.glslSources.add("quad-vert") << glu::VertexSource(
2766 "out gl_PerVertex {\n"
2767 "\tvec4 gl_Position;\n"
2770 "void main (void) {\n"
2771 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
2772 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
2775 if (config.layerCount > 1)
2777 std::ostringstream src;
2779 src << "#version 450\n"
2782 << "layout(triangles) in;\n"
2783 << "layout(triangle_strip, max_vertices = " << 3 * 2 * config.layerCount << ") out;\n"
2785 << "in gl_PerVertex {\n"
2786 << " vec4 gl_Position;\n"
2789 << "out gl_PerVertex {\n"
2790 << " vec4 gl_Position;\n"
2793 << "void main (void) {\n"
2794 << " for (int layerNdx = 0; layerNdx < " << config.layerCount << "; ++layerNdx) {\n"
2795 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
2796 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
2797 << " gl_Layer = layerNdx;\n"
2798 << " EmitVertex();\n"
2800 << " EndPrimitive();\n"
2804 dst.glslSources.add("geom") << glu::GeometrySource(src.str());
2807 const tcu::StringTemplate genericLayoutTemplate("layout(location = ${INDEX}) out ${TYPE_PREFIX}vec4 o_color${INDEX};\n");
2808 const tcu::StringTemplate genericBodyTemplate("\to_color${INDEX} = ${TYPE_PREFIX}vec4(${COLOR_VAL});\n");
2810 if (config.testType == RESOLVE || config.testType == COMPATIBILITY)
2812 const tcu::StringTemplate fragTemplate("#version 450\n"
2813 "layout(push_constant) uniform PushConstant {\n"
2814 "\thighp uint sampleMask;\n"
2815 "} pushConstants;\n"
2817 "void main (void)\n"
2822 std::map<std::string, std::string> parameters;
2823 switch (channelClass)
2825 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2826 parameters["TYPE_PREFIX"] = "u";
2827 parameters["COLOR_VAL"] = "255";
2830 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2831 parameters["TYPE_PREFIX"] = "i";
2832 parameters["COLOR_VAL"] = "127";
2835 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2836 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2837 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2838 parameters["TYPE_PREFIX"] = "";
2839 parameters["COLOR_VAL"] = "1.0";
2843 DE_FATAL("Unknown channel class");
2846 std::string layoutDefinitions = "";
2847 std::string shaderBody = "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n";
2849 for (deUint32 attIdx = 0; attIdx < config.attachmentCount; ++attIdx)
2851 parameters["INDEX"] = de::toString(attIdx);
2852 layoutDefinitions += genericLayoutTemplate.specialize(parameters);
2853 shaderBody += genericBodyTemplate.specialize(parameters);
2856 parameters["LAYOUT"] = layoutDefinitions;
2857 parameters["BODY"] = shaderBody;
2858 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragTemplate.specialize(parameters));
2860 else // MAX_ATTACMENTS
2862 const tcu::StringTemplate fragTemplate("#version 450\n"
2864 "void main (void)\n"
2869 std::map<std::string, std::string> parameters;
2870 switch (channelClass)
2872 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2873 parameters["TYPE_PREFIX"] = "u";
2874 parameters["COLOR_VAL"] = "0, 64, 192, 252";
2877 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2878 parameters["TYPE_PREFIX"] = "i";
2879 parameters["COLOR_VAL"] = "0, 32, 100, 124";
2882 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2883 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2884 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2885 parameters["TYPE_PREFIX"] = "";
2886 parameters["COLOR_VAL"] = "0.0, 0.4, 0.8, 1.0";
2890 DE_FATAL("Unknown channel class");
2893 // parts of fragment shader for second subpass - Vulkan introduced a new uniform type and syntax to glsl for input attachments
2894 const tcu::StringTemplate subpassLayoutTemplate("layout (input_attachment_index = ${INDEX}, set = 0, binding = ${INDEX}) uniform ${TYPE_PREFIX}subpassInput i_color${INDEX};\n");
2895 const tcu::StringTemplate subpassFBodyTemplate("\to_color${INDEX} = subpassLoad(i_color${INDEX})*0.5 + subpassLoad(i_color${MIX_INDEX})*0.25;\n");
2896 const tcu::StringTemplate subpassIBodyTemplate("\to_color${INDEX} = subpassLoad(i_color${INDEX}) / 2 + subpassLoad(i_color${MIX_INDEX}) / 4;\n");
2898 bool selectIBody = isIntFormat(config.format) || isUintFormat(config.format);
2899 const tcu::StringTemplate& subpassBodyTemplate = selectIBody ? subpassIBodyTemplate : subpassFBodyTemplate;
2901 std::string sp0layoutDefinitions = "";
2902 std::string sp0shaderBody = "";
2903 std::string sp1inLayoutDefinitions = "";
2904 std::string sp1outLayoutDefinitions = "";
2905 std::string sp1shaderBody = "";
2907 deUint32 halfAttachments = config.attachmentCount / 2;
2908 for (deUint32 attIdx = 0; attIdx < config.attachmentCount; ++attIdx)
2910 parameters["INDEX"] = de::toString(attIdx);
2912 sp0layoutDefinitions += genericLayoutTemplate.specialize(parameters);
2913 sp0shaderBody += genericBodyTemplate.specialize(parameters);
2915 sp1inLayoutDefinitions += subpassLayoutTemplate.specialize(parameters);
2916 if (attIdx < halfAttachments)
2918 // we are combining pairs of input attachments to produce half the number of outputs
2919 parameters["MIX_INDEX"] = de::toString(halfAttachments + attIdx);
2920 sp1outLayoutDefinitions += genericLayoutTemplate.specialize(parameters);
2921 sp1shaderBody += subpassBodyTemplate.specialize(parameters);
2925 // construct fragment shaders for subpass1 and subpass2; note that there
2926 // is different shader definition depending on number of attachments
2927 std::string nameBase = "quad-frag-sp";
2928 std::string namePostfix = de::toString(config.attachmentCount);
2929 parameters["LAYOUT"] = sp0layoutDefinitions;
2930 parameters["BODY"] = sp0shaderBody;
2931 dst.glslSources.add(nameBase + "0-" + namePostfix) << glu::FragmentSource(fragTemplate.specialize(parameters));
2932 parameters["LAYOUT"] = sp1inLayoutDefinitions + sp1outLayoutDefinitions;
2933 parameters["BODY"] = sp1shaderBody;
2934 dst.glslSources.add(nameBase + "1-" + namePostfix) << glu::FragmentSource(fragTemplate.specialize(parameters));
2939 template<class TestConfigType>
2940 void checkSupport(Context& context, TestConfigType config)
2942 if (config.layerCount > 1)
2943 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
2945 if (config.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
2946 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
2948 if (config.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
2949 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
2951 #ifndef CTS_USES_VULKANSC
2952 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
2953 !context.getPortabilitySubsetFeatures().multisampleArrayImage &&
2954 (config.sampleCount != VK_SAMPLE_COUNT_1_BIT) && (config.layerCount != 1))
2956 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support image array with multiple samples per texel");
2958 #endif // CTS_USES_VULKANSC
2960 const InstanceInterface& vki = context.getInstanceInterface();
2961 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
2962 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
2964 if (config.attachmentCount > properties.limits.maxColorAttachments)
2965 TCU_THROW(NotSupportedError, "Required number of color attachments not supported.");
2968 std::string formatToName (VkFormat format)
2970 const std::string formatStr = de::toString(format);
2971 const std::string prefix = "VK_FORMAT_";
2973 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2975 return de::toLower(formatStr.substr(prefix.length()));
2978 void initTests (tcu::TestCaseGroup* group, const SharedGroupParams groupParams)
2980 static const VkFormat formats[] =
2982 VK_FORMAT_R5G6B5_UNORM_PACK16,
2987 VK_FORMAT_R8G8_UNORM,
2988 VK_FORMAT_R8G8_SNORM,
2989 VK_FORMAT_R8G8_UINT,
2990 VK_FORMAT_R8G8_SINT,
2991 VK_FORMAT_R8G8B8A8_UNORM,
2992 VK_FORMAT_R8G8B8A8_SNORM,
2993 VK_FORMAT_R8G8B8A8_UINT,
2994 VK_FORMAT_R8G8B8A8_SINT,
2995 VK_FORMAT_R8G8B8A8_SRGB,
2996 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2997 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2998 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2999 VK_FORMAT_A8B8G8R8_SINT_PACK32,
3000 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
3001 VK_FORMAT_B8G8R8A8_UNORM,
3002 VK_FORMAT_B8G8R8A8_SRGB,
3003 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
3004 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
3005 VK_FORMAT_A2B10G10R10_UINT_PACK32,
3006 VK_FORMAT_R16_UNORM,
3007 VK_FORMAT_R16_SNORM,
3010 VK_FORMAT_R16_SFLOAT,
3011 VK_FORMAT_R16G16_UNORM,
3012 VK_FORMAT_R16G16_SNORM,
3013 VK_FORMAT_R16G16_UINT,
3014 VK_FORMAT_R16G16_SINT,
3015 VK_FORMAT_R16G16_SFLOAT,
3016 VK_FORMAT_R16G16B16A16_UNORM,
3017 VK_FORMAT_R16G16B16A16_SNORM,
3018 VK_FORMAT_R16G16B16A16_UINT,
3019 VK_FORMAT_R16G16B16A16_SINT,
3020 VK_FORMAT_R16G16B16A16_SFLOAT,
3023 VK_FORMAT_R32_SFLOAT,
3024 VK_FORMAT_R32G32_UINT,
3025 VK_FORMAT_R32G32_SINT,
3026 VK_FORMAT_R32G32_SFLOAT,
3027 VK_FORMAT_R32G32B32A32_UINT,
3028 VK_FORMAT_R32G32B32A32_SINT,
3029 VK_FORMAT_R32G32B32A32_SFLOAT,
3030 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
3032 const deUint32 sampleCounts[] =
3036 const deUint32 layerCounts[] =
3040 const deUint32 resolveLevels[] =
3044 tcu::TestContext& testCtx (group->getTestContext());
3046 for (size_t layerCountNdx = 0; layerCountNdx < DE_LENGTH_OF_ARRAY(layerCounts); layerCountNdx++)
3048 const deUint32 layerCount (layerCounts[layerCountNdx]);
3049 const std::string layerGroupName ("layers_" + de::toString(layerCount));
3050 de::MovePtr<tcu::TestCaseGroup> layerGroup (new tcu::TestCaseGroup(testCtx, layerGroupName.c_str(), layerGroupName.c_str()));
3052 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
3054 const VkFormat format (formats[formatNdx]);
3055 const std::string formatName (formatToName(format));
3056 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
3058 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
3060 const deUint32 sampleCount(sampleCounts[sampleCountNdx]);
3062 // Skip this test as it is rather slow
3063 if (layerCount == 6 && sampleCount == 8)
3066 // Reduce number of tests for dynamic rendering cases where secondary command buffer is used
3067 if (groupParams->useSecondaryCmdBuffer && ( (sampleCount > 2u) || (layerCount > 3u) ))
3070 std::string testName ("samples_" + de::toString(sampleCount));
3071 const TestConfig testConfig
3083 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));
3085 for (deUint32 resolveLevel : resolveLevels)
3087 const TestConfig2 testConfig2(testConfig, resolveLevel);
3088 std::string resolveLevelTestNameStr(testName + "_resolve_level_" + de::toString(resolveLevel));
3089 const char* resolveLevelTestName = resolveLevelTestNameStr.c_str();
3091 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassResolveLevelTestInstance, TestConfig2, FunctionSupport1<TestConfig2>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, resolveLevelTestName, resolveLevelTestName, testConfig2, typename FunctionSupport1<TestConfig2>::Args(checkSupport, testConfig2)));
3093 // Reduce number of tests for dynamic rendering cases where secondary command buffer is used
3094 if (groupParams->useSecondaryCmdBuffer)
3098 // MaxAttachmenstsRenderPassTest is ment to test extreme cases where applications might consume all available on-chip
3099 // memory. This is achieved by using maxColorAttachments attachments and two subpasses, but during test creation we
3100 // dont know what is the maximal number of attachments (spirv tools are not available on all platforms) so we cant
3101 // construct shaders during test execution. To be able to test this we need to execute tests for all available
3102 // numbers of attachments despite the fact that we are only interested in the maximal number; test construction code
3103 // assumes that the number of attachments is power of two
3104 if ((groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING) && (layerCount == 1))
3106 for (deUint32 power = 2; power < 5; ++power)
3108 deUint32 attachmentCount = 1 << power;
3109 std::string maxAttName = "max_attachments_" + de::toString(attachmentCount) + "_" + testName;
3111 TestConfig maxAttachmentsTestConfig = testConfig;
3112 maxAttachmentsTestConfig.testType = MAX_ATTACHMENTS;
3113 maxAttachmentsTestConfig.attachmentCount = attachmentCount;
3115 formatGroup->addChild(new InstanceFactory1WithSupport<MaxAttachmenstsRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, maxAttName.c_str(), maxAttName.c_str(), maxAttachmentsTestConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, maxAttachmentsTestConfig)));
3119 std::string compatibilityTestName = "compatibility_" + testName;
3121 TestConfig compatibilityTestConfig = testConfig;
3122 compatibilityTestConfig.testType = COMPATIBILITY;
3123 compatibilityTestConfig.attachmentCount = 1;
3125 formatGroup->addChild(new InstanceFactory1WithSupport<MultisampleRenderPassTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, compatibilityTestConfig)));
3130 if (layerCount == 1)
3131 group->addChild(formatGroup.release());
3133 layerGroup->addChild(formatGroup.release());
3136 if (layerCount != 1)
3137 group->addChild(layerGroup.release());
3143 tcu::TestCaseGroup* createRenderPassMultisampleResolveTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
3145 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, groupParams);
3148 tcu::TestCaseGroup* createRenderPass2MultisampleResolveTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
3150 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, groupParams);
3153 tcu::TestCaseGroup* createDynamicRenderingMultisampleResolveTests (tcu::TestContext& testCtx, const renderpass::SharedGroupParams groupParams)
3155 return createTestGroup(testCtx, "multisample_resolve", "Multisample dynamic rendering resolve tests", initTests, groupParams);