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"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
30 #include "vkDeviceUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
40 #include "tcuFloat.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuFormatUtil.hpp"
43 #include "tcuMaybe.hpp"
44 #include "tcuResultCollector.hpp"
45 #include "tcuTestLog.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuVectorUtil.hpp"
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
66 using tcu::ConstPixelBufferAccess;
67 using tcu::PixelBufferAccess;
75 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
76 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
77 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
78 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
86 MAX_COLOR_ATTACHMENT_COUNT = 4u
90 de::SharedPtr<T> safeSharedPtr (T* ptr)
94 return de::SharedPtr<T>(ptr);
103 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
105 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
108 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
110 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
113 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
115 Allocator& allocator,
118 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
119 bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
123 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
125 Allocator& allocator,
128 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
129 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
133 Move<VkImage> createImage (const DeviceInterface& vk,
135 VkImageCreateFlags flags,
136 VkImageType imageType,
140 deUint32 arrayLayers,
141 VkSampleCountFlagBits samples,
142 VkImageTiling tiling,
143 VkImageUsageFlags usage,
144 VkSharingMode sharingMode,
145 deUint32 queueFamilyCount,
146 const deUint32* pQueueFamilyIndices,
147 VkImageLayout initialLayout)
149 const VkImageCreateInfo pCreateInfo =
151 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
167 return createImage(vk, device, &pCreateInfo);
170 Move<VkImageView> createImageView (const DeviceInterface& vk,
172 VkImageViewCreateFlags flags,
174 VkImageViewType viewType,
176 VkComponentMapping components,
177 VkImageSubresourceRange subresourceRange)
179 const VkImageViewCreateInfo pCreateInfo =
181 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
190 return createImageView(vk, device, &pCreateInfo);
193 Move<VkImage> createImage (const InstanceInterface& vki,
194 VkPhysicalDevice physicalDevice,
195 const DeviceInterface& vkd,
198 VkSampleCountFlagBits sampleCountBit,
199 VkImageUsageFlags usage,
205 const tcu::TextureFormat format (mapVkFormat(vkFormat));
206 const VkImageType imageType (VK_IMAGE_TYPE_2D);
207 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
208 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
209 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
210 const VkExtent3D imageExtent =
217 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
218 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
219 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
221 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
222 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
223 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
225 if (imageFormatProperties.maxExtent.width < imageExtent.width
226 || imageFormatProperties.maxExtent.height < imageExtent.height
227 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
229 TCU_THROW(NotSupportedError, "Image type not supported");
232 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
234 catch (const vk::Error& error)
236 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
237 TCU_THROW(NotSupportedError, "Image format not supported");
243 Move<VkImageView> createImageView (const DeviceInterface& vkd,
247 VkImageAspectFlags aspect)
249 const VkImageSubresourceRange range =
258 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
261 VkDeviceSize getPixelSize (VkFormat vkFormat)
263 const tcu::TextureFormat format (mapVkFormat(vkFormat));
265 return format.getPixelSize();
268 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
274 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
275 const VkDeviceSize pixelSize (getPixelSize(format));
276 const VkBufferCreateInfo createInfo =
278 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
282 width * height * pixelSize,
285 VK_SHARING_MODE_EXCLUSIVE,
289 return createBuffer(vkd, device, &createInfo);
292 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count)
296 case 1: return VK_SAMPLE_COUNT_1_BIT;
297 case 2: return VK_SAMPLE_COUNT_2_BIT;
298 case 4: return VK_SAMPLE_COUNT_4_BIT;
299 case 8: return VK_SAMPLE_COUNT_8_BIT;
300 case 16: return VK_SAMPLE_COUNT_16_BIT;
301 case 32: return VK_SAMPLE_COUNT_32_BIT;
302 case 64: return VK_SAMPLE_COUNT_64_BIT;
305 DE_FATAL("Invalid sample count");
306 return (VkSampleCountFlagBits)0x0;
310 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface& vki,
311 VkPhysicalDevice physicalDevice,
312 const DeviceInterface& vkd,
315 deUint32 sampleCount,
319 std::vector<VkImageSp> images (MAX_COLOR_ATTACHMENT_COUNT);
321 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
322 images[imageNdx] = safeSharedPtr(new Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));
327 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface& vki,
328 VkPhysicalDevice physicalDevice,
329 const DeviceInterface& vkd,
335 std::vector<VkImageSp> images (MAX_COLOR_ATTACHMENT_COUNT);
337 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
338 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)));
343 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface& vkd,
345 Allocator& allocator,
346 const std::vector<VkImageSp> images)
348 std::vector<de::SharedPtr<Allocation> > memory (images.size());
350 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
351 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
356 std::vector<VkImageViewSp> createImageViews (const DeviceInterface& vkd,
358 const std::vector<VkImageSp>& images,
360 VkImageAspectFlagBits aspect)
362 std::vector<VkImageViewSp> views (images.size());
364 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
365 views[imageNdx] = safeSharedPtr(new Unique<VkImageView>(createImageView(vkd, device, **images[imageNdx], format, aspect)));
370 std::vector<VkBufferSp> createBuffers (const DeviceInterface& vkd,
376 std::vector<VkBufferSp> buffers (MAX_COLOR_ATTACHMENT_COUNT);
378 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
379 buffers[bufferNdx] = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));
384 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface& vkd,
386 Allocator& allocator,
387 const std::vector<VkBufferSp> buffers)
389 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
391 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
392 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
397 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
400 deUint32 sampleCount)
402 const VkSampleCountFlagBits samples (sampleCountBitFromSampleCount(sampleCount));
403 std::vector<VkAttachmentDescription> attachments;
404 std::vector<VkAttachmentReference> colorAttachmentRefs;
405 std::vector<VkAttachmentReference> resolveAttachmentRefs;
407 for (size_t attachmentNdx = 0; attachmentNdx < 4; attachmentNdx++)
410 const VkAttachmentDescription multisampleAttachment =
417 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
418 VK_ATTACHMENT_STORE_OP_DONT_CARE,
420 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
421 VK_ATTACHMENT_STORE_OP_DONT_CARE,
423 VK_IMAGE_LAYOUT_UNDEFINED,
424 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
426 const VkAttachmentReference attachmentRef =
428 (deUint32)attachments.size(),
429 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
431 colorAttachmentRefs.push_back(attachmentRef);
432 attachments.push_back(multisampleAttachment);
435 const VkAttachmentDescription singlesampleAttachment =
440 VK_SAMPLE_COUNT_1_BIT,
442 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
443 VK_ATTACHMENT_STORE_OP_STORE,
445 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
446 VK_ATTACHMENT_STORE_OP_DONT_CARE,
448 VK_IMAGE_LAYOUT_UNDEFINED,
449 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
451 const VkAttachmentReference attachmentRef =
453 (deUint32)attachments.size(),
454 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
456 resolveAttachmentRefs.push_back(attachmentRef);
457 attachments.push_back(singlesampleAttachment);
461 DE_ASSERT(colorAttachmentRefs.size() == resolveAttachmentRefs.size());
462 DE_ASSERT(attachments.size() == colorAttachmentRefs.size() + resolveAttachmentRefs.size());
465 const VkSubpassDescription subpass =
467 (VkSubpassDescriptionFlags)0,
468 VK_PIPELINE_BIND_POINT_GRAPHICS,
473 (deUint32)colorAttachmentRefs.size(),
474 &colorAttachmentRefs[0],
475 &resolveAttachmentRefs[0],
481 const VkRenderPassCreateInfo createInfo =
483 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
485 (VkRenderPassCreateFlags)0u,
487 (deUint32)attachments.size(),
497 return createRenderPass(vkd, device, &createInfo);
501 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
503 VkRenderPass renderPass,
504 const std::vector<VkImageViewSp>& multisampleImageViews,
505 const std::vector<VkImageViewSp>& singlesampleImageViews,
509 std::vector<VkImageView> attachments;
511 attachments.reserve(multisampleImageViews.size() + singlesampleImageViews.size());
513 DE_ASSERT(multisampleImageViews.size() == singlesampleImageViews.size());
515 for (size_t ndx = 0; ndx < multisampleImageViews.size(); ndx++)
517 attachments.push_back(**multisampleImageViews[ndx]);
518 attachments.push_back(**singlesampleImageViews[ndx]);
521 const VkFramebufferCreateInfo createInfo =
523 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
528 (deUint32)attachments.size(),
536 return createFramebuffer(vkd, device, &createInfo);
539 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
542 const VkPushConstantRange pushConstant =
544 VK_SHADER_STAGE_FRAGMENT_BIT,
548 const VkPipelineLayoutCreateInfo createInfo =
550 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
552 (vk::VkPipelineLayoutCreateFlags)0,
561 return createPipelineLayout(vkd, device, &createInfo);
564 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
566 VkRenderPass renderPass,
567 VkPipelineLayout pipelineLayout,
568 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
571 deUint32 sampleCount)
573 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
574 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
575 const VkSpecializationInfo emptyShaderSpecializations =
584 const VkPipelineColorBlendAttachmentState attachmentBlendState =
587 VK_BLEND_FACTOR_SRC_ALPHA,
588 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
593 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
595 const VkPipelineColorBlendAttachmentState attachmentBlendStates[] =
597 attachmentBlendState,
598 attachmentBlendState,
599 attachmentBlendState,
600 attachmentBlendState,
602 const VkPipelineShaderStageCreateInfo shaderStages[2] =
605 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
607 (VkPipelineShaderStageCreateFlags)0u,
608 VK_SHADER_STAGE_VERTEX_BIT,
611 &emptyShaderSpecializations
614 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
616 (VkPipelineShaderStageCreateFlags)0u,
617 VK_SHADER_STAGE_FRAGMENT_BIT,
618 *fragmentShaderModule,
620 &emptyShaderSpecializations
623 const VkPipelineVertexInputStateCreateInfo vertexInputState =
625 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
627 (VkPipelineVertexInputStateCreateFlags)0u,
635 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
637 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
640 (VkPipelineInputAssemblyStateCreateFlags)0u,
641 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
644 const VkViewport viewport =
647 (float)width, (float)height,
651 const VkRect2D scissor =
656 const VkPipelineViewportStateCreateInfo viewportState =
658 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
660 (VkPipelineViewportStateCreateFlags)0u,
668 const VkPipelineRasterizationStateCreateInfo rasterState =
670 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
672 (VkPipelineRasterizationStateCreateFlags)0u,
675 VK_POLYGON_MODE_FILL,
677 VK_FRONT_FACE_COUNTER_CLOCKWISE,
684 const VkPipelineMultisampleStateCreateInfo multisampleState =
686 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
688 (VkPipelineMultisampleStateCreateFlags)0u,
690 sampleCountBitFromSampleCount(sampleCount),
697 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
699 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
701 (VkPipelineDepthStencilStateCreateFlags)0u,
705 VK_COMPARE_OP_ALWAYS,
710 VK_STENCIL_OP_INCREMENT_AND_WRAP,
712 VK_COMPARE_OP_ALWAYS,
715 0xFFu / (sampleCount + 1)
719 VK_STENCIL_OP_INCREMENT_AND_WRAP,
721 VK_COMPARE_OP_ALWAYS,
724 0xFFu / (sampleCount + 1)
730 const VkPipelineColorBlendStateCreateInfo blendState =
732 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
734 (VkPipelineColorBlendStateCreateFlags)0u,
738 DE_LENGTH_OF_ARRAY(attachmentBlendStates),
739 attachmentBlendStates,
740 { 0.0f, 0.0f, 0.0f, 0.0f }
742 const VkGraphicsPipelineCreateInfo createInfo =
744 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
746 (VkPipelineCreateFlags)0u,
759 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,
768 return createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
773 TestConfig (VkFormat format_,
774 deUint32 sampleCount_)
776 , sampleCount (sampleCount_)
781 deUint32 sampleCount;
784 class MultisampleRenderPassTestInstance : public TestInstance
787 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
788 ~MultisampleRenderPassTestInstance (void);
790 tcu::TestStatus iterate (void);
796 const VkFormat m_format;
797 const deUint32 m_sampleCount;
798 const deUint32 m_width;
799 const deUint32 m_height;
801 const std::vector<VkImageSp> m_multisampleImages;
802 const std::vector<de::SharedPtr<Allocation> > m_multisampleImageMemory;
803 const std::vector<VkImageViewSp> m_multisampleImageViews;
805 const std::vector<VkImageSp> m_singlesampleImages;
806 const std::vector<de::SharedPtr<Allocation> > m_singlesampleImageMemory;
807 const std::vector<VkImageViewSp> m_singlesampleImageViews;
809 const Unique<VkRenderPass> m_renderPass;
810 const Unique<VkFramebuffer> m_framebuffer;
812 const Unique<VkPipelineLayout> m_renderPipelineLayout;
813 const Unique<VkPipeline> m_renderPipeline;
815 const std::vector<VkBufferSp> m_buffers;
816 const std::vector<de::SharedPtr<Allocation> > m_bufferMemory;
818 const Unique<VkCommandPool> m_commandPool;
819 tcu::TextureLevel m_sum;
820 deUint32 m_sampleMask;
821 tcu::ResultCollector m_resultCollector;
824 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
825 : TestInstance (context)
826 , m_format (config.format)
827 , m_sampleCount (config.sampleCount)
831 , m_multisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_format, m_sampleCount, m_width, m_height))
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))
835 , m_singlesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
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))
839 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, m_sampleCount))
840 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, m_multisampleImageViews, m_singlesampleImageViews, m_width, m_height))
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))
845 , m_buffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
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)
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::submit (void)
861 const DeviceInterface& vkd (m_context.getDeviceInterface());
862 const VkDevice device (m_context.getDevice());
863 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
866 const VkCommandBufferBeginInfo beginInfo =
868 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
871 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
875 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &beginInfo));
879 const VkRenderPassBeginInfo beginInfo =
881 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
889 { m_width, m_height }
895 vkd.cmdBeginRenderPass(*commandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
898 // Memory barriers between previous copies and rendering
900 std::vector<VkImageMemoryBarrier> barriers;
902 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
904 const VkImageMemoryBarrier barrier =
906 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
909 VK_ACCESS_TRANSFER_READ_BIT,
910 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
912 VK_IMAGE_LAYOUT_UNDEFINED,
913 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
915 VK_QUEUE_FAMILY_IGNORED,
916 VK_QUEUE_FAMILY_IGNORED,
918 **m_singlesampleImages[dstNdx],
920 VK_IMAGE_ASPECT_COLOR_BIT,
928 barriers.push_back(barrier);
931 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]);
934 // Clear everything to black
936 const tcu::TextureFormat format (mapVkFormat(m_format));
937 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
940 switch (channelClass)
942 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
943 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
946 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
947 value = makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
950 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
951 value = makeClearValueColorF32(-1.0f, -1.0f, -1.0f, -1.0f);
954 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
955 value = makeClearValueColorI32(-128, -128, -128, -128);
958 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
959 value = makeClearValueColorU32(0u, 0u, 0u, 0u);
963 DE_FATAL("Unknown channel class");
965 const VkClearAttachment colors[] =
968 VK_IMAGE_ASPECT_COLOR_BIT,
973 VK_IMAGE_ASPECT_COLOR_BIT,
978 VK_IMAGE_ASPECT_COLOR_BIT,
983 VK_IMAGE_ASPECT_COLOR_BIT,
988 const VkClearRect rect =
992 { m_width, m_height }
997 vkd.cmdClearAttachments(*commandBuffer, DE_LENGTH_OF_ARRAY(colors), colors, 1u, &rect);
1000 // Render black samples
1002 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1003 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(m_sampleMask), &m_sampleMask);
1004 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1007 vkd.cmdEndRenderPass(*commandBuffer);
1009 // Memory barriers between rendering and copies
1011 std::vector<VkImageMemoryBarrier> barriers;
1013 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
1015 const VkImageMemoryBarrier barrier =
1017 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1020 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1021 VK_ACCESS_TRANSFER_READ_BIT,
1023 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1024 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1026 VK_QUEUE_FAMILY_IGNORED,
1027 VK_QUEUE_FAMILY_IGNORED,
1029 **m_singlesampleImages[dstNdx],
1031 VK_IMAGE_ASPECT_COLOR_BIT,
1039 barriers.push_back(barrier);
1042 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]);
1045 // Copy image memory to buffers
1046 for (size_t dstNdx = 0; dstNdx < m_singlesampleImages.size(); dstNdx++)
1048 const VkBufferImageCopy region =
1054 VK_IMAGE_ASPECT_COLOR_BIT,
1060 { m_width, m_height, 1u }
1063 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImages[dstNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffers[dstNdx], 1u, ®ion);
1066 // Memory barriers between copies and host access
1068 std::vector<VkBufferMemoryBarrier> barriers;
1070 for (size_t dstNdx = 0; dstNdx < m_buffers.size(); dstNdx++)
1072 const VkBufferMemoryBarrier barrier =
1074 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1077 VK_ACCESS_TRANSFER_WRITE_BIT,
1078 VK_ACCESS_HOST_READ_BIT,
1080 VK_QUEUE_FAMILY_IGNORED,
1081 VK_QUEUE_FAMILY_IGNORED,
1083 **m_buffers[dstNdx],
1088 barriers.push_back(barrier);
1091 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);
1094 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
1097 const VkSubmitInfo submitInfo =
1099 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1113 VK_CHECK(vkd.queueSubmit(m_context.getUniversalQueue(), 1u, &submitInfo, (VkFence)0u));
1115 VK_CHECK(vkd.queueWaitIdle(m_context.getUniversalQueue()));
1119 void MultisampleRenderPassTestInstance::verify (void)
1121 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1122 const Vec4 okColor (0.0f, 0.0f, 0.0f, 1.0f);
1123 const tcu::TextureFormat format (mapVkFormat(m_format));
1124 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1125 const void* const ptrs[] =
1127 m_bufferMemory[0]->getHostPtr(),
1128 m_bufferMemory[1]->getHostPtr(),
1129 m_bufferMemory[2]->getHostPtr(),
1130 m_bufferMemory[3]->getHostPtr()
1132 const tcu::ConstPixelBufferAccess accesses[] =
1134 tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptrs[0]),
1135 tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptrs[1]),
1136 tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptrs[2]),
1137 tcu::ConstPixelBufferAccess(format, m_width, m_height, 1, ptrs[3])
1139 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height);
1140 tcu::TestLog& log (m_context.getTestContext().getLog());
1142 switch (channelClass)
1144 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1145 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1146 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1148 const int componentCount (tcu::getNumUsedChannels(format.order));
1153 switch (channelClass)
1155 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1156 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1161 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1169 DE_FATAL("Unknown channel class");
1172 for (deUint32 y = 0; y < m_height; y++)
1173 for (deUint32 x = 0; x < m_width; x++)
1175 // Color has to be black if no samples were covered, white if all samples were covered or same in every attachment
1176 const Vec4 firstColor (accesses[0].getPixel(x, y));
1177 const Vec4 refColor (m_sampleMask == 0x0u
1179 componentCount > 1 ? clearValue : 0.0f,
1180 componentCount > 2 ? clearValue : 0.0f,
1181 componentCount > 3 ? clearValue : 1.0f)
1182 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1184 componentCount > 1 ? renderValue : 0.0f,
1185 componentCount > 2 ? renderValue : 0.0f,
1186 componentCount > 3 ? renderValue : 1.0f)
1189 errorMask.getAccess().setPixel(okColor, x, y);
1191 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1193 const Vec4 color (accesses[attachmentNdx].getPixel(x, y));
1195 if (refColor != color)
1198 errorMask.getAccess().setPixel(errorColor, x, y);
1204 const Vec4 old = m_sum.getAccess().getPixel(x, y);
1206 m_sum.getAccess().setPixel(old + firstColor, x, y);
1212 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1213 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1215 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1217 const std::string name ("Attachment" + de::toString(attachmentNdx));
1218 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), accesses[attachmentNdx]);
1221 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1223 if (m_sampleMask == 0x0u)
1225 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1226 m_resultCollector.fail("Empty sample mask didn't produce correct pixel values");
1228 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1230 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1231 m_resultCollector.fail("Full sample mask didn't produce correct pixel values");
1235 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve is inconsistent between attachments" << tcu::TestLog::EndMessage;
1236 m_resultCollector.fail("Resolve is inconsistent between attachments");
1242 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1244 const int componentCount (tcu::getNumUsedChannels(format.order));
1245 const UVec4 bitDepth (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1246 const UVec4 renderValue (tcu::select((UVec4(1u) << tcu::min(UVec4(8u), bitDepth)) - UVec4(1u),
1247 UVec4(0u, 0u, 0u, 1u),
1248 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1249 const UVec4 clearValue (tcu::select(UVec4(0u),
1250 UVec4(0u, 0u, 0u, 1u),
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 y = 0; y < m_height; y++)
1257 for (deUint32 x = 0; x < m_width; x++)
1259 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1260 const UVec4 refColor (m_sampleMask == 0x0u
1262 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1264 : accesses[0].getPixelUint(x, y));
1266 errorMask.getAccess().setPixel(okColor, x, y);
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);
1275 unexpectedValues = tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true));
1276 inconsistentComponents = !(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true)));
1278 if (unexpectedValues || inconsistentComponents)
1279 errorMask.getAccess().setPixel(errorColor, x, y);
1282 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1284 const UVec4 color (accesses[attachmentNdx].getPixelUint(x, y));
1286 if (refColor != color)
1288 inconsistentAttachments = true;
1289 errorMask.getAccess().setPixel(errorColor, x, y);
1295 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1297 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1298 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1300 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1302 const std::string name ("Attachment" + de::toString(attachmentNdx));
1303 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), accesses[attachmentNdx]);
1306 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1308 if (m_sampleMask == 0x0u)
1310 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1311 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1313 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1315 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1316 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1320 if (unexpectedValues)
1322 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1323 m_resultCollector.fail("Resolve produced unexpected values");
1326 if (inconsistentComponents)
1328 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1329 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1332 if (inconsistentAttachments)
1334 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1335 m_resultCollector.fail("Different attachments were resolved to different values.");
1342 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1344 const int componentCount (tcu::getNumUsedChannels(format.order));
1345 const IVec4 bitDepth (tcu::getTextureFormatBitDepth(format));
1346 const IVec4 renderValue (tcu::select((IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))) - IVec4(1),
1348 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1349 const IVec4 clearValue (tcu::select(-(IVec4(1) << (tcu::min(IVec4(8), bitDepth) - IVec4(1))),
1351 tcu::lessThan(IVec4(0, 1, 2, 3), IVec4(componentCount))));
1352 bool unexpectedValues = false;
1353 bool inconsistentComponents = false;
1354 bool inconsistentAttachments = false;
1356 for (deUint32 y = 0; y < m_height; y++)
1357 for (deUint32 x = 0; x < m_width; x++)
1359 // Color has to be all zeros if no samples were covered, all 255 if all samples were covered or consistent across all attachments
1360 const IVec4 refColor (m_sampleMask == 0x0u
1362 : m_sampleMask == ((0x1u << m_sampleCount) - 1u)
1364 : accesses[0].getPixelInt(x, y));
1366 errorMask.getAccess().setPixel(okColor, x, y);
1368 // If reference value was taken from first attachment, check that it is valid value i.e. clear or render value
1369 if (m_sampleMask != 0x0u && m_sampleMask != ((0x1u << m_sampleCount) - 1u))
1371 // Each component must be resolved same way
1372 const BVec4 isRenderValue (refColor == renderValue);
1373 const BVec4 isClearValue (refColor == clearValue);
1375 unexpectedValues = tcu::anyNotEqual(tcu::logicalOr(isRenderValue, isClearValue), BVec4(true));
1376 inconsistentComponents = !(tcu::allEqual(isRenderValue, BVec4(true)) || tcu::allEqual(isClearValue, BVec4(true)));
1378 if (unexpectedValues || inconsistentComponents)
1379 errorMask.getAccess().setPixel(errorColor, x, y);
1383 if (unexpectedValues || inconsistentComponents || inconsistentAttachments)
1385 const std::string sectionName ("ResolveVerifyWithMask" + de::toString(m_sampleMask));
1386 const tcu::ScopedLogSection section (log, sectionName, sectionName);
1388 for (size_t attachmentNdx = 0; attachmentNdx < MAX_COLOR_ATTACHMENT_COUNT; attachmentNdx++)
1390 const std::string name ("Attachment" + de::toString(attachmentNdx));
1391 m_context.getTestContext().getLog() << tcu::LogImage(name.c_str(), name.c_str(), accesses[attachmentNdx]);
1394 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1396 if (m_sampleMask == 0x0u)
1398 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Empty sample mask didn't produce all " << clearValue << " pixels" << tcu::TestLog::EndMessage;
1399 m_resultCollector.fail("Empty sample mask didn't produce correct pixels");
1401 else if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1403 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Full sample mask didn't produce all " << renderValue << " pixels" << tcu::TestLog::EndMessage;
1404 m_resultCollector.fail("Full sample mask didn't produce correct pixels");
1408 if (unexpectedValues)
1410 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Resolve produced unexpected values i.e. not " << clearValue << " or " << renderValue << tcu::TestLog::EndMessage;
1411 m_resultCollector.fail("Resolve produced unexpected values");
1414 if (inconsistentComponents)
1416 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different components of attachment were resolved to different values." << tcu::TestLog::EndMessage;
1417 m_resultCollector.fail("Different components of attachment were resolved to different values.");
1420 if (inconsistentAttachments)
1422 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Different attachments were resolved to different values." << tcu::TestLog::EndMessage;
1423 m_resultCollector.fail("Different attachments were resolved to different values.");
1431 DE_FATAL("Unknown channel class");
1435 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1437 if (m_sampleMask == 0u)
1439 const tcu::TextureFormat format (mapVkFormat(m_format));
1440 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1441 tcu::TestLog& log (m_context.getTestContext().getLog());
1443 switch (channelClass)
1445 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1446 log << TestLog::Message << "Clearing target to zero and rendering 255 pixels with every possible sample mask" << TestLog::EndMessage;
1449 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1450 log << TestLog::Message << "Clearing target to -128 and rendering 127 pixels with every possible sample mask" << TestLog::EndMessage;
1453 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1454 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1455 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1456 log << TestLog::Message << "Clearing target to black and rendering white pixels with every possible sample mask" << TestLog::EndMessage;
1460 DE_FATAL("Unknown channel class");
1467 if (m_sampleMask == ((0x1u << m_sampleCount) - 1u))
1469 const tcu::TextureFormat format (mapVkFormat(m_format));
1470 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1471 tcu::TestLog& log (m_context.getTestContext().getLog());
1473 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT
1474 || channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT
1475 || channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1477 const float threshold = 0.05f;
1478 const int componentCount (tcu::getNumUsedChannels(format.order));
1479 const Vec4 errorColor (1.0f, 0.0f, 0.0f, 1.0f);
1480 const Vec4 okColor (0.0f, 0.0f, 0.0f, 1.0f);
1481 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), m_width, m_height);
1483 Vec4 maxDiff (0.0f);
1484 Vec4 expectedAverage;
1486 switch (channelClass)
1488 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1490 expectedAverage = Vec4(0.5f, componentCount > 1 ? 0.5f : 0.0f, componentCount > 2 ? 0.5f : 0.0f, componentCount > 3 ? 0.5f : 1.0f);
1494 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1495 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1497 expectedAverage = Vec4(0.0f, 0.0f, 0.0f, componentCount > 3 ? 0.0f : 1.0f);
1502 DE_FATAL("Unknown channel class");
1505 for (deUint32 y = 0; y < m_height; y++)
1506 for (deUint32 x = 0; x < m_width; x++)
1508 const Vec4 sum (m_sum.getAccess().getPixel(x, y));
1509 const Vec4 average (sum / Vec4((float)(0x1u << m_sampleCount)));
1510 const Vec4 diff (tcu::abs(average - expectedAverage));
1512 m_sum.getAccess().setPixel(average, x, y);
1513 errorMask.getAccess().setPixel(okColor, x, y);
1515 if (diff[0] > threshold
1516 || diff[1] > threshold
1517 || diff[2] > threshold
1518 || diff[3] > threshold)
1521 maxDiff = tcu::max(maxDiff, diff);
1522 errorMask.getAccess().setPixel(errorColor, x, y);
1526 log << TestLog::Image("Average resolved values in attachment 0", "Average resolved values in attachment 0", m_sum);
1530 m_context.getTestContext().getLog() << tcu::LogImage("ErrorMask", "ErrorMask", errorMask.getAccess());
1532 log << TestLog::Message << "Average resolved values differ from expected average values by more than " << threshold << " max per component diff " << maxDiff << TestLog::EndMessage;
1536 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1541 return tcu::TestStatus::incomplete();
1547 void init (vk::SourceCollections& dst, TestConfig config) const
1549 const tcu::TextureFormat format (mapVkFormat(config.format));
1550 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1552 dst.glslSources.add("quad-vert") << glu::VertexSource(
1554 "out gl_PerVertex {\n"
1555 "\tvec4 gl_Position;\n"
1558 "void main (void) {\n"
1559 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1560 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1563 switch (channelClass)
1565 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1566 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1568 "layout(push_constant) uniform PushConstant {\n"
1569 "\thighp uint sampleMask;\n"
1570 "} pushConstants;\n"
1571 "layout(location = 0) out highp uvec4 o_color0;\n"
1572 "layout(location = 1) out highp uvec4 o_color1;\n"
1573 "layout(location = 2) out highp uvec4 o_color2;\n"
1574 "layout(location = 3) out highp uvec4 o_color3;\n"
1575 "void main (void)\n"
1577 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1578 "\to_color0 = uvec4(255);\n"
1579 "\to_color1 = uvec4(255);\n"
1580 "\to_color2 = uvec4(255);\n"
1581 "\to_color3 = uvec4(255);\n"
1585 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1586 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1588 "layout(push_constant) uniform PushConstant {\n"
1589 "\thighp uint sampleMask;\n"
1590 "} pushConstants;\n"
1591 "layout(location = 0) out highp ivec4 o_color0;\n"
1592 "layout(location = 1) out highp ivec4 o_color1;\n"
1593 "layout(location = 2) out highp ivec4 o_color2;\n"
1594 "layout(location = 3) out highp ivec4 o_color3;\n"
1595 "void main (void)\n"
1597 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1598 "\to_color0 = ivec4(127);\n"
1599 "\to_color1 = ivec4(127);\n"
1600 "\to_color2 = ivec4(127);\n"
1601 "\to_color3 = ivec4(127);\n"
1605 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1606 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1607 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1608 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1610 "layout(push_constant) uniform PushConstant {\n"
1611 "\thighp uint sampleMask;\n"
1612 "} pushConstants;\n"
1613 "layout(location = 0) out highp vec4 o_color0;\n"
1614 "layout(location = 1) out highp vec4 o_color1;\n"
1615 "layout(location = 2) out highp vec4 o_color2;\n"
1616 "layout(location = 3) out highp vec4 o_color3;\n"
1617 "void main (void)\n"
1619 "\tgl_SampleMask[0] = int(pushConstants.sampleMask);\n"
1620 "\to_color0 = vec4(1.0);\n"
1621 "\to_color1 = vec4(1.0);\n"
1622 "\to_color2 = vec4(1.0);\n"
1623 "\to_color3 = vec4(1.0);\n"
1628 DE_FATAL("Unknown channel class");
1633 std::string formatToName (VkFormat format)
1635 const std::string formatStr = de::toString(format);
1636 const std::string prefix = "VK_FORMAT_";
1638 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1640 return de::toLower(formatStr.substr(prefix.length()));
1643 void initTests (tcu::TestCaseGroup* group)
1645 static const VkFormat formats[] =
1647 VK_FORMAT_R5G6B5_UNORM_PACK16,
1652 VK_FORMAT_R8G8_UNORM,
1653 VK_FORMAT_R8G8_SNORM,
1654 VK_FORMAT_R8G8_UINT,
1655 VK_FORMAT_R8G8_SINT,
1656 VK_FORMAT_R8G8B8A8_UNORM,
1657 VK_FORMAT_R8G8B8A8_SNORM,
1658 VK_FORMAT_R8G8B8A8_UINT,
1659 VK_FORMAT_R8G8B8A8_SINT,
1660 VK_FORMAT_R8G8B8A8_SRGB,
1661 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1662 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1663 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1664 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1665 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1666 VK_FORMAT_B8G8R8A8_UNORM,
1667 VK_FORMAT_B8G8R8A8_SRGB,
1668 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1669 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1670 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1671 VK_FORMAT_R16_UNORM,
1672 VK_FORMAT_R16_SNORM,
1675 VK_FORMAT_R16_SFLOAT,
1676 VK_FORMAT_R16G16_UNORM,
1677 VK_FORMAT_R16G16_SNORM,
1678 VK_FORMAT_R16G16_UINT,
1679 VK_FORMAT_R16G16_SINT,
1680 VK_FORMAT_R16G16_SFLOAT,
1681 VK_FORMAT_R16G16B16A16_UNORM,
1682 VK_FORMAT_R16G16B16A16_SNORM,
1683 VK_FORMAT_R16G16B16A16_UINT,
1684 VK_FORMAT_R16G16B16A16_SINT,
1685 VK_FORMAT_R16G16B16A16_SFLOAT,
1688 VK_FORMAT_R32_SFLOAT,
1689 VK_FORMAT_R32G32_UINT,
1690 VK_FORMAT_R32G32_SINT,
1691 VK_FORMAT_R32G32_SFLOAT,
1692 VK_FORMAT_R32G32B32A32_UINT,
1693 VK_FORMAT_R32G32B32A32_SINT,
1694 VK_FORMAT_R32G32B32A32_SFLOAT,
1696 const deUint32 sampleCounts[] =
1700 tcu::TestContext& testCtx (group->getTestContext());
1702 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1704 const VkFormat format (formats[formatNdx]);
1705 const std::string formatName (formatToName(format));
1706 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
1708 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1710 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1711 const std::string testName ("samples_" + de::toString(sampleCount));
1713 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), TestConfig(format, sampleCount)));
1716 group->addChild(formatGroup.release());
1722 tcu::TestCaseGroup* createRenderPassMultisampleResolveTests (tcu::TestContext& testCtx)
1724 return createTestGroup(testCtx, "multisample_resolve", "Multisample render pass resolve tests", initTests);