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 #include <limits>
53
54 using namespace vk;
55
56 using tcu::Vec4;
57 using tcu::TestLog;
58
59 typedef de::SharedPtr<vk::Unique<VkImage> > VkImageSp;
60 typedef de::SharedPtr<vk::Unique<VkImageView> > VkImageViewSp;
61 typedef de::SharedPtr<vk::Unique<VkBuffer> > VkBufferSp;
62 typedef de::SharedPtr<vk::Unique<VkPipeline> > VkPipelineSp;
63 typedef de::SharedPtr<Allocation> AllocationSp;
64
65 namespace vkt
66 {
67 namespace
68 {
69
70 using namespace renderpass;
71
72 template<typename T>
safeSharedPtr(T * ptr)73 de::SharedPtr<T> safeSharedPtr (T* ptr)
74 {
75 try
76 {
77 return de::SharedPtr<T>(ptr);
78 }
79 catch (...)
80 {
81 delete ptr;
82 throw;
83 }
84 }
85
86 enum VerifyBuffer
87 {
88 VB_DEPTH = 0,
89 VB_STENCIL
90 };
91
92 struct TestConfig
93 {
94 VkFormat format;
95 deUint32 width;
96 deUint32 height;
97 deUint32 imageLayers;
98 deUint32 viewLayers;
99 deUint32 resolveBaseLayer;
100 VkRect2D renderArea;
101 VkImageAspectFlags aspectFlag;
102 deUint32 sampleCount;
103 VkResolveModeFlagBitsKHR depthResolveMode;
104 VkResolveModeFlagBitsKHR stencilResolveMode;
105 VerifyBuffer verifyBuffer;
106 VkClearDepthStencilValue clearValue;
107 float depthExpectedValue;
108 deUint8 stencilExpectedValue;
109 };
110
get16bitDepthComponent(deUint8 * pixelPtr)111 float get16bitDepthComponent(deUint8* pixelPtr)
112 {
113 deUint16* value = reinterpret_cast<deUint16*>(pixelPtr);
114 return static_cast<float>(*value) / 65535.0f;
115 }
116
get24bitDepthComponent(deUint8 * pixelPtr)117 float get24bitDepthComponent(deUint8* pixelPtr)
118 {
119 const bool littleEndian = (DE_ENDIANNESS == DE_LITTLE_ENDIAN);
120 deUint32 value = (((deUint32)pixelPtr[0]) << (!littleEndian * 16u)) |
121 (((deUint32)pixelPtr[1]) << 8u) |
122 (((deUint32)pixelPtr[2]) << ( littleEndian * 16u));
123 return static_cast<float>(value) / 16777215.0f;
124 }
125
get32bitDepthComponent(deUint8 * pixelPtr)126 float get32bitDepthComponent(deUint8* pixelPtr)
127 {
128 return *(reinterpret_cast<float*>(pixelPtr));
129 }
130
131 class DepthStencilResolveTest : public TestInstance
132 {
133 public:
134 DepthStencilResolveTest (Context& context, TestConfig config);
135 virtual ~DepthStencilResolveTest (void);
136
137 virtual tcu::TestStatus iterate (void);
138
139 protected:
140 bool isFeaturesSupported (void);
141 VkSampleCountFlagBits sampleCountBitFromSampleCount (deUint32 count) const;
142
143 VkImageSp createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage = 0u);
144 AllocationSp createImageMemory (VkImageSp image);
145 VkImageViewSp createImageView (VkImageSp image, deUint32 baseArrayLayer);
146 AllocationSp createBufferMemory (void);
147 VkBufferSp createBuffer (void);
148
149 Move<VkRenderPass> createRenderPass (void);
150 Move<VkFramebuffer> createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView);
151 Move<VkPipelineLayout> createRenderPipelineLayout (void);
152 Move<VkPipeline> createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout);
153
154 void submit (void);
155 bool verifyDepth (void);
156 bool verifyStencil (void);
157
158 protected:
159 const TestConfig m_config;
160 const bool m_featureSupported;
161
162 const InstanceInterface& m_vki;
163 const DeviceInterface& m_vkd;
164 VkDevice m_device;
165 VkPhysicalDevice m_physicalDevice;
166
167 VkImageSp m_multisampleImage;
168 AllocationSp m_multisampleImageMemory;
169 VkImageViewSp m_multisampleImageView;
170 VkImageSp m_singlesampleImage;
171 AllocationSp m_singlesampleImageMemory;
172 VkImageViewSp m_singlesampleImageView;
173 VkBufferSp m_buffer;
174 AllocationSp m_bufferMemory;
175
176 Unique<VkRenderPass> m_renderPass;
177 Unique<VkFramebuffer> m_framebuffer;
178 Unique<VkPipelineLayout> m_renderPipelineLayout;
179 Unique<VkPipeline> m_renderPipeline;
180
181 const Unique<VkCommandPool> m_commandPool;
182 };
183
DepthStencilResolveTest(Context & context,TestConfig config)184 DepthStencilResolveTest::DepthStencilResolveTest (Context& context, TestConfig config)
185 : TestInstance (context)
186 , m_config (config)
187 , m_featureSupported (isFeaturesSupported())
188 , m_vki (context.getInstanceInterface())
189 , m_vkd (context.getDeviceInterface())
190 , m_device (context.getDevice())
191 , m_physicalDevice (context.getPhysicalDevice())
192
193 , m_multisampleImage (createImage(m_config.sampleCount))
194 , m_multisampleImageMemory (createImageMemory(m_multisampleImage))
195 , m_multisampleImageView (createImageView(m_multisampleImage, 0u))
196
197 , m_singlesampleImage (createImage(1, VK_IMAGE_USAGE_TRANSFER_SRC_BIT))
198 , m_singlesampleImageMemory (createImageMemory(m_singlesampleImage))
199 , m_singlesampleImageView (createImageView(m_singlesampleImage, m_config.resolveBaseLayer))
200
201 , m_buffer (createBuffer())
202 , m_bufferMemory (createBufferMemory())
203
204 , m_renderPass (createRenderPass())
205 , m_framebuffer (createFramebuffer(*m_renderPass, m_multisampleImageView, m_singlesampleImageView))
206 , m_renderPipelineLayout (createRenderPipelineLayout())
207 , m_renderPipeline (createRenderPipeline(*m_renderPass, *m_renderPipelineLayout))
208
209
210 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
211 {
212 }
213
~DepthStencilResolveTest(void)214 DepthStencilResolveTest::~DepthStencilResolveTest (void)
215 {
216 }
217
isFeaturesSupported()218 bool DepthStencilResolveTest::isFeaturesSupported()
219 {
220 m_context.requireDeviceExtension("VK_KHR_depth_stencil_resolve");
221 if (m_config.imageLayers > 1)
222 m_context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
223
224 VkPhysicalDeviceDepthStencilResolvePropertiesKHR dsResolveProperties;
225 deMemset(&dsResolveProperties, 0, sizeof(VkPhysicalDeviceDepthStencilResolvePropertiesKHR));
226 dsResolveProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR;
227 dsResolveProperties.pNext = DE_NULL;
228
229 VkPhysicalDeviceProperties2 deviceProperties;
230 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
231 deviceProperties.pNext = &dsResolveProperties;
232
233 // perform query to get supported float control properties
234 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
235 const vk::InstanceInterface& instanceInterface = m_context.getInstanceInterface();
236 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
237
238 // check if both modes are supported
239 VkResolveModeFlagBitsKHR depthResolveMode = m_config.depthResolveMode;
240 VkResolveModeFlagBitsKHR stencilResolveMode = m_config.stencilResolveMode;
241 if ((depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
242 !(depthResolveMode & dsResolveProperties.supportedDepthResolveModes))
243 TCU_THROW(NotSupportedError, "Depth resolve mode not supported");
244 if ((stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
245 !(stencilResolveMode & dsResolveProperties.supportedStencilResolveModes))
246 TCU_THROW(NotSupportedError, "Stencil resolve mode not supported");
247
248 // check if the implementation supports setting the depth and stencil resolve
249 // modes to different values when one of those modes is VK_RESOLVE_MODE_NONE_KHR
250 if (dsResolveProperties.independentResolveNone)
251 {
252 if ((!dsResolveProperties.independentResolve) &&
253 (depthResolveMode != stencilResolveMode) &&
254 (depthResolveMode != VK_RESOLVE_MODE_NONE_KHR) &&
255 (stencilResolveMode != VK_RESOLVE_MODE_NONE_KHR))
256 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
257 }
258 else if (depthResolveMode != stencilResolveMode)
259 {
260 // when independentResolveNone is VK_FALSE then both modes must be the same
261 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
262 }
263
264 // check if the implementation supports all combinations of the supported depth and stencil resolve modes
265 if (!dsResolveProperties.independentResolve && (depthResolveMode != stencilResolveMode))
266 TCU_THROW(NotSupportedError, "Implementation doesn't support diferent resolve modes");
267
268 return true;
269 }
270
sampleCountBitFromSampleCount(deUint32 count) const271 VkSampleCountFlagBits DepthStencilResolveTest::sampleCountBitFromSampleCount (deUint32 count) const
272 {
273 switch (count)
274 {
275 case 1: return VK_SAMPLE_COUNT_1_BIT;
276 case 2: return VK_SAMPLE_COUNT_2_BIT;
277 case 4: return VK_SAMPLE_COUNT_4_BIT;
278 case 8: return VK_SAMPLE_COUNT_8_BIT;
279 case 16: return VK_SAMPLE_COUNT_16_BIT;
280 case 32: return VK_SAMPLE_COUNT_32_BIT;
281 case 64: return VK_SAMPLE_COUNT_64_BIT;
282
283 default:
284 DE_FATAL("Invalid sample count");
285 return (VkSampleCountFlagBits)0x0;
286 }
287 }
288
createImage(deUint32 sampleCount,VkImageUsageFlags additionalUsage)289 VkImageSp DepthStencilResolveTest::createImage (deUint32 sampleCount, VkImageUsageFlags additionalUsage)
290 {
291 const tcu::TextureFormat format(mapVkFormat(m_config.format));
292 const VkImageTiling imageTiling(VK_IMAGE_TILING_OPTIMAL);
293 VkSampleCountFlagBits sampleCountBit(sampleCountBitFromSampleCount(sampleCount));
294 VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | additionalUsage;
295
296 VkImageFormatProperties imageFormatProperties;
297 if (m_vki.getPhysicalDeviceImageFormatProperties(m_physicalDevice, m_config.format, VK_IMAGE_TYPE_2D, imageTiling,
298 usage, 0u, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
299 {
300 TCU_THROW(NotSupportedError, "Format not supported");
301 }
302 if (imageFormatProperties.sampleCounts < sampleCount)
303 {
304 TCU_THROW(NotSupportedError, "Sample count not supported");
305 }
306 if (imageFormatProperties.maxArrayLayers < m_config.imageLayers)
307 {
308 TCU_THROW(NotSupportedError, "Layers count not supported");
309 }
310
311 const VkExtent3D imageExtent =
312 {
313 m_config.width,
314 m_config.height,
315 1u
316 };
317
318 if (!(tcu::hasDepthComponent(format.order) || tcu::hasStencilComponent(format.order)))
319 TCU_THROW(NotSupportedError, "Format can't be used as depth/stencil attachment");
320
321 if (imageFormatProperties.maxExtent.width < imageExtent.width
322 || imageFormatProperties.maxExtent.height < imageExtent.height
323 || ((imageFormatProperties.sampleCounts & sampleCountBit) == 0)
324 || imageFormatProperties.maxArrayLayers < m_config.imageLayers)
325 {
326 TCU_THROW(NotSupportedError, "Image type not supported");
327 }
328
329 const VkImageCreateInfo pCreateInfo =
330 {
331 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
332 DE_NULL,
333 0u,
334 VK_IMAGE_TYPE_2D,
335 m_config.format,
336 imageExtent,
337 1u,
338 m_config.imageLayers,
339 sampleCountBit,
340 imageTiling,
341 usage,
342 VK_SHARING_MODE_EXCLUSIVE,
343 0u,
344 DE_NULL,
345 VK_IMAGE_LAYOUT_UNDEFINED
346 };
347
348 return safeSharedPtr(new Unique<VkImage>(vk::createImage(m_vkd, m_device, &pCreateInfo)));
349 }
350
createImageMemory(VkImageSp image)351 AllocationSp DepthStencilResolveTest::createImageMemory (VkImageSp image)
352 {
353 Allocator& allocator = m_context.getDefaultAllocator();
354
355 de::MovePtr<Allocation> allocation (allocator.allocate(getImageMemoryRequirements(m_vkd, m_device, **image), MemoryRequirement::Any));
356 VK_CHECK(m_vkd.bindImageMemory(m_device, **image, allocation->getMemory(), allocation->getOffset()));
357 return safeSharedPtr(allocation.release());
358 }
359
createImageView(VkImageSp image,deUint32 baseArrayLayer)360 VkImageViewSp DepthStencilResolveTest::createImageView (VkImageSp image, deUint32 baseArrayLayer)
361 {
362 const VkImageSubresourceRange range =
363 {
364 m_config.aspectFlag,
365 0u,
366 1u,
367 baseArrayLayer,
368 m_config.viewLayers
369 };
370
371 const VkImageViewCreateInfo pCreateInfo =
372 {
373 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
374 DE_NULL,
375 0u,
376 **image,
377 (m_config.viewLayers > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
378 m_config.format,
379 makeComponentMappingRGBA(),
380 range,
381 };
382 return safeSharedPtr(new Unique<VkImageView>(vk::createImageView(m_vkd, m_device, &pCreateInfo)));
383 }
384
createRenderPass(void)385 Move<VkRenderPass> DepthStencilResolveTest::createRenderPass (void)
386 {
387 const VkSampleCountFlagBits samples(sampleCountBitFromSampleCount(m_config.sampleCount));
388
389 const AttachmentDescription2 multisampleAttachment // VkAttachmentDescription2KHR
390 (
391 // VkStructureType sType;
392 DE_NULL, // const void* pNext;
393 0u, // VkAttachmentDescriptionFlags flags;
394 m_config.format, // VkFormat format;
395 samples, // VkSampleCountFlagBits samples;
396 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
397 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
398 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
399 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
400 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
401 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout;
402 );
403 const AttachmentReference2 multisampleAttachmentRef // VkAttachmentReference2KHR
404 (
405 // VkStructureType sType;
406 DE_NULL, // const void* pNext;
407 0u, // deUint32 attachment;
408 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
409 0u // VkImageAspectFlags aspectMask;
410 );
411
412 const AttachmentDescription2 singlesampleAttachment // VkAttachmentDescription2KHR
413 (
414 // VkStructureType sType;
415 DE_NULL, // const void* pNext;
416 0u, // VkAttachmentDescriptionFlags flags;
417 m_config.format, // VkFormat format;
418 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
419 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
420 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
421 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
422 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
423 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
424 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL // VkImageLayout finalLayout;
425 );
426 AttachmentReference2 singlesampleAttachmentRef // VkAttachmentReference2KHR
427 (
428 // VkStructureType sType;
429 DE_NULL, // const void* pNext;
430 1u, // deUint32 attachment;
431 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
432 0u // VkImageAspectFlags aspectMask;
433 );
434
435 std::vector<AttachmentDescription2> attachments;
436 attachments.push_back(multisampleAttachment);
437 attachments.push_back(singlesampleAttachment);
438
439 VkSubpassDescriptionDepthStencilResolveKHR dsResolveDescription =
440 {
441 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR,
442 DE_NULL, // const void* pNext;
443 m_config.depthResolveMode, // VkResolveModeFlagBitsKHR depthResolveMode;
444 m_config.stencilResolveMode, // VkResolveModeFlagBitsKHR stencilResolveMode;
445 &singlesampleAttachmentRef // VkAttachmentReference2KHR pDepthStencilResolveAttachment;
446 };
447
448 const SubpassDescription2 subpass // VkSubpassDescription2KHR
449 (
450 // VkStructureType sType;
451 &dsResolveDescription, // const void* pNext;
452 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
453 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
454 0u, // deUint32 viewMask;
455 0u, // deUint32 inputAttachmentCount;
456 DE_NULL, // const VkAttachmentReference2KHR* pInputAttachments;
457 0u, // deUint32 colorAttachmentCount;
458 DE_NULL, // const VkAttachmentReference2KHR* pColorAttachments;
459 DE_NULL, // const VkAttachmentReference2KHR* pResolveAttachments;
460 &multisampleAttachmentRef, // const VkAttachmentReference2KHR* pDepthStencilAttachment;
461 0u, // deUint32 preserveAttachmentCount;
462 DE_NULL // const deUint32* pPreserveAttachments;
463 );
464
465 const RenderPassCreateInfo2 renderPassCreator // VkRenderPassCreateInfo2KHR
466 (
467 // VkStructureType sType;
468 DE_NULL, // const void* pNext;
469 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags;
470 (deUint32)attachments.size(), // deUint32 attachmentCount;
471 &attachments[0], // const VkAttachmentDescription2KHR* pAttachments;
472 1u, // deUint32 subpassCount;
473 &subpass, // const VkSubpassDescription2KHR* pSubpasses;
474 0u, // deUint32 dependencyCount;
475 DE_NULL, // const VkSubpassDependency2KHR* pDependencies;
476 0u, // deUint32 correlatedViewMaskCount;
477 DE_NULL // const deUint32* pCorrelatedViewMasks;
478 );
479
480 return renderPassCreator.createRenderPass(m_vkd, m_device);
481 }
482
createFramebuffer(VkRenderPass renderPass,VkImageViewSp multisampleImageView,VkImageViewSp singlesampleImageView)483 Move<VkFramebuffer> DepthStencilResolveTest::createFramebuffer (VkRenderPass renderPass, VkImageViewSp multisampleImageView, VkImageViewSp singlesampleImageView)
484 {
485 std::vector<VkImageView> attachments;
486 attachments.push_back(**multisampleImageView);
487 attachments.push_back(**singlesampleImageView);
488
489 const VkFramebufferCreateInfo createInfo =
490 {
491 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
492 DE_NULL,
493 0u,
494
495 renderPass,
496 (deUint32)attachments.size(),
497 &attachments[0],
498
499 m_config.width,
500 m_config.height,
501 m_config.viewLayers
502 };
503
504 return vk::createFramebuffer(m_vkd, m_device, &createInfo);
505 }
506
createRenderPipelineLayout(void)507 Move<VkPipelineLayout> DepthStencilResolveTest::createRenderPipelineLayout (void)
508 {
509 VkPushConstantRange pushConstant =
510 {
511 VK_SHADER_STAGE_FRAGMENT_BIT,
512 0u,
513 4u
514 };
515
516 deUint32 pushConstantRangeCount = 0u;
517 VkPushConstantRange* pPushConstantRanges = DE_NULL;
518 if (m_config.verifyBuffer == VB_STENCIL)
519 {
520 pushConstantRangeCount = 1u;
521 pPushConstantRanges = &pushConstant;
522 }
523
524 const VkPipelineLayoutCreateInfo createInfo =
525 {
526 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
527 DE_NULL,
528 (vk::VkPipelineLayoutCreateFlags)0,
529
530 0u,
531 DE_NULL,
532
533 pushConstantRangeCount,
534 pPushConstantRanges
535 };
536
537 return vk::createPipelineLayout(m_vkd, m_device, &createInfo);
538 }
539
createRenderPipeline(VkRenderPass renderPass,VkPipelineLayout renderPipelineLayout)540 Move<VkPipeline> DepthStencilResolveTest::createRenderPipeline (VkRenderPass renderPass, VkPipelineLayout renderPipelineLayout)
541 {
542 const bool testingStencil = (m_config.verifyBuffer == VB_STENCIL);
543 const vk::BinaryCollection& binaryCollection = m_context.getBinaryCollection();
544
545 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-vert"), 0u));
546 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(m_vkd, m_device, binaryCollection.get("quad-frag"), 0u));
547 const Move<VkShaderModule> geometryShaderModule (m_config.imageLayers == 1 ? Move<VkShaderModule>() : createShaderModule(m_vkd, m_device, binaryCollection.get("quad-geom"), 0u));
548
549 const VkPipelineVertexInputStateCreateInfo vertexInputState =
550 {
551 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
552 DE_NULL,
553 (VkPipelineVertexInputStateCreateFlags)0u,
554
555 0u,
556 DE_NULL,
557
558 0u,
559 DE_NULL
560 };
561 const tcu::UVec2 view (m_config.width, m_config.height);
562 const std::vector<VkViewport> viewports (1, makeViewport(view));
563 const std::vector<VkRect2D> scissors (1, m_config.renderArea);
564
565 const VkPipelineMultisampleStateCreateInfo multisampleState =
566 {
567 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
568 DE_NULL,
569 (VkPipelineMultisampleStateCreateFlags)0u,
570
571 sampleCountBitFromSampleCount(m_config.sampleCount),
572 VK_FALSE,
573 0.0f,
574 DE_NULL,
575 VK_FALSE,
576 VK_FALSE,
577 };
578 const VkPipelineDepthStencilStateCreateInfo depthStencilState =
579 {
580 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
581 DE_NULL,
582 (VkPipelineDepthStencilStateCreateFlags)0u,
583
584 VK_TRUE, // depthTestEnable
585 VK_TRUE,
586 VK_COMPARE_OP_ALWAYS,
587 VK_FALSE,
588 testingStencil, // stencilTestEnable
589 {
590 VK_STENCIL_OP_REPLACE, // failOp
591 VK_STENCIL_OP_REPLACE, // passOp
592 VK_STENCIL_OP_REPLACE, // depthFailOp
593 VK_COMPARE_OP_ALWAYS, // compareOp
594 0xFFu, // compareMask
595 0xFFu, // writeMask
596 1 // reference
597 },
598 {
599 VK_STENCIL_OP_REPLACE,
600 VK_STENCIL_OP_REPLACE,
601 VK_STENCIL_OP_REPLACE,
602 VK_COMPARE_OP_ALWAYS,
603 0xFFu,
604 0xFFu,
605 1
606 },
607 0.0f,
608 1.0f
609 };
610
611 std::vector<VkDynamicState> dynamicState;
612 dynamicState.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
613 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
614 {
615 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
616 DE_NULL, // const void* pNext;
617 (VkPipelineDynamicStateCreateFlags)0u, // VkPipelineDynamicStateCreateFlags flags;
618 static_cast<deUint32>(dynamicState.size()), // deUint32 dynamicStateCount;
619 &dynamicState[0] // const VkDynamicState* pDynamicStates;
620 };
621
622 return makeGraphicsPipeline(m_vkd, // const DeviceInterface& vk
623 m_device, // const VkDevice device
624 renderPipelineLayout, // const VkPipelineLayout pipelineLayout
625 *vertexShaderModule, // const VkShaderModule vertexShaderModule
626 DE_NULL, // const VkShaderModule tessellationControlShaderModule
627 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
628 m_config.imageLayers == 1 ? DE_NULL : *geometryShaderModule, // const VkShaderModule geometryShaderModule
629 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
630 renderPass, // const VkRenderPass renderPass
631 viewports, // const std::vector<VkViewport>& viewports
632 scissors, // const std::vector<VkRect2D>& scissors
633 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
634 0u, // const deUint32 subpass
635 0u, // const deUint32 patchControlPoints
636 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
637 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
638 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
639 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
640 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
641 testingStencil ? &dynamicStateCreateInfo : DE_NULL); // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
642 }
643
createBufferMemory(void)644 AllocationSp DepthStencilResolveTest::createBufferMemory (void)
645 {
646 Allocator& allocator = m_context.getDefaultAllocator();
647 de::MovePtr<Allocation> allocation(allocator.allocate(getBufferMemoryRequirements(m_vkd, m_device, **m_buffer), MemoryRequirement::HostVisible));
648 VK_CHECK(m_vkd.bindBufferMemory(m_device, **m_buffer, allocation->getMemory(), allocation->getOffset()));
649 return safeSharedPtr(allocation.release());
650 }
651
createBuffer(void)652 VkBufferSp DepthStencilResolveTest::createBuffer (void)
653 {
654 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
655 const tcu::TextureFormat textureFormat (mapVkFormat(m_config.format));
656 const VkDeviceSize pixelSize (textureFormat.getPixelSize());
657 const VkBufferCreateInfo createInfo =
658 {
659 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
660 DE_NULL,
661 0u,
662
663 m_config.width * m_config.height * m_config.imageLayers * pixelSize,
664 bufferUsage,
665
666 VK_SHARING_MODE_EXCLUSIVE,
667 0u,
668 DE_NULL
669 };
670 return safeSharedPtr(new Unique<VkBuffer>(vk::createBuffer(m_vkd, m_device, &createInfo)));
671 }
672
submit(void)673 void DepthStencilResolveTest::submit (void)
674 {
675 const DeviceInterface& vkd (m_context.getDeviceInterface());
676 const VkDevice device (m_context.getDevice());
677 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, device, *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
678 const RenderpassSubpass2::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
679 const RenderpassSubpass2::SubpassEndInfo subpassEndInfo (DE_NULL);
680
681 beginCommandBuffer(vkd, *commandBuffer);
682
683 {
684 VkClearValue clearValues[2];
685 clearValues[0].depthStencil = m_config.clearValue;
686 clearValues[1].depthStencil = m_config.clearValue;
687
688 const VkRenderPassBeginInfo beginInfo =
689 {
690 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
691 DE_NULL,
692
693 *m_renderPass,
694 *m_framebuffer,
695
696 {
697 { 0u, 0u },
698 { m_config.width, m_config.height }
699 },
700
701 2u,
702 clearValues
703 };
704 RenderpassSubpass2::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
705 }
706
707 // Render
708 bool testingDepth = (m_config.verifyBuffer == VB_DEPTH);
709 if (testingDepth)
710 {
711 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
712 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
713 }
714 else
715 {
716 // For stencil we can set reference value for just one sample at a time
717 // so we need to do as many passes as there are samples, first half
718 // of samples is initialized with 1 and second half with 255
719 const deUint32 halfOfSamples = m_config.sampleCount >> 1;
720 for (deUint32 renderPass = 0 ; renderPass < m_config.sampleCount ; renderPass++)
721 {
722 deUint32 stencilReference = 1 + 254 * (renderPass >= halfOfSamples);
723 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
724 vkd.cmdPushConstants(*commandBuffer, *m_renderPipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(renderPass), &renderPass);
725 vkd.cmdSetStencilReference(*commandBuffer, VK_STENCIL_FRONT_AND_BACK, stencilReference);
726 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
727 }
728 }
729
730 RenderpassSubpass2::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
731
732 // Memory barriers between rendering and copying
733 {
734 const VkImageMemoryBarrier barrier =
735 {
736 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
737 DE_NULL,
738
739 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
740 VK_ACCESS_TRANSFER_READ_BIT,
741
742 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
743 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
744
745 VK_QUEUE_FAMILY_IGNORED,
746 VK_QUEUE_FAMILY_IGNORED,
747
748 **m_singlesampleImage,
749 {
750 m_config.aspectFlag,
751 0u,
752 1u,
753 0u,
754 m_config.viewLayers
755 }
756 };
757
758 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
759 }
760
761 // Copy image memory to buffers
762 const VkBufferImageCopy region =
763 {
764 0u,
765 0u,
766 0u,
767 {
768 testingDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_STENCIL_BIT,
769 0u,
770 0u,
771 m_config.viewLayers,
772 },
773 { 0u, 0u, 0u },
774 { m_config.width, m_config.height, 1u }
775 };
776
777 vkd.cmdCopyImageToBuffer(*commandBuffer, **m_singlesampleImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_buffer, 1u, ®ion);
778
779 // Memory barriers between copies and host access
780 {
781 const VkBufferMemoryBarrier barrier =
782 {
783 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
784 DE_NULL,
785
786 VK_ACCESS_TRANSFER_WRITE_BIT,
787 VK_ACCESS_HOST_READ_BIT,
788
789 VK_QUEUE_FAMILY_IGNORED,
790 VK_QUEUE_FAMILY_IGNORED,
791
792 **m_buffer,
793 0u,
794 VK_WHOLE_SIZE
795 };
796
797 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL);
798 }
799
800 endCommandBuffer(vkd, *commandBuffer);
801
802 submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), *commandBuffer);
803 }
804
verifyDepth(void)805 bool DepthStencilResolveTest::verifyDepth (void)
806 {
807 deUint32 layerSize = m_config.width * m_config.height;
808 deUint32 valuesCount = layerSize * m_config.viewLayers;
809 deUint8* pixelPtr = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
810
811 float expectedValue = m_config.depthExpectedValue;
812 if (m_config.depthResolveMode == VK_RESOLVE_MODE_NONE_KHR)
813 expectedValue = m_config.clearValue.depth;
814
815 // depth data in buffer is tightly packed, ConstPixelBufferAccess
816 // coludn't be used for depth value extraction as it cant interpret
817 // formats containing just depth component
818
819 typedef float (*DepthComponentGetterFn)(deUint8*);
820 VkFormat format = m_config.format;
821 DepthComponentGetterFn getDepthComponent = &get16bitDepthComponent;
822 deUint32 pixelStep = 2;
823 float epsilon = 0.002f;
824
825 if ((format == VK_FORMAT_X8_D24_UNORM_PACK32) ||
826 (format == VK_FORMAT_D24_UNORM_S8_UINT))
827 {
828 getDepthComponent = &get24bitDepthComponent;
829 pixelStep = 4;
830 }
831 else if ((format == VK_FORMAT_D32_SFLOAT) ||
832 (format == VK_FORMAT_D32_SFLOAT_S8_UINT))
833 {
834 getDepthComponent = &get32bitDepthComponent;
835 pixelStep = 4;
836 }
837
838 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
839 {
840 float depth = (*getDepthComponent)(pixelPtr);
841 pixelPtr += pixelStep;
842
843 // check if pixel data is outside of render area
844 deInt32 layerIndex = valueIndex / layerSize;
845 deInt32 inLayerIndex = valueIndex % layerSize;
846 deInt32 x = inLayerIndex % m_config.width;
847 deInt32 y = (inLayerIndex - x) / m_config.width;
848 deInt32 x1 = m_config.renderArea.offset.x;
849 deInt32 y1 = m_config.renderArea.offset.y;
850 deInt32 x2 = x1 + m_config.renderArea.extent.width;
851 deInt32 y2 = y1 + m_config.renderArea.extent.height;
852 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
853 {
854 // verify that outside of render area there are clear values
855 float error = deFloatAbs(depth - m_config.clearValue.depth);
856 if (error > epsilon)
857 {
858 m_context.getTestContext().getLog()
859 << TestLog::Message << "(" << x << ", " << y
860 << ", layer: " << layerIndex << ") is outside of render area but depth value is: "
861 << depth << " (expected " << m_config.clearValue.depth << ")" << TestLog::EndMessage;
862 return false;
863 }
864
865 // value is correct, go to next one
866 continue;
867 }
868
869 float error = deFloatAbs(depth - expectedValue);
870 if (error > epsilon)
871 {
872 m_context.getTestContext().getLog() << TestLog::Message
873 << "At (" << x << ", " << y << ", layer: " << layerIndex
874 << ") depth value is: " << depth << " expected: "
875 << expectedValue << TestLog::EndMessage;
876 return false;
877 }
878 }
879 m_context.getTestContext().getLog() << TestLog::Message
880 << "Depth value is " << expectedValue
881 << TestLog::EndMessage;
882
883 return true;
884 }
885
verifyStencil(void)886 bool DepthStencilResolveTest::verifyStencil (void)
887 {
888 deUint32 layerSize = m_config.width * m_config.height;
889 deUint32 valuesCount = layerSize * m_config.viewLayers;
890 deUint8* pixelPtr = static_cast<deUint8*>(m_bufferMemory->getHostPtr());
891
892 // when stencil is tested we are discarding invocations and
893 // because of that depth and stencil need to be tested separately
894
895 deUint8 expectedValue = m_config.stencilExpectedValue;
896 if (m_config.stencilResolveMode == VK_RESOLVE_MODE_NONE_KHR)
897 expectedValue = static_cast<deUint8>(m_config.clearValue.stencil);
898
899 for (deUint32 valueIndex = 0; valueIndex < valuesCount; valueIndex++)
900 {
901 deUint8 stencil = *pixelPtr++;
902 deInt32 layerIndex = valueIndex / layerSize;
903 deInt32 inLayerIndex = valueIndex % layerSize;
904 deInt32 x = inLayerIndex % m_config.width;
905 deInt32 y = (inLayerIndex - x) / m_config.width;
906 deInt32 x1 = m_config.renderArea.offset.x;
907 deInt32 y1 = m_config.renderArea.offset.y;
908 deInt32 x2 = x1 + m_config.renderArea.extent.width;
909 deInt32 y2 = y1 + m_config.renderArea.extent.height;
910 if ((x < x1) || (x >= x2) || (y < y1) || (y >= y2))
911 {
912 if (stencil != m_config.clearValue.stencil)
913 {
914 m_context.getTestContext().getLog()
915 << TestLog::Message << "(" << x << ", " << y << ", layer: " << layerIndex
916 << ") is outside of render area but stencil value is: "
917 << stencil << " (expected " << m_config.clearValue.stencil << ")" << TestLog::EndMessage;
918 return false;
919 }
920
921 // value is correct, go to next one
922 continue;
923 }
924
925 if (stencil != expectedValue)
926 {
927 m_context.getTestContext().getLog() << TestLog::Message
928 << "At (" << x << ", " << y << ", layer: " << layerIndex
929 << ") stencil value is: " << static_cast<deUint32>(stencil)
930 << " expected: " << static_cast<deUint32>(expectedValue)
931 << TestLog::EndMessage;
932 return false;
933 }
934 }
935 m_context.getTestContext().getLog() << TestLog::Message
936 << "Stencil value is "
937 << static_cast<deUint32>(expectedValue)
938 << TestLog::EndMessage;
939
940 return true;
941 }
942
iterate(void)943 tcu::TestStatus DepthStencilResolveTest::iterate (void)
944 {
945 submit();
946
947 bool result = false;
948 if (m_config.verifyBuffer == VB_DEPTH)
949 result = verifyDepth();
950 else
951 result = verifyStencil();
952
953 if (result)
954 return tcu::TestStatus::pass("Pass");
955 return tcu::TestStatus::fail("Fail");
956 }
957
958 struct Programs
959 {
initvkt::__anonf560080b0111::Programs960 void init (vk::SourceCollections& dst, TestConfig config) const
961 {
962 // geometry shader is only needed in multi-layer framebuffer resolve tests
963 if (config.imageLayers > 1)
964 {
965 const deUint32 layerCount = 3;
966
967 std::ostringstream src;
968 src << "#version 450\n"
969 << "highp float;\n"
970 << "\n"
971 << "layout(triangles) in;\n"
972 << "layout(triangle_strip, max_vertices = " << 3 * 2 * layerCount << ") out;\n"
973 << "\n"
974 << "in gl_PerVertex {\n"
975 << " vec4 gl_Position;\n"
976 << "} gl_in[];\n"
977 << "\n"
978 << "out gl_PerVertex {\n"
979 << " vec4 gl_Position;\n"
980 << "};\n"
981 << "\n"
982 << "void main (void) {\n"
983 << " for (int layerNdx = 0; layerNdx < " << layerCount << "; ++layerNdx) {\n"
984 << " for(int vertexNdx = 0; vertexNdx < gl_in.length(); vertexNdx++) {\n"
985 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
986 << " gl_Layer = layerNdx;\n"
987 << " EmitVertex();\n"
988 << " };\n"
989 << " EndPrimitive();\n"
990 << " };\n"
991 << "}\n";
992
993 dst.glslSources.add("quad-geom") << glu::GeometrySource(src.str());
994 }
995
996 dst.glslSources.add("quad-vert") << glu::VertexSource(
997 "#version 450\n"
998 "out gl_PerVertex {\n"
999 "\tvec4 gl_Position;\n"
1000 "};\n"
1001 "highp float;\n"
1002 "void main (void) {\n"
1003 "\tgl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
1004 "\t ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
1005 "}\n");
1006
1007 if (config.verifyBuffer == VB_DEPTH)
1008 {
1009 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1010 "#version 450\n"
1011 "precision highp float;\n"
1012 "precision highp int;\n"
1013 "void main (void)\n"
1014 "{\n"
1015 " float sampleIndex = float(gl_SampleID);\n" // sampleIndex is integer in range <0, 63>
1016 " float valueIndex = round(mod(sampleIndex, 4.0));\n" // limit possible depth values - count to 4
1017 " float value = valueIndex + 2.0;\n" // value is one of [2, 3, 4, 5]
1018 " value = round(exp2(value));\n" // value is one of [4, 8, 16, 32]
1019 " bool condition = (int(value) == 8);\n" // select second sample value (to make it smallest)
1020 " value = round(value - float(condition) * 6.0);\n" // value is one of [4, 2, 16, 32]
1021 " gl_FragDepth = value / 100.0;\n" // sample depth is one of [0.04, 0.02, 0.16, 0.32]
1022 "}\n");
1023 }
1024 else
1025 {
1026 dst.glslSources.add("quad-frag") << glu::FragmentSource(
1027 "#version 450\n"
1028 "precision highp float;\n"
1029 "precision highp int;\n"
1030 "layout(push_constant) uniform PushConstant {\n"
1031 " highp int sampleID;\n"
1032 "} pushConstants;\n"
1033 "void main (void)\n"
1034 "{\n"
1035 " if(gl_SampleID != pushConstants.sampleID)\n"
1036 " discard;\n"
1037 " gl_FragDepth = 0.5;\n"
1038 "}\n");
1039 }
1040 }
1041 };
1042
initTests(tcu::TestCaseGroup * group)1043 void initTests (tcu::TestCaseGroup* group)
1044 {
1045 typedef InstanceFactory1<DepthStencilResolveTest, TestConfig, Programs> DSResolveTestInstance;
1046
1047 struct FormatData
1048 {
1049 VkFormat format;
1050 const char* name;
1051 bool hasDepth;
1052 bool hasStencil;
1053 };
1054 FormatData formats[] =
1055 {
1056 { VK_FORMAT_D16_UNORM, "d16_unorm", true, false },
1057 { VK_FORMAT_X8_D24_UNORM_PACK32, "x8_d24_unorm_pack32", true, false },
1058 { VK_FORMAT_D32_SFLOAT, "d32_sfloat", true, false },
1059 { VK_FORMAT_S8_UINT, "s8_uint", false, true },
1060 { VK_FORMAT_D16_UNORM_S8_UINT, "d16_unorm_s8_uint", true, true },
1061 { VK_FORMAT_D24_UNORM_S8_UINT, "d24_unorm_s8_uint", true, true },
1062 { VK_FORMAT_D32_SFLOAT_S8_UINT, "d32_sfloat_s8_uint", true, true },
1063 };
1064
1065 struct ResolveModeData
1066 {
1067 VkResolveModeFlagBitsKHR flag;
1068 std::string name;
1069 };
1070 ResolveModeData resolveModes[] =
1071 {
1072 { VK_RESOLVE_MODE_NONE_KHR, "none" },
1073 { VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR, "zero" },
1074 { VK_RESOLVE_MODE_AVERAGE_BIT_KHR, "average" },
1075 { VK_RESOLVE_MODE_MIN_BIT_KHR, "min" },
1076 { VK_RESOLVE_MODE_MAX_BIT_KHR, "max" },
1077 };
1078
1079 struct ImageTestData
1080 {
1081 const char* groupName;
1082 deUint32 width;
1083 deUint32 height;
1084 deUint32 imageLayers;
1085 VkRect2D renderArea;
1086 VkClearDepthStencilValue clearValue;
1087 };
1088
1089 // NOTE: tests cant be executed for 1D and 3D images:
1090 // 1D images are not tested because acording to specyfication sampleCounts
1091 // will be set to VK_SAMPLE_COUNT_1_BIT when type is not VK_IMAGE_TYPE_2D
1092 // 3D images are not tested because VkFramebufferCreateInfo specification
1093 // states that: each element of pAttachments that is a 2D or 2D array image
1094 // view taken from a 3D image must not be a depth/stencil format
1095 ImageTestData imagesTestData[] =
1096 {
1097 { "image_2d_32_32", 32, 32, 1, {{ 0, 0}, {32, 32}}, {0.000f, 0x00} },
1098 { "image_2d_8_32", 8, 32, 1, {{ 1, 1}, { 6, 30}}, {0.123f, 0x01} },
1099 { "image_2d_49_13", 49, 13, 1, {{10, 5}, {20, 8}}, {1.000f, 0x05} },
1100 { "image_2d_5_1", 5, 1, 1, {{ 0, 0}, { 5, 1}}, {0.500f, 0x00} },
1101 { "image_2d_17_1", 17, 1, 1, {{ 1, 0}, {15, 1}}, {0.789f, 0xfa} },
1102 };
1103 const deUint32 sampleCounts[] =
1104 {
1105 2u, 4u, 8u, 16u, 32u, 64u
1106 };
1107 const float depthExpectedValue[][6] =
1108 {
1109 // 2 samples 4 8 16 32 64
1110 { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // RESOLVE_MODE_NONE - expect clear value
1111 { 0.04f, 0.04f, 0.04f, 0.04f, 0.04f, 0.04f }, // RESOLVE_MODE_SAMPLE_ZERO_BIT
1112 { 0.03f, 0.135f, 0.135f, 0.135f, 0.135f, 0.135f }, // RESOLVE_MODE_AVERAGE_BIT
1113 { 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f }, // RESOLVE_MODE_MIN_BIT
1114 { 0.04f, 0.32f, 0.32f, 0.32f, 0.32f, 0.32f }, // RESOLVE_MODE_MAX_BIT
1115 };
1116 const deUint8 stencilExpectedValue[][6] =
1117 {
1118 // 2 samples 4 8 16 32 64
1119 { 0u, 0u, 0u, 0u, 0u, 0u }, // RESOLVE_MODE_NONE - expect clear value
1120 { 1u, 1u, 1u, 1u, 1u, 1u }, // RESOLVE_MODE_SAMPLE_ZERO_BIT
1121 { 0u, 0u, 0u, 0u, 0u, 0u }, // RESOLVE_MODE_AVERAGE_BIT - not supported
1122 { 1u, 1u, 1u, 1u, 1u, 1u }, // RESOLVE_MODE_MIN_BIT
1123 { 255u, 255u, 255u, 255u, 255u, 255u }, // RESOLVE_MODE_MAX_BIT
1124 };
1125
1126 tcu::TestContext& testCtx(group->getTestContext());
1127
1128 // iterate over image data
1129 for (deUint32 imageDataNdx = 0; imageDataNdx < DE_LENGTH_OF_ARRAY(imagesTestData); imageDataNdx++)
1130 {
1131 ImageTestData imageData = imagesTestData[imageDataNdx];
1132
1133 // create test group for image data
1134 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, imageData.groupName, imageData.groupName));
1135
1136 // iterate over sampleCounts
1137 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1138 {
1139 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1140 const std::string sampleName ("samples_" + de::toString(sampleCount));
1141
1142 // create test group for sample count
1143 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1144
1145 // iterate over depth/stencil formats
1146 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1147 {
1148 const FormatData& formatData = formats[formatNdx];
1149 VkFormat format = formatData.format;
1150 const char* formatName = formatData.name;
1151 const bool hasDepth = formatData.hasDepth;
1152 const bool hasStencil = formatData.hasStencil;
1153 VkImageAspectFlags aspectFlags = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1154 (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1155
1156 // create test group for format
1157 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName));
1158
1159 // iterate over depth resolve modes
1160 for (size_t depthResolveModeNdx = 0; depthResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); depthResolveModeNdx++)
1161 {
1162 // iterate over stencil resolve modes
1163 for (size_t stencilResolveModeNdx = 0; stencilResolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); stencilResolveModeNdx++)
1164 {
1165 // there is no average resolve mode for stencil - go to next iteration
1166 ResolveModeData& sResolve = resolveModes[stencilResolveModeNdx];
1167 if (sResolve.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
1168 continue;
1169
1170 // if pDepthStencilResolveAttachment is not NULL and does not have the value VK_ATTACHMENT_UNUSED,
1171 // depthResolveMode and stencilResolveMode must not both be VK_RESOLVE_MODE_NONE_KHR
1172 ResolveModeData& dResolve = resolveModes[depthResolveModeNdx];
1173 if ((dResolve.flag == VK_RESOLVE_MODE_NONE_KHR) && (sResolve.flag == VK_RESOLVE_MODE_NONE_KHR))
1174 continue;
1175
1176 // If there is no depth, the depth resolve mode should be NONE, or
1177 // match the stencil resolve mode.
1178 if (!hasDepth && (dResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
1179 (dResolve.flag != sResolve.flag))
1180 continue;
1181
1182 // If there is no stencil, the stencil resmove mode should be NONE, or
1183 // match the depth resolve mode.
1184 if (!hasStencil && (sResolve.flag != VK_RESOLVE_MODE_NONE_KHR) &&
1185 (dResolve.flag != sResolve.flag))
1186 continue;
1187
1188 std::string baseName = "depth_" + dResolve.name + "_stencil_" + sResolve.name;
1189
1190 if (hasDepth)
1191 {
1192 std::string name = baseName + "_testing_depth";
1193 const char* testName = name.c_str();
1194 float expectedValue = depthExpectedValue[depthResolveModeNdx][sampleCountNdx];
1195
1196 const TestConfig testConfig =
1197 {
1198 format,
1199 imageData.width,
1200 imageData.height,
1201 1u,
1202 1u,
1203 0u,
1204 imageData.renderArea,
1205 aspectFlags,
1206 sampleCount,
1207 dResolve.flag,
1208 sResolve.flag,
1209 VB_DEPTH,
1210 imageData.clearValue,
1211 expectedValue,
1212 0u
1213 };
1214 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1215 }
1216 if (hasStencil)
1217 {
1218 std::string name = baseName + "_testing_stencil";
1219 const char* testName = name.c_str();
1220 deUint8 expectedValue = stencilExpectedValue[stencilResolveModeNdx][sampleCountNdx];
1221
1222 const TestConfig testConfig =
1223 {
1224 format,
1225 imageData.width,
1226 imageData.height,
1227 1u,
1228 1u,
1229 0u,
1230 imageData.renderArea,
1231 aspectFlags,
1232 sampleCount,
1233 dResolve.flag,
1234 sResolve.flag,
1235 VB_STENCIL,
1236 imageData.clearValue,
1237 0.0f,
1238 expectedValue
1239 };
1240 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1241 }
1242 }
1243 }
1244
1245 sampleGroup->addChild(formatGroup.release());
1246 }
1247
1248 imageGroup->addChild(sampleGroup.release());
1249 }
1250
1251 group->addChild(imageGroup.release());
1252 }
1253
1254 {
1255 // layered texture tests are done for all stencil modes and depth modes - not all combinations
1256 // Test checks if all layer are resolved in multi-layered framebuffer and if we can have a framebuffer
1257 // which starts at a layer other than zero. Both parts are tested together by rendering to layers
1258 // 4-6 and resolving to layers 1-3.
1259 ImageTestData layeredTextureTestData =
1260 {
1261 "image_2d_16_64_6", 16, 64, 6, {{ 10, 10}, {6, 54}}, {1.0f, 0x0}
1262 };
1263
1264 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, layeredTextureTestData.groupName, layeredTextureTestData.groupName));
1265
1266 for (size_t sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); sampleCountNdx++)
1267 {
1268 const deUint32 sampleCount (sampleCounts[sampleCountNdx]);
1269 const std::string sampleName ("samples_" + de::toString(sampleCount));
1270
1271 // create test group for sample count
1272 de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, sampleName.c_str(), sampleName.c_str()));
1273
1274 // iterate over depth/stencil formats
1275 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
1276 {
1277 const FormatData& formatData = formats[formatNdx];
1278 VkFormat format = formatData.format;
1279 const char* formatName = formatData.name;
1280 const bool hasDepth = formatData.hasDepth;
1281 const bool hasStencil = formatData.hasStencil;
1282 VkImageAspectFlags aspectFlags = (hasDepth * VK_IMAGE_ASPECT_DEPTH_BIT) |
1283 (hasStencil * VK_IMAGE_ASPECT_STENCIL_BIT);
1284
1285 // create test group for format
1286 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, formatName, formatName));
1287
1288 for (size_t resolveModeNdx = 0; resolveModeNdx < DE_LENGTH_OF_ARRAY(resolveModes); resolveModeNdx++)
1289 {
1290 ResolveModeData& mode = resolveModes[resolveModeNdx];
1291
1292 if (hasDepth)
1293 {
1294 std::string name = "depth_" + mode.name;
1295 const char* testName = name.c_str();
1296 float expectedValue = depthExpectedValue[resolveModeNdx][sampleCountNdx];
1297 const TestConfig testConfig =
1298 {
1299 format,
1300 layeredTextureTestData.width,
1301 layeredTextureTestData.height,
1302 layeredTextureTestData.imageLayers,
1303 3u,
1304 0u,
1305 layeredTextureTestData.renderArea,
1306 aspectFlags,
1307 sampleCount,
1308 mode.flag,
1309 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
1310 VB_DEPTH,
1311 layeredTextureTestData.clearValue,
1312 expectedValue,
1313 0u
1314 };
1315 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1316 }
1317
1318 // there is no average resolve mode for stencil - go to next iteration
1319 if (mode.flag == VK_RESOLVE_MODE_AVERAGE_BIT_KHR)
1320 continue;
1321
1322 if (hasStencil)
1323 {
1324 std::string name = "stencil_" + mode.name;
1325 const char* testName = name.c_str();
1326 deUint8 expectedValue = stencilExpectedValue[resolveModeNdx][sampleCountNdx];
1327 const TestConfig testConfig =
1328 {
1329 format,
1330 layeredTextureTestData.width,
1331 layeredTextureTestData.height,
1332 layeredTextureTestData.imageLayers,
1333 3u,
1334 0u,
1335 layeredTextureTestData.renderArea,
1336 aspectFlags,
1337 sampleCount,
1338 VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR,
1339 mode.flag,
1340 VB_STENCIL,
1341 layeredTextureTestData.clearValue,
1342 0.0f,
1343 expectedValue
1344 };
1345 formatGroup->addChild(new DSResolveTestInstance(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName, testName, testConfig));
1346 }
1347 }
1348 sampleGroup->addChild(formatGroup.release());
1349 }
1350 imageGroup->addChild(sampleGroup.release());
1351 }
1352
1353 group->addChild(imageGroup.release());
1354 }
1355 }
1356
1357 } // anonymous
1358
createRenderPass2DepthStencilResolveTests(tcu::TestContext & testCtx)1359 tcu::TestCaseGroup* createRenderPass2DepthStencilResolveTests (tcu::TestContext& testCtx)
1360 {
1361 return createTestGroup(testCtx, "depth_stencil_resolve", "Depth/stencil resolve tests", initTests);
1362 }
1363
1364 } // vkt
1365