1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 The Khronos Group Inc.
6 *
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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 *//*!
20 * \file
21 * \brief VK_KHR_depth_stencil_resolve tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassDepthStencilResolveTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29
30 #include "vkDefs.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"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkObjUtil.hpp"
42
43 #include "tcuImageCompare.hpp"
44 #include "tcuFormatUtil.hpp"
45 #include "tcuResultCollector.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuTextureUtil.hpp"
48
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
51 #include "deMath.h"
52
53 #include <limits>
54 #include <map>
55
56 using namespace vk;
57
58 using tcu::Vec4;
59 using tcu::TestLog;
60
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;
66
67 namespace vkt
68 {
69 namespace
70 {
71
72 using namespace renderpass;
73
74 template<typename T>
safeSharedPtr(T * ptr)75 de::SharedPtr<T> safeSharedPtr (T* ptr)
76 {
77 try
78 {
79 return de::SharedPtr<T>(ptr);
80 }
81 catch (...)
82 {
83 delete ptr;
84 throw;
85 }
86 }
87
88 enum VerifyBuffer
89 {
90 VB_DEPTH = 0,
91 VB_STENCIL
92 };
93
94 struct TestConfig
95 {
96 VkFormat format;
97 deUint32 width;
98 deUint32 height;
99 deUint32 imageLayers;
100 deUint32 viewLayers;
101 deUint32 resolveBaseLayer;
102 VkRect2D renderArea;
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;
112 bool unusedResolve;
113 tcu::Maybe<VkFormat> compatibleFormat;
114 };
115
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.
119 //
120 // See:
121 // * VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03181
122 // * VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03182
123 class DepthCompatibilityManager
124 {
125 public:
DepthCompatibilityManager()126 DepthCompatibilityManager ()
127 : m_compatibleFormats()
128 {
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;
132 }
133
getAlternativeFormat(VkFormat format) const134 VkFormat getAlternativeFormat (VkFormat format) const
135 {
136 const auto itr = m_compatibleFormats.find(format);
137 if (itr != end(m_compatibleFormats))
138 return itr->second;
139 return VK_FORMAT_UNDEFINED;
140 }
141
142 private:
143 std::map<VkFormat, VkFormat> m_compatibleFormats;
144 };
145
get16bitDepthComponent(deUint8 * pixelPtr)146 float get16bitDepthComponent(deUint8* pixelPtr)
147 {
148 deUint16* value = reinterpret_cast<deUint16*>(pixelPtr);
149 return static_cast<float>(*value) / 65535.0f;
150 }
151
get24bitDepthComponent(deUint8 * pixelPtr)152 float get24bitDepthComponent(deUint8* pixelPtr)
153 {
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;
159 }
160
get32bitDepthComponent(deUint8 * pixelPtr)161 float get32bitDepthComponent(deUint8* pixelPtr)
162 {
163 return *(reinterpret_cast<float*>(pixelPtr));
164 }
165
166 class DepthStencilResolveTest : public TestInstance
167 {
168 public:
169 DepthStencilResolveTest (Context& context, TestConfig config);
170 virtual ~DepthStencilResolveTest (void);
171
172 virtual tcu::TestStatus iterate (void);
173
174 protected:
175 bool isFeaturesSupported (void);
176 bool isSupportedFormat (Context& context, VkFormat format) const;
177 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) const;
178
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);
184
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);
190
191 void submit (void);
192 bool verifyDepth (void);
193 bool verifyStencil (void);
194
195 protected:
196 const TestConfig m_config;
197 const bool m_featureSupported;
198
199 const InstanceInterface& m_vki;
200 const DeviceInterface& m_vkd;
201 VkDevice m_device;
202 VkPhysicalDevice m_physicalDevice;
203
204 const Unique<VkCommandPool> m_commandPool;
205
206 VkImageSp m_multisampleImage;
207 AllocationSp m_multisampleImageMemory;
208 VkImageViewSp m_multisampleImageView;
209 VkImageSp m_singlesampleImage;
210 AllocationSp m_singlesampleImageMemory;
211 VkImageViewSp m_singlesampleImageView;
212 VkBufferSp m_buffer;
213 AllocationSp m_bufferMemory;
214
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;
220 };
221
DepthStencilResolveTest(Context & context,TestConfig config)222 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
223 : TestInstance (context)
224 , m_config (config)
225 , m_featureSupported (isFeaturesSupported())
226 , m_vki (context.getInstanceInterface())
227 , m_vkd (context.getDeviceInterface())
228 , m_device (context.getDevice())
229 , m_physicalDevice (context.getPhysicalDevice())
230
231 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
232
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))
236
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))
240
241 , m_buffer (createBuffer())
242 , m_bufferMemory (createBufferMemory())
243
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))
249 {
250 }
251
~DepthStencilResolveTest(void)252 DepthStencilResolveTest::~DepthStencilResolveTest (void)
253 {
254 }
255
isFeaturesSupported()256 bool DepthStencilResolveTest::isFeaturesSupported()
257 {
258 m_context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
259 if (m_config.imageLayers > 1)
260 m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
261
262 if (m_config.separateDepthStencilLayouts)
263 m_context.requireDeviceFunctionality("VK_KHR_separate_depth_stencil_layouts");
264
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;
269
270 VkPhysicalDeviceProperties2 deviceProperties;
271 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
272 deviceProperties.pNext = &dsResolveProperties;
273
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);
278
279 // check if both modes are supported
280 VkResolveModeFlagBits depthResolveMode = m_config.depthResolveMode;
281 VkResolveModeFlagBits stencilResolveMode = m_config.stencilResolveMode;
282
283 if ((depthResolveMode != VK_RESOLVE_MODE_NONE) &&
284 !(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
285 TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
286
287 if ((stencilResolveMode != VK_RESOLVE_MODE_NONE) &&
288 !(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
289 TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");
290
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)
294 {
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");
300 }
301 else if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
302 {
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");
305 }
306
307 // Check alternative format support if needed.
308 if (m_config.compatibleFormat)
309 {
310 if (! isSupportedFormat(m_context, m_config.compatibleFormat.get()))
311 TCU_THROW(NotSupportedError, "Alternative image format for compatibility test not supported");
312 }
313
314 return true;
315 }
316
sampleCountBitFromSampleCount(deUint32 count) const317 VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const
318 {
319 switch (count)
320 {
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;
328
329 default:
330 DE_FATAL("Invalid sample count");
331 return (VkSampleCountFlagBits)0x0;
332 }
333 }
334
createImage(deUint32 sampleCount,VkImageUsageFlags additionalUsage)335 VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage)
336 {
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;
341
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)
345 {
346 TCU_THROW(NotSupportedError, "Format not supported");
347 }
348 if (imageFormatProperties.sampleCounts < sampleCount)
349 {
350 TCU_THROW(NotSupportedError, "Sample count not supported");
351 }
352 if (imageFormatProperties.maxArrayLayers < m_config.imageLayers)
353 {
354 TCU_THROW(NotSupportedError, "Layers count not supported");
355 }
356
357 const VkExtent3D imageExtent =
358 {
359 m_config.width,
360 m_config.height,
361 1u
362 };
363
364 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order)))
365 TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment");
366
367 if (imageFormatProperties.maxExtent.width < imageExtent.width
368 || imageFormatProperties.maxExtent.height < imageExtent.height
369 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
370 || imageFormatProperties.maxArrayLayers < m_config.imageLayers)
371 {
372 TCU_THROW(NotSupportedError, "Image type not supported");
373 }
374
375 const VkImageCreateInfo pCreateInfo =
376 {
377 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
378 DE_NULL,
379 0u,
380 VK_IMAGE_TYPE_2D,
381 m_config.format,
382 imageExtent,
383 1u,
384 m_config.imageLayers,
385 sampleCountBit,
386 imageTiling,
387 usage,
388 VK_SHARING_MODE_EXCLUSIVE,
389 0u,
390 DE_NULL,
391 VK_IMAGE_LAYOUT_UNDEFINED
392 };
393
394 return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo)));
395 }
396
createImageMemory(VkImageSp image)397 AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image)
398 {
399 Allocator& allocator = m_context.getDefaultAllocator();
400
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());
404 }
405
createImageView(VkImageSp image,deUint32 baseArrayLayer)406 VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer)
407 {
408 const VkImageSubresourceRange range =
409 {
410 m_config.aspectFlag,
411 0u,
412 1u,
413 baseArrayLayer,
414 m_config.viewLayers
415 };
416
417 const VkImageViewCreateInfo pCreateInfo =
418 {
419 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
420 DE_NULL,
421 0u,
422 **image,
423 (m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
424 m_config.format,
425 makeComponentMappingRGBA(),
426 range,
427 };
428 return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo)));
429 }
430
createRenderPass(VkFormat vkformat)431 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (VkFormat vkformat)
432 {
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)
435 {
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 =
439 {
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)),
442 0u,
443 VK_REMAINING_MIP_LEVELS,
444 0u,
445 VK_REMAINING_ARRAY_LAYERS,
446 };
447 const vk::VkImageMemoryBarrier preBarrier =
448 {
449 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
450 nullptr,
451
452 // src and dst access masks.
453 0,
454 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
455
456 // old and new layouts.
457 vk::VK_IMAGE_LAYOUT_UNDEFINED,
458 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
459
460 VK_QUEUE_FAMILY_IGNORED,
461 VK_QUEUE_FAMILY_IGNORED,
462
463 **m_singlesampleImage,
464 imageRange,
465 };
466 const vk::VkImageMemoryBarrier postBarrier =
467 {
468 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
469 nullptr,
470
471 // src and dst access masks.
472 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
473 0,
474
475 // old and new layouts.
476 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
477 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
478
479 VK_QUEUE_FAMILY_IGNORED,
480 VK_QUEUE_FAMILY_IGNORED,
481
482 **m_singlesampleImage,
483 imageRange,
484 };
485
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());
491
492 vk::submitCommandsAndWait(m_vkd, m_device, m_context.getUniversalQueue(), commandBuffer.get());
493 }
494
495 const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));
496
497 VkImageLayout layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
498 VkAttachmentReferenceStencilLayoutKHR stencilLayout =
499 {
500 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR,
501 DE_NULL,
502 VK_IMAGE_LAYOUT_UNDEFINED,
503 };
504 void * attachmentRefStencil = DE_NULL;
505 VkImageLayout finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
506 VkAttachmentDescriptionStencilLayoutKHR stencilFinalLayout =
507 {
508 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR,
509 DE_NULL,
510 VK_IMAGE_LAYOUT_UNDEFINED,
511 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
512 };
513 void * attachmentDescriptionStencil = DE_NULL;
514
515 if (m_config.separateDepthStencilLayouts)
516 {
517 if (m_config.verifyBuffer == VB_DEPTH)
518 {
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.
523 }
524 else
525 {
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;
530 }
531 attachmentRefStencil = &stencilLayout;
532 attachmentDescriptionStencil = &stencilFinalLayout;
533 }
534
535 const AttachmentDescription2 multisampleAttachment // VkAttachmentDescription2
536 (
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;
548 );
549 const AttachmentReference2 multisampleAttachmentRef // VkAttachmentReference2
550 (
551 // VkStructureType sType;
552 attachmentRefStencil, // const void* pNext;
553 0u, // deUint32 attachment;
554 layout, // VkImageLayout layout;
555 m_config.aspectFlag // VkImageAspectFlags aspectMask;
556 );
557
558 const vk::VkImageLayout singleSampleInitialLayout = (m_config.unusedResolve ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_UNDEFINED);
559
560
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));
565
566 const AttachmentDescription2 singlesampleAttachment // VkAttachmentDescription2
567 (
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;
579 );
580 AttachmentReference2 singlesampleAttachmentRef // VkAttachmentReference2
581 (
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;
587 );
588
589 std::vector<AttachmentDescription2> attachments;
590 attachments.push_back(multisampleAttachment);
591 attachments.push_back(singlesampleAttachment);
592
593 VkSubpassDescriptionDepthStencilResolve dsResolveDescription =
594 {
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;
600 };
601
602 const SubpassDescription2 subpass // VkSubpassDescription2
603 (
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;
617 );
618
619 const RenderPassCreateInfo2 renderPassCreator // VkRenderPassCreateInfo2
620 (
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;
632 );
633
634 return renderPassCreator.createRenderPass(m_vkd, m_device);
635 }
636
637 // Checks format support.
638 // Note: we need the context because this is called from the constructor only after m_config has been set.
isSupportedFormat(Context & context,VkFormat format) const639 bool DepthStencilResolveTest::isSupportedFormat (Context& context, VkFormat format) const
640 {
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;
645
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);
649
650 return (formatCheck == VK_SUCCESS);
651 }
652
createRenderPassCompatible(void)653 Move<VkRenderPass> DepthStencilResolveTest::createRenderPassCompatible (void)
654 {
655 // Early exit if we are not testing compatibility.
656 if (! m_config.compatibleFormat)
657 return {};
658
659 return createRenderPass(m_config.compatibleFormat.get());
660 }
661
createFramebuffer(VkRenderPass renderPass,VkImageViewSp multisampleImageView,VkImageViewSp singlesampleImageView)662 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
663 {
664 std::vector<VkImageView> attachments;
665 attachments.push_back(**multisampleImageView);
666 attachments.push_back(**singlesampleImageView);
667
668 const VkFramebufferCreateInfo createInfo =
669 {
670 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
671 DE_NULL,
672 0u,
673
674 renderPass,
675 (deUint32)attachments.size(),
676 &attachments[0],
677
678 m_config.width,
679 m_config.height,
680 m_config.viewLayers
681 };
682
683 return vk::createFramebuffer(m_vkd, m_device, &createInfo);
684 }
685
createRenderPipelineLayout(void)686 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
687 {
688 VkPushConstantRange pushConstant =
689 {
690 VK_SHADER_STAGE_FRAGMENT_BIT,
691 0u,
692 4u
693 };
694
695 deUint32 pushConstantRangeCount = 0u;
696 VkPushConstantRange* pPushConstantRanges = DE_NULL;
697 if (m_config.verifyBuffer == VB_STENCIL)
698 {
699 pushConstantRangeCount = 1u;
700 pPushConstantRanges = &pushConstant;
701 }
702
703 const VkPipelineLayoutCreateInfo createInfo =
704 {
705 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
706 DE_NULL,
707 (vk::VkPipelineLayoutCreateFlags)0,
708
709 0u,
710 DE_NULL,
711
712 pushConstantRangeCount,
713 pPushConstantRanges
714 };
715
716 return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
717 }
718
createRenderPipeline(VkRenderPass renderPass,VkPipelineLayout renderPipelineLayout)719 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout)
720 {
721 const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
722 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
723
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));
727
728 const VkPipelineVertexInputStateCreateInfo vertexInputState =
729 {
730 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
731 DE_NULL,
732 (VkPipelineVertexInputStateCreateFlags)0u,
733
734 0u,
735 DE_NULL,
736
737 0u,
738 DE_NULL
739 };
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);
743
744 const VkPipelineMultisampleStateCreateInfo multisampleState =
745 {
746 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
747 DE_NULL,
748 (VkPipelineMultisampleStateCreateFlags)0u,
749
750 sampleCountBitFromSampleCount(m_config.sampleCount),
751 VK_FALSE,
752 0.0f,
753 DE_NULL,
754 VK_FALSE,
755 VK_FALSE,
756 };
757 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
758 {
759 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
760 DE_NULL,
761 (VkPipelineDepthStencilStateCreateFlags)0u,
762
763 VK_TRUE, // depthTestEnable
764 VK_TRUE,
765 VK_COMPARE_OP_ALWAYS,
766 VK_FALSE,
767 testingStencil, // stencilTestEnable
768 {
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
774 0xFFu, // writeMask
775 1 // reference
776 },
777 {
778 VK_STENCIL_OP_REPLACE,
779 VK_STENCIL_OP_REPLACE,
780 VK_STENCIL_OP_REPLACE,
781 VK_COMPARE_OP_ALWAYS,
782 0xFFu,
783 0xFFu,
784 1
785 },
786 0.0f,
787 1.0f
788 };
789
790 std::vector<VkDynamicState> dynamicState;
791 dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
792 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
793 {
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;
799 };
800
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
821 }
822
createBufferMemory(void)823 AllocationSp DepthStencilResolveTest::createBufferMemory (void)
824 {
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());
829 }
830
createBuffer(void)831 VkBufferSp DepthStencilResolveTest::createBuffer (void)
832 {
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 =
837 {
838 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
839 DE_NULL,
840 0u,
841
842 m_config.width * m_config.height * m_config.imageLayers * pixelSize,
843 bufferUsage,
844
845 VK_SHARING_MODE_EXCLUSIVE,
846 0u,
847 DE_NULL
848 };
849 return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
850 }
851
submit(void)852 void DepthStencilResolveTest::submit (void)
853 {
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);
859
860 beginCommandBuffer(vkd, *commandBuffer);
861
862 {
863 VkClearValue clearValues[2];
864 clearValues[0].depthStencil = m_config.clearValue;
865 clearValues[1].depthStencil = m_config.clearValue;
866
867 const VkRenderPassBeginInfo beginInfo =
868 {
869 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
870 DE_NULL,
871
872 (m_config.compatibleFormat ? *m_renderPassCompatible : *m_renderPass),
873 *m_framebuffer,
874
875 {
876 { 0u, 0u },
877 { m_config.width, m_config.height }
878 },
879
880 2u,
881 clearValues
882 };
883 RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
884 }
885
886 // Render
887 bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
888 if (testingDepth)
889 {
890 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
891 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
892 }
893 else
894 {
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++)
900 {
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);
906 }
907 }
908
909 RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
910
911 // Memory barriers between rendering and copying
912 {
913 const VkImageMemoryBarrier barrier =
914 {
915 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
916 DE_NULL,
917
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,
921
922 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
923 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
924
925 VK_QUEUE_FAMILY_IGNORED,
926 VK_QUEUE_FAMILY_IGNORED,
927
928 **m_singlesampleImage,
929 {
930 (m_config.separateDepthStencilLayouts) ? VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT) : m_config.aspectFlag,
931 0u,
932 1u,
933 0u,
934 m_config.viewLayers
935 }
936 };
937
938 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
939 }
940
941 // Copy image memory to buffers
942 const VkBufferImageCopy region =
943 {
944 0u,
945 0u,
946 0u,
947 {
948 VkImageAspectFlags(testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT),
949 0u,
950 0u,
951 m_config.viewLayers,
952 },
953 { 0u, 0u, 0u },
954 { m_config.width, m_config.height, 1u }
955 };
956
957 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, ®ion);
958
959 // Memory barriers between copies and host access
960 {
961 const VkBufferMemoryBarrier barrier =
962 {
963 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
964 DE_NULL,
965
966 VK_ACCESS_TRANSFER_WRITE_BIT,
967 VK_ACCESS_HOST_READ_BIT,
968
969 VK_QUEUE_FAMILY_IGNORED,
970 VK_QUEUE_FAMILY_IGNORED,
971
972 **m_buffer,
973 0u,
974 VK_WHOLE_SIZE
975 };
976
977 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
978 }
979
980 endCommandBuffer(vkd, *commandBuffer);
981
982 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
983 }
984
verifyDepth(void)985 bool DepthStencilResolveTest::verifyDepth (void)
986 {
987 // Invalidate allocation before attempting to read buffer memory.
988 invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
989
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());
993
994 const DeviceInterface& vkd (m_context.getDeviceInterface());
995 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
996
997 float expectedValue = m_config.depthExpectedValue;
998 if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE || m_config.unusedResolve)
999 expectedValue = m_config.clearValue.depth;
1000
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
1004
1005 typedef float (*DepthComponentGetterFn)(deUint8*);
1006 VkFormat format = m_config.format;
1007 DepthComponentGetterFn getDepthComponent = &get16bitDepthComponent;
1008 deUint32 pixelStep = 2;
1009 float epsilon = 0.002f;
1010
1011 if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
1012 (format == VK_FORMAT_D24_UNORM_S8_UINT))
1013 {
1014 getDepthComponent = &get24bitDepthComponent;
1015 pixelStep = 4;
1016 }
1017 else if ((format == VK_FORMAT_D32_SFLOAT) ||
1018 (format == VK_FORMAT_D32_SFLOAT_S8_UINT))
1019 {
1020 getDepthComponent = &get32bitDepthComponent;
1021 pixelStep = 4;
1022 }
1023
1024 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1025 {
1026 float depth = (*getDepthComponent)(pixelPtr);
1027 pixelPtr += pixelStep;
1028
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))
1039 {
1040 // verify that outside of render area there are clear values
1041 float error = deFloatAbs(depth - m_config.clearValue.depth);
1042 if (error > epsilon)
1043 {
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;
1048 return false;
1049 }
1050
1051 // value is correct, go to next one
1052 continue;
1053 }
1054
1055 float error = deFloatAbs(depth - expectedValue);
1056 if (error > epsilon)
1057 {
1058 m_context.getTestContext().getLog() << TestLog::Message
1059 << "At (" << x << ", " << y << ", layer: " << layerIndex
1060 << ") depth value is: " << depth << " expected: "
1061 << expectedValue << TestLog::EndMessage;
1062 return false;
1063 }
1064 }
1065 m_context.getTestContext().getLog() << TestLog::Message
1066 << "Depth value is " << expectedValue
1067 << TestLog::EndMessage;
1068
1069 return true;
1070 }
1071
verifyStencil(void)1072 bool DepthStencilResolveTest::verifyStencil (void)
1073 {
1074 // Invalidate allocation before attempting to read buffer memory.
1075 invalidateAlloc(m_context.getDeviceInterface(), m_context.getDevice(), *m_bufferMemory);
1076
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());
1080
1081 const DeviceInterface& vkd (m_context.getDeviceInterface());
1082 invalidateMappedMemoryRange(vkd, m_context.getDevice(), m_bufferMemory->getMemory(), m_bufferMemory->getOffset(), VK_WHOLE_SIZE);
1083
1084 // when stencil is tested we are discarding invocations and
1085 // because of that depth and stencil need to be tested separately
1086
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);
1090
1091 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
1092 {
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))
1103 {
1104 if (stencil != m_config.clearValue.stencil)
1105 {
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;
1110 return false;
1111 }
1112
1113 // value is correct, go to next one
1114 continue;
1115 }
1116
1117 if (stencil != expectedValue)
1118 {
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;
1124 return false;
1125 }
1126 }
1127 m_context.getTestContext().getLog() << TestLog::Message
1128 << "Stencil value is "
1129 << static_cast<deUint32>(expectedValue)
1130 << TestLog::EndMessage;
1131
1132 return true;
1133 }
1134
iterate(void)1135 tcu::TestStatus DepthStencilResolveTest::iterate (void)
1136 {
1137 submit();
1138
1139 bool result = false;
1140 if (m_config.verifyBuffer == VB_DEPTH)
1141 result = verifyDepth();
1142 else
1143 result = verifyStencil();
1144
1145 if (result)
1146 return tcu::TestStatus::pass("Pass");
1147 return tcu::TestStatus::fail("Fail");
1148 }
1149
1150 struct Programs
1151 {
initvkt::__anonf560080b0111::Programs1152 void init (vk::SourceCollections& dst, TestConfig config) const
1153 {
1154 // geometry shader is only needed in multi-layer framebuffer resolve tests
1155 if (config.imageLayers > 1)
1156 {
1157 const deUint32 layerCount = 3;
1158
1159 std::ostringstream src;
1160 src << "#version 450\n"
1161 << "highp float;\n"
1162 << "\n"
1163 << "layout(triangles) in;\n"
1164 << "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
1165 << "\n"
1166 << "in gl_PerVertex {\n"
1167 << " vec4 gl_Position;\n"
1168 << "} gl_in[];\n"
1169 << "\n"
1170 << "out gl_PerVertex {\n"
1171 << " vec4 gl_Position;\n"
1172 << "};\n"
1173 << "\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"
1180 << " };\n"
1181 << " EndPrimitive();\n"
1182 << " };\n"
1183 << "}\n";
1184
1185 dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
1186 }
1187
1188 dst.glslSources.add("quad-vert") << glu::VertexSource(
1189 "#version 450\n"
1190 "out gl_PerVertex {\n"
1191 "\tvec4 gl_Position;\n"
1192 "};\n"
1193 "highp float;\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"
1197 "}\n");
1198
1199 if (config.verifyBuffer == VB_DEPTH)
1200 {
1201 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1202 "#version 450\n"
1203 "precision highp float;\n"
1204 "precision highp int;\n"
1205 "void main (void)\n"
1206 "{\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]
1214 "}\n");
1215 }
1216 else
1217 {
1218 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1219 "#version 450\n"
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"
1226 "{\n"
1227 " if(gl_SampleID != pushConstants.sampleID)\n"
1228 " discard;\n"
1229 " gl_FragDepth = 0.5;\n"
1230 "}\n");
1231 }
1232 }
1233 };
1234
1235 class PropertiesTestCase : public vkt::TestCase
1236 {
1237 public:
PropertiesTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description)1238 PropertiesTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description)
1239 : vkt::TestCase(testCtx, name, description)
1240 {}
~PropertiesTestCase(void)1241 virtual ~PropertiesTestCase (void) {}
1242
1243 virtual TestInstance* createInstance (Context& context) const;
1244 virtual void checkSupport (Context& context) const;
1245 };
1246
1247 class PropertiesTestInstance : public vkt::TestInstance
1248 {
1249 public:
PropertiesTestInstance(Context & context)1250 PropertiesTestInstance (Context& context)
1251 : vkt::TestInstance(context)
1252 {}
~PropertiesTestInstance(void)1253 virtual ~PropertiesTestInstance (void) {}
1254
1255 virtual tcu::TestStatus iterate (void);
1256
1257 };
1258
createInstance(Context & context) const1259 TestInstance* PropertiesTestCase::createInstance (Context& context) const
1260 {
1261 return new PropertiesTestInstance(context);
1262 }
1263
checkSupport(Context & context) const1264 void PropertiesTestCase::checkSupport (Context& context) const
1265 {
1266 context.requireDeviceFunctionality("VK_KHR_depth_stencil_resolve");
1267 }
1268
iterate(void)1269 tcu::TestStatus PropertiesTestInstance::iterate (void)
1270 {
1271 vk::VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsrProperties;
1272 dsrProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
1273 dsrProperties.pNext = nullptr;
1274
1275 vk::VkPhysicalDeviceProperties2 properties2;
1276 properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
1277 properties2.pNext = &dsrProperties;
1278
1279 m_context.getInstanceInterface().getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &properties2);
1280
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");
1283
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");
1286
1287 if ((dsrProperties.supportedStencilResolveModes & vk::VK_RESOLVE_MODE_AVERAGE_BIT_KHR) != 0)
1288 TCU_FAIL("supportedStencilResolveModes includes forbidden VK_RESOLVE_MODE_AVERAGE_BIT_KHR");
1289
1290 if (dsrProperties.independentResolve == VK_TRUE && dsrProperties.independentResolveNone != VK_TRUE)
1291 TCU_FAIL("independentResolve supported but independentResolveNone not supported");
1292
1293 return tcu::TestStatus::pass("Pass");
1294 }
1295
1296
initTests(tcu::TestCaseGroup * group)1297 void initTests (tcu::TestCaseGroup* group)
1298 {
1299 typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
1300
1301 struct FormatData
1302 {
1303 VkFormat format;
1304 const char* name;
1305 bool hasDepth;
1306 bool hasStencil;
1307 };
1308 FormatData formats[] =
1309 {
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 },
1317 };
1318
1319 struct ResolveModeData
1320 {
1321 VkResolveModeFlagBits flag;
1322 std::string name;
1323 };
1324 ResolveModeData resolveModes[] =
1325 {
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" },
1331 };
1332
1333 struct ImageTestData
1334 {
1335 const char* groupName;
1336 deUint32 width;
1337 deUint32 height;
1338 deUint32 imageLayers;
1339 VkRect2D renderArea;
1340 VkClearDepthStencilValue clearValue;
1341 };
1342
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[] =
1350 {
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} },
1356 };
1357 const deUint32 sampleCounts[] =
1358 {
1359 2u, 4u, 8u, 16u, 32u, 64u
1360 };
1361 const float depthExpectedValue[][6] =
1362 {
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
1369 };
1370 const deUint8 stencilExpectedValue[][6] =
1371 {
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
1378 };
1379
1380 const DepthCompatibilityManager compatManager;
1381
1382 tcu::TestContext& testCtx(group->getTestContext());
1383
1384 // Misc tests.
1385 {
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());
1389 }
1390
1391 // iterate over image data
1392 for (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
1393 {
1394 ImageTestData imageData = imagesTestData[imageDataNdx];
1395
1396 // create test group for image data
1397 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));
1398
1399 // iterate over sampleCounts
1400 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1401 {
1402 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1403 const std::string sampleName ("samples_" + de::toString(sampleCount));
1404
1405 // create test group for sample count
1406 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1407
1408 // iterate over depth/stencil formats
1409 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1410 {
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;
1419
1420 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1421 {
1422 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
1423 const std::string groupName = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1424
1425 // create test group for format
1426 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1427
1428 // iterate over depth resolve modes
1429 for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
1430 {
1431 // iterate over stencil resolve modes
1432 for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
1433 {
1434 for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1435 {
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)
1439 continue;
1440
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))
1445 continue;
1446
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))
1451 continue;
1452
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))
1457 continue;
1458
1459 const bool unusedResolve = (unusedIdx > 0);
1460
1461 std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
1462 if (unusedResolve)
1463 baseName += "_unused_resolve";
1464
1465 if (hasDepth)
1466 {
1467 std::string name = baseName + "_testing_depth";
1468 const char* testName = name.c_str();
1469 float expectedValue = depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
1470
1471 const TestConfig testConfig =
1472 {
1473 format,
1474 imageData.width,
1475 imageData.height,
1476 1u,
1477 1u,
1478 0u,
1479 imageData.renderArea,
1480 aspectFlags,
1481 sampleCount,
1482 dResolve.flag,
1483 sResolve.flag,
1484 VB_DEPTH,
1485 imageData.clearValue,
1486 expectedValue,
1487 0u,
1488 useSeparateDepthStencilLayouts,
1489 unusedResolve,
1490 tcu::nothing<VkFormat>(),
1491 };
1492 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1493
1494 if (sampleCountNdx == 0 && imageDataNdx == 0)
1495 {
1496 const auto compatibleFormat = compatManager.getAlternativeFormat(format);
1497
1498 if (compatibleFormat != VK_FORMAT_UNDEFINED)
1499 {
1500 std::string compatibilityTestName = "compatibility_" + name;
1501 TestConfig compatibilityTestConfig = testConfig;
1502 compatibilityTestConfig.compatibleFormat = tcu::just(compatibleFormat);
1503
1504 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig));
1505 }
1506 }
1507 }
1508 if (hasStencil)
1509 {
1510 std::string name = baseName + "_testing_stencil";
1511 const char* testName = name.c_str();
1512 deUint8 expectedValue = stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
1513
1514 const TestConfig testConfig =
1515 {
1516 format,
1517 imageData.width,
1518 imageData.height,
1519 1u,
1520 1u,
1521 0u,
1522 imageData.renderArea,
1523 aspectFlags,
1524 sampleCount,
1525 dResolve.flag,
1526 sResolve.flag,
1527 VB_STENCIL,
1528 imageData.clearValue,
1529 0.0f,
1530 expectedValue,
1531 useSeparateDepthStencilLayouts,
1532 unusedResolve,
1533 tcu::nothing<VkFormat>(),
1534 };
1535 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1536
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)
1541 {
1542 std::string compatibilityTestName = "compatibility_" + name;
1543 TestConfig compatibilityTestConfig = testConfig;
1544 compatibilityTestConfig.compatibleFormat = tcu::just(VK_FORMAT_S8_UINT);
1545
1546 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, compatibilityTestName.c_str(), compatibilityTestName.c_str(), compatibilityTestConfig));
1547 }
1548 }
1549 }
1550 }
1551 }
1552 sampleGroup->addChild(formatGroup.release());
1553 }
1554 }
1555
1556 imageGroup->addChild(sampleGroup.release());
1557 }
1558
1559 group->addChild(imageGroup.release());
1560 }
1561
1562 {
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 =
1568 {
1569 "image_2d_16_64_6", 16, 64, 6, {{ 10, 10}, {6, 54}}, {1.0f, 0x0}
1570 };
1571
1572 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));
1573
1574 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1575 {
1576 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1577 const std::string sampleName ("samples_" + de::toString(sampleCount));
1578
1579 // create test group for sample count
1580 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1581
1582 // iterate over depth/stencil formats
1583 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1584 {
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;
1593
1594 for (int separateDepthStencilLayouts = 0; separateDepthStencilLayouts < separateLayoutsLoopCount; ++separateDepthStencilLayouts)
1595 {
1596 const bool useSeparateDepthStencilLayouts = bool(separateDepthStencilLayouts);
1597 const std::string groupName = std::string(formatName) + ((useSeparateDepthStencilLayouts) ? "_separate_layouts" : "");
1598
1599 // create test group for format
1600 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupName.c_str()));
1601
1602 for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
1603 {
1604 for (int unusedIdx = 0; unusedIdx < 2; ++unusedIdx)
1605 {
1606 ResolveModeData& mode = resolveModes[resolveModeNdx];
1607
1608 const bool unusedResolve = (unusedIdx > 0);
1609 const std::string unusedSuffix = (unusedResolve ? "_unused_resolve" : "");
1610
1611 if (hasDepth)
1612 {
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 =
1617 {
1618 format,
1619 layeredTextureTestData.width,
1620 layeredTextureTestData.height,
1621 layeredTextureTestData.imageLayers,
1622 3u,
1623 0u,
1624 layeredTextureTestData.renderArea,
1625 aspectFlags,
1626 sampleCount,
1627 mode.flag,
1628 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1629 VB_DEPTH,
1630 layeredTextureTestData.clearValue,
1631 expectedValue,
1632 0u,
1633 useSeparateDepthStencilLayouts,
1634 unusedResolve,
1635 tcu::nothing<VkFormat>(),
1636 };
1637 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1638 }
1639
1640 // there is no average resolve mode for stencil - go to next iteration
1641 if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT)
1642 continue;
1643
1644 if (hasStencil)
1645 {
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 =
1650 {
1651 format,
1652 layeredTextureTestData.width,
1653 layeredTextureTestData.height,
1654 layeredTextureTestData.imageLayers,
1655 3u,
1656 0u,
1657 layeredTextureTestData.renderArea,
1658 aspectFlags,
1659 sampleCount,
1660 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT,
1661 mode.flag,
1662 VB_STENCIL,
1663 layeredTextureTestData.clearValue,
1664 0.0f,
1665 expectedValue,
1666 useSeparateDepthStencilLayouts,
1667 unusedResolve,
1668 tcu::nothing<VkFormat>(),
1669 };
1670 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1671 }
1672 }
1673 }
1674 sampleGroup->addChild(formatGroup.release());
1675 }
1676 }
1677 imageGroup->addChild(sampleGroup.release());
1678 }
1679
1680 group->addChild(imageGroup.release());
1681 }
1682 }
1683
1684 } // anonymous
1685
createRenderPass2DepthStencilResolveTests(tcu::TestContext & testCtx)1686 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
1687 {
1688 return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);
1689 }
1690
1691 } // vkt
1692