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 passses with multisample attachments
22 *//*--------------------------------------------------------------------*/
24 #include "vktRenderPassMultisampleTests.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 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
105 const tcu::TextureFormat format (mapVkFormat(vkFormat));
106 const bool hasDepth (tcu::hasDepthComponent(format.order));
107 const bool hasStencil (tcu::hasStencilComponent(format.order));
109 if (hasDepth || hasStencil)
111 return (hasDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0u)
112 | (hasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0u);
115 return VK_IMAGE_ASPECT_COLOR_BIT;
118 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
120 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
123 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
125 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
128 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
130 Allocator& allocator,
133 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
134 bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
138 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
140 Allocator& allocator,
143 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
144 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
148 Move<VkImage> createImage (const DeviceInterface& vk,
150 VkImageCreateFlags flags,
151 VkImageType imageType,
155 deUint32 arrayLayers,
156 VkSampleCountFlagBits samples,
157 VkImageTiling tiling,
158 VkImageUsageFlags usage,
159 VkSharingMode sharingMode,
160 deUint32 queueFamilyCount,
161 const deUint32* pQueueFamilyIndices,
162 VkImageLayout initialLayout)
164 const VkImageCreateInfo pCreateInfo =
166 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
182 return createImage(vk, device, &pCreateInfo);
185 Move<VkImageView> createImageView (const DeviceInterface& vk,
187 VkImageViewCreateFlags flags,
189 VkImageViewType viewType,
191 VkComponentMapping components,
192 VkImageSubresourceRange subresourceRange)
194 const VkImageViewCreateInfo pCreateInfo =
196 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
205 return createImageView(vk, device, &pCreateInfo);
208 Move<VkImage> createImage (const InstanceInterface& vki,
209 VkPhysicalDevice physicalDevice,
210 const DeviceInterface& vkd,
213 VkSampleCountFlagBits sampleCountBit,
214 VkImageUsageFlags usage,
220 const tcu::TextureFormat format (mapVkFormat(vkFormat));
221 const VkImageType imageType (VK_IMAGE_TYPE_2D);
222 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
223 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
224 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
225 const VkExtent3D imageExtent =
232 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
233 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
234 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
236 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
237 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
238 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
240 if (imageFormatProperties.maxExtent.width < imageExtent.width
241 || imageFormatProperties.maxExtent.height < imageExtent.height
242 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
244 TCU_THROW(NotSupportedError, "Image type not supported");
247 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED);
249 catch (const vk::Error& error)
251 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
252 TCU_THROW(NotSupportedError, "Image format not supported");
258 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vkd,
262 VkImageAspectFlags aspect)
264 const VkImageSubresourceRange range =
273 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
276 Move<VkImageView> createSrcPrimaryInputImageView (const DeviceInterface& vkd,
280 VkImageAspectFlags aspect)
282 const VkImageSubresourceRange range =
284 aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
285 ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT
293 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
296 Move<VkImageView> createSrcSecondaryInputImageView (const DeviceInterface& vkd,
300 VkImageAspectFlags aspect)
302 if (aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT))
304 const VkImageSubresourceRange range =
306 VK_IMAGE_ASPECT_STENCIL_BIT,
313 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
316 return Move<VkImageView>();
319 VkDeviceSize getPixelSize (VkFormat vkFormat)
321 const tcu::TextureFormat format (mapVkFormat(vkFormat));
323 return format.getPixelSize();
326 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
332 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
333 const VkDeviceSize pixelSize (getPixelSize(format));
334 const VkBufferCreateInfo createInfo =
336 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
340 width * height * pixelSize,
343 VK_SHARING_MODE_EXCLUSIVE,
347 return createBuffer(vkd, device, &createInfo);
350 VkSampleCountFlagBits sampleCountBitFromomSampleCount (deUint32 count)
354 case 1: return VK_SAMPLE_COUNT_1_BIT;
355 case 2: return VK_SAMPLE_COUNT_2_BIT;
356 case 4: return VK_SAMPLE_COUNT_4_BIT;
357 case 8: return VK_SAMPLE_COUNT_8_BIT;
358 case 16: return VK_SAMPLE_COUNT_16_BIT;
359 case 32: return VK_SAMPLE_COUNT_32_BIT;
360 case 64: return VK_SAMPLE_COUNT_64_BIT;
363 DE_FATAL("Invalid sample count");
364 return (VkSampleCountFlagBits)(0x1u << count);
368 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface& vki,
369 VkPhysicalDevice physicalDevice,
370 const DeviceInterface& vkd,
373 deUint32 sampleCount,
377 std::vector<VkImageSp> images (sampleCount);
379 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
380 images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromomSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));
385 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface& vki,
386 VkPhysicalDevice physicalDevice,
387 const DeviceInterface& vkd,
390 deUint32 sampleCount,
394 std::vector<VkImageSp> images (sampleCount);
396 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
397 images[imageNdx] = safeSharedPtr(new vk::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)));
402 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface& vkd,
404 Allocator& allocator,
405 const std::vector<VkImageSp> images)
407 std::vector<de::SharedPtr<Allocation> > memory (images.size());
409 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
410 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
415 std::vector<VkImageViewSp> createImageAttachmentViews (const DeviceInterface& vkd,
417 const std::vector<VkImageSp>& images,
419 VkImageAspectFlagBits aspect)
421 std::vector<VkImageViewSp> views (images.size());
423 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
424 views[imageNdx] = safeSharedPtr(new vk::Unique<VkImageView>(createImageAttachmentView(vkd, device, **images[imageNdx], format, aspect)));
429 std::vector<VkBufferSp> createBuffers (const DeviceInterface& vkd,
432 deUint32 sampleCount,
436 std::vector<VkBufferSp> buffers (sampleCount);
438 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
439 buffers[bufferNdx] = safeSharedPtr(new vk::Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));
444 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface& vkd,
446 Allocator& allocator,
447 const std::vector<VkBufferSp> buffers)
449 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
451 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
452 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
457 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
461 deUint32 sampleCount)
463 const VkSampleCountFlagBits samples (sampleCountBitFromomSampleCount(sampleCount));
464 const deUint32 splitSubpassCount (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT));
465 const tcu::TextureFormat format (mapVkFormat(srcFormat));
466 const bool isDepthStencilFormat (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
467 vector<VkSubpassDescription> subpasses;
468 vector<vector<VkAttachmentReference> > dstAttachmentRefs (splitSubpassCount);
469 vector<vector<VkAttachmentReference> > dstResolveAttachmentRefs (splitSubpassCount);
470 vector<VkAttachmentDescription> attachments;
471 vector<VkSubpassDependency> dependencies;
472 const VkAttachmentReference srcAttachmentRef =
476 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
477 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
479 const VkAttachmentReference srcAttachmentInputRef =
482 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
486 const VkAttachmentDescription srcAttachment =
493 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
494 VK_ATTACHMENT_STORE_OP_DONT_CARE,
496 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
497 VK_ATTACHMENT_STORE_OP_DONT_CARE,
499 VK_IMAGE_LAYOUT_UNDEFINED,
500 VK_IMAGE_LAYOUT_GENERAL
503 attachments.push_back(srcAttachment);
506 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
508 for (deUint32 sampleNdx = 0; sampleNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount - splitSubpassIndex * MAX_COLOR_ATTACHMENT_COUNT); sampleNdx++)
510 // Multisample color attachment
512 const VkAttachmentDescription dstAttachment =
519 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
520 VK_ATTACHMENT_STORE_OP_DONT_CARE,
522 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
523 VK_ATTACHMENT_STORE_OP_DONT_CARE,
525 VK_IMAGE_LAYOUT_UNDEFINED,
526 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
528 const VkAttachmentReference dstAttachmentRef =
530 (deUint32)attachments.size(),
531 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
534 attachments.push_back(dstAttachment);
535 dstAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
537 // Resolve attachment
539 const VkAttachmentDescription dstAttachment =
544 VK_SAMPLE_COUNT_1_BIT,
546 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
547 VK_ATTACHMENT_STORE_OP_STORE,
549 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
550 VK_ATTACHMENT_STORE_OP_STORE,
552 VK_IMAGE_LAYOUT_UNDEFINED,
553 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL
555 const VkAttachmentReference dstAttachmentRef =
557 (deUint32)attachments.size(),
558 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
561 attachments.push_back(dstAttachment);
562 dstResolveAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
569 const VkSubpassDescription subpass =
571 (VkSubpassDescriptionFlags)0,
572 VK_PIPELINE_BIND_POINT_GRAPHICS,
577 isDepthStencilFormat ? 0u : 1u,
578 isDepthStencilFormat ? DE_NULL : &srcAttachmentRef,
581 isDepthStencilFormat ? &srcAttachmentRef : DE_NULL,
586 subpasses.push_back(subpass);
589 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
592 const VkSubpassDescription subpass =
594 (VkSubpassDescriptionFlags)0,
595 VK_PIPELINE_BIND_POINT_GRAPHICS,
598 &srcAttachmentInputRef,
600 (deUint32)dstAttachmentRefs[splitSubpassIndex].size(),
601 &dstAttachmentRefs[splitSubpassIndex][0],
602 &dstResolveAttachmentRefs[splitSubpassIndex][0],
608 subpasses.push_back(subpass);
611 const VkSubpassDependency dependency =
613 0u, splitSubpassIndex + 1,
614 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
615 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
617 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
618 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
620 VK_DEPENDENCY_BY_REGION_BIT
623 dependencies.push_back(dependency);
626 const VkRenderPassCreateInfo createInfo =
628 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
630 (VkRenderPassCreateFlags)0u,
632 (deUint32)attachments.size(),
635 (deUint32)subpasses.size(),
638 (deUint32)dependencies.size(),
642 return createRenderPass(vkd, device, &createInfo);
646 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
648 VkRenderPass renderPass,
649 VkImageView srcImageView,
650 const std::vector<VkImageViewSp>& dstMultisampleImageViews,
651 const std::vector<VkImageViewSp>& dstSinglesampleImageViews,
655 std::vector<VkImageView> attachments;
657 attachments.reserve(dstMultisampleImageViews.size() + dstSinglesampleImageViews.size() + 1u);
659 attachments.push_back(srcImageView);
661 DE_ASSERT(dstMultisampleImageViews.size() == dstSinglesampleImageViews.size());
663 for (size_t ndx = 0; ndx < dstMultisampleImageViews.size(); ndx++)
665 attachments.push_back(**dstMultisampleImageViews[ndx]);
666 attachments.push_back(**dstSinglesampleImageViews[ndx]);
669 const VkFramebufferCreateInfo createInfo =
671 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
676 (deUint32)attachments.size(),
684 return createFramebuffer(vkd, device, &createInfo);
687 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
690 const VkPushConstantRange pushConstant =
692 VK_SHADER_STAGE_FRAGMENT_BIT,
696 const VkPipelineLayoutCreateInfo createInfo =
698 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
700 (vk::VkPipelineLayoutCreateFlags)0,
709 return createPipelineLayout(vkd, device, &createInfo);
712 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
715 VkRenderPass renderPass,
716 VkPipelineLayout pipelineLayout,
717 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
720 deUint32 sampleCount)
722 const tcu::TextureFormat format (mapVkFormat(srcFormat));
723 const bool isDepthStencilFormat (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
725 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
726 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
727 const VkSpecializationInfo emptyShaderSpecializations =
736 const VkPipelineColorBlendAttachmentState attachmentBlendState =
739 VK_BLEND_FACTOR_SRC_ALPHA,
740 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
745 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
747 const VkPipelineShaderStageCreateInfo shaderStages[2] =
750 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
752 (VkPipelineShaderStageCreateFlags)0u,
753 VK_SHADER_STAGE_VERTEX_BIT,
756 &emptyShaderSpecializations
759 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
761 (VkPipelineShaderStageCreateFlags)0u,
762 VK_SHADER_STAGE_FRAGMENT_BIT,
763 *fragmentShaderModule,
765 &emptyShaderSpecializations
768 const VkPipelineVertexInputStateCreateInfo vertexInputState =
770 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
772 (VkPipelineVertexInputStateCreateFlags)0u,
780 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
782 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
785 (VkPipelineInputAssemblyStateCreateFlags)0u,
786 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
789 const VkViewport viewport =
792 (float)width, (float)height,
796 const VkRect2D scissor =
801 const VkPipelineViewportStateCreateInfo viewportState =
803 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
805 (VkPipelineViewportStateCreateFlags)0u,
813 const VkPipelineRasterizationStateCreateInfo rasterState =
815 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
817 (VkPipelineRasterizationStateCreateFlags)0u,
820 VK_POLYGON_MODE_FILL,
822 VK_FRONT_FACE_COUNTER_CLOCKWISE,
829 const VkPipelineMultisampleStateCreateInfo multisampleState =
831 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
833 (VkPipelineMultisampleStateCreateFlags)0u,
835 sampleCountBitFromomSampleCount(sampleCount),
842 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
844 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
846 (VkPipelineDepthStencilStateCreateFlags)0u,
850 VK_COMPARE_OP_ALWAYS,
855 VK_STENCIL_OP_INCREMENT_AND_WRAP,
857 VK_COMPARE_OP_ALWAYS,
860 0xFFu / (sampleCount + 1)
864 VK_STENCIL_OP_INCREMENT_AND_WRAP,
866 VK_COMPARE_OP_ALWAYS,
869 0xFFu / (sampleCount + 1)
875 const VkPipelineColorBlendStateCreateInfo blendState =
877 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
879 (VkPipelineColorBlendStateCreateFlags)0u,
883 (isDepthStencilFormat ? 0u : 1u),
884 (isDepthStencilFormat ? DE_NULL : &attachmentBlendState),
885 { 0.0f, 0.0f, 0.0f, 0.0f }
887 const VkGraphicsPipelineCreateInfo createInfo =
889 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
891 (VkPipelineCreateFlags)0u,
904 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,
913 return createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
916 Move<VkDescriptorSetLayout> createSplitDescriptorSetLayout (const DeviceInterface& vkd,
920 const tcu::TextureFormat format (mapVkFormat(vkFormat));
921 const bool hasDepth (tcu::hasDepthComponent(format.order));
922 const bool hasStencil (tcu::hasStencilComponent(format.order));
923 const VkDescriptorSetLayoutBinding bindings[] =
927 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
929 VK_SHADER_STAGE_FRAGMENT_BIT,
934 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
936 VK_SHADER_STAGE_FRAGMENT_BIT,
940 const VkDescriptorSetLayoutCreateInfo createInfo =
942 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
946 hasDepth && hasStencil ? 2u : 1u,
950 return createDescriptorSetLayout(vkd, device, &createInfo);
953 Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface& vkd,
955 VkDescriptorSetLayout descriptorSetLayout)
957 const VkPushConstantRange pushConstant =
959 VK_SHADER_STAGE_FRAGMENT_BIT,
963 const VkPipelineLayoutCreateInfo createInfo =
965 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
967 (vk::VkPipelineLayoutCreateFlags)0,
970 &descriptorSetLayout,
976 return createPipelineLayout(vkd, device, &createInfo);
979 Move<VkPipeline> createSplitPipeline (const DeviceInterface& vkd,
981 VkRenderPass renderPass,
982 deUint32 subpassIndex,
983 VkPipelineLayout pipelineLayout,
984 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
987 deUint32 sampleCount)
989 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
990 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 0u));
991 const VkSpecializationInfo emptyShaderSpecializations =
1000 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1003 VK_BLEND_FACTOR_SRC_ALPHA,
1004 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1006 VK_BLEND_FACTOR_ONE,
1007 VK_BLEND_FACTOR_ONE,
1009 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1011 const std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates (de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount), attachmentBlendState);
1012 const VkPipelineShaderStageCreateInfo shaderStages[2] =
1015 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1017 (VkPipelineShaderStageCreateFlags)0u,
1018 VK_SHADER_STAGE_VERTEX_BIT,
1019 *vertexShaderModule,
1021 &emptyShaderSpecializations
1024 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1026 (VkPipelineShaderStageCreateFlags)0u,
1027 VK_SHADER_STAGE_FRAGMENT_BIT,
1028 *fragmentShaderModule,
1030 &emptyShaderSpecializations
1033 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1035 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1037 (VkPipelineVertexInputStateCreateFlags)0u,
1045 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
1047 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1050 (VkPipelineInputAssemblyStateCreateFlags)0u,
1051 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
1054 const VkViewport viewport =
1057 (float)width, (float)height,
1061 const VkRect2D scissor =
1066 const VkPipelineViewportStateCreateInfo viewportState =
1068 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1070 (VkPipelineViewportStateCreateFlags)0u,
1078 const VkPipelineRasterizationStateCreateInfo rasterState =
1080 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1082 (VkPipelineRasterizationStateCreateFlags)0u,
1085 VK_POLYGON_MODE_FILL,
1087 VK_FRONT_FACE_COUNTER_CLOCKWISE,
1094 const VkPipelineMultisampleStateCreateInfo multisampleState =
1096 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1098 (VkPipelineMultisampleStateCreateFlags)0u,
1100 sampleCountBitFromomSampleCount(sampleCount),
1107 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
1109 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1111 (VkPipelineDepthStencilStateCreateFlags)0u,
1115 VK_COMPARE_OP_ALWAYS,
1119 VK_STENCIL_OP_REPLACE,
1120 VK_STENCIL_OP_REPLACE,
1121 VK_STENCIL_OP_REPLACE,
1122 VK_COMPARE_OP_ALWAYS,
1128 VK_STENCIL_OP_REPLACE,
1129 VK_STENCIL_OP_REPLACE,
1130 VK_STENCIL_OP_REPLACE,
1131 VK_COMPARE_OP_ALWAYS,
1140 const VkPipelineColorBlendStateCreateInfo blendState =
1142 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1144 (VkPipelineColorBlendStateCreateFlags)0u,
1149 (deUint32)attachmentBlendStates.size(),
1150 &attachmentBlendStates[0],
1152 { 0.0f, 0.0f, 0.0f, 0.0f }
1154 const VkGraphicsPipelineCreateInfo createInfo =
1156 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1158 (VkPipelineCreateFlags)0u,
1164 &inputAssemblyState,
1171 (const VkPipelineDynamicStateCreateInfo*)DE_NULL,
1180 return createGraphicsPipeline(vkd, device, DE_NULL, &createInfo);
1183 vector<VkPipelineSp> createSplitPipelines (const DeviceInterface& vkd,
1185 VkRenderPass renderPass,
1186 VkPipelineLayout pipelineLayout,
1187 const vk::ProgramCollection<vk::ProgramBinary>& binaryCollection,
1190 deUint32 sampleCount)
1192 std::vector<VkPipelineSp> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipelineSp)0u);
1194 for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
1195 pipelines[ndx] = safeSharedPtr(new Unique<VkPipeline>(createSplitPipeline(vkd, device, renderPass, (deUint32)(ndx + 1), pipelineLayout, binaryCollection, width, height, sampleCount)));
1200 Move<VkDescriptorPool> createSplitDescriptorPool (const DeviceInterface& vkd,
1203 const VkDescriptorPoolSize size =
1205 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
1207 const VkDescriptorPoolCreateInfo createInfo =
1209 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1211 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1219 return createDescriptorPool(vkd, device, &createInfo);
1222 Move<VkDescriptorSet> createSplitDescriptorSet (const DeviceInterface& vkd,
1224 VkDescriptorPool pool,
1225 VkDescriptorSetLayout layout,
1226 VkImageView primaryImageView,
1227 VkImageView secondaryImageView)
1229 const VkDescriptorSetAllocateInfo allocateInfo =
1231 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1238 Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));
1241 const VkDescriptorImageInfo imageInfos[] =
1246 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1251 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1254 const VkWriteDescriptorSet writes[] =
1257 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1264 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1270 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1277 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1283 const deUint32 count = secondaryImageView != (VkImageView)0
1287 vkd.updateDescriptorSets(device, count, writes, 0u, DE_NULL);
1294 TestConfig (VkFormat format_,
1295 deUint32 sampleCount_)
1297 , sampleCount (sampleCount_)
1302 deUint32 sampleCount;
1305 VkImageUsageFlags getSrcImageUsage (VkFormat vkFormat)
1307 const tcu::TextureFormat format (mapVkFormat(vkFormat));
1308 const bool hasDepth (tcu::hasDepthComponent(format.order));
1309 const bool hasStencil (tcu::hasStencilComponent(format.order));
1311 if (hasDepth || hasStencil)
1312 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1314 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1317 VkFormat getDstFormat (VkFormat vkFormat)
1319 const tcu::TextureFormat format (mapVkFormat(vkFormat));
1320 const bool hasDepth (tcu::hasDepthComponent(format.order));
1321 const bool hasStencil (tcu::hasStencilComponent(format.order));
1323 if (hasDepth && hasStencil)
1324 return VK_FORMAT_R32G32_SFLOAT;
1325 else if (hasDepth || hasStencil)
1326 return VK_FORMAT_R32_SFLOAT;
1332 class MultisampleRenderPassTestInstance : public TestInstance
1335 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
1336 ~MultisampleRenderPassTestInstance (void);
1338 tcu::TestStatus iterate (void);
1341 const VkFormat m_srcFormat;
1342 const VkFormat m_dstFormat;
1343 const deUint32 m_sampleCount;
1344 const deUint32 m_width;
1345 const deUint32 m_height;
1347 const VkImageAspectFlags m_srcImageAspect;
1348 const VkImageUsageFlags m_srcImageUsage;
1349 const Unique<VkImage> m_srcImage;
1350 const de::UniquePtr<Allocation> m_srcImageMemory;
1351 const Unique<VkImageView> m_srcImageView;
1352 const Unique<VkImageView> m_srcPrimaryInputImageView;
1353 const Unique<VkImageView> m_srcSecondaryInputImageView;
1355 const std::vector<VkImageSp> m_dstMultisampleImages;
1356 const std::vector<de::SharedPtr<Allocation> > m_dstMultisampleImageMemory;
1357 const std::vector<VkImageViewSp> m_dstMultisampleImageViews;
1359 const std::vector<VkImageSp> m_dstSinglesampleImages;
1360 const std::vector<de::SharedPtr<Allocation> > m_dstSinglesampleImageMemory;
1361 const std::vector<VkImageViewSp> m_dstSinglesampleImageViews;
1363 const std::vector<VkBufferSp> m_dstBuffers;
1364 const std::vector<de::SharedPtr<Allocation> > m_dstBufferMemory;
1366 const Unique<VkRenderPass> m_renderPass;
1367 const Unique<VkFramebuffer> m_framebuffer;
1369 const Unique<VkPipelineLayout> m_renderPipelineLayout;
1370 const Unique<VkPipeline> m_renderPipeline;
1372 const Unique<VkDescriptorSetLayout> m_splitDescriptorSetLayout;
1373 const Unique<VkPipelineLayout> m_splitPipelineLayout;
1374 const std::vector<VkPipelineSp> m_splitPipelines;
1375 const Unique<VkDescriptorPool> m_splitDescriptorPool;
1376 const Unique<VkDescriptorSet> m_splitDescriptorSet;
1378 const Unique<VkCommandPool> m_commandPool;
1379 tcu::ResultCollector m_resultCollector;
1382 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1383 : TestInstance (context)
1384 , m_srcFormat (config.format)
1385 , m_dstFormat (getDstFormat(config.format))
1386 , m_sampleCount (config.sampleCount)
1390 , m_srcImageAspect (getImageAspectFlags(m_srcFormat))
1391 , m_srcImageUsage (getSrcImageUsage(m_srcFormat))
1392 , m_srcImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height))
1393 , m_srcImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1394 , m_srcImageView (createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1395 , m_srcPrimaryInputImageView (createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1396 , m_srcSecondaryInputImageView (createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1398 , m_dstMultisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1399 , m_dstMultisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1400 , m_dstMultisampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1402 , m_dstSinglesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1403 , m_dstSinglesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1404 , m_dstSinglesampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1406 , m_dstBuffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1407 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1409 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount))
1410 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1412 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1413 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1415 , m_splitDescriptorSetLayout (createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1416 , m_splitPipelineLayout (createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1417 , m_splitPipelines (createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1418 , m_splitDescriptorPool (createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1419 , m_splitDescriptorSet (createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1420 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1424 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1428 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1430 const DeviceInterface& vkd (m_context.getDeviceInterface());
1431 const VkDevice device (m_context.getDevice());
1432 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1435 const VkCommandBufferBeginInfo beginInfo =
1437 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1440 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
1444 VK_CHECK(vkd.beginCommandBuffer(*commandBuffer, &beginInfo));
1448 const VkRenderPassBeginInfo beginInfo =
1450 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1458 { m_width, m_height }
1464 vkd.cmdBeginRenderPass(*commandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
1466 // Stencil needs to be cleared if it exists.
1467 if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
1469 const VkClearAttachment clearAttachment =
1471 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
1472 0, // deUint32 colorAttachment;
1473 makeClearValueDepthStencil(0, 0) // VkClearValue clearValue;
1476 const VkClearRect clearRect =
1480 { m_width, m_height }
1482 0, // deUint32 baseArrayLayer;
1483 1 // deUint32 layerCount;
1486 vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
1490 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1492 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1494 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1495 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1498 for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1500 vkd.cmdNextSubpass(*commandBuffer, VK_SUBPASS_CONTENTS_INLINE);
1502 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
1503 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u, &*m_splitDescriptorSet, 0u, DE_NULL);
1504 vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1505 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1508 vkd.cmdEndRenderPass(*commandBuffer);
1510 // Memory barriers between rendering and copies
1512 std::vector<VkImageMemoryBarrier> barriers;
1514 for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1516 const VkImageMemoryBarrier barrier =
1518 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1521 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1522 VK_ACCESS_TRANSFER_READ_BIT,
1524 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1525 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1527 VK_QUEUE_FAMILY_IGNORED,
1528 VK_QUEUE_FAMILY_IGNORED,
1530 **m_dstSinglesampleImages[dstNdx],
1532 VK_IMAGE_ASPECT_COLOR_BIT,
1540 barriers.push_back(barrier);
1543 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]);
1546 // Copy image memory to buffers
1547 for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1549 const VkBufferImageCopy region =
1555 VK_IMAGE_ASPECT_COLOR_BIT,
1561 { m_width, m_height, 1u }
1564 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_dstSinglesampleImages[dstNdx], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_dstBuffers[dstNdx], 1u, ®ion);
1567 // Memory barriers between copies and host access
1569 std::vector<VkBufferMemoryBarrier> barriers;
1571 for (size_t dstNdx = 0; dstNdx < m_dstBuffers.size(); dstNdx++)
1573 const VkBufferMemoryBarrier barrier =
1575 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1578 VK_ACCESS_TRANSFER_WRITE_BIT,
1579 VK_ACCESS_HOST_READ_BIT,
1581 VK_QUEUE_FAMILY_IGNORED,
1582 VK_QUEUE_FAMILY_IGNORED,
1584 **m_dstBuffers[dstNdx],
1589 barriers.push_back(barrier);
1592 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, (deUint32)barriers.size(), &barriers[0], 0u, DE_NULL);
1595 VK_CHECK(vkd.endCommandBuffer(*commandBuffer));
1598 const VkSubmitInfo submitInfo =
1600 VK_STRUCTURE_TYPE_SUBMIT_INFO,
1614 VK_CHECK(vkd.queueSubmit(m_context.getUniversalQueue(), 1u, &submitInfo, (VkFence)0u));
1616 VK_CHECK(vkd.queueWaitIdle(m_context.getUniversalQueue()));
1620 const tcu::TextureFormat format (mapVkFormat(m_dstFormat));
1621 const tcu::TextureFormat srcFormat (mapVkFormat(m_srcFormat));
1622 const bool hasDepth (tcu::hasDepthComponent(srcFormat.order));
1623 const bool hasStencil (tcu::hasStencilComponent(srcFormat.order));
1625 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1627 const std::string name ("Sample" + de::toString(sampleNdx));
1628 const void* const ptr (m_dstBufferMemory[sampleNdx]->getHostPtr());
1629 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
1630 tcu::TextureLevel reference (format, m_width, m_height);
1632 if (hasDepth || hasStencil)
1636 for (deUint32 y = 0; y < m_height; y++)
1637 for (deUint32 x = 0; x < m_width; x++)
1639 const deUint32 x1 = x ^ sampleNdx;
1640 const deUint32 y1 = y ^ sampleNdx;
1641 const float range = 1.0f;
1643 deUint32 divider = 2;
1645 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1646 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1648 depth += (range / (float)divider)
1649 * (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1653 reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1658 for (deUint32 y = 0; y < m_height; y++)
1659 for (deUint32 x = 0; x < m_width; x++)
1661 const deUint32 stencil = sampleNdx + 1u;
1665 const Vec4 src (reference.getAccess().getPixel(x, y));
1667 reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1670 reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1674 const Vec4 threshold (hasDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1676 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1677 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1682 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1684 switch (channelClass)
1686 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1688 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1689 const UVec4 minValue (0);
1690 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1691 const int componentCount (tcu::getNumUsedChannels(format.order));
1692 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1694 for (deUint32 y = 0; y < m_height; y++)
1695 for (deUint32 x = 0; x < m_width; x++)
1697 const deUint32 x1 = x ^ sampleNdx;
1698 const deUint32 y1 = y ^ sampleNdx;
1699 UVec4 color (minValue);
1700 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1701 deUint32 nextSrcBit = 0;
1702 deUint32 divider = 2;
1704 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1705 while (nextSrcBit < de::min(bitSize, 10u))
1707 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1709 if (dstBitsUsed[compNdx] > bits[compNdx])
1712 color[compNdx] += (range[compNdx] / divider)
1713 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1716 dstBitsUsed[compNdx]++;
1722 reference.getAccess().setPixel(color, x, y);
1725 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1726 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1731 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1733 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1734 const IVec4 minValue (0);
1735 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1736 const int componentCount (tcu::getNumUsedChannels(format.order));
1737 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1739 for (deUint32 y = 0; y < m_height; y++)
1740 for (deUint32 x = 0; x < m_width; x++)
1742 const deUint32 x1 = x ^ sampleNdx;
1743 const deUint32 y1 = y ^ sampleNdx;
1744 IVec4 color (minValue);
1745 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1746 deUint32 nextSrcBit = 0;
1747 deUint32 divider = 2;
1749 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1750 while (nextSrcBit < de::min(bitSize, 10u))
1752 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1754 if (dstBitsUsed[compNdx] > bits[compNdx])
1757 color[compNdx] += (range[compNdx] / divider)
1758 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1761 dstBitsUsed[compNdx]++;
1767 reference.getAccess().setPixel(color, x, y);
1770 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1771 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1776 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1777 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1778 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1780 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
1781 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1782 const Vec4 minLimit (-65536.0);
1783 const Vec4 maxLimit (65536.0);
1784 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
1785 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
1786 const int componentCount (tcu::getNumUsedChannels(format.order));
1787 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1789 for (deUint32 y = 0; y < m_height; y++)
1790 for (deUint32 x = 0; x < m_width; x++)
1792 const deUint32 x1 = x ^ sampleNdx;
1793 const deUint32 y1 = y ^ sampleNdx;
1794 Vec4 color (minValue);
1795 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1796 deUint32 nextSrcBit = 0;
1797 deUint32 divider = 2;
1799 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1800 while (nextSrcBit < de::min(bitSize, 10u))
1802 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1804 if (dstBitsUsed[compNdx] > bits[compNdx])
1807 color[compNdx] += (range[compNdx] / (float)divider)
1808 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1811 dstBitsUsed[compNdx]++;
1817 if (tcu::isSRGB(format))
1818 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1820 reference.getAccess().setPixel(color, x, y);
1823 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1825 // Convert target format ulps to float ulps and allow 64ulp differences
1826 const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1828 if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1829 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1833 // Allow error of 4 times the minimum presentable difference
1834 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1836 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1837 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1844 DE_FATAL("Unknown channel class");
1850 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1855 void init (vk::SourceCollections& dst, TestConfig config) const
1857 const tcu::TextureFormat format (mapVkFormat(config.format));
1858 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1860 dst.glslSources.add("quad-vert") << glu::VertexSource(
1862 "out gl_PerVertex {\n"
1863 "\tvec4 gl_Position;\n"
1866 "void main (void) {\n"
1867 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1868 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1871 if (tcu::hasDepthComponent(format.order))
1873 const Vec4 minValue (0.0f);
1874 const Vec4 range (1.0f);
1875 std::ostringstream fragmentShader;
1879 "layout(push_constant) uniform PushConstant {\n"
1880 "\thighp uint sampleIndex;\n"
1881 "} pushConstants;\n"
1882 "void main (void)\n"
1884 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1885 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1886 "\thighp float depth;\n"
1887 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1888 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1890 fragmentShader << "\tdepth = " << minValue[0] << ";\n";
1893 deUint32 divider = 2;
1895 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1896 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1899 "\tdepth += " << (range[0] / (float)divider)
1900 << " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1907 "\tgl_FragDepth = depth;\n"
1910 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1912 else if (tcu::hasStencilComponent(format.order))
1914 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1916 "layout(push_constant) uniform PushConstant {\n"
1917 "\thighp uint sampleIndex;\n"
1918 "} pushConstants;\n"
1919 "void main (void)\n"
1921 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1922 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1927 switch (channelClass)
1929 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1931 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1932 const UVec4 minValue (0);
1933 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1934 std::ostringstream fragmentShader;
1938 "layout(location = 0) out highp uvec4 o_color;\n"
1939 "layout(push_constant) uniform PushConstant {\n"
1940 "\thighp uint sampleIndex;\n"
1941 "} pushConstants;\n"
1942 "void main (void)\n"
1944 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1945 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1946 "\thighp uint color[4];\n"
1947 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1948 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1950 for (int ndx = 0; ndx < 4; ndx++)
1951 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1954 const int componentCount = tcu::getNumUsedChannels(format.order);
1955 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1956 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1957 deUint32 nextSrcBit = 0;
1958 deUint32 divider = 2;
1960 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1961 while (nextSrcBit < de::min(bitSize, 10u))
1963 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1965 if (dstBitsUsed[compNdx] > bits[compNdx])
1969 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1970 << " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1973 dstBitsUsed[compNdx]++;
1981 "\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1984 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1988 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1990 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1991 const IVec4 minValue (0);
1992 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1993 const IVec4 maxV ((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
1994 const IVec4 clampMax (maxV - 1);
1995 const IVec4 clampMin (-maxV);
1996 std::ostringstream fragmentShader;
2000 "layout(location = 0) out highp ivec4 o_color;\n"
2001 "layout(push_constant) uniform PushConstant {\n"
2002 "\thighp uint sampleIndex;\n"
2003 "} pushConstants;\n"
2004 "void main (void)\n"
2006 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
2007 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
2008 "\thighp int color[4];\n"
2009 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
2010 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
2012 for (int ndx = 0; ndx < 4; ndx++)
2013 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
2016 const int componentCount = tcu::getNumUsedChannels(format.order);
2017 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
2018 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
2019 deUint32 nextSrcBit = 0;
2020 deUint32 divider = 2;
2022 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
2023 while (nextSrcBit < de::min(bitSize, 10u))
2025 for (int compNdx = 0; compNdx < componentCount; compNdx++)
2027 if (dstBitsUsed[compNdx] > bits[compNdx])
2031 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
2032 << " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
2035 dstBitsUsed[compNdx]++;
2042 // The spec doesn't define whether signed-integers are clamped on output,
2043 // so we'll clamp them explicitly to have well-defined outputs.
2045 "\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
2046 "ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
2049 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
2053 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2054 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2055 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2057 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
2058 const UVec4 bits (tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
2059 const Vec4 minLimit (-65536.0);
2060 const Vec4 maxLimit (65536.0);
2061 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
2062 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
2063 std::ostringstream fragmentShader;
2067 "layout(location = 0) out highp vec4 o_color;\n"
2068 "layout(push_constant) uniform PushConstant {\n"
2069 "\thighp uint sampleIndex;\n"
2070 "} pushConstants;\n"
2071 "void main (void)\n"
2073 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
2074 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
2075 "\thighp float color[4];\n"
2076 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
2077 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
2079 for (int ndx = 0; ndx < 4; ndx++)
2080 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
2083 const int componentCount = tcu::getNumUsedChannels(format.order);
2084 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
2085 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
2086 deUint32 nextSrcBit = 0;
2087 deUint32 divider = 2;
2089 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
2090 while (nextSrcBit < de::min(bitSize, 10u))
2092 for (int compNdx = 0; compNdx < componentCount; compNdx++)
2094 if (dstBitsUsed[compNdx] > bits[compNdx])
2098 "\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
2099 << " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
2102 dstBitsUsed[compNdx]++;
2110 "\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
2113 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
2118 DE_FATAL("Unknown channel class");
2122 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
2124 std::ostringstream splitShader;
2129 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
2131 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2132 << "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2134 else if (tcu::hasDepthComponent(format.order))
2135 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2136 else if (tcu::hasStencilComponent(format.order))
2137 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2140 "layout(push_constant) uniform PushConstant {\n"
2141 "\thighp uint splitSubpassIndex;\n"
2142 "} pushConstants;\n";
2144 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2146 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
2147 splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2149 splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2153 "void main (void)\n"
2156 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2158 if (tcu::hasDepthComponent(format.order))
2159 splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2161 if (tcu::hasStencilComponent(format.order))
2162 splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2164 if (tcu::hasDepthComponent(format.order) && tcu::hasStencilComponent(format.order))
2165 splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2166 else if (tcu::hasDepthComponent(format.order))
2167 splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2168 else if (tcu::hasStencilComponent(format.order))
2169 splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2175 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2179 std::string subpassType;
2180 std::string outputType;
2182 switch (channelClass)
2184 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2185 subpassType = "usubpassInputMS";
2186 outputType = "uvec4";
2189 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2190 subpassType = "isubpassInputMS";
2191 outputType = "ivec4";
2194 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2195 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2196 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2197 subpassType = "subpassInputMS";
2198 outputType = "vec4";
2202 DE_FATAL("Unknown channel class");
2205 std::ostringstream splitShader;
2208 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2209 "layout(push_constant) uniform PushConstant {\n"
2210 "\thighp uint splitSubpassIndex;\n"
2211 "} pushConstants;\n";
2213 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2214 splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2217 "void main (void)\n"
2220 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2221 splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2226 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2231 std::string formatToName (VkFormat format)
2233 const std::string formatStr = de::toString(format);
2234 const std::string prefix = "VK_FORMAT_";
2236 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2238 return de::toLower(formatStr.substr(prefix.length()));
2241 void initTests (tcu::TestCaseGroup* group)
2243 static const VkFormat formats[] =
2245 VK_FORMAT_R5G6B5_UNORM_PACK16,
2250 VK_FORMAT_R8G8_UNORM,
2251 VK_FORMAT_R8G8_SNORM,
2252 VK_FORMAT_R8G8_UINT,
2253 VK_FORMAT_R8G8_SINT,
2254 VK_FORMAT_R8G8B8A8_UNORM,
2255 VK_FORMAT_R8G8B8A8_SNORM,
2256 VK_FORMAT_R8G8B8A8_UINT,
2257 VK_FORMAT_R8G8B8A8_SINT,
2258 VK_FORMAT_R8G8B8A8_SRGB,
2259 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2260 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2261 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2262 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2263 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2264 VK_FORMAT_B8G8R8A8_UNORM,
2265 VK_FORMAT_B8G8R8A8_SRGB,
2266 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2267 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2268 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2269 VK_FORMAT_R16_UNORM,
2270 VK_FORMAT_R16_SNORM,
2273 VK_FORMAT_R16_SFLOAT,
2274 VK_FORMAT_R16G16_UNORM,
2275 VK_FORMAT_R16G16_SNORM,
2276 VK_FORMAT_R16G16_UINT,
2277 VK_FORMAT_R16G16_SINT,
2278 VK_FORMAT_R16G16_SFLOAT,
2279 VK_FORMAT_R16G16B16A16_UNORM,
2280 VK_FORMAT_R16G16B16A16_SNORM,
2281 VK_FORMAT_R16G16B16A16_UINT,
2282 VK_FORMAT_R16G16B16A16_SINT,
2283 VK_FORMAT_R16G16B16A16_SFLOAT,
2286 VK_FORMAT_R32_SFLOAT,
2287 VK_FORMAT_R32G32_UINT,
2288 VK_FORMAT_R32G32_SINT,
2289 VK_FORMAT_R32G32_SFLOAT,
2290 VK_FORMAT_R32G32B32A32_UINT,
2291 VK_FORMAT_R32G32B32A32_SINT,
2292 VK_FORMAT_R32G32B32A32_SFLOAT,
2294 VK_FORMAT_D16_UNORM,
2295 VK_FORMAT_X8_D24_UNORM_PACK32,
2296 VK_FORMAT_D32_SFLOAT,
2298 VK_FORMAT_D16_UNORM_S8_UINT,
2299 VK_FORMAT_D24_UNORM_S8_UINT,
2300 VK_FORMAT_D32_SFLOAT_S8_UINT
2302 const deUint32 sampleCounts[] =
2304 2u, 4u, 8u, 16u, 32u
2306 tcu::TestContext& testCtx (group->getTestContext());
2308 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2310 const VkFormat format (formats[formatNdx]);
2311 const std::string formatName (formatToName(format));
2312 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2314 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2316 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
2317 const std::string testName ("samples_" + de::toString(sampleCount));
2319 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), TestConfig(format, sampleCount)));
2322 group->addChild(formatGroup.release());
2328 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2330 return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests);