• 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 		if (m_useInputAttachmentToRead && (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL || m_testParams.readLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL))
413 			m_referenceImageUsage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
414 	}
415 }
416 
getAccessFlag(VkAccessFlags2KHR access)417 VkAccessFlags2KHR NoneStageTestInstance::getAccessFlag(VkAccessFlags2KHR access)
418 {
419 	if (m_testParams.useGenericAccessFlags)
420 	{
421 		switch (access)
422 		{
423 		case VK_ACCESS_2_HOST_READ_BIT_KHR:
424 		case VK_ACCESS_2_TRANSFER_READ_BIT_KHR:
425 		case VK_ACCESS_2_SHADER_READ_BIT_KHR:
426 		case VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT_KHR:
427 			return VK_ACCESS_2_MEMORY_READ_BIT_KHR;
428 
429 		case VK_ACCESS_2_HOST_WRITE_BIT_KHR:
430 		case VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR:
431 		case VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR:
432 		case VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR:
433 				return VK_ACCESS_2_MEMORY_WRITE_BIT_KHR;
434 
435 		default:
436 			TCU_THROW(TestError, "Unhandled access flag");
437 		}
438 	}
439 	return access;
440 }
441 
buildCopyRegion(VkExtent3D extent,VkImageAspectFlags aspect)442 VkBufferImageCopy NoneStageTestInstance::buildCopyRegion(VkExtent3D extent, VkImageAspectFlags aspect)
443 {
444 	return
445 	{
446 		0u,								// VkDeviceSize					bufferOffset
447 		extent.width,					// deUint32						bufferRowLength
448 		extent.height,					// deUint32						bufferImageHeight
449 		{ aspect, 0u, 0u, 1u },			// VkImageSubresourceLayers		imageSubresource
450 		{ 0, 0, 0 },					// VkOffset3D					imageOffset
451 		extent							// VkExtent3D					imageExtent
452 	};
453 }
454 
buildVertexBuffer()455 void NoneStageTestInstance::buildVertexBuffer()
456 {
457 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
458 	const VkDevice&			device	= m_context.getDevice();
459 
460 	std::vector<float> vertices
461 	{
462 		 1.0f,  1.0f, 0.0f, 1.0f,
463 		-1.0f,  1.0f, 0.0f, 1.0f,
464 		 1.0f, -1.0f, 0.0f, 1.0f,
465 		-1.0f, -1.0f, 0.0f, 1.0f,
466 	};
467 	m_vertexBuffer.create(m_context, m_alloc, sizeof(float) * vertices.size(), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
468 
469 	deMemcpy(m_vertexBuffer.memory->getHostPtr(), vertices.data(), vertices.size() * sizeof(float));
470 	flushAlloc(vk, device, *m_vertexBuffer.memory);
471 }
472 
buildBasicRenderPass(VkFormat outputFormat,VkImageLayout outputLayout,VkAttachmentLoadOp loadOp)473 Move<VkRenderPass> NoneStageTestInstance::buildBasicRenderPass(VkFormat outputFormat, VkImageLayout outputLayout, VkAttachmentLoadOp loadOp)
474 {
475 	// output color/depth attachment
476 	VkAttachmentDescription2 attachmentDescription
477 	{
478 		VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
479 		DE_NULL,												// const void*						pNext
480 		(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
481 		outputFormat,											// VkFormat							format
482 		VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
483 		loadOp,													// VkAttachmentLoadOp				loadOp
484 		VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
485 		loadOp,													// VkAttachmentLoadOp				stencilLoadOp
486 		VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp
487 		VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout
488 		outputLayout											// VkImageLayout					finalLayout
489 	};
490 
491 	VkImageAspectFlags		imageAspect		= getImageAspectFlags(mapVkFormat(outputFormat));
492 	VkAttachmentReference2	attachmentRef
493 	{
494 		VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, outputLayout, imageAspect
495 	};
496 
497 	VkAttachmentReference2* pColorAttachment			= DE_NULL;
498 	VkAttachmentReference2* pDepthStencilAttachment		= DE_NULL;
499 	if (imageAspect == VK_IMAGE_ASPECT_COLOR_BIT)
500 		pColorAttachment = &attachmentRef;
501 	else
502 		pDepthStencilAttachment = &attachmentRef;
503 
504 	VkSubpassDescription2 subpassDescription
505 	{
506 		VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
507 		DE_NULL,
508 		(VkSubpassDescriptionFlags)0,							// VkSubpassDescriptionFlags		flags
509 		VK_PIPELINE_BIND_POINT_GRAPHICS,						// VkPipelineBindPoint				pipelineBindPoint
510 		0u,														// deUint32							viewMask
511 		0u,														// deUint32							inputAttachmentCount
512 		DE_NULL,												// const VkAttachmentReference2*	pInputAttachments
513 		!!pColorAttachment,										// deUint32							colorAttachmentCount
514 		pColorAttachment,										// const VkAttachmentReference2*	pColorAttachments
515 		DE_NULL,												// const VkAttachmentReference2*	pResolveAttachments
516 		pDepthStencilAttachment,								// const VkAttachmentReference2*	pDepthStencilAttachment
517 		0u,														// deUint32							preserveAttachmentCount
518 		DE_NULL													// const deUint32*					pPreserveAttachments
519 	};
520 
521 	const VkRenderPassCreateInfo2 renderPassInfo
522 	{
523 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
524 		DE_NULL,												// const void*						pNext
525 		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
526 		1u,														// deUint32							attachmentCount
527 		&attachmentDescription,									// const VkAttachmentDescription*	pAttachments
528 		1u,														// deUint32							subpassCount
529 		&subpassDescription,									// const VkSubpassDescription*		pSubpasses
530 		0u,														// deUint32							dependencyCount
531 		DE_NULL,												// const VkSubpassDependency*		pDependencies
532 		0u,														// deUint32							correlatedViewMaskCount
533 		DE_NULL													// const deUint32*					pCorrelatedViewMasks
534 	};
535 
536 	return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
537 }
538 
buildComplexRenderPass(VkFormat intermediateFormat,VkImageLayout intermediateLayout,VkImageAspectFlags intermediateAspect,VkFormat outputFormat,VkImageLayout outputLayout)539 Move<VkRenderPass> NoneStageTestInstance::buildComplexRenderPass(VkFormat intermediateFormat,	VkImageLayout intermediateLayout, VkImageAspectFlags intermediateAspect,
540 																 VkFormat outputFormat,			VkImageLayout outputLayout)
541 {
542 	std::vector<VkAttachmentDescription2> attachmentDescriptions
543 	{
544 		// depth/stencil attachment (when used in read pipeline it loads data filed in write pipeline)
545 		{
546 			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
547 			DE_NULL,												// const void*						pNext
548 			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
549 			intermediateFormat,										// VkFormat							format
550 			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
551 			VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp				loadOp
552 			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
553 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp
554 			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				stencilStoreOp
555 			intermediateLayout,										// VkImageLayout					initialLayout
556 			intermediateLayout										// VkImageLayout					finalLayout
557 		},
558 		// color attachment
559 		{
560 			VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,				// VkStructureType					sType
561 			DE_NULL,												// const void*						pNext
562 			(VkAttachmentDescriptionFlags)0,						// VkAttachmentDescriptionFlags		flags
563 			outputFormat,											// VkFormat							format
564 			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits			samples
565 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				loadOp
566 			VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp				storeOp
567 			VK_ATTACHMENT_LOAD_OP_DONT_CARE,						// VkAttachmentLoadOp				stencilLoadOp
568 			VK_ATTACHMENT_STORE_OP_DONT_CARE,						// VkAttachmentStoreOp				stencilStoreOp
569 			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout					initialLayout
570 			outputLayout											// VkImageLayout					finalLayout
571 		}
572 	};
573 
574 	VkImageAspectFlags					outputAspect		= getImageAspectFlags(mapVkFormat(outputFormat));
575 	std::vector<VkAttachmentReference2>	attachmentRefs
576 	{
577 		{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 0u, intermediateLayout, intermediateAspect },
578 		{ VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, DE_NULL, 1u, outputLayout, outputAspect }
579 	};
580 
581 	VkAttachmentReference2* pDepthStencilAttachment = &attachmentRefs[0];
582 	VkAttachmentReference2* pColorAttachment		= &attachmentRefs[1];
583 
584 	std::vector<VkSubpassDescription2> subpassDescriptions
585 	{
586 		{
587 			VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
588 			DE_NULL,
589 			(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags
590 			VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint
591 			0u,													// deUint32							viewMask
592 			1u,													// deUint32							inputAttachmentCount
593 			pDepthStencilAttachment,							// const VkAttachmentReference2*	pInputAttachments
594 			1u,													// deUint32							colorAttachmentCount
595 			pColorAttachment,									// const VkAttachmentReference2*	pColorAttachments
596 			DE_NULL,											// const VkAttachmentReference2*	pResolveAttachments
597 			DE_NULL,											// const VkAttachmentReference2*	pDepthStencilAttachment
598 			0u,													// deUint32							preserveAttachmentCount
599 			DE_NULL												// deUint32*						pPreserveAttachments
600 		}
601 	};
602 
603 	const VkRenderPassCreateInfo2 renderPassInfo
604 	{
605 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
606 		DE_NULL,												// const void*						pNext
607 		(VkRenderPassCreateFlags)0,								// VkRenderPassCreateFlags			flags
608 		(deUint32)attachmentDescriptions.size(),				// deUint32							attachmentCount
609 		attachmentDescriptions.data(),							// const VkAttachmentDescription*	pAttachments
610 		(deUint32)subpassDescriptions.size(),					// deUint32							subpassCount
611 		subpassDescriptions.data(),								// const VkSubpassDescription*		pSubpasses
612 		0u,														// deUint32							dependencyCount
613 		DE_NULL,												// const VkSubpassDependency*		pDependencies
614 		0u,														// deUint32							correlatedViewMaskCount
615 		DE_NULL													// const deUint32*					pCorrelatedViewMasks
616 	};
617 
618 	return vk::createRenderPass2(m_context.getDeviceInterface(), m_context.getDevice(), &renderPassInfo);
619 }
620 
buildImageView(VkImage image,VkFormat format,const VkImageSubresourceRange & subresourceRange)621 Move<VkImageView> NoneStageTestInstance::buildImageView(VkImage image, VkFormat format, const VkImageSubresourceRange& subresourceRange)
622 {
623 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
624 	const VkDevice&			device	= m_context.getDevice();
625 
626 	const VkImageViewCreateInfo imageViewParams
627 	{
628 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType				sType
629 		DE_NULL,												// const void*					pNext
630 		0u,														// VkImageViewCreateFlags		flags
631 		image,													// VkImage						image
632 		VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType				viewType
633 		format,													// VkFormat						format
634 		makeComponentMappingRGBA(),								// VkComponentMapping			components
635 		subresourceRange,										// VkImageSubresourceRange		subresourceRange
636 	};
637 
638 	return createImageView(vk, device, &imageViewParams);
639 }
640 
buildFramebuffer(VkRenderPass renderPass,const VkImageView * outView1,const VkImageView * outView2)641 Move<VkFramebuffer> NoneStageTestInstance::buildFramebuffer(VkRenderPass renderPass, const VkImageView* outView1, const VkImageView* outView2)
642 {
643 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
644 	const VkDevice&			device	= m_context.getDevice();
645 
646 	std::vector<VkImageView> imageViews = { *outView1 };
647 	if (outView2)
648 		imageViews.push_back(*outView2);
649 
650 	const VkFramebufferCreateInfo framebufferParams
651 	{
652 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// VkStructureType				sType
653 		DE_NULL,												// const void*					pNext
654 		0u,														// VkFramebufferCreateFlags		flags
655 		renderPass,												// VkRenderPass					renderPass
656 		(deUint32)imageViews.size(),							// deUint32						attachmentCount
657 		imageViews.data(),										// const VkImageView*			pAttachments
658 		m_imageExtent.width,									// deUint32						width
659 		m_imageExtent.height,									// deUint32						height
660 		1u,														// deUint32						layers
661 	};
662 	return createFramebuffer(vk, device, &framebufferParams);
663 }
664 
buildSampler()665 Move<VkSampler> NoneStageTestInstance::buildSampler()
666 {
667 	const DeviceInterface&	vk		= m_context.getDeviceInterface();
668 	const VkDevice&			device	= m_context.getDevice();
669 
670 	const VkSamplerCreateInfo samplerInfo
671 	{
672 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,					// VkStructureType				sType
673 		DE_NULL,												// const void*					pNext
674 		0u,														// VkSamplerCreateFlags			flags
675 		VK_FILTER_NEAREST,										// VkFilter						magFilter
676 		VK_FILTER_NEAREST,										// VkFilter						minFilter
677 		VK_SAMPLER_MIPMAP_MODE_NEAREST,							// VkSamplerMipmapMode			mipmapMode
678 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeU
679 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeV
680 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,					// VkSamplerAddressMode			addressModeW
681 		0.0f,													// float						mipLodBias
682 		VK_FALSE,												// VkBool32						anisotropyEnable
683 		1.0f,													// float						maxAnisotropy
684 		DE_FALSE,												// VkBool32						compareEnable
685 		VK_COMPARE_OP_ALWAYS,									// VkCompareOp					compareOp
686 		0.0f,													// float						minLod
687 		0.0f,													// float						maxLod
688 		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,				// VkBorderColor				borderColor
689 		VK_FALSE,												// VkBool32						unnormalizedCoords
690 	};
691 	return createSampler(vk, device, &samplerInfo);
692 }
693 
buildDescriptorSetLayout(VkDescriptorType descriptorType)694 Move<VkDescriptorSetLayout> NoneStageTestInstance::buildDescriptorSetLayout(VkDescriptorType descriptorType)
695 {
696 	const DeviceInterface&		vk		= m_context.getDeviceInterface();
697 	const VkDevice&				device	= m_context.getDevice();
698 
699 	return
700 		DescriptorSetLayoutBuilder()
701 		.addSingleSamplerBinding(descriptorType, VK_SHADER_STAGE_FRAGMENT_BIT, DE_NULL)
702 		.build(vk, device);
703 }
704 
buildDescriptorPool(VkDescriptorType descriptorType)705 Move<VkDescriptorPool> NoneStageTestInstance::buildDescriptorPool(VkDescriptorType descriptorType)
706 {
707 	const DeviceInterface&		vk		= m_context.getDeviceInterface();
708 	const VkDevice&				device	= m_context.getDevice();
709 
710 	return
711 		DescriptorPoolBuilder()
712 		.addType(descriptorType, 1u)
713 		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
714 }
715 
buildDescriptorSet(VkDescriptorPool descriptorPool,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorType descriptorType,VkImageView inputView,VkImageLayout inputLayout,const VkSampler * sampler)716 Move<VkDescriptorSet> NoneStageTestInstance::buildDescriptorSet(VkDescriptorPool		descriptorPool,
717 																VkDescriptorSetLayout	descriptorSetLayout,
718 																VkDescriptorType		descriptorType,
719 																VkImageView				inputView,
720 																VkImageLayout			inputLayout,
721 																const VkSampler*		sampler)
722 {
723 	const DeviceInterface&		vk				= m_context.getDeviceInterface();
724 	const VkDevice&				device			= m_context.getDevice();
725 
726 	const VkDescriptorImageInfo inputImageInfo	= makeDescriptorImageInfo(sampler ? *sampler : 0u, inputView, inputLayout);
727 	Move<VkDescriptorSet>		descriptorSet	= makeDescriptorSet(vk, device, descriptorPool, descriptorSetLayout);
728 
729 	DescriptorSetUpdateBuilder()
730 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &inputImageInfo)
731 		.update(vk, device);
732 
733 	return descriptorSet;
734 }
735 
buildPipeline(deUint32 subpass,VkImageAspectFlags resultAspect,VkPipelineLayout pipelineLayout,VkShaderModule vertShaderModule,VkShaderModule fragShaderModule,VkRenderPass renderPass)736 Move<VkPipeline> NoneStageTestInstance::buildPipeline(deUint32				subpass,
737 													  VkImageAspectFlags	resultAspect,
738 													  VkPipelineLayout		pipelineLayout,
739 													  VkShaderModule		vertShaderModule,
740 													  VkShaderModule		fragShaderModule,
741 													  VkRenderPass			renderPass)
742 {
743 	const DeviceInterface&			vk				= m_context.getDeviceInterface();
744 	const VkDevice&					device			= m_context.getDevice();
745 	const std::vector<VkViewport>	viewports		{ makeViewport(m_imageExtent) };
746 	const std::vector<VkRect2D>		scissors		{ makeRect2D(m_imageExtent) };
747 	const bool						useDepth		= resultAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
748 	const bool						useStencil		= resultAspect & VK_IMAGE_ASPECT_STENCIL_BIT;
749 
750 	const VkStencilOpState stencilOpState = makeStencilOpState(
751 		VK_STENCIL_OP_REPLACE,											// stencil fail
752 		VK_STENCIL_OP_REPLACE,											// depth & stencil pass
753 		VK_STENCIL_OP_REPLACE,											// depth only fail
754 		VK_COMPARE_OP_ALWAYS,											// compare op
755 		1u,																// compare mask
756 		1u,																// write mask
757 		1u);															// reference
758 
759 	const VkPipelineDepthStencilStateCreateInfo	depthStencilStateCreateInfo
760 	{
761 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,		// VkStructureType								sType
762 		DE_NULL,														// const void*									pNext
763 		(VkPipelineDepthStencilStateCreateFlags)0,						// VkPipelineDepthStencilStateCreateFlags		flags
764 		useDepth,														// VkBool32										depthTestEnable
765 		useDepth,														// VkBool32										depthWriteEnable
766 		VK_COMPARE_OP_ALWAYS,											// VkCompareOp									depthCompareOp
767 		VK_FALSE,														// VkBool32										depthBoundsTestEnable
768 		useStencil,														// VkBool32										stencilTestEnable
769 		stencilOpState,													// VkStencilOpState								front
770 		stencilOpState,													// VkStencilOpState								back
771 		0.0f,															// float										minDepthBounds
772 		1.0f,															// float										maxDepthBounds
773 	};
774 
775 	return makeGraphicsPipeline(
776 		vk,																// DeviceInterface&								vk
777 		device,															// VkDevice										device
778 		pipelineLayout,													// VkPipelineLayout								pipelineLayout
779 		vertShaderModule,												// VkShaderModule								vertexShaderModule
780 		DE_NULL,														// VkShaderModule								tessellationControlModule
781 		DE_NULL,														// VkShaderModule								tessellationEvalModule
782 		DE_NULL,														// VkShaderModule								geometryShaderModule
783 		fragShaderModule,												// VkShaderModule								fragmentShaderModule
784 		renderPass,														// VkRenderPass									renderPass
785 		viewports,														// std::vector<VkViewport>&						viewports
786 		scissors,														// std::vector<VkRect2D>&						scissors
787 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,							// VkPrimitiveTopology							topology
788 		subpass,														// deUint32										subpass
789 		0u,																// deUint32										patchControlPoints
790 		DE_NULL,														// VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
791 		DE_NULL,														// VkPipelineRasterizationStateCreateInfo*		rasterizationStateCreateInfo
792 		DE_NULL,														// VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
793 		&depthStencilStateCreateInfo);									// VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
794 }
795 
iterate(void)796 tcu::TestStatus NoneStageTestInstance::iterate(void)
797 {
798 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
799 	const VkDevice&				device					= m_context.getDevice();
800 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
801 	VkQueue						queue					= m_context.getUniversalQueue();
802 	Move<VkCommandPool>			cmdPool					= createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
803 	Move<VkCommandBuffer>		cmdBuffer				= makeCommandBuffer(vk, device, *cmdPool);
804 	const VkDeviceSize			vertexBufferOffset		= 0;
805 	ImageWrapper*				transitionImagePtr		= &m_referenceImage;
806 	ImageWrapper*				imageToVerifyPtr		= &m_referenceImage;
807 	const deUint32				imageSizeInBytes		= m_imageExtent.width * m_imageExtent.height * 4;
808 	SynchronizationWrapperPtr	synchronizationWrapper	= getSynchronizationWrapper(m_testParams.type, vk, false);
809 	const VkRect2D				renderArea				= makeRect2D(0, 0, m_imageExtent.width, m_imageExtent.height);
810 	const VkBufferImageCopy		transitionCopyRegion	= buildCopyRegion(m_imageExtent, m_transitionImageAspect);
811 	const VkBufferImageCopy		colorCopyRegion			= buildCopyRegion(m_imageExtent, VK_IMAGE_ASPECT_COLOR_BIT);
812 
813 	// create image that will have gradient (without data atm)
814 	m_referenceImage.create(m_context, m_alloc, m_referenceImageFormat, m_imageExtent, m_referenceImageUsage);
815 
816 	// create buffer used for gradient data source
817 	BufferWrapper srcBuffer;
818 	srcBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
819 
820 	// generate gradient
821 	std::vector<deUint32>	referenceData	(m_imageExtent.width * m_imageExtent.height);
822 	tcu::TextureFormat		referenceFormat	(mapVkFormat(m_referenceImageFormat));
823 	if (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)
824 	{
825 		// when testing stencil aspect of depth stencil combined image, prepare reference date only with stencil,
826 		// as the copy operation (used when m_usePipelineToWrite == false) sources just one aspect
827 
828 		// this format is used for tcu operations only - does not need to be supported by the Vulkan implementation
829 		referenceFormat = mapVkFormat(VK_FORMAT_S8_UINT);
830 	}
831 	PixelBufferAccess		referencePBA	(referenceFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, referenceData.data());
832 	fillWithComponentGradients(referencePBA, tcu::Vec4(0.0f), tcu::Vec4(1.0f));
833 	deMemcpy(srcBuffer.memory->getHostPtr(), referenceData.data(), static_cast<size_t>(imageSizeInBytes));
834 	flushAlloc(vk, device, *srcBuffer.memory);
835 
836 	// create buffer for result transfer
837 	BufferWrapper			dstBuffer;
838 	tcu::TextureFormat		resultFormat	(mapVkFormat(m_readImageFormat));
839 	dstBuffer.create(m_context, m_alloc, imageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
840 
841 	if (m_usePipelineToWrite || m_usePipelineToRead)
842 	{
843 		buildVertexBuffer();
844 
845 		// create image view for reference image (its always at index 0)
846 		m_attachmentViews.push_back(buildImageView(*m_referenceImage.handle, m_referenceImageFormat, m_referenceSubresourceRange));
847 
848 		// create graphics pipeline used to write image data
849 		if (m_usePipelineToWrite)
850 		{
851 			// create image that will be used as attachment to write to
852 			m_imageToWrite.create(m_context, m_alloc, m_transitionImageFormat, m_imageExtent, m_imageToWriteUsage);
853 			m_attachmentViews.push_back(buildImageView(*m_imageToWrite.handle, m_transitionImageFormat, m_transitionSubresourceRange));
854 
855 			m_writeVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
856 			m_writeFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_writeFragShaderName), 0);
857 
858 			if (m_useStencilDuringWrite)
859 			{
860 				// this is used only for cases where writable layout is VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL
861 				// in this case generated gradient is only used for verification
862 				m_writeRenderPass			= buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout, VK_ATTACHMENT_LOAD_OP_CLEAR);
863 				m_writePipelineLayout		= makePipelineLayout(vk, device, DE_NULL);
864 				m_writePipeline				= buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
865 															*m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
866 				m_writeFramebuffer			= buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
867 			}
868 			else
869 			{
870 				m_writeRenderPass			= buildBasicRenderPass(m_transitionImageFormat, m_writeRenderPassOutputLayout);
871 				m_writeSampler				= buildSampler();
872 				m_writeDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
873 				m_writeDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
874 				m_writeDescriptorSet		= buildDescriptorSet(*m_writeDescriptorPool, *m_writeDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
875 																 *m_attachmentViews[0], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, &m_writeSampler.get());
876 				m_writePipelineLayout		= makePipelineLayout(vk, device, *m_writeDescriptorSetLayout);
877 				m_writePipeline				= buildPipeline(0u, m_transitionImageAspect, *m_writePipelineLayout,
878 															*m_writeVertShaderModule, *m_writeFragShaderModule, *m_writeRenderPass);
879 				m_writeFramebuffer			= buildFramebuffer(*m_writeRenderPass, &m_attachmentViews[1].get());
880 			}
881 
882 			transitionImagePtr	= &m_imageToWrite;
883 			imageToVerifyPtr	= &m_imageToWrite;
884 		}
885 
886 		// create graphics pipeline used to read image data
887 		if (m_usePipelineToRead)
888 		{
889 			m_imageToRead.create(m_context, m_alloc, m_readImageFormat, m_imageExtent, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
890 			m_attachmentViews.push_back(buildImageView(*m_imageToRead.handle, m_readImageFormat, m_readSubresourceRange));
891 			imageToVerifyPtr = &m_imageToRead;
892 
893 			m_readVertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0);
894 			m_readFragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get(m_readFragShaderName), 0);
895 
896 			if (m_useInputAttachmentToRead)
897 			{
898 				m_readDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
899 				m_readDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT);
900 				m_readDescriptorSet			= buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
901 																 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout);
902 				m_readRenderPass			= buildComplexRenderPass(m_transitionImageFormat, m_testParams.readLayout, m_transitionImageAspect,
903 																	 m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
904 				m_readFramebuffer			= buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite].get(),
905 																				  &m_attachmentViews[m_usePipelineToWrite+1].get());
906 				m_readPipelineLayout		= makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
907 				m_readPipeline				= buildPipeline(0u, VK_IMAGE_ASPECT_COLOR_BIT, *m_readPipelineLayout,
908 															*m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
909 			}
910 			else
911 			{
912 				m_readSampler				= buildSampler();
913 				m_readDescriptorSetLayout	= buildDescriptorSetLayout(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
914 				m_readDescriptorPool		= buildDescriptorPool(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
915 				m_readDescriptorSet			= buildDescriptorSet(*m_readDescriptorPool, *m_readDescriptorSetLayout, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
916 																 *m_attachmentViews[m_usePipelineToWrite], m_testParams.readLayout, &m_readSampler.get());
917 				m_readRenderPass			= buildBasicRenderPass(m_readImageFormat, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
918 				m_readFramebuffer			= buildFramebuffer(*m_readRenderPass, &m_attachmentViews[m_usePipelineToWrite + 1].get());
919 				m_readPipelineLayout		= makePipelineLayout(vk, device, *m_readDescriptorSetLayout);
920 				m_readPipeline				= buildPipeline(0u, m_transitionImageAspect, *m_readPipelineLayout,
921 															*m_readVertShaderModule, *m_readFragShaderModule, *m_readRenderPass);
922 			}
923 		}
924 	}
925 
926 	beginCommandBuffer(vk, *cmdBuffer);
927 
928 	// write data from buffer with gradient to image (for stencil_attachment cases we dont need to do that)
929 	if (!m_useStencilDuringWrite)
930 	{
931 		// wait for reference data to be in buffer
932 		const VkBufferMemoryBarrier2KHR preBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
933 			VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			srcStageMask
934 			getAccessFlag(VK_ACCESS_2_HOST_WRITE_BIT_KHR),		// VkAccessFlags2KHR				srcAccessMask
935 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			dstStageMask
936 			getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),	// VkAccessFlags2KHR				dstAccessMask
937 			*srcBuffer.handle,									// VkBuffer							buffer
938 			0u,													// VkDeviceSize						offset
939 			imageSizeInBytes									// VkDeviceSize						size
940 		);
941 
942 		VkImageLayout copyBufferToImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
943 		if(m_testParams.writeLayout == VK_IMAGE_LAYOUT_GENERAL)
944 			copyBufferToImageLayout = VK_IMAGE_LAYOUT_GENERAL;
945 
946 		// change image layout so that we can copy to it data from buffer
947 		const VkImageMemoryBarrier2KHR preImageMemoryBarrier2 = makeImageMemoryBarrier2(
948 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
949 			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
950 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			dstStageMask
951 			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				dstAccessMask
952 			VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout					oldLayout
953 			copyBufferToImageLayout,							// VkImageLayout					newLayout
954 			*m_referenceImage.handle,							// VkImage							image
955 			m_referenceSubresourceRange							// VkImageSubresourceRange			subresourceRange
956 		);
957 		VkDependencyInfoKHR buffDependencyInfo = makeCommonDependencyInfo(DE_NULL, &preBufferMemoryBarrier2, &preImageMemoryBarrier2);
958 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &buffDependencyInfo);
959 
960 		const VkBufferImageCopy* copyRegion = m_usePipelineToWrite ? &colorCopyRegion : &transitionCopyRegion;
961 		vk.cmdCopyBufferToImage(*cmdBuffer, *srcBuffer.handle, *m_referenceImage.handle, copyBufferToImageLayout, 1u, copyRegion);
962 	}
963 
964 	if (m_usePipelineToWrite)
965 	{
966 		// wait till data is transfered to image (in all cases except when stencil_attachment is tested)
967 		if (!m_useStencilDuringWrite)
968 		{
969 			const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
970 				VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
971 				getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
972 				VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR,		// VkPipelineStageFlags2KHR			dstStageMask
973 				getAccessFlag(VK_ACCESS_2_SHADER_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
974 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout					oldLayout
975 				VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,			// VkImageLayout					newLayout
976 				*m_referenceImage.handle,							// VkImage							image
977 				m_referenceSubresourceRange							// VkImageSubresourceRange			subresourceRange
978 			);
979 			VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
980 			synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
981 		}
982 
983 		beginRenderPass(vk, *cmdBuffer, *m_writeRenderPass, *m_writeFramebuffer, renderArea, tcu::Vec4(0.0f ,0.0f, 0.0f, 1.0f));
984 
985 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipeline);
986 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
987 		if (m_useStencilDuringWrite)
988 		{
989 			// when writing to stencil buffer draw single triangle (to simulate gradient over 1bit)
990 			vk.cmdDraw(*cmdBuffer, 3u, 1u, 0u, 0u);
991 		}
992 		else
993 		{
994 			vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_writePipelineLayout, 0, 1, &m_writeDescriptorSet.get(), 0, DE_NULL);
995 			vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
996 		}
997 
998 		endRenderPass(vk, *cmdBuffer);
999 	}
1000 
1001 	// use none stage to wait till data is transfered to image
1002 	{
1003 		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1004 			m_srcStageToNoneStageMask,							// VkPipelineStageFlags2KHR			srcStageMask
1005 			m_srcAccessToNoneAccessMask,						// VkAccessFlags2KHR				srcAccessMask
1006 			VK_PIPELINE_STAGE_2_NONE_KHR,						// VkPipelineStageFlags2KHR			dstStageMask
1007 			VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				dstAccessMask
1008 			m_testParams.writeLayout,							// VkImageLayout					oldLayout
1009 			m_testParams.writeLayout,							// VkImageLayout					newLayout
1010 			*transitionImagePtr->handle,						// VkImage							image
1011 			m_transitionSubresourceRange						// VkImageSubresourceRange			subresourceRange
1012 		);
1013 		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1014 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1015 	}
1016 
1017 	// use all commands stage to change image layout
1018 	{
1019 		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1020 			VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR,			// VkPipelineStageFlags2KHR			srcStageMask
1021 			VK_ACCESS_2_NONE_KHR,								// VkAccessFlags2KHR				srcAccessMask
1022 			m_dstStageFromNoneStageMask,						// VkPipelineStageFlags2KHR			dstStageMask
1023 			m_dstAccessFromNoneAccessMask,						// VkAccessFlags2KHR				dstAccessMask
1024 			m_testParams.writeLayout,							// VkImageLayout					oldLayout
1025 			m_testParams.readLayout,							// VkImageLayout					newLayout
1026 			*transitionImagePtr->handle,						// VkImage							image
1027 			m_transitionSubresourceRange						// VkImageSubresourceRange			subresourceRange
1028 		);
1029 		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1030 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1031 	}
1032 
1033 	VkImageLayout copyImageToBufferLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1034 	if (m_testParams.readLayout == VK_IMAGE_LAYOUT_GENERAL)
1035 		copyImageToBufferLayout = VK_IMAGE_LAYOUT_GENERAL;
1036 
1037 	if (m_usePipelineToRead)
1038 	{
1039 		beginRenderPass(vk, *cmdBuffer, *m_readRenderPass, *m_readFramebuffer, renderArea);
1040 
1041 		vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipeline);
1042 		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_readPipelineLayout, 0, 1, &m_readDescriptorSet.get(), 0, DE_NULL);
1043 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &m_vertexBuffer.handle.get(), &vertexBufferOffset);
1044 		vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
1045 
1046 		endRenderPass(vk, *cmdBuffer);
1047 
1048 		// wait till data is transfered to image
1049 		const VkImageMemoryBarrier2KHR imageMemoryBarrier2 = makeImageMemoryBarrier2(
1050 			VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,	// VkPipelineStageFlags2KHR			srcStageMask
1051 			VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR,				// VkAccessFlags2KHR				srcAccessMask
1052 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
1053 			getAccessFlag(VK_ACCESS_2_TRANSFER_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
1054 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout					oldLayout
1055 			copyImageToBufferLayout,								// VkImageLayout					newLayout
1056 			*imageToVerifyPtr->handle,								// VkImage							image
1057 			m_readSubresourceRange									// VkImageSubresourceRange			subresourceRange
1058 		);
1059 		VkDependencyInfoKHR dependencyInfo = makeCommonDependencyInfo(DE_NULL, DE_NULL, &imageMemoryBarrier2);
1060 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &dependencyInfo);
1061 	}
1062 
1063 	// read back image
1064 	{
1065 		const VkBufferImageCopy* copyRegion = m_usePipelineToRead ? &colorCopyRegion : &transitionCopyRegion;
1066 		vk.cmdCopyImageToBuffer(*cmdBuffer, *imageToVerifyPtr->handle, copyImageToBufferLayout, *dstBuffer.handle, 1u, copyRegion);
1067 
1068 		const VkBufferMemoryBarrier2KHR postBufferMemoryBarrier2 = makeBufferMemoryBarrier2(
1069 			VK_PIPELINE_STAGE_2_TRANSFER_BIT_KHR,				// VkPipelineStageFlags2KHR			srcStageMask
1070 			getAccessFlag(VK_ACCESS_2_TRANSFER_WRITE_BIT_KHR),	// VkAccessFlags2KHR				srcAccessMask
1071 			VK_PIPELINE_STAGE_2_HOST_BIT_KHR,					// VkPipelineStageFlags2KHR			dstStageMask
1072 			getAccessFlag(VK_ACCESS_2_HOST_READ_BIT_KHR),		// VkAccessFlags2KHR				dstAccessMask
1073 			*dstBuffer.handle,									// VkBuffer							buffer
1074 			0u,													// VkDeviceSize						offset
1075 			imageSizeInBytes									// VkDeviceSize						size
1076 		);
1077 		VkDependencyInfoKHR bufDependencyInfo = makeCommonDependencyInfo(DE_NULL, &postBufferMemoryBarrier2);
1078 		synchronizationWrapper->cmdPipelineBarrier(*cmdBuffer, &bufDependencyInfo);
1079 	}
1080 
1081 	endCommandBuffer(vk, *cmdBuffer);
1082 
1083 	Move<VkFence>					fence			= createFence(vk, device);
1084 	VkCommandBufferSubmitInfoKHR	cmdBuffersInfo	= makeCommonCommandBufferSubmitInfo(*cmdBuffer);
1085 	synchronizationWrapper->addSubmitInfo(0u, DE_NULL, 1u, &cmdBuffersInfo, 0u, DE_NULL);
1086 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
1087 	VK_CHECK(vk.waitForFences(device, 1, &fence.get(), VK_TRUE, ~0ull));
1088 
1089 	// read image data
1090 	invalidateAlloc(vk, device, *dstBuffer.memory);
1091 	PixelBufferAccess resultPBA(resultFormat, m_imageExtent.width, m_imageExtent.height, m_imageExtent.depth, dstBuffer.memory->getHostPtr());
1092 
1093 	// if result/reference is depth-stencil format then focus only on tested component
1094 	if (isCombinedDepthStencilType(referenceFormat.type))
1095 		referencePBA = getEffectiveDepthStencilAccess(referencePBA, (m_referenceSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1096 	if (isCombinedDepthStencilType(resultFormat.type))
1097 		resultPBA = getEffectiveDepthStencilAccess(resultPBA, (m_readSubresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) ? tcu::Sampler::MODE_DEPTH : tcu::Sampler::MODE_STENCIL);
1098 
1099 	if (verifyResult(referencePBA, resultPBA))
1100 		return TestStatus::pass("Pass");
1101 	return TestStatus::fail("Fail");
1102 }
1103 
verifyResult(const PixelBufferAccess & reference,const PixelBufferAccess & result)1104 bool NoneStageTestInstance::verifyResult(const PixelBufferAccess& reference, const PixelBufferAccess& result)
1105 {
1106 	TestLog& log = m_context.getTestContext().getLog();
1107 
1108 	const auto forceStencil = (m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL);
1109 
1110 	if (isIntFormat(m_referenceImageFormat) || isUintFormat(m_referenceImageFormat) || forceStencil)
1111 	{
1112 		// special case for stencil (1bit gradient - top-left of image is 0, bottom-right is 1)
1113 
1114 		bool				isResultCorrect = true;
1115 		TextureLevel		errorMaskStorage(TextureFormat(TextureFormat::RGB, TextureFormat::UNORM_INT8),
1116 											 m_imageExtent.width, m_imageExtent.height, 1);
1117 		PixelBufferAccess	errorMask		= errorMaskStorage.getAccess();
1118 
1119 		for (deUint32 y = 0; y < m_imageExtent.height; y++)
1120 			for (deUint32 x = 0; x < m_imageExtent.width; x++)
1121 			{
1122 				// skip textels on diagonal (gradient lights texels on diagonal and stencil operation in test does not)
1123 				if ((x + y) == (m_imageExtent.width - 1))
1124 				{
1125 					errorMask.setPixel(IVec4(0, 0xff, 0, 0xff), x, y, 0);
1126 					continue;
1127 				}
1128 
1129 				IVec4	refPix = reference.getPixelInt(x, y, 0);
1130 				IVec4	cmpPix = result.getPixelInt(x, y, 0);
1131 				bool	isOk = (refPix[0] == cmpPix[0]);
1132 				errorMask.setPixel(isOk ? IVec4(0, 0xff, 0, 0xff) : IVec4(0xff, 0, 0, 0xff), x, y, 0);
1133 				isResultCorrect &= isOk;
1134 			}
1135 
1136 		Vec4 pixelBias(0.0f);
1137 		Vec4 pixelScale(1.0f);
1138 		if (isResultCorrect)
1139 		{
1140 			log << TestLog::ImageSet("Image comparison", "")
1141 				<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1142 				<< TestLog::EndImageSet;
1143 			return true;
1144 		}
1145 
1146 		log << TestLog::ImageSet("Image comparison", "")
1147 			<< TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
1148 			<< TestLog::Image("Reference", "Reference", reference, pixelScale, pixelBias)
1149 			<< TestLog::Image("ErrorMask", "Error mask", errorMask)
1150 			<< TestLog::EndImageSet;
1151 		return false;
1152 	}
1153 
1154 	return floatThresholdCompare(log, "Image comparison", "", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_RESULT);
1155 }
1156 
1157 class NoneStageTestCase : public vkt::TestCase
1158 {
1159 public:
1160 							NoneStageTestCase		(tcu::TestContext&		testContext,
1161 													 const std::string&		name,
1162 													 const TestParams&		testParams);
1163 							~NoneStageTestCase		(void) = default;
1164 
1165 	void					initPrograms			(SourceCollections&		sourceCollections) const override;
1166 	TestInstance*			createInstance			(Context&				context) const override;
1167 	void					checkSupport			(Context&				context) const override;
1168 
1169 private:
1170 	const TestParams		m_testParams;
1171 };
1172 
NoneStageTestCase(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)1173 NoneStageTestCase::NoneStageTestCase(tcu::TestContext&	testContext, const std::string&	name, const TestParams&	testParams)
1174 	: vkt::TestCase	(testContext, name)
1175 	, m_testParams	(testParams)
1176 {
1177 }
1178 
initPrograms(SourceCollections & sourceCollections) const1179 void NoneStageTestCase::initPrograms(SourceCollections& sourceCollections) const
1180 {
1181 	const auto writeLayout	= m_testParams.writeLayout;
1182 	const auto writeAspect	= m_testParams.writeAspect;
1183 	const auto readLayout	= m_testParams.readLayout;
1184 	const auto readAspect	= m_testParams.readAspect;
1185 
1186 	// for tests that use only transfer and general layouts we don't create pipeline
1187 	if (((writeLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) || (readLayout == VK_IMAGE_LAYOUT_GENERAL)) &&
1188 		((writeLayout == VK_IMAGE_LAYOUT_GENERAL) || (readLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)))
1189 		return;
1190 
1191 	sourceCollections.glslSources.add("vert") << glu::VertexSource(
1192 		"#version 450\n"
1193 		"layout(location = 0) in  vec4 inPosition;\n"
1194 		"layout(location = 0) out vec2 outUV;\n"
1195 		"void main(void)\n"
1196 		"{\n"
1197 		"  outUV = vec2(inPosition.x * 0.5 + 0.5, inPosition.y * 0.5 + 0.5);\n"
1198 		"  gl_Position = inPosition;\n"
1199 		"}\n"
1200 	);
1201 
1202 	sourceCollections.glslSources.add("frag-color") << glu::FragmentSource(
1203 		"#version 450\n"
1204 		"layout(binding = 0) uniform sampler2D u_sampler;\n"
1205 		"layout(location = 0) in vec2 inUV;\n"
1206 		"layout(location = 0) out vec4 fragColor;\n"
1207 		"void main(void)\n"
1208 		"{\n"
1209 		"  fragColor = texture(u_sampler, inUV);\n"
1210 		"}\n"
1211 	);
1212 
1213 	if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1214 	{
1215 		sourceCollections.glslSources.add("frag-color-to-depth") << glu::FragmentSource(
1216 			"#version 450\n"
1217 			"layout(binding = 0) uniform sampler2D u_sampler;\n"
1218 			"layout(location = 0) in vec2 inUV;\n"
1219 			"void main(void)\n"
1220 			"{\n"
1221 			"  gl_FragDepth = texture(u_sampler, inUV).r;\n"
1222 			"}\n"
1223 		);
1224 	}
1225 
1226 	if (writeAspect & VK_IMAGE_ASPECT_STENCIL_BIT)
1227 	{
1228 		sourceCollections.glslSources.add("frag-color-to-stencil") << glu::FragmentSource(
1229 			"#version 450\n"
1230 			"void main(void)\n"
1231 			"{\n"
1232 			"}\n"
1233 		);
1234 	}
1235 	if ((readLayout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) &&
1236 		(readLayout != VK_IMAGE_LAYOUT_GENERAL) &&
1237 		((readAspect | writeAspect) == VK_IMAGE_ASPECT_STENCIL_BIT || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL && m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL)))
1238 	{
1239 		// use usampler2D and uvec4 for color
1240 		sourceCollections.glslSources.add("frag-stencil-to-color") << glu::FragmentSource(
1241 			"#version 450\n"
1242 			"layout(binding = 0) uniform usampler2D u_sampler;\n"
1243 			"layout(location = 0) in vec2 inUV;\n"
1244 			"layout(location = 0) out uvec4 fragColor;\n"
1245 			"void main(void)\n"
1246 			"{\n"
1247 			"  fragColor = texture(u_sampler, inUV);\n"
1248 			"}\n"
1249 		);
1250 	}
1251 
1252 	if (readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1253 	{
1254 		// for stencil only cases we need to use usubpassInput (for depth and depth_stencil we need to use subpassInput)
1255 		const bool									readDepth			= readAspect & VK_IMAGE_ASPECT_DEPTH_BIT;
1256 		const std::map<std::string, std::string>	specializations
1257 		{
1258 			{ "SUBPASS_INPUT",	(readDepth ? "subpassInput"	: "usubpassInput")	},
1259 			{ "VALUE_TYPE",		(readDepth ? "float"		: "uint")			}
1260 		};
1261 
1262 		std::string source =
1263 			"#version 450\n"
1264 			"layout (input_attachment_index = 0, binding = 0) uniform ${SUBPASS_INPUT} depthOrStencilInput;\n"
1265 			"layout(location = 0) in vec2 inUV;\n"
1266 			"layout(location = 0) out ${VALUE_TYPE} fragColor;\n"
1267 			"void main (void)\n"
1268 			"{\n"
1269 			"  fragColor = subpassLoad(depthOrStencilInput).x;\n"
1270 			"}\n";
1271 		sourceCollections.glslSources.add("frag-depth-or-stencil-to-color")
1272 			<< glu::FragmentSource(tcu::StringTemplate(source).specialize(specializations));
1273 	}
1274 }
1275 
createInstance(Context & context) const1276 TestInstance* NoneStageTestCase::createInstance(Context& context) const
1277 {
1278 	return new NoneStageTestInstance(context, m_testParams);
1279 }
1280 
checkSupport(Context & context) const1281 void NoneStageTestCase::checkSupport(Context& context) const
1282 {
1283 	context.requireDeviceFunctionality("VK_KHR_synchronization2");
1284 
1285 	const auto writeAspect	= m_testParams.writeAspect;
1286 	const auto readAspect	= m_testParams.readAspect;
1287 
1288 	// check whether implementation supports separate depth/stencil layouts
1289 	if (((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) && (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1290 		((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) && (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT)))
1291 	{
1292 		if(!context.getSeparateDepthStencilLayoutsFeatures().separateDepthStencilLayouts)
1293 			TCU_THROW(NotSupportedError, "Implementation does not support separateDepthStencilLayouts");
1294 	}
1295 
1296 	const auto writeLayout	= m_testParams.writeLayout;
1297 	const auto readLayout	= m_testParams.readLayout;
1298 	bool usePipelineToWrite	= (writeLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) && (writeLayout != VK_IMAGE_LAYOUT_GENERAL);
1299 	bool usePipelineToRead	= (readLayout  != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) && (readLayout  != VK_IMAGE_LAYOUT_GENERAL);
1300 
1301 	if (!usePipelineToWrite && !usePipelineToRead)
1302 		return;
1303 
1304 	VkFormat transitionImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
1305 	if ((writeAspect == VK_IMAGE_ASPECT_DEPTH_BIT) || (readAspect == VK_IMAGE_ASPECT_DEPTH_BIT))
1306 		transitionImageFormat = VK_FORMAT_D32_SFLOAT;
1307 	else if ((writeAspect == VK_IMAGE_ASPECT_STENCIL_BIT) || (readAspect == VK_IMAGE_ASPECT_STENCIL_BIT))
1308 		transitionImageFormat = VK_FORMAT_S8_UINT;
1309 	else if ((writeAspect == IMAGE_ASPECT_DEPTH_STENCIL) || (readAspect == IMAGE_ASPECT_DEPTH_STENCIL))
1310 		transitionImageFormat = VK_FORMAT_D24_UNORM_S8_UINT;
1311 
1312 	struct FormatToCheck
1313 	{
1314 		VkFormat			format;
1315 		VkImageUsageFlags	usage;
1316 	};
1317 	std::vector<FormatToCheck> formatsToCheck
1318 	{
1319 		// reference image
1320 		{ transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_DST_BIT },
1321 
1322 		// image to write
1323 		{ transitionImageFormat, (VkImageUsageFlags)VK_IMAGE_USAGE_TRANSFER_SRC_BIT }
1324 	};
1325 
1326 	// note: conditions here are analogic to conditions in test case constructor
1327 	//       everything not needed was cout out leaving only logic related to
1328 	//       m_referenceImage and m_imageToWrite
1329 	if (usePipelineToWrite)
1330 	{
1331 		if (writeAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT))
1332 		{
1333 			if (writeAspect & VK_IMAGE_ASPECT_DEPTH_BIT)
1334 			{
1335 				formatsToCheck[0].format = VK_FORMAT_R32_SFLOAT;
1336 				formatsToCheck[0].usage	|= VK_IMAGE_USAGE_SAMPLED_BIT;
1337 			}
1338 			else
1339 				formatsToCheck[0].usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1340 
1341 			formatsToCheck[1].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1342 		}
1343 		else
1344 		{
1345 			formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1346 			formatsToCheck[1].usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1347 		}
1348 	}
1349 
1350 	if (usePipelineToRead)
1351 	{
1352 		// for layouts that operate on depth or stencil (not depth_stencil) use input attachment to read
1353 		if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
1354 		{
1355 			formatsToCheck[1].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1356 
1357 			if (!usePipelineToWrite)
1358 				formatsToCheck[0].usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1359 		}
1360 		else // use image sampler for color and depth_stencil layouts
1361 		{
1362 			formatsToCheck[0].usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
1363 
1364 			// for depth_stencil layouts we need to have depth_stencil_attachment usage
1365 			if (!usePipelineToWrite && (readAspect & VK_IMAGE_ASPECT_STENCIL_BIT))
1366 				formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1367 		}
1368 		if ((readAspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) && (readAspect != IMAGE_ASPECT_DEPTH_STENCIL))
1369 			if ((m_testParams.readLayout == VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL || m_testParams.readLayout == VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL))
1370 				formatsToCheck[0].usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1371 	}
1372 
1373 	// it simplifies logic to pop image to write then to add conditions everywhere above
1374 	if (!usePipelineToWrite)
1375 		formatsToCheck.pop_back();
1376 
1377 	for (const auto& formatData : formatsToCheck)
1378 	{
1379 		VkImageFormatProperties			properties;
1380 		const vk::InstanceInterface&	vki = context.getInstanceInterface();
1381 		if (vki.getPhysicalDeviceImageFormatProperties(context.getPhysicalDevice(),
1382 													   formatData.format,
1383 													   VK_IMAGE_TYPE_2D,
1384 													   VK_IMAGE_TILING_OPTIMAL,
1385 													   formatData.usage,
1386 													   0,
1387 													   &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
1388 		{
1389 			std::string error = std::string("Format (") +
1390 								vk::getFormatName(formatData.format) + ") doesn't support required capabilities.";
1391 			TCU_THROW(NotSupportedError, error.c_str());
1392 		}
1393 	}
1394 }
1395 
1396 } // anonymous
1397 
createNoneStageTests(tcu::TestContext & testCtx)1398 tcu::TestCaseGroup* createNoneStageTests(tcu::TestContext& testCtx)
1399 {
1400 	de::MovePtr<tcu::TestCaseGroup> noneStageTests(new tcu::TestCaseGroup(testCtx, "none_stage"));
1401 
1402 	struct LayoutData
1403 	{
1404 		VkImageLayout		token;
1405 		VkImageAspectFlags	aspect;
1406 		std::string			name;
1407 	};
1408 
1409 	const std::vector<LayoutData> writableLayoutsData
1410 	{
1411 		{ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,							IMAGE_ASPECT_ALL,				"transfer_dst" },
1412 		{ VK_IMAGE_LAYOUT_GENERAL,										IMAGE_ASPECT_ALL,				"general" },
1413 		{ VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,						VK_IMAGE_ASPECT_COLOR_BIT,		"color_attachment" },
1414 		{ VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				IMAGE_ASPECT_DEPTH_STENCIL,		"depth_stencil_attachment" },
1415 		{ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL,						VK_IMAGE_ASPECT_DEPTH_BIT,		"depth_attachment" },
1416 		{ VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL,					VK_IMAGE_ASPECT_STENCIL_BIT,	"stencil_attachment" },
1417 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_COLOR_BIT,		"generic_color_attachment" },
1418 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_DEPTH_BIT,		"generic_depth_attachment" },
1419 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						VK_IMAGE_ASPECT_STENCIL_BIT,	"generic_stencil_attachment" },
1420 		{ VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,						IMAGE_ASPECT_DEPTH_STENCIL,		"generic_depth_stencil_attachment" },
1421 	};
1422 	const std::vector<LayoutData> readableLayoutsData
1423 	{
1424 		{ VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,							IMAGE_ASPECT_ALL,				"transfer_src" },
1425 		{ VK_IMAGE_LAYOUT_GENERAL,										IMAGE_ASPECT_ALL,				"general" },
1426 		{ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,						IMAGE_ASPECT_ALL,				"shader_read" },
1427 		{ VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL,				IMAGE_ASPECT_DEPTH_STENCIL,		"depth_stencil_read" },
1428 		{ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL,	IMAGE_ASPECT_DEPTH_STENCIL,		"depth_read_stencil_attachment" },
1429 		{ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL,	IMAGE_ASPECT_DEPTH_STENCIL,		"depth_attachment_stencil_read" },
1430 		{ VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL,						VK_IMAGE_ASPECT_DEPTH_BIT,		"depth_read" },
1431 		{ VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL,					VK_IMAGE_ASPECT_STENCIL_BIT,	"stencil_read" },
1432 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						IMAGE_ASPECT_ALL,				"generic_color_read" },
1433 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						VK_IMAGE_ASPECT_DEPTH_BIT,		"generic_depth_read" },
1434 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						VK_IMAGE_ASPECT_STENCIL_BIT,	"generic_stencil_read" },
1435 		{ VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR,						IMAGE_ASPECT_DEPTH_STENCIL,		"generic_depth_stencil_read" },
1436 	};
1437 
1438 	struct SynchronizationData
1439 	{
1440 		SynchronizationType		type;
1441 		std::string				casePrefix;
1442 		bool					useGenericAccessFlags;
1443 	};
1444 	std::vector<SynchronizationData> synchronizationData
1445 	{
1446 		{ SynchronizationType::SYNCHRONIZATION2,	"",					true },
1447 		{ SynchronizationType::SYNCHRONIZATION2,	"old_access_",		false },
1448 
1449 		// using legacy synchronization structures with NONE_STAGE
1450 		{ SynchronizationType::LEGACY,				"legacy_",			false }
1451 	};
1452 
1453 	for (const auto& syncData : synchronizationData)
1454 	{
1455 		for (const auto& writeData : writableLayoutsData)
1456 		{
1457 			for (const auto& readData : readableLayoutsData)
1458 			{
1459 				if (readData.aspect && writeData.aspect &&
1460 				   (readData.aspect != writeData.aspect))
1461 					continue;
1462 
1463 				const std::string name = syncData.casePrefix + writeData.name + "_to_" + readData.name;
1464 				noneStageTests->addChild(new NoneStageTestCase(testCtx, name, {
1465 					syncData.type,
1466 					syncData.useGenericAccessFlags,
1467 					writeData.token,
1468 					writeData.aspect,
1469 					readData.token,
1470 					readData.aspect
1471 				}));
1472 			}
1473 		}
1474 	}
1475 
1476 	return noneStageTests.release();
1477 }
1478 
1479 } // synchronization
1480 } // vkt
1481