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