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"
25 #include "vktRenderPassTestsUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
31 #include "vkDeviceUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPlatform.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
43 #include "tcuFloat.hpp"
44 #include "tcuImageCompare.hpp"
45 #include "tcuFormatUtil.hpp"
46 #include "tcuMaybe.hpp"
47 #include "tcuResultCollector.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorUtil.hpp"
52 #include "deUniquePtr.hpp"
53 #include "deSharedPtr.hpp"
68 using tcu::ConstPixelBufferAccess;
69 using tcu::PixelBufferAccess;
77 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
78 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
79 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
80 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
86 using namespace renderpass;
90 MAX_COLOR_ATTACHMENT_COUNT = 4u
93 enum TestSeparateUsage
95 TEST_DEPTH = (1 << 0),
96 TEST_STENCIL = (1 << 1)
100 de::SharedPtr<T> safeSharedPtr (T* ptr)
104 return de::SharedPtr<T>(ptr);
113 VkImageAspectFlags getImageAspectFlags (VkFormat vkFormat)
115 const tcu::TextureFormat format (mapVkFormat(vkFormat));
116 const bool hasDepth (tcu::hasDepthComponent(format.order));
117 const bool hasStencil (tcu::hasStencilComponent(format.order));
119 if (hasDepth || hasStencil)
121 return (hasDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : (VkImageAspectFlagBits)0u)
122 | (hasStencil ? VK_IMAGE_ASPECT_STENCIL_BIT : (VkImageAspectFlagBits)0u);
125 return VK_IMAGE_ASPECT_COLOR_BIT;
128 void bindBufferMemory (const DeviceInterface& vk, VkDevice device, VkBuffer buffer, VkDeviceMemory mem, VkDeviceSize memOffset)
130 VK_CHECK(vk.bindBufferMemory(device, buffer, mem, memOffset));
133 void bindImageMemory (const DeviceInterface& vk, VkDevice device, VkImage image, VkDeviceMemory mem, VkDeviceSize memOffset)
135 VK_CHECK(vk.bindImageMemory(device, image, mem, memOffset));
138 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
140 Allocator& allocator,
143 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
144 bindBufferMemory(vk, device, buffer, allocation->getMemory(), allocation->getOffset());
148 de::MovePtr<Allocation> createImageMemory (const DeviceInterface& vk,
150 Allocator& allocator,
153 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(vk, device, image), MemoryRequirement::Any));
154 bindImageMemory(vk, device, image, allocation->getMemory(), allocation->getOffset());
158 Move<VkImage> createImage (const DeviceInterface& vk,
160 VkImageCreateFlags flags,
161 VkImageType imageType,
165 deUint32 arrayLayers,
166 VkSampleCountFlagBits samples,
167 VkImageTiling tiling,
168 VkImageUsageFlags usage,
169 VkSharingMode sharingMode,
170 deUint32 queueFamilyCount,
171 const deUint32* pQueueFamilyIndices,
172 VkImageLayout initialLayout,
173 TestSeparateUsage separateStencilUsage)
175 VkImageUsageFlags depthUsage = (separateStencilUsage == TEST_DEPTH) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
176 VkImageUsageFlags stencilUsage = (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
178 const VkImageStencilUsageCreateInfo stencilUsageInfo =
180 VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
185 const VkImageCreateInfo pCreateInfo =
187 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
188 separateStencilUsage ? &stencilUsageInfo : DE_NULL,
197 separateStencilUsage ? depthUsage : usage,
204 return createImage(vk, device, &pCreateInfo);
207 Move<VkImageView> createImageView (const DeviceInterface& vk,
209 VkImageViewCreateFlags flags,
211 VkImageViewType viewType,
213 VkComponentMapping components,
214 VkImageSubresourceRange subresourceRange)
216 const VkImageViewCreateInfo pCreateInfo =
218 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
227 return createImageView(vk, device, &pCreateInfo);
230 Move<VkImage> createImage (const InstanceInterface& vki,
231 VkPhysicalDevice physicalDevice,
232 const DeviceInterface& vkd,
235 VkSampleCountFlagBits sampleCountBit,
236 VkImageUsageFlags usage,
239 TestSeparateUsage separateStencilUsage = (TestSeparateUsage)0u)
243 const tcu::TextureFormat format (mapVkFormat(vkFormat));
244 const VkImageType imageType (VK_IMAGE_TYPE_2D);
245 const VkImageTiling imageTiling (VK_IMAGE_TILING_OPTIMAL);
246 const VkFormatProperties formatProperties (getPhysicalDeviceFormatProperties(vki, physicalDevice, vkFormat));
247 const VkImageFormatProperties imageFormatProperties (getPhysicalDeviceImageFormatProperties(vki, physicalDevice, vkFormat, imageType, imageTiling, usage, 0u));
248 const VkImageUsageFlags depthUsage = (separateStencilUsage == TEST_DEPTH) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
249 const VkImageUsageFlags stencilUsage = (separateStencilUsage == TEST_STENCIL) ? usage : (VkImageUsageFlags)VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
250 const VkExtent3D imageExtent =
257 if ((tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
258 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
259 TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
261 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
262 && (formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
263 TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
265 if (imageFormatProperties.maxExtent.width < imageExtent.width
266 || imageFormatProperties.maxExtent.height < imageExtent.height
267 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0))
269 TCU_THROW(NotSupportedError, "Image type not supported");
272 if (separateStencilUsage)
274 const VkImageStencilUsageCreateInfo stencilUsageInfo =
276 VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO, // VkStructureType sType
277 DE_NULL, // const void* pNext
278 stencilUsage // VkImageUsageFlags stencilUsage
281 const VkPhysicalDeviceImageFormatInfo2 formatInfo2 =
283 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // VkStructureType sType
284 &stencilUsageInfo, // const void* pNext
285 vkFormat, // VkFormat format
286 imageType, // VkImageType type
287 imageTiling, // VkImageTiling tiling
288 depthUsage, // VkImageUsageFlags usage
289 (VkImageCreateFlags)0u // VkImageCreateFlags flags
292 VkImageFormatProperties2 extProperties =
294 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
303 0u, // maxArrayLayers
305 0u, // maxResourceSize
309 if ((vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &formatInfo2, &extProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
310 || extProperties.imageFormatProperties.maxExtent.width < imageExtent.width
311 || extProperties.imageFormatProperties.maxExtent.height < imageExtent.height
312 || ((extProperties.imageFormatProperties.sampleCounts & sampleCountBit) == 0))
314 TCU_THROW(NotSupportedError, "Image format not supported");
319 return createImage(vkd, device, 0u, imageType, vkFormat, imageExtent, 1u, 1u, sampleCountBit, imageTiling, usage, VK_SHARING_MODE_EXCLUSIVE, 0u, DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED, separateStencilUsage);
321 catch (const vk::Error& error)
323 if (error.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
324 TCU_THROW(NotSupportedError, "Image format not supported");
330 Move<VkImageView> createImageAttachmentView (const DeviceInterface& vkd,
334 VkImageAspectFlags aspect)
336 const VkImageSubresourceRange range =
345 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
348 Move<VkImageView> createSrcPrimaryInputImageView (const DeviceInterface& vkd,
352 VkImageAspectFlags aspect,
353 TestSeparateUsage testSeparateUsage)
355 VkImageAspectFlags primaryDepthStencilAspect = (testSeparateUsage == TEST_STENCIL) ? VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_DEPTH_BIT;
357 const VkImageSubresourceRange range =
359 aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)
360 ? primaryDepthStencilAspect
368 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
371 Move<VkImageView> createSrcSecondaryInputImageView (const DeviceInterface& vkd,
375 VkImageAspectFlags aspect,
376 TestSeparateUsage separateStencilUsage)
378 if ((aspect == (VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT)) && !separateStencilUsage)
380 const VkImageSubresourceRange range =
382 VK_IMAGE_ASPECT_STENCIL_BIT,
389 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
392 return Move<VkImageView>();
395 VkDeviceSize getPixelSize (VkFormat vkFormat)
397 const tcu::TextureFormat format (mapVkFormat(vkFormat));
399 return format.getPixelSize();
402 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
408 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
409 const VkDeviceSize pixelSize (getPixelSize(format));
410 const VkBufferCreateInfo createInfo =
412 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
416 width * height * pixelSize,
419 VK_SHARING_MODE_EXCLUSIVE,
423 return createBuffer(vkd, device, &createInfo);
426 VkSampleCountFlagBits sampleCountBitFromomSampleCount (deUint32 count)
430 case 1: return VK_SAMPLE_COUNT_1_BIT;
431 case 2: return VK_SAMPLE_COUNT_2_BIT;
432 case 4: return VK_SAMPLE_COUNT_4_BIT;
433 case 8: return VK_SAMPLE_COUNT_8_BIT;
434 case 16: return VK_SAMPLE_COUNT_16_BIT;
435 case 32: return VK_SAMPLE_COUNT_32_BIT;
436 case 64: return VK_SAMPLE_COUNT_64_BIT;
439 DE_FATAL("Invalid sample count");
440 return (VkSampleCountFlagBits)(0x1u << count);
444 std::vector<VkImageSp> createMultisampleImages (const InstanceInterface& vki,
445 VkPhysicalDevice physicalDevice,
446 const DeviceInterface& vkd,
449 deUint32 sampleCount,
453 std::vector<VkImageSp> images (sampleCount);
455 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
456 images[imageNdx] = safeSharedPtr(new vk::Unique<VkImage>(createImage(vki, physicalDevice, vkd, device, format, sampleCountBitFromomSampleCount(sampleCount), VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, width, height)));
461 std::vector<VkImageSp> createSingleSampleImages (const InstanceInterface& vki,
462 VkPhysicalDevice physicalDevice,
463 const DeviceInterface& vkd,
466 deUint32 sampleCount,
470 std::vector<VkImageSp> images (sampleCount);
472 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
473 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)));
478 std::vector<de::SharedPtr<Allocation> > createImageMemory (const DeviceInterface& vkd,
480 Allocator& allocator,
481 const std::vector<VkImageSp> images)
483 std::vector<de::SharedPtr<Allocation> > memory (images.size());
485 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
486 memory[memoryNdx] = safeSharedPtr(createImageMemory(vkd, device, allocator, **images[memoryNdx]).release());
491 std::vector<VkImageViewSp> createImageAttachmentViews (const DeviceInterface& vkd,
493 const std::vector<VkImageSp>& images,
495 VkImageAspectFlagBits aspect)
497 std::vector<VkImageViewSp> views (images.size());
499 for (size_t imageNdx = 0; imageNdx < images.size(); imageNdx++)
500 views[imageNdx] = safeSharedPtr(new vk::Unique<VkImageView>(createImageAttachmentView(vkd, device, **images[imageNdx], format, aspect)));
505 std::vector<VkBufferSp> createBuffers (const DeviceInterface& vkd,
508 deUint32 sampleCount,
512 std::vector<VkBufferSp> buffers (sampleCount);
514 for (size_t bufferNdx = 0; bufferNdx < buffers.size(); bufferNdx++)
515 buffers[bufferNdx] = safeSharedPtr(new vk::Unique<VkBuffer>(createBuffer(vkd, device, format, width, height)));
520 std::vector<de::SharedPtr<Allocation> > createBufferMemory (const DeviceInterface& vkd,
522 Allocator& allocator,
523 const std::vector<VkBufferSp> buffers)
525 std::vector<de::SharedPtr<Allocation> > memory (buffers.size());
527 for (size_t memoryNdx = 0; memoryNdx < memory.size(); memoryNdx++)
528 memory[memoryNdx] = safeSharedPtr(createBufferMemory(vkd, device, allocator, **buffers[memoryNdx]).release());
533 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
534 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
538 deUint32 sampleCount,
539 RenderingType renderingType,
540 TestSeparateUsage separateStencilUsage)
542 const VkSampleCountFlagBits samples (sampleCountBitFromomSampleCount(sampleCount));
543 const deUint32 splitSubpassCount (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT));
544 const tcu::TextureFormat format (mapVkFormat(srcFormat));
545 const bool isDepthStencilFormat (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
546 const VkImageAspectFlags inputAspect (separateStencilUsage == TEST_DEPTH ? (VkImageAspectFlags)VK_IMAGE_ASPECT_DEPTH_BIT
547 : separateStencilUsage == TEST_STENCIL ? (VkImageAspectFlags)VK_IMAGE_ASPECT_STENCIL_BIT
548 : getImageAspectFlags(srcFormat));
549 vector<SubpassDesc> subpasses;
550 vector<vector<AttachmentRef> > dstAttachmentRefs (splitSubpassCount);
551 vector<vector<AttachmentRef> > dstResolveAttachmentRefs (splitSubpassCount);
552 vector<AttachmentDesc> attachments;
553 vector<SubpassDep> dependencies;
554 const AttachmentRef srcAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
556 // || VkStructureType sType;
557 DE_NULL, // || const void* pNext;
558 0u, // deUint32 attachment; || deUint32 attachment;
559 isDepthStencilFormat // VkImageLayout layout; || VkImageLayout layout;
560 ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
561 : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
562 0u // || VkImageAspectFlags aspectMask;
564 const AttachmentRef srcAttachmentInputRef // VkAttachmentReference || VkAttachmentReference2KHR
566 // || VkStructureType sType;
567 DE_NULL, // || const void* pNext;
568 0u, // deUint32 attachment; || deUint32 attachment;
569 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
570 (renderingType == RENDERING_TYPE_RENDERPASS2) // || VkImageAspectFlags aspectMask;
576 const AttachmentDesc srcAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
578 // || VkStructureType sType;
579 DE_NULL, // || const void* pNext;
580 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
581 srcFormat, // VkFormat format; || VkFormat format;
582 samples, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
583 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
584 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
585 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
586 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
587 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
588 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
591 attachments.push_back(srcAttachment);
594 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
596 for (deUint32 sampleNdx = 0; sampleNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount - splitSubpassIndex * MAX_COLOR_ATTACHMENT_COUNT); sampleNdx++)
598 // Multisample color attachment
600 const AttachmentDesc dstAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
602 // || VkStructureType sType;
603 DE_NULL, // || const void* pNext;
604 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
605 dstFormat, // VkFormat format; || VkFormat format;
606 samples, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
607 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
608 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
609 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
610 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
611 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
612 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
614 const AttachmentRef dstAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
616 // || VkStructureType sType;
617 DE_NULL, // || const void* pNext;
618 (deUint32)attachments.size(), // deUint32 attachment; || deUint32 attachment;
619 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
620 0u // || VkImageAspectFlags aspectMask;
623 attachments.push_back(dstAttachment);
624 dstAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
626 // Resolve attachment
628 const AttachmentDesc dstAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
630 // || VkStructureType sType;
631 DE_NULL, // || const void* pNext;
632 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
633 dstFormat, // VkFormat format; || VkFormat format;
634 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
635 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
636 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
637 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
638 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
639 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
640 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
642 const AttachmentRef dstAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
644 // || VkStructureType sType;
645 DE_NULL, // || const void* pNext;
646 (deUint32)attachments.size(), // deUint32 attachment; || deUint32 attachment;
647 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
648 0u // || VkImageAspectFlags aspectMask;
651 attachments.push_back(dstAttachment);
652 dstResolveAttachmentRefs[splitSubpassIndex].push_back(dstAttachmentRef);
659 const SubpassDesc subpass // VkSubpassDescription || VkSubpassDescription2KHR
661 // || VkStructureType sType;
662 DE_NULL, // || const void* pNext;
663 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
664 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
665 0u, // || deUint32 viewMask;
666 0u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
667 DE_NULL, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
668 isDepthStencilFormat ? 0u : 1u, // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
669 isDepthStencilFormat ? DE_NULL : &srcAttachmentRef, // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
670 DE_NULL, // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
671 isDepthStencilFormat ? &srcAttachmentRef : DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
672 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
673 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
676 subpasses.push_back(subpass);
679 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < splitSubpassCount; splitSubpassIndex++)
682 const SubpassDesc subpass // VkSubpassDescription || VkSubpassDescription2KHR
684 // || VkStructureType sType;
685 DE_NULL, // || const void* pNext;
686 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
687 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
688 0u, // || deUint32 viewMask;
689 1u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
690 &srcAttachmentInputRef, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
691 (deUint32)dstAttachmentRefs[splitSubpassIndex].size(), // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
692 &dstAttachmentRefs[splitSubpassIndex][0], // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
693 &dstResolveAttachmentRefs[splitSubpassIndex][0], // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
694 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
695 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
696 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
698 subpasses.push_back(subpass);
701 const SubpassDep dependency // VkSubpassDependency || VkSubpassDependency2KHR
703 // || VkStructureType sType;
704 DE_NULL, // || const void* pNext;
705 0u, // deUint32 srcSubpass; || deUint32 srcSubpass;
706 splitSubpassIndex + 1, // deUint32 dstSubpass; || deUint32 dstSubpass;
707 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
708 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
709 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
710 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
711 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
712 0u // || deInt32 viewOffset;
715 dependencies.push_back(dependency);
718 // the last subpass must synchronize with all prior subpasses
719 for (deUint32 splitSubpassIndex = 0; splitSubpassIndex < (splitSubpassCount - 1); splitSubpassIndex++)
721 const SubpassDep dependency // VkSubpassDependency || VkSubpassDependency2KHR
723 // || VkStructureType sType;
724 DE_NULL, // || const void* pNext;
725 splitSubpassIndex + 1, // deUint32 srcSubpass; || deUint32 srcSubpass;
726 splitSubpassCount, // deUint32 dstSubpass; || deUint32 dstSubpass;
727 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
728 | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask; || VkPipelineStageFlags srcStageMask;
729 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask; || VkPipelineStageFlags dstStageMask;
730 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask; || VkAccessFlags srcAccessMask;
731 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask; || VkAccessFlags dstAccessMask;
732 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags; || VkDependencyFlags dependencyFlags;
733 0u // || deInt32 viewOffset;
735 dependencies.push_back(dependency);
737 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
739 // VkStructureType sType; || VkStructureType sType;
740 DE_NULL, // const void* pNext; || const void* pNext;
741 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
742 (deUint32)attachments.size(), // deUint32 attachmentCount; || deUint32 attachmentCount;
743 &attachments[0], // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
744 (deUint32)subpasses.size(), // deUint32 subpassCount; || deUint32 subpassCount;
745 &subpasses[0], // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
746 (deUint32)dependencies.size(), // deUint32 dependencyCount; || deUint32 dependencyCount;
747 &dependencies[0], // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
748 0u, // || deUint32 correlatedViewMaskCount;
749 DE_NULL // || const deUint32* pCorrelatedViewMasks;
752 return renderPassCreator.createRenderPass(vkd, device);
756 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
760 deUint32 sampleCount,
761 const RenderingType renderingType,
762 const TestSeparateUsage separateStencilUsage)
764 switch (renderingType)
766 case RENDERING_TYPE_RENDERPASS_LEGACY:
767 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
768 case RENDERING_TYPE_RENDERPASS2:
769 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, srcFormat, dstFormat, sampleCount, renderingType, separateStencilUsage);
771 TCU_THROW(InternalError, "Impossible");
775 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
777 VkRenderPass renderPass,
778 VkImageView srcImageView,
779 const std::vector<VkImageViewSp>& dstMultisampleImageViews,
780 const std::vector<VkImageViewSp>& dstSinglesampleImageViews,
784 std::vector<VkImageView> attachments;
786 attachments.reserve(dstMultisampleImageViews.size() + dstSinglesampleImageViews.size() + 1u);
788 attachments.push_back(srcImageView);
790 DE_ASSERT(dstMultisampleImageViews.size() == dstSinglesampleImageViews.size());
792 for (size_t ndx = 0; ndx < dstMultisampleImageViews.size(); ndx++)
794 attachments.push_back(**dstMultisampleImageViews[ndx]);
795 attachments.push_back(**dstSinglesampleImageViews[ndx]);
798 const VkFramebufferCreateInfo createInfo =
800 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
805 (deUint32)attachments.size(),
813 return createFramebuffer(vkd, device, &createInfo);
816 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
819 const VkPushConstantRange pushConstant =
821 VK_SHADER_STAGE_FRAGMENT_BIT,
825 const VkPipelineLayoutCreateInfo createInfo =
827 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
829 (vk::VkPipelineLayoutCreateFlags)0,
838 return createPipelineLayout(vkd, device, &createInfo);
841 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
844 VkRenderPass renderPass,
845 VkPipelineLayout pipelineLayout,
846 const vk::BinaryCollection& binaryCollection,
849 deUint32 sampleCount)
851 const tcu::TextureFormat format (mapVkFormat(srcFormat));
852 const bool isDepthStencilFormat (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order));
854 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
855 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
857 const VkPipelineColorBlendAttachmentState attachmentBlendState =
860 VK_BLEND_FACTOR_SRC_ALPHA,
861 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
866 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
868 const VkPipelineVertexInputStateCreateInfo vertexInputState =
870 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
872 (VkPipelineVertexInputStateCreateFlags)0u,
880 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
881 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
883 const VkPipelineMultisampleStateCreateInfo multisampleState =
885 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
887 (VkPipelineMultisampleStateCreateFlags)0u,
889 sampleCountBitFromomSampleCount(sampleCount),
896 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
898 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
900 (VkPipelineDepthStencilStateCreateFlags)0u,
904 VK_COMPARE_OP_ALWAYS,
909 VK_STENCIL_OP_INCREMENT_AND_WRAP,
911 VK_COMPARE_OP_ALWAYS,
914 0xFFu / (sampleCount + 1)
918 VK_STENCIL_OP_INCREMENT_AND_WRAP,
920 VK_COMPARE_OP_ALWAYS,
923 0xFFu / (sampleCount + 1)
929 const VkPipelineColorBlendStateCreateInfo blendState =
931 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
933 (VkPipelineColorBlendStateCreateFlags)0u,
937 (isDepthStencilFormat ? 0u : 1u),
938 (isDepthStencilFormat ? DE_NULL : &attachmentBlendState),
939 { 0.0f, 0.0f, 0.0f, 0.0f }
942 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
943 device, // const VkDevice device
944 pipelineLayout, // const VkPipelineLayout pipelineLayout
945 *vertexShaderModule, // const VkShaderModule vertexShaderModule
946 DE_NULL, // const VkShaderModule tessellationControlShaderModule
947 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
948 DE_NULL, // const VkShaderModule geometryShaderModule
949 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
950 renderPass, // const VkRenderPass renderPass
951 viewports, // const std::vector<VkViewport>& viewports
952 scissors, // const std::vector<VkRect2D>& scissors
953 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
954 0u, // const deUint32 subpass
955 0u, // const deUint32 patchControlPoints
956 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
957 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
958 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
959 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
960 &blendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
963 Move<VkDescriptorSetLayout> createSplitDescriptorSetLayout (const DeviceInterface& vkd,
967 const tcu::TextureFormat format (mapVkFormat(vkFormat));
968 const bool hasDepth (tcu::hasDepthComponent(format.order));
969 const bool hasStencil (tcu::hasStencilComponent(format.order));
970 const VkDescriptorSetLayoutBinding bindings[] =
974 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
976 VK_SHADER_STAGE_FRAGMENT_BIT,
981 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
983 VK_SHADER_STAGE_FRAGMENT_BIT,
987 const VkDescriptorSetLayoutCreateInfo createInfo =
989 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
993 hasDepth && hasStencil ? 2u : 1u,
997 return createDescriptorSetLayout(vkd, device, &createInfo);
1000 Move<VkPipelineLayout> createSplitPipelineLayout (const DeviceInterface& vkd,
1002 VkDescriptorSetLayout descriptorSetLayout)
1004 const VkPushConstantRange pushConstant =
1006 VK_SHADER_STAGE_FRAGMENT_BIT,
1010 const VkPipelineLayoutCreateInfo createInfo =
1012 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1014 (vk::VkPipelineLayoutCreateFlags)0,
1017 &descriptorSetLayout,
1023 return createPipelineLayout(vkd, device, &createInfo);
1026 Move<VkPipeline> createSplitPipeline (const DeviceInterface& vkd,
1028 VkRenderPass renderPass,
1029 deUint32 subpassIndex,
1030 VkPipelineLayout pipelineLayout,
1031 const vk::BinaryCollection& binaryCollection,
1034 deUint32 sampleCount)
1036 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
1037 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-split-frag"), 0u));
1039 const VkPipelineColorBlendAttachmentState attachmentBlendState =
1042 VK_BLEND_FACTOR_SRC_ALPHA,
1043 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
1045 VK_BLEND_FACTOR_ONE,
1046 VK_BLEND_FACTOR_ONE,
1048 VK_COLOR_COMPONENT_R_BIT|VK_COLOR_COMPONENT_G_BIT|VK_COLOR_COMPONENT_B_BIT|VK_COLOR_COMPONENT_A_BIT
1050 const std::vector<VkPipelineColorBlendAttachmentState> attachmentBlendStates (de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, sampleCount), attachmentBlendState);
1051 const VkPipelineVertexInputStateCreateInfo vertexInputState =
1053 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1055 (VkPipelineVertexInputStateCreateFlags)0u,
1063 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
1064 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
1066 const VkPipelineMultisampleStateCreateInfo multisampleState =
1068 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1070 (VkPipelineMultisampleStateCreateFlags)0u,
1072 sampleCountBitFromomSampleCount(sampleCount),
1079 const VkPipelineColorBlendStateCreateInfo blendState =
1081 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1083 (VkPipelineColorBlendStateCreateFlags)0u,
1088 (deUint32)attachmentBlendStates.size(),
1089 &attachmentBlendStates[0],
1091 { 0.0f, 0.0f, 0.0f, 0.0f }
1094 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
1095 device, // const VkDevice device
1096 pipelineLayout, // const VkPipelineLayout pipelineLayout
1097 *vertexShaderModule, // const VkShaderModule vertexShaderModule
1098 DE_NULL, // const VkShaderModule tessellationControlShaderModule
1099 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
1100 DE_NULL, // const VkShaderModule geometryShaderModule
1101 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
1102 renderPass, // const VkRenderPass renderPass
1103 viewports, // const std::vector<VkViewport>& viewports
1104 scissors, // const std::vector<VkRect2D>& scissors
1105 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
1106 subpassIndex, // const deUint32 subpass
1107 0u, // const deUint32 patchControlPoints
1108 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
1109 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
1110 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
1111 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
1112 &blendState); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
1115 vector<VkPipelineSp> createSplitPipelines (const DeviceInterface& vkd,
1117 VkRenderPass renderPass,
1118 VkPipelineLayout pipelineLayout,
1119 const vk::BinaryCollection& binaryCollection,
1122 deUint32 sampleCount)
1124 std::vector<VkPipelineSp> pipelines (deDivRoundUp32(sampleCount, MAX_COLOR_ATTACHMENT_COUNT), (VkPipelineSp)0u);
1126 for (size_t ndx = 0; ndx < pipelines.size(); ndx++)
1127 pipelines[ndx] = safeSharedPtr(new Unique<VkPipeline>(createSplitPipeline(vkd, device, renderPass, (deUint32)(ndx + 1), pipelineLayout, binaryCollection, width, height, sampleCount)));
1132 Move<VkDescriptorPool> createSplitDescriptorPool (const DeviceInterface& vkd,
1135 const VkDescriptorPoolSize size =
1137 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 2u
1139 const VkDescriptorPoolCreateInfo createInfo =
1141 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1143 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1151 return createDescriptorPool(vkd, device, &createInfo);
1154 Move<VkDescriptorSet> createSplitDescriptorSet (const DeviceInterface& vkd,
1156 VkDescriptorPool pool,
1157 VkDescriptorSetLayout layout,
1158 VkImageView primaryImageView,
1159 VkImageView secondaryImageView)
1161 const VkDescriptorSetAllocateInfo allocateInfo =
1163 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1170 Move<VkDescriptorSet> set (allocateDescriptorSet(vkd, device, &allocateInfo));
1173 const VkDescriptorImageInfo imageInfos[] =
1178 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1183 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1186 const VkWriteDescriptorSet writes[] =
1189 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1196 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1202 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1209 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1215 const deUint32 count = secondaryImageView != (VkImageView)0
1219 vkd.updateDescriptorSets(device, count, writes, 0u, DE_NULL);
1226 TestConfig (VkFormat format_,
1227 deUint32 sampleCount_,
1228 RenderingType renderingType_,
1229 TestSeparateUsage separateStencilUsage_ = (TestSeparateUsage)0u)
1231 , sampleCount (sampleCount_)
1232 , renderingType (renderingType_)
1233 , separateStencilUsage(separateStencilUsage_)
1238 deUint32 sampleCount;
1239 RenderingType renderingType;
1240 TestSeparateUsage separateStencilUsage;
1243 VkImageUsageFlags getSrcImageUsage (VkFormat vkFormat)
1245 const tcu::TextureFormat format (mapVkFormat(vkFormat));
1246 const bool hasDepth (tcu::hasDepthComponent(format.order));
1247 const bool hasStencil (tcu::hasStencilComponent(format.order));
1249 if (hasDepth || hasStencil)
1250 return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1252 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1255 VkFormat getDstFormat (VkFormat vkFormat, TestSeparateUsage separateStencilUsage)
1257 const tcu::TextureFormat format (mapVkFormat(vkFormat));
1258 const bool hasDepth (tcu::hasDepthComponent(format.order));
1259 const bool hasStencil (tcu::hasStencilComponent(format.order));
1261 if (hasDepth && hasStencil && !separateStencilUsage)
1262 return VK_FORMAT_R32G32_SFLOAT;
1263 else if (hasDepth || hasStencil)
1264 return VK_FORMAT_R32_SFLOAT;
1269 bool isExtensionSupported(Context& context, RenderingType renderingType, TestSeparateUsage separateStencilUsage)
1271 if (renderingType == RENDERING_TYPE_RENDERPASS2)
1272 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
1274 if (separateStencilUsage)
1276 context.requireDeviceFunctionality ("VK_EXT_separate_stencil_usage");
1277 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
1284 class MultisampleRenderPassTestInstance : public TestInstance
1287 MultisampleRenderPassTestInstance (Context& context, TestConfig config);
1288 ~MultisampleRenderPassTestInstance (void);
1290 tcu::TestStatus iterate (void);
1292 template<typename RenderpassSubpass>
1293 tcu::TestStatus iterateInternal (void);
1296 const bool m_extensionSupported;
1297 const RenderingType m_renderingType;
1298 const TestSeparateUsage m_separateStencilUsage;
1300 const VkFormat m_srcFormat;
1301 const VkFormat m_dstFormat;
1302 const deUint32 m_sampleCount;
1303 const deUint32 m_width;
1304 const deUint32 m_height;
1306 const VkImageAspectFlags m_srcImageAspect;
1307 const VkImageUsageFlags m_srcImageUsage;
1308 const Unique<VkImage> m_srcImage;
1309 const de::UniquePtr<Allocation> m_srcImageMemory;
1310 const Unique<VkImageView> m_srcImageView;
1311 const Unique<VkImageView> m_srcPrimaryInputImageView;
1312 const Unique<VkImageView> m_srcSecondaryInputImageView;
1314 const std::vector<VkImageSp> m_dstMultisampleImages;
1315 const std::vector<de::SharedPtr<Allocation> > m_dstMultisampleImageMemory;
1316 const std::vector<VkImageViewSp> m_dstMultisampleImageViews;
1318 const std::vector<VkImageSp> m_dstSinglesampleImages;
1319 const std::vector<de::SharedPtr<Allocation> > m_dstSinglesampleImageMemory;
1320 const std::vector<VkImageViewSp> m_dstSinglesampleImageViews;
1322 const std::vector<VkBufferSp> m_dstBuffers;
1323 const std::vector<de::SharedPtr<Allocation> > m_dstBufferMemory;
1325 const Unique<VkRenderPass> m_renderPass;
1326 const Unique<VkFramebuffer> m_framebuffer;
1328 const Unique<VkPipelineLayout> m_renderPipelineLayout;
1329 const Unique<VkPipeline> m_renderPipeline;
1331 const Unique<VkDescriptorSetLayout> m_splitDescriptorSetLayout;
1332 const Unique<VkPipelineLayout> m_splitPipelineLayout;
1333 const std::vector<VkPipelineSp> m_splitPipelines;
1334 const Unique<VkDescriptorPool> m_splitDescriptorPool;
1335 const Unique<VkDescriptorSet> m_splitDescriptorSet;
1337 const Unique<VkCommandPool> m_commandPool;
1338 tcu::ResultCollector m_resultCollector;
1341 MultisampleRenderPassTestInstance::MultisampleRenderPassTestInstance (Context& context, TestConfig config)
1342 : TestInstance (context)
1343 , m_extensionSupported (isExtensionSupported(context, config.renderingType, config.separateStencilUsage))
1344 , m_renderingType (config.renderingType)
1345 , m_separateStencilUsage (config.separateStencilUsage)
1346 , m_srcFormat (config.format)
1347 , m_dstFormat (getDstFormat(config.format, config.separateStencilUsage))
1348 , m_sampleCount (config.sampleCount)
1352 , m_srcImageAspect (getImageAspectFlags(m_srcFormat))
1353 , m_srcImageUsage (getSrcImageUsage(m_srcFormat))
1354 , m_srcImage (createImage(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_srcFormat, sampleCountBitFromomSampleCount(m_sampleCount), m_srcImageUsage, m_width, m_height, m_separateStencilUsage))
1355 , m_srcImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_srcImage))
1356 , m_srcImageView (createImageAttachmentView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect))
1357 , m_srcPrimaryInputImageView (createSrcPrimaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1358 , m_srcSecondaryInputImageView (createSrcSecondaryInputImageView(context.getDeviceInterface(), context.getDevice(), *m_srcImage, m_srcFormat, m_srcImageAspect, m_separateStencilUsage))
1360 , m_dstMultisampleImages (createMultisampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1361 , m_dstMultisampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstMultisampleImages))
1362 , m_dstMultisampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstMultisampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1364 , m_dstSinglesampleImages (createSingleSampleImages(context.getInstanceInterface(), context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1365 , m_dstSinglesampleImageMemory (createImageMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstSinglesampleImages))
1366 , m_dstSinglesampleImageViews (createImageAttachmentViews(context.getDeviceInterface(), context.getDevice(), m_dstSinglesampleImages, m_dstFormat, VK_IMAGE_ASPECT_COLOR_BIT))
1368 , m_dstBuffers (createBuffers(context.getDeviceInterface(), context.getDevice(), m_dstFormat, m_sampleCount, m_width, m_height))
1369 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), m_dstBuffers))
1371 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_srcFormat, m_dstFormat, m_sampleCount, config.renderingType, m_separateStencilUsage))
1372 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_srcImageView, m_dstMultisampleImageViews, m_dstSinglesampleImageViews, m_width, m_height))
1374 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
1375 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), m_srcFormat, *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1377 , m_splitDescriptorSetLayout (createSplitDescriptorSetLayout(context.getDeviceInterface(), context.getDevice(), m_srcFormat))
1378 , m_splitPipelineLayout (createSplitPipelineLayout(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorSetLayout))
1379 , m_splitPipelines (createSplitPipelines(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_splitPipelineLayout, context.getBinaryCollection(), m_width, m_height, m_sampleCount))
1380 , m_splitDescriptorPool (createSplitDescriptorPool(context.getDeviceInterface(), context.getDevice()))
1381 , m_splitDescriptorSet (createSplitDescriptorSet(context.getDeviceInterface(), context.getDevice(), *m_splitDescriptorPool, *m_splitDescriptorSetLayout, *m_srcPrimaryInputImageView, *m_srcSecondaryInputImageView))
1382 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
1386 MultisampleRenderPassTestInstance::~MultisampleRenderPassTestInstance (void)
1390 tcu::TestStatus MultisampleRenderPassTestInstance::iterate (void)
1392 switch (m_renderingType)
1394 case RENDERING_TYPE_RENDERPASS_LEGACY:
1395 return iterateInternal<RenderpassSubpass1>();
1396 case RENDERING_TYPE_RENDERPASS2:
1397 return iterateInternal<RenderpassSubpass2>();
1399 TCU_THROW(InternalError, "Impossible");
1403 template<typename RenderpassSubpass>
1404 tcu::TestStatus MultisampleRenderPassTestInstance::iterateInternal (void)
1406 const DeviceInterface& vkd (m_context.getDeviceInterface());
1407 const VkDevice device (m_context.getDevice());
1408 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1409 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
1410 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
1412 beginCommandBuffer(vkd, *commandBuffer);
1415 const VkRenderPassBeginInfo beginInfo =
1417 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1425 { m_width, m_height }
1431 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
1433 // Stencil needs to be cleared if it exists.
1434 if (tcu::hasStencilComponent(mapVkFormat(m_srcFormat).order))
1436 const VkClearAttachment clearAttachment =
1438 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
1439 0, // deUint32 colorAttachment;
1440 makeClearValueDepthStencil(0, 0) // VkClearValue clearValue;
1443 const VkClearRect clearRect =
1447 { m_width, m_height }
1449 0, // deUint32 baseArrayLayer;
1450 1 // deUint32 layerCount;
1453 vkd.cmdClearAttachments(*commandBuffer, 1, &clearAttachment, 1, &clearRect);
1457 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
1459 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1461 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(sampleNdx), &sampleNdx);
1462 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1465 for (deUint32 splitPipelineNdx = 0; splitPipelineNdx < m_splitPipelines.size(); splitPipelineNdx++)
1467 RenderpassSubpass::cmdNextSubpass(vkd, *commandBuffer, &subpassBeginInfo, &subpassEndInfo);
1469 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_splitPipelines[splitPipelineNdx]);
1470 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_splitPipelineLayout, 0u, 1u, &*m_splitDescriptorSet, 0u, DE_NULL);
1471 vkd.cmdPushConstants(*commandBuffer, *m_splitPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(splitPipelineNdx), &splitPipelineNdx);
1472 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
1475 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
1477 for (size_t dstNdx = 0; dstNdx < m_dstSinglesampleImages.size(); dstNdx++)
1478 copyImageToBuffer(vkd, *commandBuffer, **m_dstSinglesampleImages[dstNdx], **m_dstBuffers[dstNdx], tcu::IVec2(m_width, m_height), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1480 endCommandBuffer(vkd, *commandBuffer);
1482 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
1485 const tcu::TextureFormat format (mapVkFormat(m_dstFormat));
1486 const tcu::TextureFormat srcFormat (mapVkFormat(m_srcFormat));
1487 const bool verifyDepth (m_separateStencilUsage ? (m_separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(srcFormat.order));
1488 const bool verifyStencil (m_separateStencilUsage ? (m_separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(srcFormat.order));
1490 for (deUint32 sampleNdx = 0; sampleNdx < m_sampleCount; sampleNdx++)
1492 Allocation *dstBufMem = m_dstBufferMemory[sampleNdx].get();
1493 invalidateAlloc(vkd, device, *dstBufMem);
1495 const std::string name ("Sample" + de::toString(sampleNdx));
1496 const void* const ptr (dstBufMem->getHostPtr());
1497 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
1498 tcu::TextureLevel reference (format, m_width, m_height);
1500 if (verifyDepth || verifyStencil)
1504 for (deUint32 y = 0; y < m_height; y++)
1505 for (deUint32 x = 0; x < m_width; x++)
1507 const deUint32 x1 = x ^ sampleNdx;
1508 const deUint32 y1 = y ^ sampleNdx;
1509 const float range = 1.0f;
1511 deUint32 divider = 2;
1513 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1514 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1516 depth += (range / (float)divider)
1517 * (((bitNdx % 2 == 0 ? x1 : y1) & (0x1u << (bitNdx / 2u))) == 0u ? 0u : 1u);
1521 reference.getAccess().setPixel(Vec4(depth, 0.0f, 0.0f, 0.0f), x, y);
1526 for (deUint32 y = 0; y < m_height; y++)
1527 for (deUint32 x = 0; x < m_width; x++)
1529 const deUint32 stencil = sampleNdx + 1u;
1533 const Vec4 src (reference.getAccess().getPixel(x, y));
1535 reference.getAccess().setPixel(Vec4(src.x(), (float)stencil, 0.0f, 0.0f), x, y);
1538 reference.getAccess().setPixel(Vec4((float)stencil, 0.0f, 0.0f, 0.0f), x, y);
1542 const Vec4 threshold (verifyDepth ? (1.0f / 1024.0f) : 0.0f, 0.0f, 0.0f, 0.0f);
1544 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1545 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1550 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1552 switch (channelClass)
1554 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1556 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1557 const UVec4 minValue (0);
1558 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1559 const int componentCount (tcu::getNumUsedChannels(format.order));
1560 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1562 for (deUint32 y = 0; y < m_height; y++)
1563 for (deUint32 x = 0; x < m_width; x++)
1565 const deUint32 x1 = x ^ sampleNdx;
1566 const deUint32 y1 = y ^ sampleNdx;
1567 UVec4 color (minValue);
1568 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1569 deUint32 nextSrcBit = 0;
1570 deUint32 divider = 2;
1572 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1573 while (nextSrcBit < de::min(bitSize, 10u))
1575 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1577 if (dstBitsUsed[compNdx] > bits[compNdx])
1580 color[compNdx] += (range[compNdx] / divider)
1581 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1584 dstBitsUsed[compNdx]++;
1590 reference.getAccess().setPixel(color, x, y);
1593 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1594 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1599 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1601 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1602 const IVec4 minValue (0);
1603 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1604 const int componentCount (tcu::getNumUsedChannels(format.order));
1605 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1607 for (deUint32 y = 0; y < m_height; y++)
1608 for (deUint32 x = 0; x < m_width; x++)
1610 const deUint32 x1 = x ^ sampleNdx;
1611 const deUint32 y1 = y ^ sampleNdx;
1612 IVec4 color (minValue);
1613 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1614 deUint32 nextSrcBit = 0;
1615 deUint32 divider = 2;
1617 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1618 while (nextSrcBit < de::min(bitSize, 10u))
1620 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1622 if (dstBitsUsed[compNdx] > bits[compNdx])
1625 color[compNdx] += (range[compNdx] / divider)
1626 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1629 dstBitsUsed[compNdx]++;
1635 reference.getAccess().setPixel(color, x, y);
1638 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
1639 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1644 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1645 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1646 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1648 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
1649 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1650 const Vec4 minLimit (-65536.0);
1651 const Vec4 maxLimit (65536.0);
1652 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
1653 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
1654 const int componentCount (tcu::getNumUsedChannels(format.order));
1655 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1657 for (deUint32 y = 0; y < m_height; y++)
1658 for (deUint32 x = 0; x < m_width; x++)
1660 const deUint32 x1 = x ^ sampleNdx;
1661 const deUint32 y1 = y ^ sampleNdx;
1662 Vec4 color (minValue);
1663 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1664 deUint32 nextSrcBit = 0;
1665 deUint32 divider = 2;
1667 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1668 while (nextSrcBit < de::min(bitSize, 10u))
1670 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1672 if (dstBitsUsed[compNdx] > bits[compNdx])
1675 color[compNdx] += (range[compNdx] / (float)divider)
1676 * (((nextSrcBit % 2 == 0 ? x1 : y1) & (0x1u << (nextSrcBit / 2u))) == 0u ? 0u : 1u);
1679 dstBitsUsed[compNdx]++;
1685 if (tcu::isSRGB(format))
1686 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
1688 reference.getAccess().setPixel(color, x, y);
1691 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
1693 // Convert target format ulps to float ulps and allow 64ulp differences
1694 const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
1696 if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1697 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1701 // Allow error of 4 times the minimum presentable difference
1702 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
1704 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), name.c_str(), name.c_str(), reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
1705 m_resultCollector.fail("Compare failed for sample " + de::toString(sampleNdx));
1712 DE_FATAL("Unknown channel class");
1718 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
1723 void init (vk::SourceCollections& dst, TestConfig config) const
1725 const tcu::TextureFormat format (mapVkFormat(config.format));
1726 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
1727 const bool testDepth (config.separateStencilUsage ? (config.separateStencilUsage == TEST_DEPTH) : tcu::hasDepthComponent(format.order));
1728 const bool testStencil (config.separateStencilUsage ? (config.separateStencilUsage == TEST_STENCIL) : tcu::hasStencilComponent(format.order));
1730 dst.glslSources.add("quad-vert") << glu::VertexSource(
1732 "out gl_PerVertex {\n"
1733 "\tvec4 gl_Position;\n"
1736 "void main (void) {\n"
1737 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1738 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1743 const Vec4 minValue (0.0f);
1744 const Vec4 range (1.0f);
1745 std::ostringstream fragmentShader;
1749 "layout(push_constant) uniform PushConstant {\n"
1750 "\thighp uint sampleIndex;\n"
1751 "} pushConstants;\n"
1752 "void main (void)\n"
1754 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1755 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1756 "\thighp float depth;\n"
1757 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1758 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1760 fragmentShader << "\tdepth = " << minValue[0] << ";\n";
1763 deUint32 divider = 2;
1765 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1766 for (size_t bitNdx = 0; bitNdx < 10; bitNdx++)
1769 "\tdepth += " << (range[0] / (float)divider)
1770 << " * float(bitfieldExtract(" << (bitNdx % 2 == 0 ? "x" : "y") << ", " << (bitNdx / 2) << ", 1));\n";
1777 "\tgl_FragDepth = depth;\n"
1780 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1782 else if (testStencil)
1784 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1786 "layout(push_constant) uniform PushConstant {\n"
1787 "\thighp uint sampleIndex;\n"
1788 "} pushConstants;\n"
1789 "void main (void)\n"
1791 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1792 "\tgl_SampleMask[0] = int((~0x0u) << sampleIndex);\n"
1797 switch (channelClass)
1799 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1801 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1802 const UVec4 minValue (0);
1803 const UVec4 range (UVec4(1u) << tcu::min(bits, UVec4(31)));
1804 std::ostringstream fragmentShader;
1808 "layout(location = 0) out highp uvec4 o_color;\n"
1809 "layout(push_constant) uniform PushConstant {\n"
1810 "\thighp uint sampleIndex;\n"
1811 "} pushConstants;\n"
1812 "void main (void)\n"
1814 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1815 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1816 "\thighp uint color[4];\n"
1817 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1818 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1820 for (int ndx = 0; ndx < 4; ndx++)
1821 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1824 const int componentCount = tcu::getNumUsedChannels(format.order);
1825 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1826 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1827 deUint32 nextSrcBit = 0;
1828 deUint32 divider = 2;
1830 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1831 while (nextSrcBit < de::min(bitSize, 10u))
1833 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1835 if (dstBitsUsed[compNdx] > bits[compNdx])
1839 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1840 << " * bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1);\n";
1843 dstBitsUsed[compNdx]++;
1851 "\to_color = uvec4(color[0], color[1], color[2], color[3]);\n"
1854 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1858 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
1860 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
1861 const IVec4 minValue (0);
1862 const IVec4 range ((UVec4(1u) << tcu::min(bits, UVec4(30))).cast<deInt32>());
1863 const IVec4 maxV ((UVec4(1u) << (bits - UVec4(1u))).cast<deInt32>());
1864 const IVec4 clampMax (maxV - 1);
1865 const IVec4 clampMin (-maxV);
1866 std::ostringstream fragmentShader;
1870 "layout(location = 0) out highp ivec4 o_color;\n"
1871 "layout(push_constant) uniform PushConstant {\n"
1872 "\thighp uint sampleIndex;\n"
1873 "} pushConstants;\n"
1874 "void main (void)\n"
1876 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1877 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1878 "\thighp int color[4];\n"
1879 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1880 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1882 for (int ndx = 0; ndx < 4; ndx++)
1883 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1886 const int componentCount = tcu::getNumUsedChannels(format.order);
1887 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1888 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1889 deUint32 nextSrcBit = 0;
1890 deUint32 divider = 2;
1892 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1893 while (nextSrcBit < de::min(bitSize, 10u))
1895 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1897 if (dstBitsUsed[compNdx] > bits[compNdx])
1901 "\tcolor[" << compNdx << "] += " << (range[compNdx] / divider)
1902 << " * int(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1905 dstBitsUsed[compNdx]++;
1912 // The spec doesn't define whether signed-integers are clamped on output,
1913 // so we'll clamp them explicitly to have well-defined outputs.
1915 "\to_color = clamp(ivec4(color[0], color[1], color[2], color[3]), " <<
1916 "ivec4" << clampMin << ", ivec4" << clampMax << ");\n" <<
1919 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1923 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1924 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1925 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
1927 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
1928 const UVec4 bits (tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>());
1929 const Vec4 minLimit (-65536.0);
1930 const Vec4 maxLimit (65536.0);
1931 const Vec4 minValue (tcu::max(info.valueMin, minLimit));
1932 const Vec4 range (tcu::min(info.valueMax, maxLimit) - minValue);
1933 std::ostringstream fragmentShader;
1937 "layout(location = 0) out highp vec4 o_color;\n"
1938 "layout(push_constant) uniform PushConstant {\n"
1939 "\thighp uint sampleIndex;\n"
1940 "} pushConstants;\n"
1941 "void main (void)\n"
1943 "\thighp uint sampleIndex = pushConstants.sampleIndex;\n"
1944 "\tgl_SampleMask[0] = int(0x1u << sampleIndex);\n"
1945 "\thighp float color[4];\n"
1946 "\thighp uint x = sampleIndex ^ uint(gl_FragCoord.x);\n"
1947 "\thighp uint y = sampleIndex ^ uint(gl_FragCoord.y);\n";
1949 for (int ndx = 0; ndx < 4; ndx++)
1950 fragmentShader << "\tcolor[" << ndx << "] = " << minValue[ndx] << ";\n";
1953 const int componentCount = tcu::getNumUsedChannels(format.order);
1954 const deUint32 bitSize (bits[0] + bits[1] + bits[2] + bits[3]);
1955 deUint32 dstBitsUsed[4] = { 0u, 0u, 0u, 0u };
1956 deUint32 nextSrcBit = 0;
1957 deUint32 divider = 2;
1959 // \note Limited to ten bits since the target is 32x32, so there are 10 input bits
1960 while (nextSrcBit < de::min(bitSize, 10u))
1962 for (int compNdx = 0; compNdx < componentCount; compNdx++)
1964 if (dstBitsUsed[compNdx] > bits[compNdx])
1968 "\tcolor[" << compNdx << "] += " << (range[compNdx] / (float)divider)
1969 << " * float(bitfieldExtract(" << (nextSrcBit % 2 == 0 ? "x" : "y") << ", " << (nextSrcBit / 2) << ", 1));\n";
1972 dstBitsUsed[compNdx]++;
1980 "\to_color = vec4(color[0], color[1], color[2], color[3]);\n"
1983 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
1988 DE_FATAL("Unknown channel class");
1992 if (tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order))
1994 std::ostringstream splitShader;
1999 if (testDepth && testStencil)
2001 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n"
2002 << "layout(input_attachment_index = 0, set = 0, binding = 1) uniform highp usubpassInputMS i_stencil;\n";
2005 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInputMS i_depth;\n";
2006 else if (testStencil)
2007 splitShader << "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp usubpassInputMS i_stencil;\n";
2010 "layout(push_constant) uniform PushConstant {\n"
2011 "\thighp uint splitSubpassIndex;\n"
2012 "} pushConstants;\n";
2014 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2016 if (testDepth && testStencil)
2017 splitShader << "layout(location = " << attachmentNdx << ") out highp vec2 o_color" << attachmentNdx << ";\n";
2019 splitShader << "layout(location = " << attachmentNdx << ") out highp float o_color" << attachmentNdx << ";\n";
2023 "void main (void)\n"
2026 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2029 splitShader << "\thighp float depth" << attachmentNdx << " = subpassLoad(i_depth, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2032 splitShader << "\thighp uint stencil" << attachmentNdx << " = subpassLoad(i_stencil, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u)).x;\n";
2034 if (testDepth && testStencil)
2035 splitShader << "\to_color" << attachmentNdx << " = vec2(depth" << attachmentNdx << ", float(stencil" << attachmentNdx << "));\n";
2037 splitShader << "\to_color" << attachmentNdx << " = float(depth" << attachmentNdx << ");\n";
2038 else if (testStencil)
2039 splitShader << "\to_color" << attachmentNdx << " = float(stencil" << attachmentNdx << ");\n";
2045 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2049 std::string subpassType;
2050 std::string outputType;
2052 switch (channelClass)
2054 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
2055 subpassType = "usubpassInputMS";
2056 outputType = "uvec4";
2059 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
2060 subpassType = "isubpassInputMS";
2061 outputType = "ivec4";
2064 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
2065 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
2066 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
2067 subpassType = "subpassInputMS";
2068 outputType = "vec4";
2072 DE_FATAL("Unknown channel class");
2075 std::ostringstream splitShader;
2078 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp " << subpassType << " i_color;\n"
2079 "layout(push_constant) uniform PushConstant {\n"
2080 "\thighp uint splitSubpassIndex;\n"
2081 "} pushConstants;\n";
2083 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2084 splitShader << "layout(location = " << attachmentNdx << ") out highp " << outputType << " o_color" << attachmentNdx << ";\n";
2087 "void main (void)\n"
2090 for (deUint32 attachmentNdx = 0; attachmentNdx < de::min((deUint32)MAX_COLOR_ATTACHMENT_COUNT, config.sampleCount); attachmentNdx++)
2091 splitShader << "\to_color" << attachmentNdx << " = subpassLoad(i_color, int(" << MAX_COLOR_ATTACHMENT_COUNT << " * pushConstants.splitSubpassIndex + " << attachmentNdx << "u));\n";
2096 dst.glslSources.add("quad-split-frag") << glu::FragmentSource(splitShader.str());
2101 std::string formatToName (VkFormat format)
2103 const std::string formatStr = de::toString(format);
2104 const std::string prefix = "VK_FORMAT_";
2106 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
2108 return de::toLower(formatStr.substr(prefix.length()));
2111 void initTests (tcu::TestCaseGroup* group, RenderingType renderingType)
2113 static const VkFormat formats[] =
2115 VK_FORMAT_R5G6B5_UNORM_PACK16,
2120 VK_FORMAT_R8G8_UNORM,
2121 VK_FORMAT_R8G8_SNORM,
2122 VK_FORMAT_R8G8_UINT,
2123 VK_FORMAT_R8G8_SINT,
2124 VK_FORMAT_R8G8B8A8_UNORM,
2125 VK_FORMAT_R8G8B8A8_SNORM,
2126 VK_FORMAT_R8G8B8A8_UINT,
2127 VK_FORMAT_R8G8B8A8_SINT,
2128 VK_FORMAT_R8G8B8A8_SRGB,
2129 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2130 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2131 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2132 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2133 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2134 VK_FORMAT_B8G8R8A8_UNORM,
2135 VK_FORMAT_B8G8R8A8_SRGB,
2136 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2137 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2138 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2139 VK_FORMAT_R16_UNORM,
2140 VK_FORMAT_R16_SNORM,
2143 VK_FORMAT_R16_SFLOAT,
2144 VK_FORMAT_R16G16_UNORM,
2145 VK_FORMAT_R16G16_SNORM,
2146 VK_FORMAT_R16G16_UINT,
2147 VK_FORMAT_R16G16_SINT,
2148 VK_FORMAT_R16G16_SFLOAT,
2149 VK_FORMAT_R16G16B16A16_UNORM,
2150 VK_FORMAT_R16G16B16A16_SNORM,
2151 VK_FORMAT_R16G16B16A16_UINT,
2152 VK_FORMAT_R16G16B16A16_SINT,
2153 VK_FORMAT_R16G16B16A16_SFLOAT,
2156 VK_FORMAT_R32_SFLOAT,
2157 VK_FORMAT_R32G32_UINT,
2158 VK_FORMAT_R32G32_SINT,
2159 VK_FORMAT_R32G32_SFLOAT,
2160 VK_FORMAT_R32G32B32A32_UINT,
2161 VK_FORMAT_R32G32B32A32_SINT,
2162 VK_FORMAT_R32G32B32A32_SFLOAT,
2163 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2165 VK_FORMAT_D16_UNORM,
2166 VK_FORMAT_X8_D24_UNORM_PACK32,
2167 VK_FORMAT_D32_SFLOAT,
2169 VK_FORMAT_D16_UNORM_S8_UINT,
2170 VK_FORMAT_D24_UNORM_S8_UINT,
2171 VK_FORMAT_D32_SFLOAT_S8_UINT
2173 const deUint32 sampleCounts[] =
2175 2u, 4u, 8u, 16u, 32u
2177 tcu::TestContext& testCtx (group->getTestContext());
2178 de::MovePtr<tcu::TestCaseGroup> extGroup (new tcu::TestCaseGroup(testCtx, "separate_stencil_usage", "test VK_EXT_separate_stencil_usage"));
2180 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2182 const VkFormat format (formats[formatNdx]);
2183 const std::string formatName (formatToName(format));
2184 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2185 de::MovePtr<tcu::TestCaseGroup> extFormatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), formatName.c_str()));
2187 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
2189 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
2190 const TestConfig testConfig (format, sampleCount, renderingType);
2191 const std::string testName ("samples_" + de::toString(sampleCount));
2193 formatGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
2195 // create tests for VK_EXT_separate_stencil_usage
2196 if (tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order))
2198 de::MovePtr<tcu::TestCaseGroup> sampleGroup (new tcu::TestCaseGroup(testCtx, testName.c_str(), testName.c_str()));
2200 const TestConfig separateUsageDepthTestConfig (format, sampleCount, renderingType, TEST_DEPTH);
2201 sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_depth", "depth with input attachment bit", separateUsageDepthTestConfig));
2203 const TestConfig separateUsageStencilTestConfig (format, sampleCount, renderingType, TEST_STENCIL);
2204 sampleGroup->addChild(new InstanceFactory1<MultisampleRenderPassTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, "test_stencil", "stencil with input attachment bit", separateUsageStencilTestConfig));
2207 extFormatGroup->addChild(sampleGroup.release());
2211 group->addChild(formatGroup.release());
2212 extGroup->addChild(extFormatGroup.release());
2215 group->addChild(extGroup.release());
2220 tcu::TestCaseGroup* createRenderPassMultisampleTests (tcu::TestContext& testCtx)
2222 return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
2225 tcu::TestCaseGroup* createRenderPass2MultisampleTests (tcu::TestContext& testCtx)
2227 return createTestGroup(testCtx, "multisample", "Multisample render pass tests", initTests, RENDERING_TYPE_RENDERPASS2);