1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2018 The Khronos Group 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 VK_KHR_depth_stencil_resolve tests.
22 *//*--------------------------------------------------------------------*/
24 #include "vktRenderPassDepthStencilResolveTests.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 "tcuImageCompare.hpp"
44 #include "tcuFormatUtil.hpp"
45 #include "tcuResultCollector.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuTextureUtil.hpp"
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
61 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
62 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
63 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
64 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
65 typedef de::SharedPtr<Allocation> AllocationSp;
72 using namespace renderpass;
75 de::SharedPtr<T> safeSharedPtr (T* ptr)
79 return de::SharedPtr<T>(ptr);
101 deUint32 resolveBaseLayer;
103 VkImageAspectFlags aspectFlag;
104 deUint32 sampleCount;
105 VkResolveModeFlagBits depthResolveMode;
106 VkResolveModeFlagBits stencilResolveMode;
107 VerifyBuffer verifyBuffer;
108 VkClearDepthStencilValue clearValue;
109 float depthExpectedValue;
110 deUint8 stencilExpectedValue;
111 bool separateDepthStencilLayouts;
113 tcu::Maybe<VkFormat> compatibleFormat;
116 // Auxiliar class to group depth formats by compatibility in bit size and format. Note there is at most one alternative format for
117 // each given format as of the time this comment is being written, and the alternative (compatible) format for a given format can
118 // only remove aspects but not add them. That is, we cannot use a depth/stencil attachment to resolve a depth-only attachment.
121 // * VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03181
122 // * VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03182
123 class DepthCompatibilityManager
126 DepthCompatibilityManager ()
127 : m_compatibleFormats()
129 m_compatibleFormats[VK_FORMAT_D32_SFLOAT_S8_UINT] = VK_FORMAT_D32_SFLOAT;
130 m_compatibleFormats[VK_FORMAT_D16_UNORM_S8_UINT] = VK_FORMAT_D16_UNORM;
131 m_compatibleFormats[VK_FORMAT_D24_UNORM_S8_UINT] = VK_FORMAT_X8_D24_UNORM_PACK32;
134 VkFormat getAlternativeFormat (VkFormat format) const
136 const auto itr = m_compatibleFormats.find(format);
137 if (itr != end(m_compatibleFormats))
139 return VK_FORMAT_UNDEFINED;
143 std::map<VkFormat, VkFormat> m_compatibleFormats;
146 float get16bitDepthComponent(deUint8* pixelPtr)
148 deUint16* value = reinterpret_cast<deUint16*>(pixelPtr);
149 return static_cast<float>(*value) / 65535.0f;
152 float get24bitDepthComponent(deUint8* pixelPtr)
154 const bool littleEndian = (DE_ENDIANNESS == DE_LITTLE_ENDIAN);
155 deUint32 value = (((deUint32)pixelPtr[0]) << (!littleEndian * 16u)) |
156 (((deUint32)pixelPtr[1]) << 8u) |
157 (((deUint32)pixelPtr[2]) << ( littleEndian * 16u));
158 return static_cast<float>(value) / 16777215.0f;
161 float get32bitDepthComponent(deUint8* pixelPtr)
163 return *(reinterpret_cast<float*>(pixelPtr));
166 class DepthStencilResolveTest : public TestInstance
169 DepthStencilResolveTest (Context& context, TestConfig config);
170 virtual ~DepthStencilResolveTest (void);
172 virtual tcu::TestStatus iterate (void);
175 bool isFeaturesSupported (void);
176 bool isSupportedFormat (Context& context, VkFormat format) const;
177 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) const;
179 VkImageSp createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage = 0u);
180 AllocationSp createImageMemory (VkImageSp image);
181 VkImageViewSp createImageView (VkImageSp image, deUint32 baseArrayLayer);
182 AllocationSp createBufferMemory (void);
183 VkBufferSp createBuffer (void);
185 Move<VkRenderPass> createRenderPass (VkFormat vkformat);
186 Move<VkRenderPass> createRenderPassCompatible (void);
187 Move<VkFramebuffer> createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView);
188 Move<VkPipelineLayout> createRenderPipelineLayout (void);
189 Move<VkPipeline> createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout);
192 bool verifyDepth (void);
193 bool verifyStencil (void);
196 const TestConfig m_config;
197 const bool m_featureSupported;
199 const InstanceInterface& m_vki;
200 const DeviceInterface& m_vkd;
202 VkPhysicalDevice m_physicalDevice;
204 const Unique<VkCommandPool> m_commandPool;
206 VkImageSp m_multisampleImage;
207 AllocationSp m_multisampleImageMemory;
208 VkImageViewSp m_multisampleImageView;
209 VkImageSp m_singlesampleImage;
210 AllocationSp m_singlesampleImageMemory;
211 VkImageViewSp m_singlesampleImageView;
213 AllocationSp m_bufferMemory;
215 Unique<VkRenderPass> m_renderPass;
216 Unique<VkRenderPass> m_renderPassCompatible;
217 Unique<VkFramebuffer> m_framebuffer;
218 Unique<VkPipelineLayout> m_renderPipelineLayout;
219 Unique<VkPipeline> m_renderPipeline;
222 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
223 : TestInstance (context)
225 , m_featureSupported (isFeaturesSupported())
226 , m_vki (context.getInstanceInterface())
227 , m_vkd (context.getDeviceInterface())
228 , m_device (context.getDevice())
229 , m_physicalDevice (context.getPhysicalDevice())
231 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
233 , m_multisampleImage (createImage(m_config.sampleCount, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
234 , m_multisampleImageMemory (createImageMemory(m_multisampleImage))
235 , m_multisampleImageView (createImageView(m_multisampleImage, 0u))
237 , m_singlesampleImage (createImage(1, (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | (config.unusedResolve ? static_cast<vk::VkImageUsageFlags>(VK_IMAGE_USAGE_TRANSFER_DST_BIT) : 0u))))
238 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImage))
239 , m_singlesampleImageView (createImageView(m_singlesampleImage, m_config.resolveBaseLayer))
241 , m_buffer (createBuffer())
242 , m_bufferMemory (createBufferMemory())
244 , m_renderPass (createRenderPass(m_config.format))
245 , m_renderPassCompatible (createRenderPassCompatible())
246 , m_framebuffer (createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView))
247 , m_renderPipelineLayout (createRenderPipelineLayout())
248 , m_renderPipeline (createRenderPipeline(*m_renderPass, *m_renderPipelineLayout))
252 DepthStencilResolveTest::~DepthStencilResolveTest (void)
256 bool DepthStencilResolveTest::isFeaturesSupported()
258 m_context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
259 if (m_config.imageLayers > 1)
260 m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
262 if (m_config.separateDepthStencilLayouts)
263 m_context.requireDeviceFunctionality("VK_KHR_separate_depth_stencil_layouts");
265 VkPhysicalDeviceDepthStencilResolveProperties dsResolveProperties;
266 deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolveProperties));
267 dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES;
268 dsResolveProperties.pNext = DE_NULL;
270 VkPhysicalDeviceProperties2 deviceProperties;
271 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
272 deviceProperties.pNext = &dsResolveProperties;
274 // perform query to get supported float control properties
275 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
276 const vk::InstanceInterface& instanceInterface = m_context.getInstanceInterface();
277 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
279 // check if both modes are supported
280 VkResolveModeFlagBits depthResolveMode = m_config.depthResolveMode;
281 VkResolveModeFlagBits stencilResolveMode = m_config.stencilResolveMode;
283 if ((depthResolveMode != VK_RESOLVE_MODE_NONE) &&
284 !(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
285 TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
287 if ((stencilResolveMode != VK_RESOLVE_MODE_NONE) &&
288 !(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
289 TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");
291 // check if the implementation supports setting the depth and stencil resolve
292 // modes to different values when one of those modes is VK_RESOLVE_MODE_NONE
293 if (dsResolveProperties.independentResolveNone)
295 if ((!dsResolveProperties.independentResolve) &&
296 (depthResolveMode != stencilResolveMode) &&
297 (depthResolveMode != VK_RESOLVE_MODE_NONE) &&
298 (stencilResolveMode != VK_RESOLVE_MODE_NONE))
299 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
301 else if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
303 // when independentResolveNone and independentResolve are VK_FALSE then both modes must be the same
304 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
307 // Check alternative format support if needed.
308 if (m_config.compatibleFormat)
310 if (! isSupportedFormat(m_context, m_config.compatibleFormat.get()))
311 TCU_THROW(NotSupportedError, "Alternative image format for compatibility test not supported");
317 VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const
321 case 1: return VK_SAMPLE_COUNT_1_BIT;
322 case 2: return VK_SAMPLE_COUNT_2_BIT;
323 case 4: return VK_SAMPLE_COUNT_4_BIT;
324 case 8: return VK_SAMPLE_COUNT_8_BIT;
325 case 16: return VK_SAMPLE_COUNT_16_BIT;
326 case 32: return VK_SAMPLE_COUNT_32_BIT;
327 case 64: return VK_SAMPLE_COUNT_64_BIT;
330 DE_FATAL("Invalid sample count");
331 return (VkSampleCountFlagBits)0x0;
335 VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage)
337 const tcu::TextureFormat format(mapVkFormat(m_config.format));
338 const VkImageTiling imageTiling(VK_IMAGE_TILING_OPTIMAL);
339 VkSampleCountFlagBits sampleCountBit(sampleCountBitFromSampleCount(sampleCount));
340 VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | additionalUsage;
342 VkImageFormatProperties imageFormatProperties;
343 if (m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice, m_config.format, VK_IMAGE_TYPE_2D, imageTiling,
344 usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
346 TCU_THROW(NotSupportedError, "Format not supported");
348 if (imageFormatProperties.sampleCounts < sampleCount)
350 TCU_THROW(NotSupportedError, "Sample count not supported");
352 if (imageFormatProperties.maxArrayLayers < m_config.imageLayers)
354 TCU_THROW(NotSupportedError, "Layers count not supported");
357 const VkExtent3D imageExtent =
364 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order)))
365 TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment");
367 if (imageFormatProperties.maxExtent.width < imageExtent.width
368 || imageFormatProperties.maxExtent.height < imageExtent.height
369 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
370 || imageFormatProperties.maxArrayLayers < m_config.imageLayers)
372 TCU_THROW(NotSupportedError, "Image type not supported");
375 const VkImageCreateInfo pCreateInfo =
377 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
384 m_config.imageLayers,
388 VK_SHARING_MODE_EXCLUSIVE,
391 VK_IMAGE_LAYOUT_UNDEFINED
394 return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo)));
397 AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image)
399 Allocator& allocator = m_context.getDefaultAllocator();
401 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, **image), MemoryRequirement::Any));
402 VK_CHECK(m_vkd.bindImageMemory(m_device, **image, allocation->getMemory(), allocation->getOffset()));
403 return safeSharedPtr(allocation.release());
406 VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer)
408 const VkImageSubresourceRange range =
417 const VkImageViewCreateInfo pCreateInfo =
419 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
423 (m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
425 makeComponentMappingRGBA(),
428 return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo)));
431 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (VkFormat vkformat)
433 // When the depth/stencil resolve attachment is unused, it needs to be cleared outside the render pass so it has the expected values.
434 if (m_config.unusedResolve)
436 const tcu::TextureFormat format (mapVkFormat(vkformat));
437 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(m_vkd, m_device, *m_commandPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
438 const vk::VkImageSubresourceRange imageRange =
440 ((tcu::hasDepthComponent(format.order) ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_DEPTH_BIT) : 0u) |
441 (tcu::hasStencilComponent(format.order) ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_STENCIL_BIT) : 0u)),
443 VK_REMAINING_MIP_LEVELS,
445 VK_REMAINING_ARRAY_LAYERS,
447 const vk::VkImageMemoryBarrier preBarrier =
449 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
452 // src and dst access masks.
454 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
456 // old and new layouts.
457 vk::VK_IMAGE_LAYOUT_UNDEFINED,
458 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
460 VK_QUEUE_FAMILY_IGNORED,
461 VK_QUEUE_FAMILY_IGNORED,
463 **m_singlesampleImage,
466 const vk::VkImageMemoryBarrier postBarrier =
468 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
471 // src and dst access masks.
472 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
475 // old and new layouts.
476 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
477 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
479 VK_QUEUE_FAMILY_IGNORED,
480 VK_QUEUE_FAMILY_IGNORED,
482 **m_singlesampleImage,
486 vk::beginCommandBuffer(m_vkd, commandBuffer.get());
487 m_vkd.cmdPipelineBarrier(commandBuffer.get(), vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &preBarrier);
488 m_vkd.cmdClearDepthStencilImage(commandBuffer.get(), **m_singlesampleImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_config.clearValue, 1u, &imageRange);
489 m_vkd.cmdPipelineBarrier(commandBuffer.get(), vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &postBarrier);
490 vk::endCommandBuffer(m_vkd, commandBuffer.get());
492 vk::submitCommandsAndWait(m_vkd, m_device, m_context.getUniversalQueue(), commandBuffer.get());
495 const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));
497 VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
498 VkAttachmentReferenceStencilLayoutKHR stencilLayout =
500 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR,
502 VK_IMAGE_LAYOUT_UNDEFINED,
504 void * attachmentRefStencil = DE_NULL;
505 VkImageLayout finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
506 VkAttachmentDescriptionStencilLayoutKHR stencilFinalLayout =
508 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR,
510 VK_IMAGE_LAYOUT_UNDEFINED,
511 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
513 void * attachmentDescriptionStencil = DE_NULL;
515 if (m_config.separateDepthStencilLayouts)
517 if (m_config.verifyBuffer == VB_DEPTH)
519 layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR;
520 stencilLayout.stencilLayout = VK_IMAGE_LAYOUT_GENERAL;
521 finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
522 stencilFinalLayout.stencilFinalLayout = VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR; // This aspect should be unused.
526 layout = VK_IMAGE_LAYOUT_GENERAL;
527 stencilLayout.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR;
528 finalLayout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR; // This aspect should be unused.
529 stencilFinalLayout.stencilFinalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
531 attachmentRefStencil = &stencilLayout;
532 attachmentDescriptionStencil = &stencilFinalLayout;
535 const AttachmentDescription2 multisampleAttachment // VkAttachmentDescription2
537 // VkStructureType sType;
538 attachmentDescriptionStencil, // const void* pNext;
539 0u, // VkAttachmentDescriptionFlags flags;
540 m_config.format, // VkFormat format;
541 samples, // VkSampleCountFlagBits samples;
542 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
543 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
544 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
545 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
546 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
547 finalLayout // VkImageLayout finalLayout;
549 const AttachmentReference2 multisampleAttachmentRef // VkAttachmentReference2
551 // VkStructureType sType;
552 attachmentRefStencil, // const void* pNext;
553 0u, // deUint32 attachment;
554 layout, // VkImageLayout layout;
555 m_config.aspectFlag // VkImageAspectFlags aspectMask;
558 const vk::VkImageLayout singleSampleInitialLayout = (m_config.unusedResolve ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED);
561 const tcu::TextureFormat format (mapVkFormat(vkformat));
562 VkImageAspectFlags aspectFlags =
563 ((tcu::hasDepthComponent(format.order) ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_DEPTH_BIT) : 0u) |
564 (tcu::hasStencilComponent(format.order) ? static_cast<vk::VkImageAspectFlags>(vk::VK_IMAGE_ASPECT_STENCIL_BIT) : 0u));
566 const AttachmentDescription2 singlesampleAttachment // VkAttachmentDescription2
568 // VkStructureType sType;
569 attachmentDescriptionStencil, // const void* pNext;
570 0u, // VkAttachmentDescriptionFlags flags;
571 vkformat, // VkFormat format;
572 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
573 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
574 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
575 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
576 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
577 singleSampleInitialLayout, // VkImageLayout initialLayout;
578 finalLayout // VkImageLayout finalLayout;
580 AttachmentReference2 singlesampleAttachmentRef // VkAttachmentReference2
582 // VkStructureType sType;
583 DE_NULL, // const void* pNext;
584 (m_config.unusedResolve ? VK_ATTACHMENT_UNUSED : 1u), // deUint32 attachment;
585 layout, // VkImageLayout layout;
586 aspectFlags // VkImageAspectFlags aspectMask;
589 std::vector<AttachmentDescription2> attachments;
590 attachments.push_back(multisampleAttachment);
591 attachments.push_back(singlesampleAttachment);
593 VkSubpassDescriptionDepthStencilResolve dsResolveDescription =
595 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
596 DE_NULL, // const void* pNext;
597 m_config.depthResolveMode, // VkResolveModeFlagBits depthResolveMode;
598 m_config.stencilResolveMode, // VkResolveModeFlagBits stencilResolveMode;
599 &singlesampleAttachmentRef // VkAttachmentReference2 pDepthStencilResolveAttachment;
602 const SubpassDescription2 subpass // VkSubpassDescription2
604 // VkStructureType sType;
605 &dsResolveDescription, // const void* pNext;
606 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
607 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
608 0u, // deUint32 viewMask;
609 0u, // deUint32 inputAttachmentCount;
610 DE_NULL, // const VkAttachmentReference2* pInputAttachments;
611 0u, // deUint32 colorAttachmentCount;
612 DE_NULL, // const VkAttachmentReference2* pColorAttachments;
613 DE_NULL, // const VkAttachmentReference2* pResolveAttachments;
614 &multisampleAttachmentRef, // const VkAttachmentReference2* pDepthStencilAttachment;
615 0u, // deUint32 preserveAttachmentCount;
616 DE_NULL // const deUint32* pPreserveAttachments;
619 const RenderPassCreateInfo2 renderPassCreator // VkRenderPassCreateInfo2
621 // VkStructureType sType;
622 DE_NULL, // const void* pNext;
623 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags;
624 (deUint32)attachments.size(), // deUint32 attachmentCount;
625 &attachments[0], // const VkAttachmentDescription2* pAttachments;
626 1u, // deUint32 subpassCount;
627 &subpass, // const VkSubpassDescription2* pSubpasses;
628 0u, // deUint32 dependencyCount;
629 DE_NULL, // const VkSubpassDependency2* pDependencies;
630 0u, // deUint32 correlatedViewMaskCount;
631 DE_NULL // const deUint32* pCorrelatedViewMasks;
634 return renderPassCreator.createRenderPass(m_vkd, m_device);
637 // Checks format support.
638 // Note: we need the context because this is called from the constructor only after m_config has been set.
639 bool DepthStencilResolveTest::isSupportedFormat (Context& context, VkFormat format) const
641 const VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
642 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
643 | (m_config.unusedResolve ? VK_IMAGE_USAGE_TRANSFER_DST_BIT : static_cast<vk::VkImageUsageFlagBits>(0u));
644 VkImageFormatProperties props;
646 const auto& vki = context.getInstanceInterface();
647 const auto physicalDevice = context.getPhysicalDevice();
648 const auto formatCheck = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0u, &props);
650 return (formatCheck == VK_SUCCESS);
653 Move<VkRenderPass> DepthStencilResolveTest::createRenderPassCompatible (void)
655 // Early exit if we are not testing compatibility.
656 if (! m_config.compatibleFormat)
659 return createRenderPass(m_config.compatibleFormat.get());
662 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
664 std::vector<VkImageView> attachments;
665 attachments.push_back(**multisampleImageView);
666 attachments.push_back(**singlesampleImageView);
668 const VkFramebufferCreateInfo createInfo =
670 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
675 (deUint32)attachments.size(),
683 return vk::createFramebuffer(m_vkd, m_device, &createInfo);
686 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
688 VkPushConstantRange pushConstant =
690 VK_SHADER_STAGE_FRAGMENT_BIT,
695 deUint32 pushConstantRangeCount = 0u;
696 VkPushConstantRange* pPushConstantRanges = DE_NULL;
697 if (m_config.verifyBuffer == VB_STENCIL)
699 pushConstantRangeCount = 1u;
700 pPushConstantRanges = &pushConstant;
703 const VkPipelineLayoutCreateInfo createInfo =
705 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
707 (vk::VkPipelineLayoutCreateFlags)0,
712 pushConstantRangeCount,
716 return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
719 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout)
721 const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
722 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
724 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u));
725 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u));
726 const Move<VkShaderModule> geometryShaderModule (m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u));
728 const VkPipelineVertexInputStateCreateInfo vertexInputState =
730 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
732 (VkPipelineVertexInputStateCreateFlags)0u,
740 const tcu::UVec2 view (m_config.width, m_config.height);
741 const std::vector<VkViewport> viewports (1, makeViewport(view));
742 const std::vector<VkRect2D> scissors (1, m_config.renderArea);
744 const VkPipelineMultisampleStateCreateInfo multisampleState =
746 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
748 (VkPipelineMultisampleStateCreateFlags)0u,
750 sampleCountBitFromSampleCount(m_config.sampleCount),
757 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
759 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
761 (VkPipelineDepthStencilStateCreateFlags)0u,
763 VK_TRUE, // depthTestEnable
765 VK_COMPARE_OP_ALWAYS,
767 testingStencil, // stencilTestEnable
769 VK_STENCIL_OP_REPLACE, // failOp
770 VK_STENCIL_OP_REPLACE, // passOp
771 VK_STENCIL_OP_REPLACE, // depthFailOp
772 VK_COMPARE_OP_ALWAYS, // compareOp
773 0xFFu, // compareMask
778 VK_STENCIL_OP_REPLACE,
779 VK_STENCIL_OP_REPLACE,
780 VK_STENCIL_OP_REPLACE,
781 VK_COMPARE_OP_ALWAYS,
790 std::vector<VkDynamicState> dynamicState;
791 dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
792 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
794 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
795 DE_NULL, // const void* pNext;
796 (VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags;
797 static_cast<deUint32>(dynamicState.size()), // deUint32 dynamicStateCount;
798 &dynamicState[0] // const VkDynamicState* pDynamicStates;
801 return makeGraphicsPipeline(m_vkd, // const DeviceInterface& vk
802 m_device, // const VkDevice device
803 renderPipelineLayout, // const VkPipelineLayout pipelineLayout
804 *vertexShaderModule, // const VkShaderModule vertexShaderModule
805 DE_NULL, // const VkShaderModule tessellationControlShaderModule
806 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
807 m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule, // const VkShaderModule geometryShaderModule
808 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
809 renderPass, // const VkRenderPass renderPass
810 viewports, // const std::vector<VkViewport>& viewports
811 scissors, // const std::vector<VkRect2D>& scissors
812 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
813 0u, // const deUint32 subpass
814 0u, // const deUint32 patchControlPoints
815 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
816 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
817 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
818 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
819 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
820 testingStencil ? &dynamicStateCreateInfo : DE_NULL); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
823 AllocationSp DepthStencilResolveTest::createBufferMemory (void)
825 Allocator& allocator = m_context.getDefaultAllocator();
826 de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible));
827 VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset()));
828 return safeSharedPtr(allocation.release());
831 VkBufferSp DepthStencilResolveTest::createBuffer (void)
833 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
834 const tcu::TextureFormat textureFormat (mapVkFormat(m_config.format));
835 const VkDeviceSize pixelSize (textureFormat.getPixelSize());
836 const VkBufferCreateInfo createInfo =
838 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
842 m_config.width * m_config.height * m_config.imageLayers * pixelSize,
845 VK_SHARING_MODE_EXCLUSIVE,
849 return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
852 void DepthStencilResolveTest::submit (void)
854 const DeviceInterface& vkd (m_context.getDeviceInterface());
855 const VkDevice device (m_context.getDevice());
856 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
857 const RenderpassSubpass2::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
858 const RenderpassSubpass2::SubpassEndInfo subpassEndInfo (DE_NULL);
860 beginCommandBuffer(vkd, *commandBuffer);
863 VkClearValue clearValues[2];
864 clearValues[0].depthStencil = m_config.clearValue;
865 clearValues[1].depthStencil = m_config.clearValue;
867 const VkRenderPassBeginInfo beginInfo =
869 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
872 (m_config.compatibleFormat ? *m_renderPassCompatible : *m_renderPass),
877 { m_config.width, m_config.height }
883 RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
887 bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
890 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
891 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
895 // For stencil we can set reference value for just one sample at a time
896 // so we need to do as many passes as there are samples, first half
897 // of samples is initialized with 1 and second half with 255
898 const deUint32 halfOfSamples = m_config.sampleCount >> 1;
899 for (deUint32 renderPass = 0 ; renderPass < m_config.sampleCount ; renderPass++)
901 deUint32 stencilReference = 1 + 254 * (renderPass >= halfOfSamples);
902 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
903 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(renderPass), &renderPass);
904 vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference);
905 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
909 RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
911 // Memory barriers between rendering and copying
913 const VkImageMemoryBarrier barrier =
915 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
918 // Note: as per the spec, depth/stencil *resolve* operations are synchronized using the color attachment write access.
919 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
920 VK_ACCESS_TRANSFER_READ_BIT,
922 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
923 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
925 VK_QUEUE_FAMILY_IGNORED,
926 VK_QUEUE_FAMILY_IGNORED,
928 **m_singlesampleImage,
930 (m_config.separateDepthStencilLayouts) ? VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT) : m_config.aspectFlag,
938 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
941 // Copy image memory to buffers
942 const VkBufferImageCopy region =
948 VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT),
954 { m_config.width, m_config.height, 1u }
957 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, ®ion);
959 // Memory barriers between copies and host access
961 const VkBufferMemoryBarrier barrier =
963 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
966 VK_ACCESS_TRANSFER_WRITE_BIT,
967 VK_ACCESS_HOST_READ_BIT,
969 VK_QUEUE_FAMILY_IGNORED,
970 VK_QUEUE_FAMILY_IGNORED,
977 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
980 endCommandBuffer(vkd, *commandBuffer);
982 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
985 bool DepthStencilResolveTest::verifyDepth (void)
987 // Invalidate allocation before attempting to read buffer memory.
988 invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
990 deUint32 layerSize = m_config.width * m_config.height;
991 deUint32 valuesCount = layerSize * m_config.viewLayers;
992 deUint8* pixelPtr = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
994 const DeviceInterface& vkd (m_context.getDeviceInterface());
995 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
997 float expectedValue = m_config.depthExpectedValue;
998 if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
999 expectedValue = m_config.clearValue.depth;
1001 // depth data in buffer is tightly packed, ConstPixelBufferAccess
1002 // coludn't be used for depth value extraction as it cant interpret
1003 // formats containing just depth component
1005 typedef float (*DepthComponentGetterFn)(deUint8*);
1006 VkFormat format = m_config.format;
1007 DepthComponentGetterFn getDepthComponent = &get16bitDepthComponent;
1008 deUint32 pixelStep = 2;
1009 float epsilon = 0.002f;
1011 if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
1012 (format == VK_FORMAT_D24_UNORM_S8_UINT))
1014 getDepthComponent = &get24bitDepthComponent;
1017 else if ((format == VK_FORMAT_D32_SFLOAT) ||
1018 (format == VK_FORMAT_D32_SFLOAT_S8_UINT))
1020 getDepthComponent = &get32bitDepthComponent;
1024 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1026 float depth = (*getDepthComponent)(pixelPtr);
1027 pixelPtr += pixelStep;
1029 // check if pixel data is outside of render area
1030 deInt32 layerIndex = valueIndex / layerSize;
1031 deInt32 inLayerIndex = valueIndex % layerSize;
1032 deInt32 x = inLayerIndex % m_config.width;
1033 deInt32 y = (inLayerIndex - x) / m_config.width;
1034 deInt32 x1 = m_config.renderArea.offset.x;
1035 deInt32 y1 = m_config.renderArea.offset.y;
1036 deInt32 x2 = x1 + m_config.renderArea.extent.width;
1037 deInt32 y2 = y1 + m_config.renderArea.extent.height;
1038 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
1040 // verify that outside of render area there are clear values
1041 float error = deFloatAbs(depth - m_config.clearValue.depth);
1042 if (error > epsilon)
1044 m_context.getTestContext().getLog()
1045 << TestLog::Message << "(" << x << ", " << y
1046 << ", layer: " << layerIndex << ") is outside of render area but depth value is: "
1047 << depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage;
1051 // value is correct, go to next one
1055 float error = deFloatAbs(depth - expectedValue);
1056 if (error > epsilon)
1058 m_context.getTestContext().getLog() << TestLog::Message
1059 << "At (" << x << ", " << y << ", layer: " << layerIndex
1060 << ") depth value is: " << depth << " expected: "
1061 << expectedValue << TestLog::EndMessage;
1065 m_context.getTestContext().getLog() << TestLog::Message
1066 << "Depth value is " << expectedValue
1067 << TestLog::EndMessage;
1072 bool DepthStencilResolveTest::verifyStencil (void)
1074 // Invalidate allocation before attempting to read buffer memory.
1075 invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
1077 deUint32 layerSize = m_config.width * m_config.height;
1078 deUint32 valuesCount = layerSize * m_config.viewLayers;
1079 deUint8* pixelPtr = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
1081 const DeviceInterface& vkd (m_context.getDeviceInterface());
1082 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
1084 // when stencil is tested we are discarding invocations and
1085 // because of that depth and stencil need to be tested separately
1087 deUint8 expectedValue = m_config.stencilExpectedValue;
1088 if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
1089 expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);
1091 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1093 deUint8 stencil = *pixelPtr++;
1094 deInt32 layerIndex = valueIndex / layerSize;
1095 deInt32 inLayerIndex = valueIndex % layerSize;
1096 deInt32 x = inLayerIndex % m_config.width;
1097 deInt32 y = (inLayerIndex - x) / m_config.width;
1098 deInt32 x1 = m_config.renderArea.offset.x;
1099 deInt32 y1 = m_config.renderArea.offset.y;
1100 deInt32 x2 = x1 + m_config.renderArea.extent.width;
1101 deInt32 y2 = y1 + m_config.renderArea.extent.height;
1102 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
1104 if (stencil != m_config.clearValue.stencil)
1106 m_context.getTestContext().getLog()
1107 << TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex
1108 << ") is outside of render area but stencil value is: "
1109 << stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage;
1113 // value is correct, go to next one
1117 if (stencil != expectedValue)
1119 m_context.getTestContext().getLog() << TestLog::Message
1120 << "At (" << x << ", " << y << ", layer: " << layerIndex
1121 << ") stencil value is: " << static_cast<deUint32>(stencil)
1122 << " expected: " << static_cast<deUint32>(expectedValue)
1123 << TestLog::EndMessage;
1127 m_context.getTestContext().getLog() << TestLog::Message
1128 << "Stencil value is "
1129 << static_cast<deUint32>(expectedValue)
1130 << TestLog::EndMessage;
1135 tcu::TestStatus DepthStencilResolveTest::iterate (void)
1139 bool result = false;
1140 if (m_config.verifyBuffer == VB_DEPTH)
1141 result = verifyDepth();
1143 result = verifyStencil();
1146 return tcu::TestStatus::pass("Pass");
1147 return tcu::TestStatus::fail("Fail");
1152 void init (vk::SourceCollections& dst, TestConfig config) const
1154 // geometry shader is only needed in multi-layer framebuffer resolve tests
1155 if (config.imageLayers > 1)
1157 const deUint32 layerCount = 3;
1159 std::ostringstream src;
1160 src << "#version 450\n"
1163 << "layout(triangles) in;\n"
1164 << "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
1166 << "in gl_PerVertex {\n"
1167 << " vec4 gl_Position;\n"
1170 << "out gl_PerVertex {\n"
1171 << " vec4 gl_Position;\n"
1174 << "void main (void) {\n"
1175 << " for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n"
1176 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
1177 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
1178 << " gl_Layer = layerNdx;\n"
1179 << " EmitVertex();\n"
1181 << " EndPrimitive();\n"
1185 dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
1188 dst.glslSources.add("quad-vert") << glu::VertexSource(
1190 "out gl_PerVertex {\n"
1191 "\tvec4 gl_Position;\n"
1194 "void main (void) {\n"
1195 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1196 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1199 if (config.verifyBuffer == VB_DEPTH)
1201 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1203 "precision highp float;\n"
1204 "precision highp int;\n"
1205 "void main (void)\n"
1207 " float sampleIndex = float(gl_SampleID);\n" // sampleIndex is integer in range <0, 63>
1208 " float valueIndex = round(mod(sampleIndex, 4.0));\n" // limit possible depth values - count to 4
1209 " float value = valueIndex + 2.0;\n" // value is one of [2, 3, 4, 5]
1210 " value = round(exp2(value));\n" // value is one of [4, 8, 16, 32]
1211 " bool condition = (int(value) == 8);\n" // select second sample value (to make it smallest)
1212 " value = round(value - float(condition) * 6.0);\n" // value is one of [4, 2, 16, 32]
1213 " gl_FragDepth = value / 100.0;\n" // sample depth is one of [0.04, 0.02, 0.16, 0.32]
1218 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1220 "precision highp float;\n"
1221 "precision highp int;\n"
1222 "layout(push_constant) uniform PushConstant {\n"
1223 " highp int sampleID;\n"
1224 "} pushConstants;\n"
1225 "void main (void)\n"
1227 " if(gl_SampleID != pushConstants.sampleID)\n"
1229 " gl_FragDepth = 0.5;\n"
1235 class PropertiesTestCase : public vkt::TestCase
1238 PropertiesTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description)
1239 : vkt::TestCase(testCtx, name, description)
1241 virtual ~PropertiesTestCase (void) {}
1243 virtual TestInstance* createInstance (Context& context) const;
1244 virtual void checkSupport (Context& context) const;
1247 class PropertiesTestInstance : public vkt::TestInstance
1250 PropertiesTestInstance (Context& context)
1251 : vkt::TestInstance(context)
1253 virtual ~PropertiesTestInstance (void) {}
1255 virtual tcu::TestStatus iterate (void);
1259 TestInstance* PropertiesTestCase::createInstance (Context& context) const
1261 return new PropertiesTestInstance(context);
1264 void PropertiesTestCase::checkSupport (Context& context) const
1266 context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
1269 tcu::TestStatus PropertiesTestInstance::iterate (void)
1271 vk::VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsrProperties;
1272 dsrProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
1273 dsrProperties.pNext = nullptr;
1275 vk::VkPhysicalDeviceProperties2 properties2;
1276 properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1277 properties2.pNext = &dsrProperties;
1279 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties2);
1281 if ((dsrProperties.supportedDepthResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
1282 TCU_FAIL("supportedDepthResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
1284 if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR) == 0)
1285 TCU_FAIL("supportedStencilResolveModes does not include VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR");
1287 if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_AVERAGE_BIT_KHR) != 0)
1288 TCU_FAIL("supportedStencilResolveModes includes forbidden VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
1290 if (dsrProperties.independentResolve == VK_TRUE && dsrProperties.independentResolveNone != VK_TRUE)
1291 TCU_FAIL("independentResolve supported but independentResolveNone not supported");
1293 return tcu::TestStatus::pass("Pass");
1297 void initTests (tcu::TestCaseGroup* group)
1299 typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
1308 FormatData formats[] =
1310 { VK_FORMAT_D16_UNORM, "d16_unorm", true, false },
1311 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32", true, false },
1312 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", true, false },
1313 { VK_FORMAT_S8_UINT, "s8_uint", false, true },
1314 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint", true, true },
1315 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint", true, true },
1316 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", true, true },
1319 struct ResolveModeData
1321 VkResolveModeFlagBits flag;
1324 ResolveModeData resolveModes[] =
1326 { VK_RESOLVE_MODE_NONE, "none" },
1327 { VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, "zero" },
1328 { VK_RESOLVE_MODE_AVERAGE_BIT, "average" },
1329 { VK_RESOLVE_MODE_MIN_BIT, "min" },
1330 { VK_RESOLVE_MODE_MAX_BIT, "max" },
1333 struct ImageTestData
1335 const char* groupName;
1338 deUint32 imageLayers;
1339 VkRect2D renderArea;
1340 VkClearDepthStencilValue clearValue;
1343 // NOTE: tests cant be executed for 1D and 3D images:
1344 // 1D images are not tested because acording to specyfication sampleCounts
1345 // will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D
1346 // 3D images are not tested because VkFramebufferCreateInfo specification
1347 // states that: each element of pAttachments that is a 2D or 2D array image
1348 // view taken from a 3D image must not be a depth/stencil format
1349 ImageTestData imagesTestData[] =
1351 { "image_2d_32_32", 32, 32, 1, {{ 0, 0}, {32, 32}}, {0.000f, 0x00} },
1352 { "image_2d_8_32", 8, 32, 1, {{ 1, 1}, { 6, 30}}, {0.123f, 0x01} },
1353 { "image_2d_49_13", 49, 13, 1, {{10, 5}, {20, 8}}, {1.000f, 0x05} },
1354 { "image_2d_5_1", 5, 1, 1, {{ 0, 0}, { 5, 1}}, {0.500f, 0x00} },
1355 { "image_2d_17_1", 17, 1, 1, {{ 1, 0}, {15, 1}}, {0.789f, 0xfa} },
1357 const deUint32 sampleCounts[] =
1359 2u, 4u, 8u, 16u, 32u, 64u
1361 const float depthExpectedValue[][6] =
1363 // 2 samples 4 8 16 32 64
1364 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // RESOLVE_MODE_NONE - expect clear value
1365 { 0.04f, 0.04f, 0.04f, 0.04f, 0.04f, 0.04f }, // RESOLVE_MODE_SAMPLE_ZERO_BIT
1366 { 0.03f, 0.135f, 0.135f, 0.135f, 0.135f, 0.135f }, // RESOLVE_MODE_AVERAGE_BIT
1367 { 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f }, // RESOLVE_MODE_MIN_BIT
1368 { 0.04f, 0.32f, 0.32f, 0.32f, 0.32f, 0.32f }, // RESOLVE_MODE_MAX_BIT
1370 const deUint8 stencilExpectedValue[][6] =
1372 // 2 samples 4 8 16 32 64
1373 { 0u, 0u, 0u, 0u, 0u, 0u }, // RESOLVE_MODE_NONE - expect clear value
1374 { 1u, 1u, 1u, 1u, 1u, 1u }, // RESOLVE_MODE_SAMPLE_ZERO_BIT
1375 { 0u, 0u, 0u, 0u, 0u, 0u }, // RESOLVE_MODE_AVERAGE_BIT - not supported
1376 { 1u, 1u, 1u, 1u, 1u, 1u }, // RESOLVE_MODE_MIN_BIT
1377 { 255u, 255u, 255u, 255u, 255u, 255u }, // RESOLVE_MODE_MAX_BIT
1380 const DepthCompatibilityManager compatManager;
1382 tcu::TestContext& testCtx(group->getTestContext());
1386 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", "Miscellaneous depth/stencil resolve tests"));
1387 miscGroup->addChild(new PropertiesTestCase(testCtx, "properties", "Check reported depth/stencil resolve properties"));
1388 group->addChild(miscGroup.release());
1391 // iterate over image data
1392 for (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
1394 ImageTestData imageData = imagesTestData[imageDataNdx];
1396 // create test group for image data
1397 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));
1399 // iterate over sampleCounts
1400 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1402 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1403 const std::string sampleName ("samples_" + de::toString(sampleCount));
1405 // create test group for sample count
1406 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1408 // iterate over depth/stencil formats
1409 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1411 const FormatData& formatData = formats[formatNdx];
1412 VkFormat format = formatData.format;
1413 const char* formatName = formatData.name;
1414 const bool hasDepth = formatData.hasDepth;
1415 const bool hasStencil = formatData.hasStencil;
1416 VkImageAspectFlags aspectFlags = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1417 (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1418 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 2 : 1;
1420 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1422 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
1423 const std::string groupName = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1425 // create test group for format
1426 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1428 // iterate over depth resolve modes
1429 for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
1431 // iterate over stencil resolve modes
1432 for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
1434 for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1436 // there is no average resolve mode for stencil - go to next iteration
1437 ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
1438 if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1441 // if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
1442 // depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
1443 ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
1444 if ((dResolve.flag == VK_RESOLVE_MODE_NONE) && (sResolve.flag == VK_RESOLVE_MODE_NONE))
1447 // If there is no depth, the depth resolve mode should be NONE, or
1448 // match the stencil resolve mode.
1449 if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE) &&
1450 (dResolve.flag != sResolve.flag))
1453 // If there is no stencil, the stencil resolve mode should be NONE, or
1454 // match the depth resolve mode.
1455 if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE) &&
1456 (dResolve.flag != sResolve.flag))
1459 const bool unusedResolve = (unusedIdx > 0);
1461 std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
1463 baseName += "_unused_resolve";
1467 std::string name = baseName + "_testing_depth";
1468 const char* testName = name.c_str();
1469 float expectedValue = depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
1471 const TestConfig testConfig =
1479 imageData.renderArea,
1485 imageData.clearValue,
1488 useSeparateDepthStencilLayouts,
1490 tcu::nothing<VkFormat>(),
1492 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1494 if (sampleCountNdx == 0 && imageDataNdx == 0)
1496 const auto compatibleFormat = compatManager.getAlternativeFormat(format);
1498 if (compatibleFormat != VK_FORMAT_UNDEFINED)
1500 std::string compatibilityTestName = "compatibility_" + name;
1501 TestConfig compatibilityTestConfig = testConfig;
1502 compatibilityTestConfig.compatibleFormat = tcu::just(compatibleFormat);
1504 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig));
1510 std::string name = baseName + "_testing_stencil";
1511 const char* testName = name.c_str();
1512 deUint8 expectedValue = stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
1514 const TestConfig testConfig =
1522 imageData.renderArea,
1528 imageData.clearValue,
1531 useSeparateDepthStencilLayouts,
1533 tcu::nothing<VkFormat>(),
1535 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1537 // All formats with stencil and depth aspects have incompatible formats and sizes in the depth
1538 // aspect, so their only alternative is the VK_FORMAT_S8_UINT format. Finally, that stencil-only
1539 // format has no compatible formats that can be used.
1540 if (sampleCountNdx == 0 && imageDataNdx == 0 && hasDepth)
1542 std::string compatibilityTestName = "compatibility_" + name;
1543 TestConfig compatibilityTestConfig = testConfig;
1544 compatibilityTestConfig.compatibleFormat = tcu::just(VK_FORMAT_S8_UINT);
1546 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig));
1552 sampleGroup->addChild(formatGroup.release());
1556 imageGroup->addChild(sampleGroup.release());
1559 group->addChild(imageGroup.release());
1563 // layered texture tests are done for all stencil modes and depth modes - not all combinations
1564 // Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer
1565 // which starts at a layer other than zero. Both parts are tested together by rendering to layers
1566 // 4-6 and resolving to layers 1-3.
1567 ImageTestData layeredTextureTestData =
1569 "image_2d_16_64_6", 16, 64, 6, {{ 10, 10}, {6, 54}}, {1.0f, 0x0}
1572 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));
1574 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1576 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1577 const std::string sampleName ("samples_" + de::toString(sampleCount));
1579 // create test group for sample count
1580 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1582 // iterate over depth/stencil formats
1583 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1585 const FormatData& formatData = formats[formatNdx];
1586 VkFormat format = formatData.format;
1587 const char* formatName = formatData.name;
1588 const bool hasDepth = formatData.hasDepth;
1589 const bool hasStencil = formatData.hasStencil;
1590 VkImageAspectFlags aspectFlags = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1591 (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1592 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 2 : 1;
1594 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1596 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
1597 const std::string groupName = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1599 // create test group for format
1600 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1602 for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
1604 for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1606 ResolveModeData& mode = resolveModes[resolveModeNdx];
1608 const bool unusedResolve = (unusedIdx > 0);
1609 const std::string unusedSuffix = (unusedResolve ? "_unused_resolve" : "");
1613 std::string name = "depth_" + mode.name + unusedSuffix;
1614 const char* testName = name.c_str();
1615 float expectedValue = depthExpectedValue[resolveModeNdx][sampleCountNdx];
1616 const TestConfig testConfig =
1619 layeredTextureTestData.width,
1620 layeredTextureTestData.height,
1621 layeredTextureTestData.imageLayers,
1624 layeredTextureTestData.renderArea,
1628 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1630 layeredTextureTestData.clearValue,
1633 useSeparateDepthStencilLayouts,
1635 tcu::nothing<VkFormat>(),
1637 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1640 // there is no average resolve mode for stencil - go to next iteration
1641 if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1646 std::string name = "stencil_" + mode.name + unusedSuffix;
1647 const char* testName = name.c_str();
1648 deUint8 expectedValue = stencilExpectedValue[resolveModeNdx][sampleCountNdx];
1649 const TestConfig testConfig =
1652 layeredTextureTestData.width,
1653 layeredTextureTestData.height,
1654 layeredTextureTestData.imageLayers,
1657 layeredTextureTestData.renderArea,
1660 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1663 layeredTextureTestData.clearValue,
1666 useSeparateDepthStencilLayouts,
1668 tcu::nothing<VkFormat>(),
1670 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1674 sampleGroup->addChild(formatGroup.release());
1677 imageGroup->addChild(sampleGroup.release());
1680 group->addChild(imageGroup.release());
1686 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
1688 return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);