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, &region);
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