• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 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 vktSynchronizationNoneStageTests.cpp
21  * \brief Tests for VK_PIPELINE_STAGE_NONE{_2}_KHR that iterate over each writable layout
22 		  and over each readable layout. Data to tested image is writen using method
23 		  appropriate for the writable layout and read via readable layout appropriate method.
24 		  Betwean read and write operation there are bariers that use none stage.
25 		  Implemented tests are also testing generalized layouts (VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,
26 		  VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR) and access flags (MEMORY_ACCESS_READ|WRITE_BIT) to
27 		  test contextual synchronization introduced with VK_KHR_synchronization2 extension.
28  *//*--------------------------------------------------------------------*/
29 
30 #include "vktSynchronizationNoneStageTests.hpp"
31 #include "vktSynchronizationOperation.hpp"
32 #include "vktSynchronizationUtil.hpp"
33 #include "vktTestCase.hpp"
34 
35 #include "vkBuilderUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 
42 #include "tcuImageCompare.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuStringTemplate.hpp"
46 
47 #include "deUniquePtr.hpp"
48 
49 #include <vector>
50 
51 namespace vkt
52 {
53 namespace synchronization
54 {
55 
56 using namespace vk;
57 using namespace de;
58 using namespace tcu;
59 
60 namespace
61 {
62 
63 static const deUint32 IMAGE_ASPECT_DEPTH_STENCIL	= VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
64 static const deUint32 IMAGE_ASPECT_ALL				= 0u;
65 
66 struct TestParams
67 {
68 	SynchronizationType		type;
69 	bool					useGenericAccessFlags;
70 	VkImageLayout			writeLayout;
71 	VkImageAspectFlags		writeAspect;
72 	VkImageLayout			readLayout;
73 	VkImageAspectFlags		readAspect;
74 };
75 
76 // Helper class representing image
77 class ImageWrapper
78 {
79 public:
80 
81 			ImageWrapper	() = default;
82 	void	create			(Context& context, SimpleAllocator& alloc, VkFormat format, VkExtent3D extent, VkImageUsageFlags usage);
83 
84 public:
85 	Move<VkImage>			handle;
86 	MovePtr<Allocation>		memory;
87 };
88 
create(Context & context,SimpleAllocator & alloc,VkFormat format,VkExtent3D extent,VkImageUsageFlags usage)89 void ImageWrapper::create(Context& context, SimpleAllocator& alloc, VkFormat format, VkExtent3D extent, VkImageUsageFlags usage)
90 {
91 	const DeviceInterface&	vk					= context.getDeviceInterface();
92 	const VkDevice&			device				= context.getDevice();
93 	const deUint32			queueFamilyIndex	= context.getUniversalQueueFamilyIndex();
94 	const VkImageCreateInfo imageParams
95 	{
96 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// sType
97 		DE_NULL,								// pNext
98 		0u,										// flags
99 		VK_IMAGE_TYPE_2D,						// imageType
100 		format,									// format
101 		extent,									// extent
102 		1u,										// mipLevels
103 		1u,										// arraySize
104 		VK_SAMPLE_COUNT_1_BIT,					// samples
105 		VK_IMAGE_TILING_OPTIMAL,				// tiling
106 		usage,									// usage
107 		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
108 		1u,										// queueFamilyIndexCount
109 		&queueFamilyIndex,						// pQueueFamilyIndices
110 		VK_IMAGE_LAYOUT_UNDEFINED,				// initialLayout
111 	};
112 
113 	handle = createImage(vk, device, &imageParams);
114 	memory = alloc.allocate(getImageMemoryRequirements(vk, device, *handle), MemoryRequirement::Any);
115 
116 	vk.bindImageMemory(device, *handle, memory->getMemory(), memory->getOffset());
117 }
118 
119 // Helper class representing buffer
120 class BufferWrapper
121 {
122 public:
123 
124 			BufferWrapper	() = default;
125 	void	create			(Context& context, SimpleAllocator& alloc, VkDeviceSize size, VkBufferUsageFlags usage);
126 
127 public:
128 	Move<VkBuffer>			handle;
129 	MovePtr<Allocation>		memory;
130 };
131 
create(Context & context,SimpleAllocator & alloc,VkDeviceSize size,VkBufferUsageFlags usage)132 void BufferWrapper::create(Context& context, SimpleAllocator& alloc, VkDeviceSize size, VkBufferUsageFlags usage)
133 {
134 	const DeviceInterface&		vk					= context.getDeviceInterface();
135 	const VkDevice&				device				= context.getDevice();
136 	const VkBufferCreateInfo	bufferCreateInfo	= makeBufferCreateInfo(size, usage);
137 
138 	handle = createBuffer(vk, device, &bufferCreateInfo);
139 	memory = alloc.allocate(getBufferMemoryRequirements(vk, device, *handle), MemoryRequirement::HostVisible);
140 
141 	VK_CHECK(vk.bindBufferMemory(device, *handle, memory->getMemory(), memory->getOffset()));
142 }
143 
144 class NoneStageTestInstance : public vkt::TestInstance
145 {
146 public:
147 									NoneStageTestInstance			(Context&			context,
148 																	 const TestParams&	testParams);
149 	virtual							~NoneStageTestInstance			(void) = default;
150 
151 	tcu::TestStatus					iterate							(void) override;
152 
153 protected:
154 
155 	VkAccessFlags2KHR				getAccessFlag					(VkAccessFlags2KHR					access);
156 	VkBufferImageCopy				buildCopyRegion					(VkExtent3D							extent,
157 																	 VkImageAspectFlags					aspect);
158 	void							buildVertexBuffer				(void);
159 	Move<VkRenderPass>				buildBasicRenderPass			(VkFormat							outputFormat,
160 																	 VkImageLayout						outputLayout,
161 																	 VkAttachmentLoadOp					loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE);
162 	Move<VkRenderPass>				buildComplexRenderPass			(VkFormat							intermediateFormat,
163 																	 VkImageLayout						intermediateLayout,
164 																	 VkImageAspectFlags					intermediateAspect,
165 																	 VkFormat							outputFormat,
166 																	 VkImageLayout						outputLayout);
167 	Move<VkImageView>				buildImageView					(VkImage							image,
168 																	 VkFormat							format,
169 																	 const VkImageSubresourceRange&		subresourceRange);
170 	Move<VkFramebuffer>				buildFramebuffer				(VkRenderPass						renderPass,
171 																	 const VkImageView*					outView1,
172 																	 const VkImageView*					outView2 = DE_NULL);
173 	Move<VkSampler>					buildSampler					(void);
174 	Move<VkDescriptorSetLayout>		buildDescriptorSetLayout		(VkDescriptorType					descriptorType);
175 	Move<VkDescriptorPool>			buildDescriptorPool				(VkDescriptorType					descriptorType);
176 	Move<VkDescriptorSet>			buildDescriptorSet				(VkDescriptorPool					descriptorPool,
177 																	 VkDescriptorSetLayout				descriptorSetLayout,
178 																	 VkDescriptorType					descriptorType,
179 																	 VkImageView						inputView,
180 																	 VkImageLayout						inputLayout,
181 																	 const VkSampler*					sampler = DE_NULL);
182 	Move<VkPipeline>				buildPipeline					(deUint32							subpass,
183 																	 VkImageAspectFlags					resultAspect,
184 																	 VkPipelineLayout					pipelineLayout,
185 																	 VkShaderModule						vertShaderModule,
186 																	 VkShaderModule						fragShaderModule,
187 																	 VkRenderPass						renderPass);
188 	bool							verifyResult					(const PixelBufferAccess&			reference,
189 																	 const PixelBufferAccess&			result);
190 
191 private:
192 
193 	const TestParams				m_testParams;
194 
195 	VkFormat						m_referenceImageFormat;
196 	VkFormat						m_transitionImageFormat;
197 	VkFormat						m_readImageFormat;
198 	VkImageSubresourceRange			m_referenceSubresourceRange;
199 	VkImageSubresourceRange			m_transitionSubresourceRange;
200 	VkImageSubresourceRange			m_readSubresourceRange;
201 	VkImageAspectFlags				m_transitionImageAspect;
202 
203 	VkExtent3D						m_imageExtent;
204 	VkImageLayout					m_writeRenderPassOutputLayout;
205 
206 	// flag indicating that graphics pipeline is constructed to write data to tested image
207 	bool							m_usePipelineToWrite;
208 
209 	// flag indicating that graphics pipeline is constructed to read data from tested image
210 	bool							m_usePipelineToRead;
211 
212 	// flag indicating that write pipeline should be constructed in a special way to fill stencil buffer
213 	bool							m_useStencilDuringWrite;
214 
215 	// flag indicating that read pipeline should be constructed in a special way to use input attachment as a data source
216 	bool							m_useInputAttachmentToRead;
217 
218 	VkPipelineStageFlags2KHR		m_srcStageToNoneStageMask;
219 	VkAccessFlags2KHR				m_srcAccessToNoneAccessMask;
220 	VkPipelineStageFlags2KHR		m_dstStageFromNoneStageMask;
221 	VkAccessFlags2KHR				m_dstAccessFromNoneAccessMask;
222 
223 	SimpleAllocator					m_alloc;
224 
225 	ImageWrapper					m_referenceImage;
226 	VkImageUsageFlags				m_referenceImageUsage;
227 
228 	// objects/variables initialized only when needed
229 	ImageWrapper					m_imageToWrite;
230 	VkImageUsageFlags				m_imageToWriteUsage;
231 
232 	ImageWrapper					m_imageToRead;
233 
234 	BufferWrapper					m_vertexBuffer;
235 	std::vector<Move<VkImageView> >	m_attachmentViews;
236 
237 	std::string						m_writeFragShaderName;
238 	Move<VkShaderModule>			m_writeVertShaderModule;
239 	Move<VkShaderModule>			m_writeFragShaderModule;
240 	Move<VkRenderPass>				m_writeRenderPass;
241 	Move<VkSampler>					m_writeSampler;
242 	Move<VkDescriptorSetLayout>		m_writeDescriptorSetLayout;
243 	Move<VkDescriptorPool>			m_writeDescriptorPool;
244 	Move<VkDescriptorSet>			m_writeDescriptorSet;
245 	Move<VkPipelineLayout>			m_writePipelineLayout;
246 	Move<VkPipeline>				m_writePipeline;
247 	Move<VkFramebuffer>				m_writeFramebuffer;
248 
249 	std::string						m_readFragShaderName;
250 	Move<VkShaderModule>			m_readVertShaderModule;
251 	Move<VkShaderModule>			m_readFragShaderModule;
252 	Move<VkShaderModule>			m_readFragShaderModule2;
253 	Move<VkRenderPass>				m_readRenderPass;
254 	Move<VkSampler>					m_readSampler;
255 	Move<VkDescriptorSetLayout>		m_readDescriptorSetLayout;
256 	Move<VkDescriptorPool>			m_readDescriptorPool;
257 	Move<VkDescriptorSet>			m_readDescriptorSet;
258 	Move<VkPipelineLayout>			m_readPipelineLayout;
259 	Move<VkPipeline>				m_readPipeline;
260 	Move<VkFramebuffer>				m_readFramebuffer;
261 };
262 
NoneStageTestInstance(Context & context,const TestParams & testParams)263 NoneStageTestInstance::NoneStageTestInstance(Context& context, const TestParams& testParams)
264 	: vkt::TestInstance(context)
265 	, m_testParams		(testParams)
266 	, m_imageExtent		{ 32, 32, 1 }
267 	, m_alloc			(m_context.getDeviceInterface(),
268 		m_context.getDevice(),
269 		getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()))
270 {
271 	// note: for clarity whole configuration of whats going on in iterate method was moved here
272 
273 	const auto writeLayout	= m_testParams.writeLayout;
274 	const auto writeAspect	= m_testParams.writeAspect;
275 	const auto readLayout	= m_testParams.readLayout;
276 	const auto readAspect	= m_testParams.readAspect;
277 
278 	// When testing depth stencil combined images, the stencil aspect is only tested when depth aspect is in ATTACHMENT_OPTIMAL layout.
279 	// - it is invalid to read depth using sampler or input attachment in such layout
280 	const auto readStencilFromCombinedDepthStencil = (readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
281 
282 	// select format that will be used for test
283 	if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
284 	{
285 		m_transitionImageFormat			= VK_FORMAT_D32_SFLOAT;
286 		m_transitionImageAspect			= VK_IMAGE_ASPECT_DEPTH_BIT;
287 		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
288 	}
289 	else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
290 	{
291 		m_transitionImageFormat			= VK_FORMAT_S8_UINT;
292 		m_transitionImageAspect			= VK_IMAGE_ASPECT_STENCIL_BIT;
293 		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
294 	}
295 	else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
296 	{
297 		m_transitionImageFormat			= VK_FORMAT_D24_UNORM_S8_UINT;
298 		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
299 
300 		if (readStencilFromCombinedDepthStencil)
301 		{
302 			m_transitionImageAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
303 		}
304 		else
305 		{
306 			// note: in test we focus only on depth aspect; no need to check both in those cases
307 			m_transitionImageAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
308 		}
309 	}
310 	else
311 	{
312 		m_transitionImageFormat			= VK_FORMAT_R8G8B8A8_UNORM;
313 		m_transitionImageAspect			= VK_IMAGE_ASPECT_COLOR_BIT;
314 		m_writeRenderPassOutputLayout	= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
315 	}
316 
317 	m_referenceSubresourceRange		= { m_transitionImageAspect, 0u, 1u, 0u, 1u };
318 	m_transitionSubresourceRange	= { m_transitionImageAspect, 0u, 1u, 0u, 1u };
319 	m_readSubresourceRange			= { m_transitionImageAspect, 0u, 1u, 0u, 1u };
320 	m_referenceImageFormat			= m_transitionImageFormat;
321 	m_readImageFormat				= m_transitionImageFormat;
322 	m_referenceImageUsage			= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
323 	m_imageToWriteUsage				= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
324 
325 	// pipeline is not created for transfer and general layouts (general layouts in tests follow same path as transfer layouts)
326 	m_usePipelineToWrite	= (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
327 	m_usePipelineToRead		= (readLayout  != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout  != VK_IMAGE_LAYOUT_GENERAL);
328 	m_useStencilDuringWrite = false;
329 
330 	m_srcStageToNoneStageMask		= VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
331 	m_srcAccessToNoneAccessMask		= getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR);
332 	m_dstStageFromNoneStageMask		= VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR;
333 	m_dstAccessFromNoneAccessMask	= getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR);
334 
335 	// when graphics pipelines are not created only image with gradient is used for test
336 	if (!m_usePipelineToWrite && !m_usePipelineToRead)
337 	{
338 		m_referenceImageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
339 		return;
340 	}
341 
342 	if (m_usePipelineToWrite)
343 	{
344 		// depth/stencil layouts need diferent configuration
345 		if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
346 		{
347 			if ((writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT) && !readStencilFromCombinedDepthStencil)
348 			{
349 				m_referenceImageFormat					 = VK_FORMAT_R32_SFLOAT;
350 				m_referenceImageUsage					|= VK_IMAGE_USAGE_SAMPLED_BIT;
351 				m_referenceSubresourceRange.aspectMask	 = VK_IMAGE_ASPECT_COLOR_BIT;
352 				m_writeFragShaderName					 = "frag-color-to-depth";
353 			}
354 			else
355 			{
356 				m_referenceImageUsage					 = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
357 				m_useStencilDuringWrite					 = true;
358 				m_writeFragShaderName					 = "frag-color-to-stencil";
359 			}
360 
361 			m_srcStageToNoneStageMask		 = VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR;
362 			m_srcAccessToNoneAccessMask		 = getAccessFlag(VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR);
363 			m_imageToWriteUsage				|= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
364 		}
365 		else
366 		{
367 			m_referenceImageUsage			|= VK_IMAGE_USAGE_SAMPLED_BIT;
368 			m_srcStageToNoneStageMask		 = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR;
369 			m_srcAccessToNoneAccessMask		 = getAccessFlag(VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR);
370 			m_writeFragShaderName			 = "frag-color";
371 			m_imageToWriteUsage				|= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
372 		}
373 	}
374 
375 	if (m_usePipelineToRead)
376 	{
377 		m_dstStageFromNoneStageMask		= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR;
378 		m_dstAccessFromNoneAccessMask	= getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR);
379 
380 		m_readSubresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
381 		if (((readAspect | writeAspect) & VK_IMAGE_ASPECT_DEPTH_BIT) && !readStencilFromCombinedDepthStencil)
382 			m_readImageFormat = VK_FORMAT_R32_SFLOAT;
383 		else if ((readAspect | writeAspect) & VK_IMAGE_ASPECT_STENCIL_BIT)
384 			m_readImageFormat = VK_FORMAT_R8_UINT;
385 
386 		// for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
387 		if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
388 		{
389 			m_useInputAttachmentToRead		 = true;
390 			m_readFragShaderName			 = "frag-depth-or-stencil-to-color";
391 			m_imageToWriteUsage				|= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
392 			m_dstAccessFromNoneAccessMask	 = getAccessFlag(VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR);
393 
394 			if (!m_usePipelineToWrite)
395 				m_referenceImageUsage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
396 		}
397 		else // use image sampler for color and depth_stencil layouts
398 		{
399 			m_useInputAttachmentToRead		 = false;
400 			m_readFragShaderName			 = "frag-color";
401 			m_referenceImageUsage			|= VK_IMAGE_USAGE_SAMPLED_BIT;
402 			m_imageToWriteUsage				|= VK_IMAGE_USAGE_SAMPLED_BIT;
403 
404 			// for depth_stencil layouts we need to have depth_stencil_attachment usage
405 			if (!m_usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
406 				m_referenceImageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
407 
408 			// when we read stencil as color we need to use usampler2D
409 			if ((readAspect | writeAspect) == VK_IMAGE_ASPECT_STENCIL_BIT || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL && readStencilFromCombinedDepthStencil))
410 				m_readFragShaderName		 = "frag-stencil-to-color";
411 		}
412 	}
413 }
414 
getAccessFlag(VkAccessFlags2KHR access)415 VkAccessFlags2KHR NoneStageTestInstance::getAccessFlag(VkAccessFlags2KHR access)
416 {
417 	if (m_testParams.useGenericAccessFlags)
418 	{
419 		switch (access)
420 		{
421 		case VK_ACCESS_2_HOST_READ_BIT_KHR:
422 		case VK_ACCESS_2_TRANSFER_READ_BIT_KHR:
423 		case VK_ACCESS_2_SHADER_READ_BIT_KHR:
424 		case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
425 			return VK_ACCESS_2_MEMORY_READ_BIT_KHR;
426 
427 		case VK_ACCESS_2_HOST_WRITE_BIT_KHR:
428 		case VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR:
429 		case VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR:
430 		case VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR:
431 				return VK_ACCESS_2_MEMORY_WRITE_BIT_KHR;
432 
433 		default:
434 			TCU_THROW(TestError, "Unhandled access flag");
435 		}
436 	}
437 	return access;
438 }
439 
buildCopyRegion(VkExtent3D extent,VkImageAspectFlags aspect)440 VkBufferImageCopy NoneStageTestInstance::buildCopyRegion(VkExtent3D extent, VkImageAspectFlags aspect)
441 {
442 	return
443 	{
444 		0u,								// VkDeviceSize					bufferOffset
445 		extent.width,					// deUint32						bufferRowLength
446 		extent.height,					// deUint32						bufferImageHeight
447 		{ aspect, 0u, 0u, 1u },			// VkImageSubresourceLayers		imageSubresource
448 		{ 0, 0, 0 },					// VkOffset3D					imageOffset
449 		extent							// VkExtent3D					imageExtent
450 	};
451 }
452 
buildVertexBuffer()453 void NoneStageTestInstance::buildVertexBuffer()
454 {
455 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
456 	const VkDevice&			device	= m_context.getDevice();
457 
458 	std::vector<float> vertices
459 	{
460 		 1.0f,  1.0f, 0.0f, 1.0f,
461 		-1.0f,  1.0f, 0.0f, 1.0f,
462 		 1.0f, -1.0f, 0.0f, 1.0f,
463 		-1.0f, -1.0f, 0.0f, 1.0f,
464 	};
465 	m_vertexBuffer.create(m_context, m_alloc, sizeof(float) * vertices.size(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
466 
467 	deMemcpy(m_vertexBuffer.memory->getHostPtr(), vertices.data(), vertices.size() * sizeof(float));
468 	flushAlloc(vk, device, *m_vertexBuffer.memory);
469 }
470 
buildBasicRenderPass(VkFormat outputFormat,VkImageLayout outputLayout,VkAttachmentLoadOp loadOp)471 Move<VkRenderPass> NoneStageTestInstance::buildBasicRenderPass(VkFormat outputFormat, VkImageLayout outputLayout, VkAttachmentLoadOp loadOp)
472 {
473 	// output color/depth attachment
474 	VkAttachmentDescription2 attachmentDescription
475 	{
476 		VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
477 		DE_NULL,												// const void*						pNext
478 		(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
479 		outputFormat,											// VkFormat							format
480 		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
481 		loadOp,													// VkAttachmentLoadOp				loadOp
482 		VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
483 		loadOp,													// VkAttachmentLoadOp				stencilLoadOp
484 		VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp
485 		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout
486 		outputLayout											// VkImageLayout					finalLayout
487 	};
488 
489 	VkImageAspectFlags		imageAspect		= getImageAspectFlags(mapVkFormat(outputFormat));
490 	VkAttachmentReference2	attachmentRef
491 	{
492 		VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, outputLayout, imageAspect
493 	};
494 
495 	VkAttachmentReference2* pColorAttachment			= DE_NULL;
496 	VkAttachmentReference2* pDepthStencilAttachment		= DE_NULL;
497 	if (imageAspect == VK_IMAGE_ASPECT_COLOR_BIT)
498 		pColorAttachment = &attachmentRef;
499 	else
500 		pDepthStencilAttachment = &attachmentRef;
501 
502 	VkSubpassDescription2 subpassDescription
503 	{
504 		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
505 		DE_NULL,
506 		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags		flags
507 		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint				pipelineBindPoint
508 		0u,														// deUint32							viewMask
509 		0u,														// deUint32							inputAttachmentCount
510 		DE_NULL,												// const VkAttachmentReference2*	pInputAttachments
511 		!!pColorAttachment,										// deUint32							colorAttachmentCount
512 		pColorAttachment,										// const VkAttachmentReference2*	pColorAttachments
513 		DE_NULL,												// const VkAttachmentReference2*	pResolveAttachments
514 		pDepthStencilAttachment,								// const VkAttachmentReference2*	pDepthStencilAttachment
515 		0u,														// deUint32							preserveAttachmentCount
516 		DE_NULL													// const deUint32*					pPreserveAttachments
517 	};
518 
519 	const VkRenderPassCreateInfo2 renderPassInfo
520 	{
521 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
522 		DE_NULL,												// const void*						pNext
523 		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
524 		1u,														// deUint32							attachmentCount
525 		&attachmentDescription,									// const VkAttachmentDescription*	pAttachments
526 		1u,														// deUint32							subpassCount
527 		&subpassDescription,									// const VkSubpassDescription*		pSubpasses
528 		0u,														// deUint32							dependencyCount
529 		DE_NULL,												// const VkSubpassDependency*		pDependencies
530 		0u,														// deUint32							correlatedViewMaskCount
531 		DE_NULL													// const deUint32*					pCorrelatedViewMasks
532 	};
533 
534 	return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
535 }
536 
buildComplexRenderPass(VkFormat intermediateFormat,VkImageLayout intermediateLayout,VkImageAspectFlags intermediateAspect,VkFormat outputFormat,VkImageLayout outputLayout)537 Move<VkRenderPass> NoneStageTestInstance::buildComplexRenderPass(VkFormat intermediateFormat,	VkImageLayout intermediateLayout, VkImageAspectFlags intermediateAspect,
538 																 VkFormat outputFormat,			VkImageLayout outputLayout)
539 {
540 	std::vector<VkAttachmentDescription2> attachmentDescriptions
541 	{
542 		// depth/stencil attachment (when used in read pipeline it loads data filed in write pipeline)
543 		{
544 			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
545 			DE_NULL,												// const void*						pNext
546 			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
547 			intermediateFormat,										// VkFormat							format
548 			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
549 			VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp				loadOp
550 			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
551 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp
552 			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp
553 			intermediateLayout,										// VkImageLayout					initialLayout
554 			intermediateLayout										// VkImageLayout					finalLayout
555 		},
556 		// color attachment
557 		{
558 			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
559 			DE_NULL,												// const void*						pNext
560 			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
561 			outputFormat,											// VkFormat							format
562 			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
563 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				loadOp
564 			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
565 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp
566 			VK_ATTACHMENT_STORE_OP_DONT_CARE,						// VkAttachmentStoreOp				stencilStoreOp
567 			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout
568 			outputLayout											// VkImageLayout					finalLayout
569 		}
570 	};
571 
572 	VkImageAspectFlags					outputAspect		= getImageAspectFlags(mapVkFormat(outputFormat));
573 	std::vector<VkAttachmentReference2>	attachmentRefs
574 	{
575 		{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, intermediateLayout, intermediateAspect },
576 		{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 1u, outputLayout, outputAspect }
577 	};
578 
579 	VkAttachmentReference2* pDepthStencilAttachment = &attachmentRefs[0];
580 	VkAttachmentReference2* pColorAttachment		= &attachmentRefs[1];
581 
582 	std::vector<VkSubpassDescription2> subpassDescriptions
583 	{
584 		{
585 			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
586 			DE_NULL,
587 			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags
588 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint
589 			0u,													// deUint32							viewMask
590 			1u,													// deUint32							inputAttachmentCount
591 			pDepthStencilAttachment,							// const VkAttachmentReference2*	pInputAttachments
592 			1u,													// deUint32							colorAttachmentCount
593 			pColorAttachment,									// const VkAttachmentReference2*	pColorAttachments
594 			DE_NULL,											// const VkAttachmentReference2*	pResolveAttachments
595 			DE_NULL,											// const VkAttachmentReference2*	pDepthStencilAttachment
596 			0u,													// deUint32							preserveAttachmentCount
597 			DE_NULL												// deUint32*						pPreserveAttachments
598 		}
599 	};
600 
601 	const VkRenderPassCreateInfo2 renderPassInfo
602 	{
603 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
604 		DE_NULL,												// const void*						pNext
605 		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
606 		(deUint32)attachmentDescriptions.size(),				// deUint32							attachmentCount
607 		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments
608 		(deUint32)subpassDescriptions.size(),					// deUint32							subpassCount
609 		subpassDescriptions.data(),								// const VkSubpassDescription*		pSubpasses
610 		0u,														// deUint32							dependencyCount
611 		DE_NULL,												// const VkSubpassDependency*		pDependencies
612 		0u,														// deUint32							correlatedViewMaskCount
613 		DE_NULL													// const deUint32*					pCorrelatedViewMasks
614 	};
615 
616 	return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
617 }
618 
buildImageView(VkImage image,VkFormat format,const VkImageSubresourceRange & subresourceRange)619 Move<VkImageView> NoneStageTestInstance::buildImageView(VkImage image, VkFormat format, const VkImageSubresourceRange& subresourceRange)
620 {
621 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
622 	const VkDevice&			device	= m_context.getDevice();
623 
624 	const VkImageViewCreateInfo imageViewParams
625 	{
626 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType				sType
627 		DE_NULL,												// const void*					pNext
628 		0u,														// VkImageViewCreateFlags		flags
629 		image,													// VkImage						image
630 		VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType				viewType
631 		format,													// VkFormat						format
632 		makeComponentMappingRGBA(),								// VkComponentMapping			components
633 		subresourceRange,										// VkImageSubresourceRange		subresourceRange
634 	};
635 
636 	return createImageView(vk, device, &imageViewParams);
637 }
638 
buildFramebuffer(VkRenderPass renderPass,const VkImageView * outView1,const VkImageView * outView2)639 Move<VkFramebuffer> NoneStageTestInstance::buildFramebuffer(VkRenderPass renderPass, const VkImageView* outView1, const VkImageView* outView2)
640 {
641 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
642 	const VkDevice&			device	= m_context.getDevice();
643 
644 	std::vector<VkImageView> imageViews = { *outView1 };
645 	if (outView2)
646 		imageViews.push_back(*outView2);
647 
648 	const VkFramebufferCreateInfo framebufferParams
649 	{
650 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// VkStructureType				sType
651 		DE_NULL,												// const void*					pNext
652 		0u,														// VkFramebufferCreateFlags		flags
653 		renderPass,												// VkRenderPass					renderPass
654 		(deUint32)imageViews.size(),							// deUint32						attachmentCount
655 		imageViews.data(),										// const VkImageView*			pAttachments
656 		m_imageExtent.width,									// deUint32						width
657 		m_imageExtent.height,									// deUint32						height
658 		1u,														// deUint32						layers
659 	};
660 	return createFramebuffer(vk, device, &framebufferParams);
661 }
662 
buildSampler()663 Move<VkSampler> NoneStageTestInstance::buildSampler()
664 {
665 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
666 	const VkDevice&			device	= m_context.getDevice();
667 
668 	const VkSamplerCreateInfo samplerInfo
669 	{
670 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,					// VkStructureType				sType
671 		DE_NULL,												// const void*					pNext
672 		0u,														// VkSamplerCreateFlags			flags
673 		VK_FILTER_NEAREST,										// VkFilter						magFilter
674 		VK_FILTER_NEAREST,										// VkFilter						minFilter
675 		VK_SAMPLER_MIPMAP_MODE_NEAREST,							// VkSamplerMipmapMode			mipmapMode
676 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeU
677 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeV
678 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeW
679 		0.0f,													// float						mipLodBias
680 		VK_FALSE,												// VkBool32						anisotropyEnable
681 		1.0f,													// float						maxAnisotropy
682 		DE_FALSE,												// VkBool32						compareEnable
683 		VK_COMPARE_OP_ALWAYS,									// VkCompareOp					compareOp
684 		0.0f,													// float						minLod
685 		0.0f,													// float						maxLod
686 		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,				// VkBorderColor				borderColor
687 		VK_FALSE,												// VkBool32						unnormalizedCoords
688 	};
689 	return createSampler(vk, device, &samplerInfo);
690 }
691 
buildDescriptorSetLayout(VkDescriptorType descriptorType)692 Move<VkDescriptorSetLayout> NoneStageTestInstance::buildDescriptorSetLayout(VkDescriptorType descriptorType)
693 {
694 	const DeviceInterface&		vk		= m_context.getDeviceInterface();
695 	const VkDevice&				device	= m_context.getDevice();
696 
697 	return
698 		DescriptorSetLayoutBuilder()
699 		.addSingleSamplerBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
700 		.build(vk, device);
701 }
702 
buildDescriptorPool(VkDescriptorType descriptorType)703 Move<VkDescriptorPool> NoneStageTestInstance::buildDescriptorPool(VkDescriptorType descriptorType)
704 {
705 	const DeviceInterface&		vk		= m_context.getDeviceInterface();
706 	const VkDevice&				device	= m_context.getDevice();
707 
708 	return
709 		DescriptorPoolBuilder()
710 		.addType(descriptorType, 1u)
711 		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
712 }
713 
buildDescriptorSet(VkDescriptorPool descriptorPool,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorType descriptorType,VkImageView inputView,VkImageLayout inputLayout,const VkSampler * sampler)714 Move<VkDescriptorSet> NoneStageTestInstance::buildDescriptorSet(VkDescriptorPool		descriptorPool,
715 																VkDescriptorSetLayout	descriptorSetLayout,
716 																VkDescriptorType		descriptorType,
717 																VkImageView				inputView,
718 																VkImageLayout			inputLayout,
719 																const VkSampler*		sampler)
720 {
721 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
722 	const VkDevice&				device			= m_context.getDevice();
723 
724 	const VkDescriptorImageInfo inputImageInfo	= makeDescriptorImageInfo(sampler ? *sampler : 0u, inputView, inputLayout);
725 	Move<VkDescriptorSet>		descriptorSet	= makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout);
726 
727 	DescriptorSetUpdateBuilder()
728 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &inputImageInfo)
729 		.update(vk, device);
730 
731 	return descriptorSet;
732 }
733 
buildPipeline(deUint32 subpass,VkImageAspectFlags resultAspect,VkPipelineLayout pipelineLayout,VkShaderModule vertShaderModule,VkShaderModule fragShaderModule,VkRenderPass renderPass)734 Move<VkPipeline> NoneStageTestInstance::buildPipeline(deUint32				subpass,
735 													  VkImageAspectFlags	resultAspect,
736 													  VkPipelineLayout		pipelineLayout,
737 													  VkShaderModule		vertShaderModule,
738 													  VkShaderModule		fragShaderModule,
739 													  VkRenderPass			renderPass)
740 {
741 	const DeviceInterface&			vk				= m_context.getDeviceInterface();
742 	const VkDevice&					device			= m_context.getDevice();
743 	const std::vector<VkViewport>	viewports		{ makeViewport(m_imageExtent) };
744 	const std::vector<VkRect2D>		scissors		{ makeRect2D(m_imageExtent) };
745 	const bool						useDepth		= resultAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
746 	const bool						useStencil		= resultAspect & VK_IMAGE_ASPECT_STENCIL_BIT;
747 
748 	const VkStencilOpState stencilOpState = makeStencilOpState(
749 		VK_STENCIL_OP_REPLACE,											// stencil fail
750 		VK_STENCIL_OP_REPLACE,											// depth & stencil pass
751 		VK_STENCIL_OP_REPLACE,											// depth only fail
752 		VK_COMPARE_OP_ALWAYS,											// compare op
753 		1u,																// compare mask
754 		1u,																// write mask
755 		1u);															// reference
756 
757 	const VkPipelineDepthStencilStateCreateInfo	depthStencilStateCreateInfo
758 	{
759 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType								sType
760 		DE_NULL,														// const void*									pNext
761 		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags		flags
762 		useDepth,														// VkBool32										depthTestEnable
763 		useDepth,														// VkBool32										depthWriteEnable
764 		VK_COMPARE_OP_ALWAYS,											// VkCompareOp									depthCompareOp
765 		VK_FALSE,														// VkBool32										depthBoundsTestEnable
766 		useStencil,														// VkBool32										stencilTestEnable
767 		stencilOpState,													// VkStencilOpState								front
768 		stencilOpState,													// VkStencilOpState								back
769 		0.0f,															// float										minDepthBounds
770 		1.0f,															// float										maxDepthBounds
771 	};
772 
773 	return makeGraphicsPipeline(
774 		vk,																// DeviceInterface&								vk
775 		device,															// VkDevice										device
776 		pipelineLayout,													// VkPipelineLayout								pipelineLayout
777 		vertShaderModule,												// VkShaderModule								vertexShaderModule
778 		DE_NULL,														// VkShaderModule								tessellationControlModule
779 		DE_NULL,														// VkShaderModule								tessellationEvalModule
780 		DE_NULL,														// VkShaderModule								geometryShaderModule
781 		fragShaderModule,												// VkShaderModule								fragmentShaderModule
782 		renderPass,														// VkRenderPass									renderPass
783 		viewports,														// std::vector<VkViewport>&						viewports
784 		scissors,														// std::vector<VkRect2D>&						scissors
785 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology							topology
786 		subpass,														// deUint32										subpass
787 		0u,																// deUint32										patchControlPoints
788 		DE_NULL,														// VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
789 		DE_NULL,														// VkPipelineRasterizationStateCreateInfo*		rasterizationStateCreateInfo
790 		DE_NULL,														// VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
791 		&depthStencilStateCreateInfo);									// VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
792 }
793 
iterate(void)794 tcu::TestStatus NoneStageTestInstance::iterate(void)
795 {
796 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
797 	const VkDevice&				device					= m_context.getDevice();
798 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
799 	VkQueue						queue					= m_context.getUniversalQueue();
800 	Move<VkCommandPool>			cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
801 	Move<VkCommandBuffer>		cmdBuffer				= makeCommandBuffer(vk, device, *cmdPool);
802 	const VkDeviceSize			vertexBufferOffset		= 0;
803 	ImageWrapper*				transitionImagePtr		= &m_referenceImage;
804 	ImageWrapper*				imageToVerifyPtr		= &m_referenceImage;
805 	const deUint32				imageSizeInBytes		= m_imageExtent.width * m_imageExtent.height * 4;
806 	SynchronizationWrapperPtr	synchronizationWrapper	= getSynchronizationWrapper(m_testParams.type, vk, false);
807 	const VkRect2D				renderArea				= makeRect2D(0, 0, m_imageExtent.width, m_imageExtent.height);
808 	const VkBufferImageCopy		transitionCopyRegion	= buildCopyRegion(m_imageExtent, m_transitionImageAspect);
809 	const VkBufferImageCopy		colorCopyRegion			= buildCopyRegion(m_imageExtent, VK_IMAGE_ASPECT_COLOR_BIT);
810 
811 	// create image that will have gradient (without data atm)
812 	m_referenceImage.create(m_context, m_alloc, m_referenceImageFormat, m_imageExtent, m_referenceImageUsage);
813 
814 	// create buffer used for gradient data source
815 	BufferWrapper srcBuffer;
816 	srcBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
817 
818 	// generate gradient
819 	std::vector<deUint32>	referenceData	(m_imageExtent.width * m_imageExtent.height);
820 	tcu::TextureFormat		referenceFormat	(mapVkFormat(m_referenceImageFormat));
821 	if (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
822 	{
823 		// when testing stencil aspect of depth stencil combined image, prepare reference date only with stencil,
824 		// as the copy operation (used when m_usePipelineToWrite == false) sources just one aspect
825 
826 		// this format is used for tcu operations only - does not need to be supported by the Vulkan implementation
827 		referenceFormat = mapVkFormat(VK_FORMAT_S8_UINT);
828 	}
829 	PixelBufferAccess		referencePBA	(referenceFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, referenceData.data());
830 	fillWithComponentGradients(referencePBA, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
831 	deMemcpy(srcBuffer.memory->getHostPtr(), referenceData.data(), static_cast<size_t>(imageSizeInBytes));
832 	flushAlloc(vk, device, *srcBuffer.memory);
833 
834 	// create buffer for result transfer
835 	BufferWrapper			dstBuffer;
836 	tcu::TextureFormat		resultFormat	(mapVkFormat(m_readImageFormat));
837 	dstBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
838 
839 	if (m_usePipelineToWrite || m_usePipelineToRead)
840 	{
841 		buildVertexBuffer();
842 
843 		// create image view for reference image (its always at index 0)
844 		m_attachmentViews.push_back(buildImageView(*m_referenceImage.handle, m_referenceImageFormat, m_referenceSubresourceRange));
845 
846 		// create graphics pipeline used to write image data
847 		if (m_usePipelineToWrite)
848 		{
849 			// create image that will be used as attachment to write to
850 			m_imageToWrite.create(m_context, m_alloc, m_transitionImageFormat, m_imageExtent, m_imageToWriteUsage);
851 			m_attachmentViews.push_back(buildImageView(*m_imageToWrite.handle, m_transitionImageFormat, m_transitionSubresourceRange));
852 
853 			m_writeVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
854 			m_writeFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_writeFragShaderName), 0);
855 
856 			if (m_useStencilDuringWrite)
857 			{
858 				// this is used only for cases where writable layout is VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL
859 				// in this case generated gradient is only used for verification
860 				m_writeRenderPass			= buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout, VK_ATTACHMENT_LOAD_OP_CLEAR);
861 				m_writePipelineLayout		= makePipelineLayout(vk, device, DE_NULL);
862 				m_writePipeline				= buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
863 															*m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
864 				m_writeFramebuffer			= buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
865 			}
866 			else
867 			{
868 				m_writeRenderPass			= buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout);
869 				m_writeSampler				= buildSampler();
870 				m_writeDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
871 				m_writeDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
872 				m_writeDescriptorSet		= buildDescriptorSet(*m_writeDescriptorPool, *m_writeDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
873 																 *m_attachmentViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_writeSampler.get());
874 				m_writePipelineLayout		= makePipelineLayout(vk, device, *m_writeDescriptorSetLayout);
875 				m_writePipeline				= buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
876 															*m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
877 				m_writeFramebuffer			= buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
878 			}
879 
880 			transitionImagePtr	= &m_imageToWrite;
881 			imageToVerifyPtr	= &m_imageToWrite;
882 		}
883 
884 		// create graphics pipeline used to read image data
885 		if (m_usePipelineToRead)
886 		{
887 			m_imageToRead.create(m_context, m_alloc, m_readImageFormat, m_imageExtent, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
888 			m_attachmentViews.push_back(buildImageView(*m_imageToRead.handle, m_readImageFormat, m_readSubresourceRange));
889 			imageToVerifyPtr = &m_imageToRead;
890 
891 			m_readVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
892 			m_readFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_readFragShaderName), 0);
893 
894 			if (m_useInputAttachmentToRead)
895 			{
896 				m_readDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
897 				m_readDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
898 				m_readDescriptorSet			= buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
899 																 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout);
900 				m_readRenderPass			= buildComplexRenderPass(m_transitionImageFormat, m_testParams.readLayout, m_transitionImageAspect,
901 																	 m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
902 				m_readFramebuffer			= buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite].get(),
903 																				  &m_attachmentViews[m_usePipelineToWrite+1].get());
904 				m_readPipelineLayout		= makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
905 				m_readPipeline				= buildPipeline(0u, VK_IMAGE_ASPECT_COLOR_BIT, *m_readPipelineLayout,
906 															*m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
907 			}
908 			else
909 			{
910 				m_readSampler				= buildSampler();
911 				m_readDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
912 				m_readDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
913 				m_readDescriptorSet			= buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
914 																 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout, &m_readSampler.get());
915 				m_readRenderPass			= buildBasicRenderPass(m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
916 				m_readFramebuffer			= buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite + 1].get());
917 				m_readPipelineLayout		= makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
918 				m_readPipeline				= buildPipeline(0u, m_transitionImageAspect, *m_readPipelineLayout,
919 															*m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
920 			}
921 		}
922 	}
923 
924 	beginCommandBuffer(vk, *cmdBuffer);
925 
926 	// write data from buffer with gradient to image (for stencil_attachment cases we dont need to do that)
927 	if (!m_useStencilDuringWrite)
928 	{
929 		// wait for reference data to be in buffer
930 		const VkBufferMemoryBarrier2KHR preBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
931 			VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			srcStageMask
932 			getAccessFlag(VK_ACCESS_2_HOST_WRITE_BIT_KHR),		// VkAccessFlags2KHR				srcAccessMask
933 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			dstStageMask
934 			getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),	// VkAccessFlags2KHR				dstAccessMask
935 			*srcBuffer.handle,									// VkBuffer							buffer
936 			0u,													// VkDeviceSize						offset
937 			imageSizeInBytes									// VkDeviceSize						size
938 		);
939 
940 		VkImageLayout copyBufferToImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
941 		if(m_testParams.writeLayout == VK_IMAGE_LAYOUT_GENERAL)
942 			copyBufferToImageLayout = VK_IMAGE_LAYOUT_GENERAL;
943 
944 		// change image layout so that we can copy to it data from buffer
945 		const VkImageMemoryBarrier2KHR preImageMemoryBarrier2 = makeImageMemoryBarrier2(
946 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
947 			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
948 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			dstStageMask
949 			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				dstAccessMask
950 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					oldLayout
951 			copyBufferToImageLayout,							// VkImageLayout					newLayout
952 			*m_referenceImage.handle,							// VkImage							image
953 			m_referenceSubresourceRange							// VkImageSubresourceRange			subresourceRange
954 		);
955 		VkDependencyInfoKHR buffDependencyInfo = makeCommonDependencyInfo(DE_NULL, &preBufferMemoryBarrier2, &preImageMemoryBarrier2);
956 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &buffDependencyInfo);
957 
958 		const VkBufferImageCopy* copyRegion = m_usePipelineToWrite ? &colorCopyRegion : &transitionCopyRegion;
959 		vk.cmdCopyBufferToImage(*cmdBuffer, *srcBuffer.handle, *m_referenceImage.handle, copyBufferToImageLayout, 1u, copyRegion);
960 	}
961 
962 	if (m_usePipelineToWrite)
963 	{
964 		// wait till data is transfered to image (in all cases except when stencil_attachment is tested)
965 		if (!m_useStencilDuringWrite)
966 		{
967 			const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
968 				VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
969 				getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
970 				VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR,		// VkPipelineStageFlags2KHR			dstStageMask
971 				getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
972 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout					oldLayout
973 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,			// VkImageLayout					newLayout
974 				*m_referenceImage.handle,							// VkImage							image
975 				m_referenceSubresourceRange							// VkImageSubresourceRange			subresourceRange
976 			);
977 			VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
978 			synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
979 		}
980 
981 		beginRenderPass(vk, *cmdBuffer, *m_writeRenderPass, *m_writeFramebuffer, renderArea, tcu::Vec4(0.0f ,0.0f, 0.0f, 1.0f));
982 
983 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipeline);
984 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
985 		if (m_useStencilDuringWrite)
986 		{
987 			// when writing to stencil buffer draw single triangle (to simulate gradient over 1bit)
988 			vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
989 		}
990 		else
991 		{
992 			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipelineLayout, 0, 1, &m_writeDescriptorSet.get(), 0, DE_NULL);
993 			vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
994 		}
995 
996 		endRenderPass(vk, *cmdBuffer);
997 	}
998 
999 	// use none stage to wait till data is transfered to image
1000 	{
1001 		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1002 			m_srcStageToNoneStageMask,							// VkPipelineStageFlags2KHR			srcStageMask
1003 			m_srcAccessToNoneAccessMask,						// VkAccessFlags2KHR				srcAccessMask
1004 			VK_PIPELINE_STAGE_2_NONE_KHR,						// VkPipelineStageFlags2KHR			dstStageMask
1005 			VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				dstAccessMask
1006 			m_testParams.writeLayout,							// VkImageLayout					oldLayout
1007 			m_testParams.writeLayout,							// VkImageLayout					newLayout
1008 			*transitionImagePtr->handle,						// VkImage							image
1009 			m_transitionSubresourceRange						// VkImageSubresourceRange			subresourceRange
1010 		);
1011 		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1012 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1013 	}
1014 
1015 	// use all commands stage to change image layout
1016 	{
1017 		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1018 			VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR,			// VkPipelineStageFlags2KHR			srcStageMask
1019 			VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				srcAccessMask
1020 			m_dstStageFromNoneStageMask,						// VkPipelineStageFlags2KHR			dstStageMask
1021 			m_dstAccessFromNoneAccessMask,						// VkAccessFlags2KHR				dstAccessMask
1022 			m_testParams.writeLayout,							// VkImageLayout					oldLayout
1023 			m_testParams.readLayout,							// VkImageLayout					newLayout
1024 			*transitionImagePtr->handle,						// VkImage							image
1025 			m_transitionSubresourceRange						// VkImageSubresourceRange			subresourceRange
1026 		);
1027 		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1028 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1029 	}
1030 
1031 	VkImageLayout copyImageToBufferLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1032 	if (m_testParams.readLayout == VK_IMAGE_LAYOUT_GENERAL)
1033 		copyImageToBufferLayout = VK_IMAGE_LAYOUT_GENERAL;
1034 
1035 	if (m_usePipelineToRead)
1036 	{
1037 		beginRenderPass(vk, *cmdBuffer, *m_readRenderPass, *m_readFramebuffer, renderArea);
1038 
1039 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipeline);
1040 		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipelineLayout, 0, 1, &m_readDescriptorSet.get(), 0, DE_NULL);
1041 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
1042 		vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
1043 
1044 		endRenderPass(vk, *cmdBuffer);
1045 
1046 		// wait till data is transfered to image
1047 		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1048 			VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,	// VkPipelineStageFlags2KHR			srcStageMask
1049 			VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR,				// VkAccessFlags2KHR				srcAccessMask
1050 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
1051 			getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
1052 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout					oldLayout
1053 			copyImageToBufferLayout,								// VkImageLayout					newLayout
1054 			*imageToVerifyPtr->handle,								// VkImage							image
1055 			m_readSubresourceRange									// VkImageSubresourceRange			subresourceRange
1056 		);
1057 		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1058 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1059 	}
1060 
1061 	// read back image
1062 	{
1063 		const VkBufferImageCopy* copyRegion = m_usePipelineToRead ? &colorCopyRegion : &transitionCopyRegion;
1064 		vk.cmdCopyImageToBuffer(*cmdBuffer, *imageToVerifyPtr->handle, copyImageToBufferLayout, *dstBuffer.handle, 1u, copyRegion);
1065 
1066 		const VkBufferMemoryBarrier2KHR postBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
1067 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
1068 			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
1069 			VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
1070 			getAccessFlag(VK_ACCESS_2_HOST_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
1071 			*dstBuffer.handle,									// VkBuffer							buffer
1072 			0u,													// VkDeviceSize						offset
1073 			imageSizeInBytes									// VkDeviceSize						size
1074 		);
1075 		VkDependencyInfoKHR bufDependencyInfo = makeCommonDependencyInfo(DE_NULL, &postBufferMemoryBarrier2);
1076 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &bufDependencyInfo);
1077 	}
1078 
1079 	endCommandBuffer(vk, *cmdBuffer);
1080 
1081 	Move<VkFence>					fence			= createFence(vk, device);
1082 	VkCommandBufferSubmitInfoKHR	cmdBuffersInfo	= makeCommonCommandBufferSubmitInfo(*cmdBuffer);
1083 	synchronizationWrapper->addSubmitInfo(0u, DE_NULL, 1u, &cmdBuffersInfo, 0u, DE_NULL);
1084 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
1085 	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), VK_TRUE, ~0ull));
1086 
1087 	// read image data
1088 	invalidateAlloc(vk, device, *dstBuffer.memory);
1089 	PixelBufferAccess resultPBA(resultFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, dstBuffer.memory->getHostPtr());
1090 
1091 	// if result/reference is depth-stencil format then focus only on tested component
1092 	if (isCombinedDepthStencilType(referenceFormat.type))
1093 		referencePBA = getEffectiveDepthStencilAccess(referencePBA, (m_referenceSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1094 	if (isCombinedDepthStencilType(resultFormat.type))
1095 		resultPBA = getEffectiveDepthStencilAccess(resultPBA, (m_readSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1096 
1097 	if (verifyResult(referencePBA, resultPBA))
1098 		return TestStatus::pass("Pass");
1099 	return TestStatus::fail("Fail");
1100 }
1101 
verifyResult(const PixelBufferAccess & reference,const PixelBufferAccess & result)1102 bool NoneStageTestInstance::verifyResult(const PixelBufferAccess& reference, const PixelBufferAccess& result)
1103 {
1104 	TestLog& log = m_context.getTestContext().getLog();
1105 
1106 	const auto forceStencil = (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
1107 
1108 	if (isIntFormat(m_referenceImageFormat) || isUintFormat(m_referenceImageFormat) || forceStencil)
1109 	{
1110 		// special case for stencil (1bit gradient - top-left of image is 0, bottom-right is 1)
1111 
1112 		bool				isResultCorrect = true;
1113 		TextureLevel		errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8),
1114 											 m_imageExtent.width, m_imageExtent.height, 1);
1115 		PixelBufferAccess	errorMask		= errorMaskStorage.getAccess();
1116 
1117 		for (deUint32 y = 0; y < m_imageExtent.height; y++)
1118 			for (deUint32 x = 0; x < m_imageExtent.width; x++)
1119 			{
1120 				// skip textels on diagonal (gradient lights texels on diagonal and stencil operation in test does not)
1121 				if ((x + y) == (m_imageExtent.width - 1))
1122 				{
1123 					errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, 0);
1124 					continue;
1125 				}
1126 
1127 				IVec4	refPix = reference.getPixelInt(x, y, 0);
1128 				IVec4	cmpPix = result.getPixelInt(x, y, 0);
1129 				bool	isOk = (refPix[0] == cmpPix[0]);
1130 				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, 0);
1131 				isResultCorrect &= isOk;
1132 			}
1133 
1134 		Vec4 pixelBias(0.0f);
1135 		Vec4 pixelScale(1.0f);
1136 		if (isResultCorrect)
1137 		{
1138 			log << TestLog::ImageSet("Image comparison", "")
1139 				<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1140 				<< TestLog::EndImageSet;
1141 			return true;
1142 		}
1143 
1144 		log << TestLog::ImageSet("Image comparison", "")
1145 			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1146 			<< TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
1147 			<< TestLog::Image("ErrorMask", "Error mask", errorMask)
1148 			<< TestLog::EndImageSet;
1149 		return false;
1150 	}
1151 
1152 	return floatThresholdCompare(log, "Image comparison", "", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1153 }
1154 
1155 class NoneStageTestCase : public vkt::TestCase
1156 {
1157 public:
1158 							NoneStageTestCase		(tcu::TestContext&		testContext,
1159 													 const std::string&		name,
1160 													 const TestParams&		testParams);
1161 							~NoneStageTestCase		(void) = default;
1162 
1163 	void					initPrograms			(SourceCollections&		sourceCollections) const override;
1164 	TestInstance*			createInstance			(Context&				context) const override;
1165 	void					checkSupport			(Context&				context) const override;
1166 
1167 private:
1168 	const TestParams		m_testParams;
1169 };
1170 
NoneStageTestCase(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)1171 NoneStageTestCase::NoneStageTestCase(tcu::TestContext&	testContext, const std::string&	name, const TestParams&	testParams)
1172 	: vkt::TestCase	(testContext, name, "")
1173 	, m_testParams	(testParams)
1174 {
1175 }
1176 
initPrograms(SourceCollections & sourceCollections) const1177 void NoneStageTestCase::initPrograms(SourceCollections& sourceCollections) const
1178 {
1179 	const auto writeLayout	= m_testParams.writeLayout;
1180 	const auto writeAspect	= m_testParams.writeAspect;
1181 	const auto readLayout	= m_testParams.readLayout;
1182 	const auto readAspect	= m_testParams.readAspect;
1183 
1184 	// for tests that use only transfer and general layouts we don't create pipeline
1185 	if (((writeLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) || (readLayout == VK_IMAGE_LAYOUT_GENERAL)) &&
1186 		((writeLayout == VK_IMAGE_LAYOUT_GENERAL) || (readLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)))
1187 		return;
1188 
1189 	sourceCollections.glslSources.add("vert") << glu::VertexSource(
1190 		"#version 450\n"
1191 		"layout(location = 0) in  vec4 inPosition;\n"
1192 		"layout(location = 0) out vec2 outUV;\n"
1193 		"void main(void)\n"
1194 		"{\n"
1195 		"  outUV = vec2(inPosition.x * 0.5 + 0.5, inPosition.y * 0.5 + 0.5);\n"
1196 		"  gl_Position = inPosition;\n"
1197 		"}\n"
1198 	);
1199 
1200 	sourceCollections.glslSources.add("frag-color") << glu::FragmentSource(
1201 		"#version 450\n"
1202 		"layout(binding = 0) uniform sampler2D u_sampler;\n"
1203 		"layout(location = 0) in vec2 inUV;\n"
1204 		"layout(location = 0) out vec4 fragColor;\n"
1205 		"void main(void)\n"
1206 		"{\n"
1207 		"  fragColor = texture(u_sampler, inUV);\n"
1208 		"}\n"
1209 	);
1210 
1211 	if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1212 	{
1213 		sourceCollections.glslSources.add("frag-color-to-depth") << glu::FragmentSource(
1214 			"#version 450\n"
1215 			"layout(binding = 0) uniform sampler2D u_sampler;\n"
1216 			"layout(location = 0) in vec2 inUV;\n"
1217 			"void main(void)\n"
1218 			"{\n"
1219 			"  gl_FragDepth = texture(u_sampler, inUV).r;\n"
1220 			"}\n"
1221 		);
1222 	}
1223 
1224 	if (writeAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
1225 	{
1226 		sourceCollections.glslSources.add("frag-color-to-stencil") << glu::FragmentSource(
1227 			"#version 450\n"
1228 			"void main(void)\n"
1229 			"{\n"
1230 			"}\n"
1231 		);
1232 	}
1233 	if ((readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) &&
1234 		(readLayout != VK_IMAGE_LAYOUT_GENERAL) &&
1235 		((readAspect | writeAspect) == VK_IMAGE_ASPECT_STENCIL_BIT || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL && m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)))
1236 	{
1237 		// use usampler2D and uvec4 for color
1238 		sourceCollections.glslSources.add("frag-stencil-to-color") << glu::FragmentSource(
1239 			"#version 450\n"
1240 			"layout(binding = 0) uniform usampler2D u_sampler;\n"
1241 			"layout(location = 0) in vec2 inUV;\n"
1242 			"layout(location = 0) out uvec4 fragColor;\n"
1243 			"void main(void)\n"
1244 			"{\n"
1245 			"  fragColor = texture(u_sampler, inUV);\n"
1246 			"}\n"
1247 		);
1248 	}
1249 
1250 	if (readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1251 	{
1252 		// for stencil only cases we need to use usubpassInput (for depth and depth_stencil we need to use subpassInput)
1253 		const bool									readDepth			= readAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
1254 		const std::map<std::string, std::string>	specializations
1255 		{
1256 			{ "SUBPASS_INPUT",	(readDepth ? "subpassInput"	: "usubpassInput")	},
1257 			{ "VALUE_TYPE",		(readDepth ? "float"		: "uint")			}
1258 		};
1259 
1260 		std::string source =
1261 			"#version 450\n"
1262 			"layout (input_attachment_index = 0, binding = 0) uniform ${SUBPASS_INPUT} depthOrStencilInput;\n"
1263 			"layout(location = 0) in vec2 inUV;\n"
1264 			"layout(location = 0) out ${VALUE_TYPE} fragColor;\n"
1265 			"void main (void)\n"
1266 			"{\n"
1267 			"  fragColor = subpassLoad(depthOrStencilInput).x;\n"
1268 			"}\n";
1269 		sourceCollections.glslSources.add("frag-depth-or-stencil-to-color")
1270 			<< glu::FragmentSource(tcu::StringTemplate(source).specialize(specializations));
1271 	}
1272 }
1273 
createInstance(Context & context) const1274 TestInstance* NoneStageTestCase::createInstance(Context& context) const
1275 {
1276 	return new NoneStageTestInstance(context, m_testParams);
1277 }
1278 
checkSupport(Context & context) const1279 void NoneStageTestCase::checkSupport(Context& context) const
1280 {
1281 	context.requireDeviceFunctionality("VK_KHR_synchronization2");
1282 
1283 	const auto writeAspect	= m_testParams.writeAspect;
1284 	const auto readAspect	= m_testParams.readAspect;
1285 
1286 	// check whether implementation supports separate depth/stencil layouts
1287 	if (((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) && (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1288 		((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) && (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT)))
1289 	{
1290 		if(!context.getSeparateDepthStencilLayoutsFeatures().separateDepthStencilLayouts)
1291 			TCU_THROW(NotSupportedError, "Implementation does not support separateDepthStencilLayouts");
1292 	}
1293 
1294 	const auto writeLayout	= m_testParams.writeLayout;
1295 	const auto readLayout	= m_testParams.readLayout;
1296 	bool usePipelineToWrite	= (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
1297 	bool usePipelineToRead	= (readLayout  != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout  != VK_IMAGE_LAYOUT_GENERAL);
1298 
1299 	if (!usePipelineToWrite && !usePipelineToRead)
1300 		return;
1301 
1302 	VkFormat transitionImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
1303 	if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
1304 		transitionImageFormat = VK_FORMAT_D32_SFLOAT;
1305 	else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
1306 		transitionImageFormat = VK_FORMAT_S8_UINT;
1307 	else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
1308 		transitionImageFormat = VK_FORMAT_D24_UNORM_S8_UINT;
1309 
1310 	struct FormatToCheck
1311 	{
1312 		VkFormat			format;
1313 		VkImageUsageFlags	usage;
1314 	};
1315 	std::vector<FormatToCheck> formatsToCheck
1316 	{
1317 		// reference image
1318 		{ transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_DST_BIT },
1319 
1320 		// image to write
1321 		{ transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_SRC_BIT }
1322 	};
1323 
1324 	// note: conditions here are analogic to conditions in test case constructor
1325 	//       everything not needed was cout out leaving only logic related to
1326 	//       m_referenceImage and m_imageToWrite
1327 	if (usePipelineToWrite)
1328 	{
1329 		if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1330 		{
1331 			if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1332 			{
1333 				formatsToCheck[0].format = VK_FORMAT_R32_SFLOAT;
1334 				formatsToCheck[0].usage	|= VK_IMAGE_USAGE_SAMPLED_BIT;
1335 			}
1336 			else
1337 				formatsToCheck[0].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1338 
1339 			formatsToCheck[1].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1340 		}
1341 		else
1342 		{
1343 			formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1344 			formatsToCheck[1].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1345 		}
1346 	}
1347 
1348 	if (usePipelineToRead)
1349 	{
1350 		// for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
1351 		if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
1352 		{
1353 			formatsToCheck[1].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1354 
1355 			if (!usePipelineToWrite)
1356 				formatsToCheck[0].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1357 		}
1358 		else // use image sampler for color and depth_stencil layouts
1359 		{
1360 			formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1361 
1362 			// for depth_stencil layouts we need to have depth_stencil_attachment usage
1363 			if (!usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
1364 				formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1365 		}
1366 	}
1367 
1368 	// it simplifies logic to pop image to write then to add conditions everywhere above
1369 	if (!usePipelineToWrite)
1370 		formatsToCheck.pop_back();
1371 
1372 	for (const auto& formatData : formatsToCheck)
1373 	{
1374 		VkImageFormatProperties			properties;
1375 		const vk::InstanceInterface&	vki = context.getInstanceInterface();
1376 		if (vki.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
1377 													   formatData.format,
1378 													   VK_IMAGE_TYPE_2D,
1379 													   VK_IMAGE_TILING_OPTIMAL,
1380 													   formatData.usage,
1381 													   0,
1382 													   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
1383 		{
1384 			std::string error = std::string("Format (") +
1385 								vk::getFormatName(formatData.format) + ") doesn't support required capabilities.";
1386 			TCU_THROW(NotSupportedError, error.c_str());
1387 		}
1388 	}
1389 }
1390 
1391 } // anonymous
1392 
createNoneStageTests(tcu::TestContext & testCtx)1393 tcu::TestCaseGroup* createNoneStageTests(tcu::TestContext& testCtx)
1394 {
1395 	de::MovePtr<tcu::TestCaseGroup> noneStageTests(new tcu::TestCaseGroup(testCtx, "none_stage", ""));
1396 
1397 	struct LayoutData
1398 	{
1399 		VkImageLayout		token;
1400 		VkImageAspectFlags	aspect;
1401 		std::string			name;
1402 	};
1403 
1404 	const std::vector<LayoutData> writableLayoutsData
1405 	{
1406 		{ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,							IMAGE_ASPECT_ALL,				"transfer_dst" },
1407 		{ VK_IMAGE_LAYOUT_GENERAL,										IMAGE_ASPECT_ALL,				"general" },
1408 		{ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,						VK_IMAGE_ASPECT_COLOR_BIT,		"color_attachment" },
1409 		{ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				IMAGE_ASPECT_DEPTH_STENCIL,		"depth_stencil_attachment" },
1410 		{ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,						VK_IMAGE_ASPECT_DEPTH_BIT,		"depth_attachment" },
1411 		{ VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,					VK_IMAGE_ASPECT_STENCIL_BIT,	"stencil_attachment" },
1412 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_COLOR_BIT,		"generic_color_attachment" },
1413 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_DEPTH_BIT,		"generic_depth_attachment" },
1414 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_STENCIL_BIT,	"generic_stencil_attachment" },
1415 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						IMAGE_ASPECT_DEPTH_STENCIL,		"generic_depth_stencil_attachment" },
1416 	};
1417 	const std::vector<LayoutData> readableLayoutsData
1418 	{
1419 		{ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							IMAGE_ASPECT_ALL,				"transfer_src" },
1420 		{ VK_IMAGE_LAYOUT_GENERAL,										IMAGE_ASPECT_ALL,				"general" },
1421 		{ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,						IMAGE_ASPECT_ALL,				"shader_read" },
1422 		{ VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,				IMAGE_ASPECT_DEPTH_STENCIL,		"depth_stencil_read" },
1423 		{ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,	IMAGE_ASPECT_DEPTH_STENCIL,		"depth_read_stencil_attachment" },
1424 		{ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,	IMAGE_ASPECT_DEPTH_STENCIL,		"depth_attachment_stencil_read" },
1425 		{ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,						VK_IMAGE_ASPECT_DEPTH_BIT,		"depth_read" },
1426 		{ VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,					VK_IMAGE_ASPECT_STENCIL_BIT,	"stencil_read" },
1427 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						IMAGE_ASPECT_ALL,				"generic_color_read" },
1428 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						VK_IMAGE_ASPECT_DEPTH_BIT,		"generic_depth_read" },
1429 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						VK_IMAGE_ASPECT_STENCIL_BIT,	"generic_stencil_read" },
1430 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						IMAGE_ASPECT_DEPTH_STENCIL,		"generic_depth_stencil_read" },
1431 	};
1432 
1433 	struct SynchronizationData
1434 	{
1435 		SynchronizationType		type;
1436 		std::string				casePrefix;
1437 		bool					useGenericAccessFlags;
1438 	};
1439 	std::vector<SynchronizationData> synchronizationData
1440 	{
1441 		{ SynchronizationType::SYNCHRONIZATION2,	"",					true },
1442 		{ SynchronizationType::SYNCHRONIZATION2,	"old_access_",		false },
1443 
1444 		// using legacy synchronization structures with NONE_STAGE
1445 		{ SynchronizationType::LEGACY,				"legacy_",			false }
1446 	};
1447 
1448 	for (const auto& syncData : synchronizationData)
1449 	{
1450 		for (const auto& writeData : writableLayoutsData)
1451 		{
1452 			for (const auto& readData : readableLayoutsData)
1453 			{
1454 				if (readData.aspect && writeData.aspect &&
1455 				   (readData.aspect != writeData.aspect))
1456 					continue;
1457 
1458 				const std::string name = syncData.casePrefix + writeData.name + "_to_" + readData.name;
1459 				noneStageTests->addChild(new NoneStageTestCase(testCtx, name, {
1460 					syncData.type,
1461 					syncData.useGenericAccessFlags,
1462 					writeData.token,
1463 					writeData.aspect,
1464 					readData.token,
1465 					readData.aspect
1466 				}));
1467 			}
1468 		}
1469 	}
1470 
1471 	return noneStageTests.release();
1472 }
1473 
1474 } // synchronization
1475 } // vkt
1476