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"
52 #include "deUniquePtr.hpp"
53 #include "deSharedPtr.hpp"
70 using tcu::ConstPixelBufferAccess;
71 using tcu::PixelBufferAccess;
79 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
80 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
81 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
82 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
89 using namespace renderpass;
93 MAX_COLOR_ATTACHMENT_COUNT = 4u
97 de::SharedPtr<T> safeSharedPtr (T* ptr)
101 return de::SharedPtr<T>(ptr);
110 tcu::Vec4 getFormatThreshold (VkFormat format)
112 const tcu::TextureFormat tcuFormat (mapVkFormat(format));
113 const deUint32 componentCount (tcu::getNumUsedChannels(tcuFormat.order));
115 if (isSnormFormat(format))
117 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffSnorm(format, 0) : 0.0f,
118 (componentCount >= 2) ? 1.5f * getRepresentableDiffSnorm(format, 1) : 0.0f,
119 (componentCount >= 3) ? 1.5f * getRepresentableDiffSnorm(format, 2) : 0.0f,
120 (componentCount == 4) ? 1.5f * getRepresentableDiffSnorm(format, 3) : 0.0f);
122 else if (isUnormFormat(format))
124 return Vec4((componentCount >= 1) ? 1.5f * getRepresentableDiffUnorm(format, 0) : 0.0f,
125 (componentCount >= 2) ? 1.5f * getRepresentableDiffUnorm(format, 1) : 0.0f,
126 (componentCount >= 3) ? 1.5f * getRepresentableDiffUnorm(format, 2) : 0.0f,
127 (componentCount == 4) ? 1.5f * getRepresentableDiffUnorm(format, 3) : 0.0f);
129 else if (isFloatFormat(format))
130 return Vec4(0.00001f);
135 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
137 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
140 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
142 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
145 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
147 Allocator& allocator,
150 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
151 bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
155 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
157 Allocator& allocator,
160 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
161 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
165 Move<VkImage> createImage (const DeviceInterface& vk,
167 VkImageCreateFlags flags,
168 VkImageType imageType,
172 deUint32 arrayLayers,
173 VkSampleCountFlagBits samples,
174 VkImageTiling tiling,
175 VkImageUsageFlags usage,
176 VkSharingMode sharingMode,
177 deUint32 queueFamilyCount,
178 const deUint32* pQueueFamilyIndices,
179 VkImageLayout initialLayout)
181 const VkImageCreateInfo pCreateInfo =
183 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
199 return createImage(vk, device, &pCreateInfo);
202 Move<VkImageView> createImageView (const DeviceInterface& vk,
204 VkImageViewCreateFlags flags,
206 VkImageViewType viewType,
208 VkComponentMapping components,
209 VkImageSubresourceRange subresourceRange)
211 const VkImageViewCreateInfo pCreateInfo =
213 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
222 return createImageView(vk, device, &pCreateInfo);
225 Move<VkImage> createImage (const InstanceInterface& vki,
226 VkPhysicalDevice physicalDevice,
227 const DeviceInterface& vkd,
230 VkSampleCountFlagBits sampleCountBit,
231 VkImageUsageFlags usage,
238 const tcu::TextureFormat format (mapVkFormat(vkFormat));
239 const VkImageType imageType (VK_IMAGE_TYPE_2D);
240 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
241 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
242 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
243 const VkExtent3D imageExtent =
250 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
251 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
252 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
254 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
255 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
256 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
258 if (imageFormatProperties.maxExtent.width < imageExtent.width
259 || imageFormatProperties.maxExtent.height < imageExtent.height
260 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
261 || imageFormatProperties.maxArrayLayers < layerCount)
263 TCU_THROW(NotSupportedError, "Image type not supported");
266 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, layerCount, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
268 catch (const vk::Error& error)
270 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
271 TCU_THROW(NotSupportedError, "Image format not supported");
277 Move<VkImageView> createImageView (const DeviceInterface& vkd,
281 VkImageAspectFlags aspect,
284 const VkImageSubresourceRange range =
293 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, format, makeComponentMappingRGBA(), range);
296 VkDeviceSize getPixelSize (VkFormat vkFormat)
298 const tcu::TextureFormat format (mapVkFormat(vkFormat));
300 return format.getPixelSize();
303 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
310 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
311 const VkDeviceSize pixelSize (getPixelSize(format));
312 const VkBufferCreateInfo createInfo =
314 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
318 width * height * layerCount * pixelSize,
321 VK_SHARING_MODE_EXCLUSIVE,
325 return createBuffer(vkd, device, &createInfo);
328 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
332 case 1: return VK_SAMPLE_COUNT_1_BIT;
333 case 2: return VK_SAMPLE_COUNT_2_BIT;
334 case 4: return VK_SAMPLE_COUNT_4_BIT;
335 case 8: return VK_SAMPLE_COUNT_8_BIT;
336 case 16: return VK_SAMPLE_COUNT_16_BIT;
337 case 32: return VK_SAMPLE_COUNT_32_BIT;
338 case 64: return VK_SAMPLE_COUNT_64_BIT;
341 DE_FATAL("Invalid sample count");
342 return (VkSampleCountFlagBits)0x0;
346 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface& vki,
347 VkPhysicalDevice physicalDevice,
348 const DeviceInterface& vkd,
351 deUint32 sampleCount,
356 std::vector<VkImageSp> images (MAX_COLOR_ATTACHMENT_COUNT);
358 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
359 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height, layerCount)));
364 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface& vki,
365 VkPhysicalDevice physicalDevice,
366 const DeviceInterface& vkd,
373 std::vector<VkImageSp> images (MAX_COLOR_ATTACHMENT_COUNT);
375 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
376 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, width, height, layerCount)));
381 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface& vkd,
383 Allocator& allocator,
384 const std::vector<VkImageSp> images)
386 std::vector<de::SharedPtr<Allocation> > memory (images.size());
388 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
389 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
394 std::vector<VkImageViewSp> createImageViews (const DeviceInterface& vkd,
396 const std::vector<VkImageSp>& images,
398 VkImageAspectFlagBits aspect,
401 std::vector<VkImageViewSp> views (images.size());
403 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
404 views[imageNdx] = safeSharedPtr(new Unique<VkImageView>(createImageView(vkd, device, **images[imageNdx], format, aspect, layerCount)));
409 std::vector<VkBufferSp> createBuffers (const DeviceInterface& vkd,
416 std::vector<VkBufferSp> buffers (MAX_COLOR_ATTACHMENT_COUNT);
418 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
419 buffers[bufferNdx] = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vkd, device, format, width, height, layerCount)));
424 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface& vkd,
426 Allocator& allocator,
427 const std::vector<VkBufferSp> buffers)
429 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
431 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
432 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
437 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
438 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
441 deUint32 sampleCount)
443 const VkSampleCountFlagBits samples (sampleCountBitFromSampleCount(sampleCount));
444 std::vector<AttachmentDesc> attachments;
445 std::vector<AttachmentRef> colorAttachmentRefs;
446 std::vector<AttachmentRef> resolveAttachmentRefs;
448 for (size_t attachmentNdx = 0; attachmentNdx < 4; attachmentNdx++)
451 const AttachmentDesc multisampleAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
453 // || VkStructureType sType;
454 DE_NULL, // || const void* pNext;
455 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
456 format, // VkFormat format; || VkFormat format;
457 samples, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
458 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
459 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
460 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
461 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
462 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
463 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
465 const AttachmentRef attachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
467 // || VkStructureType sType;
468 DE_NULL, // || const void* pNext;
469 (deUint32)attachments.size(), // deUint32 attachment; || deUint32 attachment;
470 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
471 0u // || VkImageAspectFlags aspectMask;
473 colorAttachmentRefs.push_back(attachmentRef);
474 attachments.push_back(multisampleAttachment);
477 const AttachmentDesc singlesampleAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
479 // || VkStructureType sType;
480 DE_NULL, // || const void* pNext;
481 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
482 format, // VkFormat format; || VkFormat format;
483 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
484 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
485 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
486 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
487 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
488 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
489 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
491 const AttachmentRef attachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
493 // || VkStructureType sType;
494 DE_NULL, // || const void* pNext;
495 (deUint32)attachments.size(), // deUint32 attachment; || deUint32 attachment;
496 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
497 0u // || VkImageAspectFlags aspectMask;
499 resolveAttachmentRefs.push_back(attachmentRef);
500 attachments.push_back(singlesampleAttachment);
504 DE_ASSERT(colorAttachmentRefs.size() == resolveAttachmentRefs.size());
505 DE_ASSERT(attachments.size() == colorAttachmentRefs.size() + resolveAttachmentRefs.size());
508 const SubpassDesc subpass // VkSubpassDescription || VkSubpassDescription2KHR
510 // || VkStructureType sType;
511 DE_NULL, // || const void* pNext;
512 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
513 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
514 0u, // || deUint32 viewMask;
515 0u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
516 DE_NULL, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
517 (deUint32)colorAttachmentRefs.size(), // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
518 &colorAttachmentRefs[0], // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
519 &resolveAttachmentRefs[0], // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
520 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
521 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
522 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
524 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
526 // VkStructureType sType; || VkStructureType sType;
527 DE_NULL, // const void* pNext; || const void* pNext;
528 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
529 (deUint32)attachments.size(), // deUint32 attachmentCount; || deUint32 attachmentCount;
530 &attachments[0], // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
531 1u, // deUint32 subpassCount; || deUint32 subpassCount;
532 &subpass, // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
533 0u, // deUint32 dependencyCount; || deUint32 dependencyCount;
534 DE_NULL, // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
535 0u, // || deUint32 correlatedViewMaskCount;
536 DE_NULL // || const deUint32* pCorrelatedViewMasks;
539 return renderPassCreator.createRenderPass(vkd, device);
543 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
546 deUint32 sampleCount,
547 const RenderPassType renderPassType)
549 switch (renderPassType)
551 case RENDERPASS_TYPE_LEGACY:
552 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, format, sampleCount);
553 case RENDERPASS_TYPE_RENDERPASS2:
554 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, format, sampleCount);
556 TCU_THROW(InternalError, "Impossible");
560 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
562 VkRenderPass renderPass,
563 const std::vector<VkImageViewSp>& multisampleImageViews,
564 const std::vector<VkImageViewSp>& singlesampleImageViews,
569 std::vector<VkImageView> attachments;
571 attachments.reserve(multisampleImageViews.size() + singlesampleImageViews.size());
573 DE_ASSERT(multisampleImageViews.size() == singlesampleImageViews.size());
575 for (size_t ndx = 0; ndx < multisampleImageViews.size(); ndx++)
577 attachments.push_back(**multisampleImageViews[ndx]);
578 attachments.push_back(**singlesampleImageViews[ndx]);
581 const VkFramebufferCreateInfo createInfo =
583 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
588 (deUint32)attachments.size(),
596 return createFramebuffer(vkd, device, &createInfo);
599 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
602 const VkPushConstantRange pushConstant =
604 VK_SHADER_STAGE_FRAGMENT_BIT,
608 const VkPipelineLayoutCreateInfo createInfo =
610 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
612 (vk::VkPipelineLayoutCreateFlags)0,
621 return createPipelineLayout(vkd, device, &createInfo);
624 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
626 VkRenderPass renderPass,
627 VkPipelineLayout pipelineLayout,
628 const vk::BinaryCollection& binaryCollection,
631 deUint32 sampleCount,
634 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
635 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
636 const Move<VkShaderModule> geometryShaderModule (layerCount == 1 ? Move<VkShaderModule>() : createShaderModule(vkd, device, binaryCollection.get("geom"), 0u));
638 const VkPipelineColorBlendAttachmentState attachmentBlendState =
641 VK_BLEND_FACTOR_SRC_ALPHA,
642 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
647 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
649 const VkPipelineColorBlendAttachmentState attachmentBlendStates[] =
651 attachmentBlendState,
652 attachmentBlendState,
653 attachmentBlendState,
654 attachmentBlendState,
656 const VkPipelineVertexInputStateCreateInfo vertexInputState =
658 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
660 (VkPipelineVertexInputStateCreateFlags)0u,
668 const tcu::UVec2 renderArea (width, height);
669 const std::vector<VkViewport> viewports (1, makeViewport(renderArea));
670 const std::vector<VkRect2D> scissors (1, makeRect2D(renderArea));
672 const VkPipelineMultisampleStateCreateInfo multisampleState =
674 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
676 (VkPipelineMultisampleStateCreateFlags)0u,
678 sampleCountBitFromSampleCount(sampleCount),
685 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
687 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
689 (VkPipelineDepthStencilStateCreateFlags)0u,
693 VK_COMPARE_OP_ALWAYS,
698 VK_STENCIL_OP_INCREMENT_AND_WRAP,
700 VK_COMPARE_OP_ALWAYS,
703 0xFFu / (sampleCount + 1)
707 VK_STENCIL_OP_INCREMENT_AND_WRAP,
709 VK_COMPARE_OP_ALWAYS,
712 0xFFu / (sampleCount + 1)
718 const VkPipelineColorBlendStateCreateInfo blendState =
720 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
722 (VkPipelineColorBlendStateCreateFlags)0u,
726 DE_LENGTH_OF_ARRAY(attachmentBlendStates),
727 attachmentBlendStates,
728 { 0.0f, 0.0f, 0.0f, 0.0f }
731 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
732 device, // const VkDevice device
733 pipelineLayout, // const VkPipelineLayout pipelineLayout
734 *vertexShaderModule, // const VkShaderModule vertexShaderModule
735 DE_NULL, // const VkShaderModule tessellationControlShaderModule
736 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
737 layerCount != 1 ? *geometryShaderModule : DE_NULL, // const VkShaderModule geometryShaderModule
738 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
739 renderPass, // const VkRenderPass renderPass
740 viewports, // const std::vector<VkViewport>& viewports
741 scissors, // const std::vector<VkRect2D>& scissors
742 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
743 0u, // const deUint32 subpass
744 0u, // const deUint32 patchControlPoints
745 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
746 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
747 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
748 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
749 &blendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
754 TestConfig (VkFormat format_,
755 deUint32 sampleCount_,
756 deUint32 layerCount_,
757 RenderPassType renderPassType_)
759 , sampleCount (sampleCount_)
760 , layerCount (layerCount_)
761 , renderPassType (renderPassType_)
766 deUint32 sampleCount;
768 RenderPassType renderPassType;
771 class MultisampleRenderPassTestInstance : public TestInstance
774 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
775 ~MultisampleRenderPassTestInstance (void);
777 tcu::TestStatus iterate (void);
780 template<typename RenderpassSubpass>
782 void submitSwitch (RenderPassType renderPassType);
784 void logImage (const std::string& name,
785 const tcu::ConstPixelBufferAccess& image);
787 const bool m_featuresSupported;
788 const bool m_extensionSupported;
789 const RenderPassType m_renderPassType;
791 const VkFormat m_format;
792 const deUint32 m_sampleCount;
793 const deUint32 m_layerCount;
794 const deUint32 m_width;
795 const deUint32 m_height;
797 const std::vector<VkImageSp> m_multisampleImages;
798 const std::vector<de::SharedPtr<Allocation> > m_multisampleImageMemory;
799 const std::vector<VkImageViewSp> m_multisampleImageViews;
801 const std::vector<VkImageSp> m_singlesampleImages;
802 const std::vector<de::SharedPtr<Allocation> > m_singlesampleImageMemory;
803 const std::vector<VkImageViewSp> m_singlesampleImageViews;
805 const Unique<VkRenderPass> m_renderPass;
806 const Unique<VkFramebuffer> m_framebuffer;
808 const Unique<VkPipelineLayout> m_renderPipelineLayout;
809 const Unique<VkPipeline> m_renderPipeline;
811 const std::vector<VkBufferSp> m_buffers;
812 const std::vector<de::SharedPtr<Allocation> > m_bufferMemory;
814 const Unique<VkCommandPool> m_commandPool;
815 tcu::TextureLevel m_sum;
816 deUint32 m_sampleMask;
817 tcu::ResultCollector m_resultCollector;
820 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
821 : TestInstance (context)
822 , m_featuresSupported ((config.layerCount > 1) && context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER))
823 , m_extensionSupported ((config.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
824 , m_renderPassType (config.renderPassType)
825 , m_format (config.format)
826 , m_sampleCount (config.sampleCount)
827 , m_layerCount (config.layerCount)
831 , m_multisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_format, m_sampleCount, m_width, m_height, m_layerCount))
832 , m_multisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_multisampleImages))
833 , m_multisampleImageViews (createImageViews(context.getDeviceInterface(), context.getDevice(), m_multisampleImages, m_format, VK_IMAGE_ASPECT_COLOR_BIT, m_layerCount))
835 , m_singlesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height, m_layerCount))
836 , m_singlesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_singlesampleImages))
837 , m_singlesampleImageViews (createImageViews(context.getDeviceInterface(), context.getDevice(), m_singlesampleImages, m_format, VK_IMAGE_ASPECT_COLOR_BIT, m_layerCount))
839 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, m_sampleCount, config.renderPassType))
840 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, m_multisampleImageViews, m_singlesampleImageViews, m_width, m_height, m_layerCount))
842 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
843 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount, m_layerCount))
845 , m_buffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height, m_layerCount))
846 , m_bufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_buffers))
848 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
849 , m_sum (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), m_width, m_height, m_layerCount)
850 , m_sampleMask (0x0u)
852 tcu::clear(m_sum.getAccess(), Vec4(0.0f, 0.0f, 0.0f, 0.0f));
855 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
859 void MultisampleRenderPassTestInstance::logImage (const std::string& name, const tcu::ConstPixelBufferAccess& image)
861 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), image);
863 for (deUint32 layerNdx = 0; layerNdx < m_layerCount; ++layerNdx)
865 const std::string layerName (name + " Layer:" + de::toString(layerNdx));
866 tcu::ConstPixelBufferAccess layerImage (image.getFormat(), m_width, m_height, 1, image.getPixelPtr(0, 0, layerNdx));
868 m_context.getTestContext().getLog() << tcu::LogImage(layerName.c_str(), layerName.c_str(), layerImage);
872 template<typename RenderpassSubpass>
873 void MultisampleRenderPassTestInstance::submit (void)
875 const DeviceInterface& vkd (m_context.getDeviceInterface());
876 const VkDevice device (m_context.getDevice());
877 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
878 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
879 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
881 beginCommandBuffer(vkd, *commandBuffer);
883 // Memory barriers between previous copies and rendering
885 std::vector<VkImageMemoryBarrier> barriers;
887 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
889 const VkImageMemoryBarrier barrier =
891 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
894 VK_ACCESS_TRANSFER_READ_BIT,
895 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
897 VK_IMAGE_LAYOUT_UNDEFINED,
898 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
900 VK_QUEUE_FAMILY_IGNORED,
901 VK_QUEUE_FAMILY_IGNORED,
903 **m_singlesampleImages[dstNdx],
905 VK_IMAGE_ASPECT_COLOR_BIT,
913 barriers.push_back(barrier);
916 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]);
920 const VkRenderPassBeginInfo beginInfo =
922 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
930 { m_width, m_height }
936 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
939 // Clear everything to black
941 const tcu::TextureFormat format (mapVkFormat(m_format));
942 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
945 switch (channelClass)
947 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
948 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
951 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
952 value = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
955 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
956 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
959 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
960 value = makeClearValueColorI32(-128, -128, -128, -128);
963 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
964 value = makeClearValueColorU32(0u, 0u, 0u, 0u);
968 DE_FATAL("Unknown channel class");
970 const VkClearAttachment colors[] =
973 VK_IMAGE_ASPECT_COLOR_BIT,
978 VK_IMAGE_ASPECT_COLOR_BIT,
983 VK_IMAGE_ASPECT_COLOR_BIT,
988 VK_IMAGE_ASPECT_COLOR_BIT,
993 const VkClearRect rect =
997 { m_width, m_height }
1002 vkd.cmdClearAttachments(*commandBuffer, DE_LENGTH_OF_ARRAY(colors), colors, 1u, &rect);
1005 // Render black samples
1007 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1008 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(m_sampleMask), &m_sampleMask);
1009 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1012 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1014 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
1015 copyImageToBuffer(vkd, *commandBuffer, **m_singlesampleImages[dstNdx], **m_buffers[dstNdx], tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_layerCount);
1017 endCommandBuffer(vkd, *commandBuffer);
1019 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1021 for (size_t memoryBufferNdx = 0; memoryBufferNdx < m_bufferMemory.size(); memoryBufferNdx++)
1022 invalidateMappedMemoryRange(vkd, device, m_bufferMemory[memoryBufferNdx]->getMemory(), 0u, VK_WHOLE_SIZE);
1025 void MultisampleRenderPassTestInstance::submitSwitch (RenderPassType renderPassType)
1027 switch (renderPassType)
1029 case RENDERPASS_TYPE_LEGACY:
1030 submit<RenderpassSubpass1>();
1032 case RENDERPASS_TYPE_RENDERPASS2:
1033 submit<RenderpassSubpass2>();
1036 TCU_THROW(InternalError, "Impossible");
1040 void MultisampleRenderPassTestInstance::verify (void)
1042 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1043 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1044 const tcu::TextureFormat format (mapVkFormat(m_format));
1045 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1046 const void* const ptrs[] =
1048 m_bufferMemory[0]->getHostPtr(),
1049 m_bufferMemory[1]->getHostPtr(),
1050 m_bufferMemory[2]->getHostPtr(),
1051 m_bufferMemory[3]->getHostPtr()
1053 const tcu::ConstPixelBufferAccess accesses[] =
1055 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[0]),
1056 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[1]),
1057 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[2]),
1058 tcu::ConstPixelBufferAccess(format, m_width, m_height, m_layerCount, ptrs[3])
1060 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
1061 tcu::TestLog& log (m_context.getTestContext().getLog());
1063 switch (channelClass)
1065 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1066 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1067 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1069 const int componentCount (tcu::getNumUsedChannels(format.order));
1074 switch (channelClass)
1076 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1077 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1082 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1090 DE_FATAL("Unknown channel class");
1093 for (deUint32 z = 0; z < m_layerCount; z++)
1094 for (deUint32 y = 0; y < m_height; y++)
1095 for (deUint32 x = 0; x < m_width; x++)
1097 // Color has to be black if no samples were covered, white if all samples were covered or same in every attachment
1098 const Vec4 firstColor (accesses[0].getPixel(x, y, z));
1099 const Vec4 refColor (m_sampleMask == 0x0u
1101 componentCount > 1 ? clearValue : 0.0f,
1102 componentCount > 2 ? clearValue : 0.0f,
1103 componentCount > 3 ? clearValue : 1.0f)
1104 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1106 componentCount > 1 ? renderValue : 0.0f,
1107 componentCount > 2 ? renderValue : 0.0f,
1108 componentCount > 3 ? renderValue : 1.0f)
1111 errorMask.getAccess().setPixel(okColor, x, y, z);
1113 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1115 const Vec4 color (accesses[attachmentNdx].getPixel(x, y, z));
1117 if (refColor != color)
1120 errorMask.getAccess().setPixel(errorColor, x, y, z);
1126 const Vec4 old = m_sum.getAccess().getPixel(x, y, z);
1127 m_sum.getAccess().setPixel(old + (tcu::isSRGB(format) ? tcu::sRGBToLinear(firstColor) : firstColor), x, y, z);
1133 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1134 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1136 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1137 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1139 logImage("ErrorMask", errorMask.getAccess());
1141 if (m_sampleMask == 0x0u)
1143 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1144 m_resultCollector.fail("Empty sample mask didn't produce correct pixel values");
1146 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1148 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1149 m_resultCollector.fail("Full sample mask didn't produce correct pixel values");
1153 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve is inconsistent between attachments" << tcu::TestLog::EndMessage;
1154 m_resultCollector.fail("Resolve is inconsistent between attachments");
1160 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1162 const int componentCount (tcu::getNumUsedChannels(format.order));
1163 const UVec4 bitDepth (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1164 const UVec4 renderValue (tcu::select((UVec4(1u) << tcu::min(UVec4(8u), bitDepth)) - UVec4(1u),
1165 UVec4(0u, 0u, 0u, 1u),
1166 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1167 const UVec4 clearValue (tcu::select(UVec4(0u),
1168 UVec4(0u, 0u, 0u, 1u),
1169 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1170 bool unexpectedValues = false;
1171 bool inconsistentComponents = false;
1172 bool inconsistentAttachments = false;
1174 for (deUint32 z = 0; z < m_layerCount; z++)
1175 for (deUint32 y = 0; y < m_height; y++)
1176 for (deUint32 x = 0; x < m_width; x++)
1178 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1179 const UVec4 refColor (m_sampleMask == 0x0u
1181 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1183 : accesses[0].getPixelUint(x, y, z));
1186 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1187 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1189 // Each component must be resolved same way
1190 const BVec4 isRenderValue (refColor == renderValue);
1191 const BVec4 isClearValue (refColor == clearValue);
1192 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1193 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1195 unexpectedValues |= unexpectedValue;
1196 inconsistentComponents |= inconsistentComponent;
1198 if (unexpectedValue || inconsistentComponent)
1202 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1204 const UVec4 color (accesses[attachmentNdx].getPixelUint(x, y, z));
1206 if (refColor != color)
1209 inconsistentAttachments = true;
1214 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1217 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1219 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1220 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1222 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1223 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1225 logImage("ErrorMask", errorMask.getAccess());
1227 if (m_sampleMask == 0x0u)
1229 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1230 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1232 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1234 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1235 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1239 if (unexpectedValues)
1241 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1242 m_resultCollector.fail("Resolve produced unexpected values");
1245 if (inconsistentComponents)
1247 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1248 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1251 if (inconsistentAttachments)
1253 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1254 m_resultCollector.fail("Different attachments were resolved to different values.");
1261 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1263 const int componentCount (tcu::getNumUsedChannels(format.order));
1264 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
1265 const IVec4 renderValue (tcu::select((IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))) - IVec4(1),
1267 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1268 const IVec4 clearValue (tcu::select(-(IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))),
1270 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1271 bool unexpectedValues = false;
1272 bool inconsistentComponents = false;
1273 bool inconsistentAttachments = false;
1275 for (deUint32 z = 0; z < m_layerCount; z++)
1276 for (deUint32 y = 0; y < m_height; y++)
1277 for (deUint32 x = 0; x < m_width; x++)
1279 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1280 const IVec4 refColor (m_sampleMask == 0x0u
1282 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1284 : accesses[0].getPixelInt(x, y, z));
1287 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1288 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1290 // Each component must be resolved same way
1291 const BVec4 isRenderValue (refColor == renderValue);
1292 const BVec4 isClearValue (refColor == clearValue);
1293 const bool unexpectedValue (tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true)));
1294 const bool inconsistentComponent (!(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true))));
1296 unexpectedValues |= unexpectedValue;
1297 inconsistentComponents |= inconsistentComponent;
1299 if (unexpectedValue || inconsistentComponent)
1303 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1305 const IVec4 color (accesses[attachmentNdx].getPixelInt(x, y, z));
1307 if (refColor != color)
1310 inconsistentAttachments = true;
1315 errorMask.getAccess().setPixel((isOk ? okColor : errorColor), x, y, z);
1318 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1320 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1321 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1323 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1324 logImage(std::string("Attachment") + de::toString(attachmentNdx), accesses[attachmentNdx]);
1326 logImage("ErrorMask", errorMask.getAccess());
1328 if (m_sampleMask == 0x0u)
1330 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1331 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1333 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1335 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1336 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1340 if (unexpectedValues)
1342 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1343 m_resultCollector.fail("Resolve produced unexpected values");
1346 if (inconsistentComponents)
1348 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1349 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1352 if (inconsistentAttachments)
1354 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1355 m_resultCollector.fail("Different attachments were resolved to different values.");
1363 DE_FATAL("Unknown channel class");
1367 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1369 if (m_sampleMask == 0u)
1371 const tcu::TextureFormat format (mapVkFormat(m_format));
1372 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1373 tcu::TestLog& log (m_context.getTestContext().getLog());
1375 switch (channelClass)
1377 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1378 log << TestLog::Message << "Clearing target to zero and rendering 255 pixels with every possible sample mask" << TestLog::EndMessage;
1381 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1382 log << TestLog::Message << "Clearing target to -128 and rendering 127 pixels with every possible sample mask" << TestLog::EndMessage;
1385 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1386 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1387 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1388 log << TestLog::Message << "Clearing target to black and rendering white pixels with every possible sample mask" << TestLog::EndMessage;
1392 DE_FATAL("Unknown channel class");
1396 submitSwitch(m_renderPassType);
1399 if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1401 const tcu::TextureFormat format (mapVkFormat(m_format));
1402 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1403 const Vec4 threshold (getFormatThreshold(m_format));
1404 tcu::TestLog& log (m_context.getTestContext().getLog());
1406 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
1407 || channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
1408 || channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1410 const int componentCount (tcu::getNumUsedChannels(format.order));
1411 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1412 const Vec4 okColor (0.0f, 1.0f, 0.0f, 1.0f);
1413 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height, m_layerCount);
1415 Vec4 maxDiff (0.0f);
1416 Vec4 expectedAverage;
1418 switch (channelClass)
1420 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1422 expectedAverage = Vec4(0.5f, componentCount > 1 ? 0.5f : 0.0f, componentCount > 2 ? 0.5f : 0.0f, componentCount > 3 ? 0.5f : 1.0f);
1426 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1427 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1429 expectedAverage = Vec4(0.0f, 0.0f, 0.0f, componentCount > 3 ? 0.0f : 1.0f);
1434 DE_FATAL("Unknown channel class");
1437 for (deUint32 z = 0; z < m_layerCount; z++)
1438 for (deUint32 y = 0; y < m_height; y++)
1439 for (deUint32 x = 0; x < m_width; x++)
1441 const Vec4 sum (m_sum.getAccess().getPixel(x, y, z));
1442 const Vec4 average (sum / Vec4((float)(0x1u << m_sampleCount)));
1443 const Vec4 diff (tcu::abs(average - expectedAverage));
1445 m_sum.getAccess().setPixel(average, x, y, z);
1446 errorMask.getAccess().setPixel(okColor, x, y, z);
1448 if (diff[0] > threshold.x()
1449 || diff[1] > threshold.y()
1450 || diff[2] > threshold.z()
1451 || diff[3] > threshold.w())
1454 maxDiff = tcu::max(maxDiff, diff);
1455 errorMask.getAccess().setPixel(errorColor, x, y, z);
1459 log << TestLog::Image("Average resolved values in attachment 0", "Average resolved values in attachment 0", m_sum);
1463 std::stringstream message;
1465 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1467 message << "Average resolved values differ from expected average values by more than ";
1469 switch (componentCount)
1472 message << threshold.x();
1475 message << "vec2" << Vec2(threshold.x(), threshold.y());
1478 message << "vec3" << Vec3(threshold.x(), threshold.y(), threshold.z());
1481 message << "vec4" << threshold;
1484 message << ". Max diff " << maxDiff;
1485 log << TestLog::Message << message.str() << TestLog::EndMessage;
1487 m_resultCollector.fail("Average resolved values differ from expected average values");
1491 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1496 return tcu::TestStatus::incomplete();
1502 void init (vk::SourceCollections& dst, TestConfig config) const
1504 const tcu::TextureFormat format (mapVkFormat(config.format));
1505 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1507 dst.glslSources.add("quad-vert") << glu::VertexSource(
1509 "out gl_PerVertex {\n"
1510 "\tvec4 gl_Position;\n"
1513 "void main (void) {\n"
1514 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1515 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1518 if (config.layerCount > 1)
1520 std::ostringstream src;
1522 src << "#version 450\n"
1525 << "layout(triangles) in;\n"
1526 << "layout(triangle_strip, max_vertices = " << 3 * 2 * config.layerCount << ") out;\n"
1528 << "in gl_PerVertex {\n"
1529 << " vec4 gl_Position;\n"
1532 << "out gl_PerVertex {\n"
1533 << " vec4 gl_Position;\n"
1536 << "void main (void) {\n"
1537 << " for (int layerNdx = 0; layerNdx < " << config.layerCount << "; ++layerNdx) {\n"
1538 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
1539 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
1540 << " gl_Layer = layerNdx;\n"
1541 << " EmitVertex();\n"
1543 << " EndPrimitive();\n"
1547 dst.glslSources.add("geom") << glu::GeometrySource(src.str());
1550 switch (channelClass)
1552 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1553 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1555 "layout(push_constant) uniform PushConstant {\n"
1556 "\thighp uint sampleMask;\n"
1557 "} pushConstants;\n"
1558 "layout(location = 0) out highp uvec4 o_color0;\n"
1559 "layout(location = 1) out highp uvec4 o_color1;\n"
1560 "layout(location = 2) out highp uvec4 o_color2;\n"
1561 "layout(location = 3) out highp uvec4 o_color3;\n"
1562 "void main (void)\n"
1564 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1565 "\to_color0 = uvec4(255);\n"
1566 "\to_color1 = uvec4(255);\n"
1567 "\to_color2 = uvec4(255);\n"
1568 "\to_color3 = uvec4(255);\n"
1572 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1573 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1575 "layout(push_constant) uniform PushConstant {\n"
1576 "\thighp uint sampleMask;\n"
1577 "} pushConstants;\n"
1578 "layout(location = 0) out highp ivec4 o_color0;\n"
1579 "layout(location = 1) out highp ivec4 o_color1;\n"
1580 "layout(location = 2) out highp ivec4 o_color2;\n"
1581 "layout(location = 3) out highp ivec4 o_color3;\n"
1582 "void main (void)\n"
1584 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1585 "\to_color0 = ivec4(127);\n"
1586 "\to_color1 = ivec4(127);\n"
1587 "\to_color2 = ivec4(127);\n"
1588 "\to_color3 = ivec4(127);\n"
1592 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1593 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1594 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1595 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1597 "layout(push_constant) uniform PushConstant {\n"
1598 "\thighp uint sampleMask;\n"
1599 "} pushConstants;\n"
1600 "layout(location = 0) out highp vec4 o_color0;\n"
1601 "layout(location = 1) out highp vec4 o_color1;\n"
1602 "layout(location = 2) out highp vec4 o_color2;\n"
1603 "layout(location = 3) out highp vec4 o_color3;\n"
1604 "void main (void)\n"
1606 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1607 "\to_color0 = vec4(1.0);\n"
1608 "\to_color1 = vec4(1.0);\n"
1609 "\to_color2 = vec4(1.0);\n"
1610 "\to_color3 = vec4(1.0);\n"
1615 DE_FATAL("Unknown channel class");
1620 std::string formatToName (VkFormat format)
1622 const std::string formatStr = de::toString(format);
1623 const std::string prefix = "VK_FORMAT_";
1625 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1627 return de::toLower(formatStr.substr(prefix.length()));
1630 void initTests (tcu::TestCaseGroup* group, RenderPassType renderPassType)
1632 static const VkFormat formats[] =
1634 VK_FORMAT_R5G6B5_UNORM_PACK16,
1639 VK_FORMAT_R8G8_UNORM,
1640 VK_FORMAT_R8G8_SNORM,
1641 VK_FORMAT_R8G8_UINT,
1642 VK_FORMAT_R8G8_SINT,
1643 VK_FORMAT_R8G8B8A8_UNORM,
1644 VK_FORMAT_R8G8B8A8_SNORM,
1645 VK_FORMAT_R8G8B8A8_UINT,
1646 VK_FORMAT_R8G8B8A8_SINT,
1647 VK_FORMAT_R8G8B8A8_SRGB,
1648 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1649 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1650 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1651 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1652 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1653 VK_FORMAT_B8G8R8A8_UNORM,
1654 VK_FORMAT_B8G8R8A8_SRGB,
1655 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1656 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1657 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1658 VK_FORMAT_R16_UNORM,
1659 VK_FORMAT_R16_SNORM,
1662 VK_FORMAT_R16_SFLOAT,
1663 VK_FORMAT_R16G16_UNORM,
1664 VK_FORMAT_R16G16_SNORM,
1665 VK_FORMAT_R16G16_UINT,
1666 VK_FORMAT_R16G16_SINT,
1667 VK_FORMAT_R16G16_SFLOAT,
1668 VK_FORMAT_R16G16B16A16_UNORM,
1669 VK_FORMAT_R16G16B16A16_SNORM,
1670 VK_FORMAT_R16G16B16A16_UINT,
1671 VK_FORMAT_R16G16B16A16_SINT,
1672 VK_FORMAT_R16G16B16A16_SFLOAT,
1675 VK_FORMAT_R32_SFLOAT,
1676 VK_FORMAT_R32G32_UINT,
1677 VK_FORMAT_R32G32_SINT,
1678 VK_FORMAT_R32G32_SFLOAT,
1679 VK_FORMAT_R32G32B32A32_UINT,
1680 VK_FORMAT_R32G32B32A32_SINT,
1681 VK_FORMAT_R32G32B32A32_SFLOAT,
1683 const deUint32 sampleCounts[] =
1687 const deUint32 layerCounts[] =
1691 tcu::TestContext& testCtx (group->getTestContext());
1693 for (size_t layerCountNdx = 0; layerCountNdx < DE_LENGTH_OF_ARRAY(layerCounts); layerCountNdx++)
1695 const deUint32 layerCount (layerCounts[layerCountNdx]);
1696 const std::string layerGroupName ("layers_" + de::toString(layerCount));
1697 de::MovePtr<tcu::TestCaseGroup> layerGroup (new tcu::TestCaseGroup(testCtx, layerGroupName.c_str(), layerGroupName.c_str()));
1699 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1701 const VkFormat format (formats[formatNdx]);
1702 const std::string formatName (formatToName(format));
1703 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
1705 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1707 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1708 const std::string testName ("samples_" + de::toString(sampleCount));
1709 const TestConfig testConfig (format, sampleCount, layerCount, renderPassType);
1711 // Skip this test as it is rather slow
1712 if (layerCount == 6 && sampleCount == 8)
1715 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
1718 if (layerCount == 1)
1719 group->addChild(formatGroup.release());
1721 layerGroup->addChild(formatGroup.release());
1724 if (layerCount != 1)
1725 group->addChild(layerGroup.release());
1731 tcu::TestCaseGroup* createRenderPassMultisampleResolveTests (tcu::TestContext& testCtx)
1733 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, RENDERPASS_TYPE_LEGACY);
1736 tcu::TestCaseGroup* createRenderPass2MultisampleResolveTests (tcu::TestContext& testCtx)
1738 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests, RENDERPASS_TYPE_RENDERPASS2);