• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Vulkan Multi View Render Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktMultiViewRenderTests.hpp"
25 #include "vktMultiViewRenderUtil.hpp"
26 #include "vktMultiViewRenderPassUtil.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28 
29 #include "vktTestCase.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkPlatform.hpp"
36 #include "vkMemUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40 
41 #include "tcuTestLog.hpp"
42 #include "tcuResource.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuCommandLine.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuRGBA.hpp"
47 
48 #include "deRandom.hpp"
49 #include "deMath.h"
50 #include "deSharedPtr.hpp"
51 
52 namespace vkt
53 {
54 namespace MultiView
55 {
56 namespace
57 {
58 
59 using namespace vk;
60 using de::MovePtr;
61 using de::UniquePtr;
62 using std::vector;
63 using std::map;
64 using std::string;
65 
66 enum TestType
67 {
68 	TEST_TYPE_VIEW_MASK,
69 	TEST_TYPE_VIEW_INDEX_IN_VERTEX,
70 	TEST_TYPE_VIEW_INDEX_IN_FRAGMENT,
71 	TEST_TYPE_VIEW_INDEX_IN_GEOMETRY,
72 	TEST_TYPE_VIEW_INDEX_IN_TESELLATION,
73 	TEST_TYPE_INPUT_ATTACHMENTS,
74 	TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY,
75 	TEST_TYPE_INSTANCED_RENDERING,
76 	TEST_TYPE_INPUT_RATE_INSTANCE,
77 	TEST_TYPE_DRAW_INDIRECT,
78 	TEST_TYPE_DRAW_INDIRECT_INDEXED,
79 	TEST_TYPE_DRAW_INDEXED,
80 	TEST_TYPE_CLEAR_ATTACHMENTS,
81 	TEST_TYPE_SECONDARY_CMD_BUFFER,
82 	TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY,
83 	TEST_TYPE_POINT_SIZE,
84 	TEST_TYPE_MULTISAMPLE,
85 	TEST_TYPE_QUERIES,
86 	TEST_TYPE_NON_PRECISE_QUERIES,
87 	TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR,
88 	TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR,
89 	TEST_TYPE_DEPTH,
90 	TEST_TYPE_DEPTH_DIFFERENT_RANGES,
91 	TEST_TYPE_STENCIL,
92 	TEST_TYPE_LAST
93 };
94 
95 enum RenderingType
96 {
97 	RENDERING_TYPE_RENDERPASS_LEGACY = 0,
98 	RENDERING_TYPE_RENDERPASS2,
99 	RENDERING_TYPE_DYNAMIC_RENDERING
100 };
101 
102 struct TestParameters
103 {
104 	VkExtent3D				extent;
105 	vector<deUint32>		viewMasks;
106 	TestType				viewIndex;
107 	VkSampleCountFlagBits	samples;
108 	VkFormat				colorFormat;
109 	RenderingType			renderingType;
110 };
111 
112 const int	TEST_POINT_SIZE_SMALL	= 2;
113 const int	TEST_POINT_SIZE_WIDE	= 4;
114 
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const vector<deUint32> & viewMasks,RenderingType renderingType,const VkSampleCountFlagBits samples=VK_SAMPLE_COUNT_1_BIT,const VkAttachmentLoadOp colorLoadOp=VK_ATTACHMENT_LOAD_OP_CLEAR,const VkFormat dsFormat=VK_FORMAT_UNDEFINED)115 vk::Move<vk::VkRenderPass> makeRenderPass (const DeviceInterface&		vk,
116 										   const VkDevice				device,
117 										   const VkFormat				colorFormat,
118 										   const vector<deUint32>&		viewMasks,
119 										   RenderingType				renderingType,
120 										   const VkSampleCountFlagBits	samples = VK_SAMPLE_COUNT_1_BIT,
121 										   const VkAttachmentLoadOp		colorLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
122 										   const VkFormat				dsFormat = VK_FORMAT_UNDEFINED)
123 {
124 	switch (renderingType)
125 	{
126 		case RENDERING_TYPE_RENDERPASS_LEGACY:
127 			return MultiView::makeRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat);
128 		case RENDERING_TYPE_RENDERPASS2:
129 			return MultiView::makeRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, samples, colorLoadOp, dsFormat);
130 		default:
131 			TCU_THROW(InternalError, "Impossible");
132 	}
133 }
134 
makeRenderPassWithAttachments(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const vector<deUint32> & viewMasks,RenderingType renderingType)135 vk::Move<vk::VkRenderPass> makeRenderPassWithAttachments (const DeviceInterface&	vk,
136 														  const VkDevice			device,
137 														  const VkFormat			colorFormat,
138 														  const vector<deUint32>&	viewMasks,
139 														  RenderingType				renderingType)
140 {
141 	switch (renderingType)
142 	{
143 		case RENDERING_TYPE_RENDERPASS_LEGACY:
144 			return MultiView::makeRenderPassWithAttachments<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, false);
145 		case RENDERING_TYPE_RENDERPASS2:
146 			return MultiView::makeRenderPassWithAttachments<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, true);
147 		default:
148 			TCU_THROW(InternalError, "Impossible");
149 	}
150 }
151 
makeRenderPassWithDepth(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat,const vector<deUint32> & viewMasks,const VkFormat dsFormat,RenderingType renderingType)152 vk::Move<vk::VkRenderPass> makeRenderPassWithDepth (const DeviceInterface&	vk,
153 													const VkDevice			device,
154 													const VkFormat			colorFormat,
155 													const vector<deUint32>&	viewMasks,
156 													const VkFormat			dsFormat,
157 													RenderingType			renderingType)
158 {
159 	switch (renderingType)
160 	{
161 		case RENDERING_TYPE_RENDERPASS_LEGACY:
162 			return MultiView::makeRenderPassWithDepth<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, device, colorFormat, viewMasks, dsFormat);
163 		case RENDERING_TYPE_RENDERPASS2:
164 			return MultiView::makeRenderPassWithDepth<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, device, colorFormat, viewMasks, dsFormat);
165 		default:
166 			TCU_THROW(InternalError, "Impossible");
167 	}
168 }
169 
170 template<typename RenderpassSubpass>
cmdBeginRenderPass(DeviceInterface & vkd,VkCommandBuffer cmdBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassContents contents)171 void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents)
172 {
173 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, contents);
174 
175 	RenderpassSubpass::cmdBeginRenderPass(vkd, cmdBuffer, pRenderPassBegin, &subpassBeginInfo);
176 }
177 
cmdBeginRenderPass(DeviceInterface & vkd,VkCommandBuffer cmdBuffer,const VkRenderPassBeginInfo * pRenderPassBegin,const VkSubpassContents contents,RenderingType renderingType)178 void cmdBeginRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkRenderPassBeginInfo* pRenderPassBegin, const VkSubpassContents contents, RenderingType renderingType)
179 {
180 	switch (renderingType)
181 	{
182 		case RENDERING_TYPE_RENDERPASS_LEGACY:	cmdBeginRenderPass<RenderpassSubpass1>(vkd, cmdBuffer, pRenderPassBegin, contents);	break;
183 		case RENDERING_TYPE_RENDERPASS2:		cmdBeginRenderPass<RenderpassSubpass2>(vkd, cmdBuffer, pRenderPassBegin, contents);	break;
184 		default:								TCU_THROW(InternalError, "Impossible");
185 	}
186 }
187 
188 template<typename RenderpassSubpass>
cmdNextSubpass(DeviceInterface & vkd,VkCommandBuffer cmdBuffer,const VkSubpassContents contents)189 void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents)
190 {
191 	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, contents);
192 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
193 
194 	RenderpassSubpass::cmdNextSubpass(vkd, cmdBuffer, &subpassBeginInfo, &subpassEndInfo);
195 }
196 
cmdNextSubpass(DeviceInterface & vkd,VkCommandBuffer cmdBuffer,const VkSubpassContents contents,RenderingType renderingType)197 void cmdNextSubpass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, const VkSubpassContents contents, RenderingType renderingType)
198 {
199 	switch (renderingType)
200 	{
201 		case RENDERING_TYPE_RENDERPASS_LEGACY:	cmdNextSubpass<RenderpassSubpass1>(vkd, cmdBuffer, contents);	break;
202 		case RENDERING_TYPE_RENDERPASS2:		cmdNextSubpass<RenderpassSubpass2>(vkd, cmdBuffer, contents);	break;
203 		default:								TCU_THROW(InternalError, "Impossible");
204 	}
205 }
206 
207 template<typename RenderpassSubpass>
cmdEndRenderPass(DeviceInterface & vkd,VkCommandBuffer cmdBuffer)208 void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer)
209 {
210 	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo	(DE_NULL);
211 
212 	RenderpassSubpass::cmdEndRenderPass(vkd, cmdBuffer, &subpassEndInfo);
213 }
214 
cmdEndRenderPass(DeviceInterface & vkd,VkCommandBuffer cmdBuffer,RenderingType renderingType)215 void cmdEndRenderPass (DeviceInterface& vkd, VkCommandBuffer cmdBuffer, RenderingType renderingType)
216 {
217 	switch (renderingType)
218 	{
219 		case RENDERING_TYPE_RENDERPASS_LEGACY:	cmdEndRenderPass<RenderpassSubpass1>(vkd, cmdBuffer);	break;
220 		case RENDERING_TYPE_RENDERPASS2:		cmdEndRenderPass<RenderpassSubpass2>(vkd, cmdBuffer);	break;
221 		default:								TCU_THROW(InternalError, "Impossible");
222 	}
223 }
224 
225 class ImageAttachment
226 {
227 public:
228 				ImageAttachment	(VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT);
getImageView(void) const229 	VkImageView	getImageView	(void) const
230 	{
231 		return *m_imageView;
232 	}
getImage(void) const233 	VkImage		getImage		(void) const
234 	{
235 		return *m_image;
236 	}
237 private:
238 	Move<VkImage>			m_image;
239 	MovePtr<Allocation>		m_allocationImage;
240 	Move<VkImageView>		m_imageView;
241 };
242 
ImageAttachment(VkDevice logicalDevice,DeviceInterface & device,Allocator & allocator,const VkExtent3D extent,VkFormat colorFormat,const VkSampleCountFlagBits samples)243 ImageAttachment::ImageAttachment (VkDevice logicalDevice, DeviceInterface& device, Allocator& allocator, const VkExtent3D extent, VkFormat colorFormat, const VkSampleCountFlagBits samples)
244 {
245 	const bool						depthStencilFormat			= isDepthStencilFormat(colorFormat);
246 	const VkImageAspectFlags		aspectFlags					= depthStencilFormat ? VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT : VK_IMAGE_ASPECT_COLOR_BIT;
247 	const VkImageSubresourceRange	colorImageSubresourceRange	= makeImageSubresourceRange(aspectFlags, 0u, 1u, 0u, extent.depth);
248 	const VkImageUsageFlags			imageUsageFlagsDependent	= depthStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
249 	const VkImageUsageFlags			imageUsageFlags				= imageUsageFlagsDependent | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
250 	const VkImageCreateInfo			colorAttachmentImageInfo	= makeImageCreateInfo(VK_IMAGE_TYPE_2D, extent, colorFormat, imageUsageFlags, samples);
251 
252 	m_image							= createImage(device, logicalDevice, &colorAttachmentImageInfo);
253 	m_allocationImage				= allocator.allocate(getImageMemoryRequirements(device, logicalDevice, *m_image), MemoryRequirement::Any);
254 	VK_CHECK(device.bindImageMemory(logicalDevice, *m_image, m_allocationImage->getMemory(), m_allocationImage->getOffset()));
255 	m_imageView						= makeImageView(device, logicalDevice, *m_image, VK_IMAGE_VIEW_TYPE_2D_ARRAY, colorFormat, colorImageSubresourceRange);
256 }
257 
258 class MultiViewRenderTestInstance : public TestInstance
259 {
260 public:
261 									MultiViewRenderTestInstance	(Context& context, const TestParameters& parameters);
262 protected:
263 	typedef de::SharedPtr<Unique<VkPipeline> >		PipelineSp;
264 	typedef de::SharedPtr<Unique<VkShaderModule> >	ShaderModuleSP;
265 
266 	virtual tcu::TestStatus					iterate					(void);
267 	virtual void							beforeDraw				(void);
268 	virtual void							afterDraw				(void);
269 	virtual void							draw					(const deUint32			subpassCount,
270 																	 VkRenderPass			renderPass,
271 																	 VkFramebuffer			frameBuffer,
272 																	 vector<PipelineSp>&	pipelines);
273 	virtual void							createVertexData		(void);
274 	virtual MovePtr<tcu::Texture2DArray>	imageData				(void) const;
275 	TestParameters							fillMissingParameters	(const TestParameters&	parameters);
276 	void									createVertexBuffer		(void);
277 	void									createMultiViewDevices	(void);
278 	void									createCommandBuffer		(void);
279 	void									madeShaderModule		(map<VkShaderStageFlagBits,ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams);
280 	Move<VkPipeline>						makeGraphicsPipeline	(const VkRenderPass							renderPass,
281 																	 const VkPipelineLayout						pipelineLayout,
282 																	 const deUint32								pipelineShaderStageCount,
283 																	 const VkPipelineShaderStageCreateInfo*		pipelineShaderStageCreate,
284 																	 const deUint32								subpass,
285 																	 const VkVertexInputRate					vertexInputRate = VK_VERTEX_INPUT_RATE_VERTEX,
286 																	 const bool									useDepthTest = false,
287 																	 const bool									useStencilTest = false,
288 																	 const float								minDepth = 0.0f,
289 																	 const float								maxDepth = 1.0f,
290 																	 const VkFormat                                                         dsFormat = VK_FORMAT_UNDEFINED);
291 	void									readImage				(VkImage image, const tcu::PixelBufferAccess& dst);
292 	bool									checkImage				(tcu::ConstPixelBufferAccess& dst);
293 	const tcu::Vec4							getQuarterRefColor		(const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background = true, const deUint32 subpassNdx = 0u) const;
294 	void									appendVertex			(const tcu::Vec4& coord, const tcu::Vec4& color);
295 	void									setPoint				(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter) const;
296 	void									fillTriangle			(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter) const;
297 	void									fillLayer				(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx) const;
298 	void									fillQuarter				(const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx) const;
299 
300 	const TestParameters			m_parameters;
301 	const bool						m_useDynamicRendering;
302 	const int						m_seed;
303 	const deUint32					m_squareCount;
304 	Move<VkDevice>					m_logicalDevice;
305 	MovePtr<DeviceInterface>		m_device;
306 	MovePtr<Allocator>				m_allocator;
307 	deUint32						m_queueFamilyIndex;
308 	VkQueue							m_queue;
309 	vector<tcu::Vec4>				m_vertexCoord;
310 	Move<VkBuffer>					m_vertexCoordBuffer;
311 	MovePtr<Allocation>				m_vertexCoordAlloc;
312 	vector<tcu::Vec4>				m_vertexColor;
313 	Move<VkBuffer>					m_vertexColorBuffer;
314 	MovePtr<Allocation>				m_vertexColorAlloc;
315 	vector<deUint32>				m_vertexIndices;
316 	Move<VkBuffer>					m_vertexIndicesBuffer;
317 	MovePtr<Allocation>				m_vertexIndicesAllocation;
318 	Move<VkCommandPool>				m_cmdPool;
319 	Move<VkCommandBuffer>			m_cmdBuffer;
320 	de::SharedPtr<ImageAttachment>	m_colorAttachment;
321 	VkBool32						m_hasMultiDrawIndirect;
322 	vector<tcu::Vec4>				m_colorTable;
323 };
324 
MultiViewRenderTestInstance(Context & context,const TestParameters & parameters)325 MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters)
326 	: TestInstance			(context)
327 	, m_parameters			(fillMissingParameters(parameters))
328 	, m_useDynamicRendering	(parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
329 	, m_seed				(context.getTestContext().getCommandLine().getBaseSeed())
330 	, m_squareCount			(4u)
331 	, m_queueFamilyIndex	(0u)
332 {
333 	const float v	= 0.75f;
334 	const float o	= 0.25f;
335 
336 	m_colorTable.push_back(tcu::Vec4(v, o, o, 1.0f));
337 	m_colorTable.push_back(tcu::Vec4(o, v, o, 1.0f));
338 	m_colorTable.push_back(tcu::Vec4(o, o, v, 1.0f));
339 	m_colorTable.push_back(tcu::Vec4(o, v, v, 1.0f));
340 	m_colorTable.push_back(tcu::Vec4(v, o, v, 1.0f));
341 	m_colorTable.push_back(tcu::Vec4(v, v, o, 1.0f));
342 	m_colorTable.push_back(tcu::Vec4(o, o, o, 1.0f));
343 	m_colorTable.push_back(tcu::Vec4(v, v, v, 1.0f));
344 
345 	createMultiViewDevices();
346 
347 	// Color attachment
348 	m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, m_parameters.samples));
349 }
350 
iterate(void)351 tcu::TestStatus MultiViewRenderTestInstance::iterate (void)
352 {
353 	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());
354 	Move<VkRenderPass>							renderPass;
355 	Move<VkFramebuffer>							frameBuffer;
356 
357 	// FrameBuffer & renderPass
358 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
359 	{
360 		renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType);
361 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
362 	}
363 
364 	// pipelineLayout
365 	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));
366 
367 	// pipelines
368 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
369 	vector<PipelineSp>							pipelines(subpassCount);
370 	const VkVertexInputRate						vertexInputRate				= (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
371 
372 	{
373 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
374 		madeShaderModule(shaderModule, shaderStageParams);
375 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
376 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
377 	}
378 
379 	createCommandBuffer();
380 	createVertexData();
381 	createVertexBuffer();
382 
383 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
384 
385 	{
386 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
387 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
388 
389 		readImage(m_colorAttachment->getImage(), dst);
390 
391 		if (!checkImage(dst))
392 			return tcu::TestStatus::fail("Fail");
393 	}
394 
395 	return tcu::TestStatus::pass("Pass");
396 }
397 
beforeDraw(void)398 void MultiViewRenderTestInstance::beforeDraw (void)
399 {
400 	const VkImageSubresourceRange	subresourceRange		=
401 	{
402 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
403 		0u,							//deUint32				baseMipLevel;
404 		1u,							//deUint32				levelCount;
405 		0u,							//deUint32				baseArrayLayer;
406 		m_parameters.extent.depth,	//deUint32				layerCount;
407 	};
408 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
409 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
410 		0, VK_ACCESS_TRANSFER_WRITE_BIT,
411 		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
412 
413 	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
414 	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
415 
416 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
417 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
418 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
419 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
420 }
421 
afterDraw(void)422 void MultiViewRenderTestInstance::afterDraw (void)
423 {
424 	const VkImageSubresourceRange	subresourceRange		=
425 	{
426 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
427 		0u,							//deUint32				baseMipLevel;
428 		1u,							//deUint32				levelCount;
429 		0u,							//deUint32				baseArrayLayer;
430 		m_parameters.extent.depth,	//deUint32				layerCount;
431 	};
432 
433 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
434 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
435 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
436 		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
437 }
438 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)439 void MultiViewRenderTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
440 {
441 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
442 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
443 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
444 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
445 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
446 
447 	beginCommandBuffer(*m_device, *m_cmdBuffer);
448 
449 	beforeDraw();
450 
451 	if (!m_useDynamicRendering)
452 	{
453 		const VkRenderPassBeginInfo renderPassBeginInfo
454 		{
455 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
456 			DE_NULL,									// const void*			pNext;
457 			renderPass,									// VkRenderPass			renderPass;
458 			frameBuffer,								// VkFramebuffer		framebuffer;
459 			renderArea,									// VkRect2D				renderArea;
460 			1u,											// uint32_t				clearValueCount;
461 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
462 		};
463 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
464 	}
465 
466 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
467 
468 	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
469 		m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);
470 
471 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
472 	{
473 		if (m_useDynamicRendering)
474 		{
475 			beginRendering(
476 				*m_device,
477 				*m_cmdBuffer,
478 				m_colorAttachment->getImageView(),
479 				renderArea,
480 				renderPassClearValue,
481 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
482 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
483 				0u,
484 				m_parameters.extent.depth,
485 				m_parameters.viewMasks[subpassNdx]);
486 		}
487 
488 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
489 
490 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
491 			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
492 				m_device->cmdDrawIndexed(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u, 0u);
493 			else
494 				m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
495 
496 		if (m_useDynamicRendering)
497 			endRendering(*m_device, *m_cmdBuffer);
498 		else if (subpassNdx < subpassCount - 1u)
499 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
500 	}
501 
502 	if (!m_useDynamicRendering)
503 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
504 
505 	afterDraw();
506 
507 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
508 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
509 }
510 
createVertexData(void)511 void MultiViewRenderTestInstance::createVertexData (void)
512 {
513 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
514 
515 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
516 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
517 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
518 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
519 
520 	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
521 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
522 	appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
523 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
524 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
525 
526 	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
527 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
528 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
529 	appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);
530 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
531 
532 	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
533 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
534 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
535 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
536 	appendVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color);
537 
538 	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
539 	{
540 		const size_t		verticesCount	= m_vertexCoord.size();
541 		vector<tcu::Vec4>	vertexColor		(verticesCount);
542 		vector<tcu::Vec4>	vertexCoord		(verticesCount);
543 
544 		m_vertexIndices.clear();
545 		m_vertexIndices.reserve(verticesCount);
546 		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
547 			m_vertexIndices.push_back(vertexIdx);
548 
549 		de::Random(m_seed).shuffle(m_vertexIndices.begin(), m_vertexIndices.end());
550 
551 		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
552 			vertexColor[m_vertexIndices[vertexIdx]] = m_vertexColor[vertexIdx];
553 		m_vertexColor.assign(vertexColor.begin(), vertexColor.end());
554 
555 		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
556 			vertexCoord[m_vertexIndices[vertexIdx]] = m_vertexCoord[vertexIdx];
557 		m_vertexCoord.assign(vertexCoord.begin(), vertexCoord.end());
558 	}
559 }
560 
fillMissingParameters(const TestParameters & parameters)561 TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters)
562 {
563 	if (!parameters.viewMasks.empty())
564 		return parameters;
565 	else
566 	{
567 		const InstanceInterface&			instance			= m_context.getInstanceInterface();
568 		const VkPhysicalDevice				physicalDevice		= m_context.getPhysicalDevice();
569 
570 		VkPhysicalDeviceMultiviewProperties multiviewProperties =
571 		{
572 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,	// VkStructureType	sType;
573 			DE_NULL,													// void*			pNext;
574 			0u,															// deUint32			maxMultiviewViewCount;
575 			0u															// deUint32			maxMultiviewInstanceIndex;
576 		};
577 
578 		VkPhysicalDeviceProperties2 deviceProperties2;
579 		deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
580 		deviceProperties2.pNext = &multiviewProperties;
581 
582 		instance.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
583 
584 		TestParameters newParameters = parameters;
585 		newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount;
586 
587 		vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount);
588 		for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++)
589 			viewMasks[i] = 1 << i;
590 		newParameters.viewMasks = viewMasks;
591 
592 		return newParameters;
593 	}
594 }
595 
createVertexBuffer(void)596 void MultiViewRenderTestInstance::createVertexBuffer (void)
597 {
598 	DE_ASSERT(m_vertexCoord.size() == m_vertexColor.size());
599 	DE_ASSERT(m_vertexCoord.size() != 0);
600 
601 	const size_t	nonCoherentAtomSize	= static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);
602 
603 	// Upload vertex coordinates
604 	{
605 		const size_t				dataSize		= static_cast<size_t>(m_vertexCoord.size() * sizeof(m_vertexCoord[0]));
606 		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
607 		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
608 
609 		m_vertexCoordBuffer	= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
610 		m_vertexCoordAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexCoordBuffer), MemoryRequirement::HostVisible);
611 
612 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexCoordBuffer, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset()));
613 		deMemcpy(m_vertexCoordAlloc->getHostPtr(), m_vertexCoord.data(), static_cast<size_t>(dataSize));
614 		flushAlloc(*m_device, *m_logicalDevice, *m_vertexCoordAlloc);
615 	}
616 
617 	// Upload vertex colors
618 	{
619 		const size_t				dataSize		= static_cast<size_t>(m_vertexColor.size() * sizeof(m_vertexColor[0]));
620 		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
621 		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
622 
623 		m_vertexColorBuffer	= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
624 		m_vertexColorAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexColorBuffer), MemoryRequirement::HostVisible);
625 
626 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexColorBuffer, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset()));
627 		deMemcpy(m_vertexColorAlloc->getHostPtr(), m_vertexColor.data(), static_cast<size_t>(dataSize));
628 		flushAlloc(*m_device, *m_logicalDevice, *m_vertexColorAlloc);
629 	}
630 
631 	// Upload vertex indices
632 	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
633 	{
634 		const size_t				dataSize		= static_cast<size_t>(m_vertexIndices.size() * sizeof(m_vertexIndices[0]));
635 		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
636 		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
637 
638 		DE_ASSERT(m_vertexIndices.size() == m_vertexCoord.size());
639 
640 		m_vertexIndicesBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
641 		m_vertexIndicesAllocation	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexIndicesBuffer), MemoryRequirement::HostVisible);
642 
643 		// Init host buffer data
644 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexIndicesBuffer, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset()));
645 		deMemcpy(m_vertexIndicesAllocation->getHostPtr(), m_vertexIndices.data(), static_cast<size_t>(dataSize));
646 		flushAlloc(*m_device, *m_logicalDevice, *m_vertexIndicesAllocation);
647 	}
648 	else
649 		DE_ASSERT(m_vertexIndices.empty());
650 }
651 
createMultiViewDevices(void)652 void MultiViewRenderTestInstance::createMultiViewDevices (void)
653 {
654 	const InstanceInterface&				instance				= m_context.getInstanceInterface();
655 	const VkPhysicalDevice					physicalDevice			= m_context.getPhysicalDevice();
656 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
657 
658 	for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex)
659 	{
660 		if ((queueFamilyProperties[m_queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
661 			break;
662 	}
663 
664 	const float								queuePriorities			= 1.0f;
665 	const VkDeviceQueueCreateInfo			queueInfo				=
666 	{
667 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,					//VkStructureType			sType;
668 		DE_NULL,													//const void*				pNext;
669 		(VkDeviceQueueCreateFlags)0u,								//VkDeviceQueueCreateFlags	flags;
670 		m_queueFamilyIndex,											//deUint32					queueFamilyIndex;
671 		1u,															//deUint32					queueCount;
672 		&queuePriorities											//const float*				pQueuePriorities;
673 	};
674 
675 	VkPhysicalDeviceMultiviewFeatures		multiviewFeatures		=
676 	{
677 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR,	// VkStructureType			sType;
678 		DE_NULL,													// void*					pNext;
679 		DE_FALSE,													// VkBool32					multiview;
680 		DE_FALSE,													// VkBool32					multiviewGeometryShader;
681 		DE_FALSE,													// VkBool32					multiviewTessellationShader;
682 	};
683 
684 	VkPhysicalDeviceFeatures2				enabledFeatures;
685 	enabledFeatures.sType					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
686 	enabledFeatures.pNext					= &multiviewFeatures;
687 
688 	instance.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
689 
690 	if (!multiviewFeatures.multiview)
691 		TCU_THROW(NotSupportedError, "MultiView not supported");
692 
693 	bool requiresGeomShader = (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex) ||
694 								(TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex) ||
695 								(TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex);
696 
697 	if (requiresGeomShader && !multiviewFeatures.multiviewGeometryShader)
698 		TCU_THROW(NotSupportedError, "Geometry shader is not supported");
699 
700 	if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader)
701 		TCU_THROW(NotSupportedError, "Tessellation shader is not supported");
702 
703 	VkPhysicalDeviceMultiviewProperties	multiviewProperties			=
704 	{
705 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR,	//VkStructureType	sType;
706 		DE_NULL,													//void*				pNext;
707 		0u,															//deUint32			maxMultiviewViewCount;
708 		0u															//deUint32			maxMultiviewInstanceIndex;
709 	};
710 
711 	VkPhysicalDeviceProperties2			propertiesDeviceProperties2;
712 	propertiesDeviceProperties2.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
713 	propertiesDeviceProperties2.pNext	= &multiviewProperties;
714 
715 	instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2);
716 
717 	if (multiviewProperties.maxMultiviewViewCount < 6u)
718 		TCU_FAIL("maxMultiviewViewCount below min value");
719 
720 	if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1
721 		TCU_FAIL("maxMultiviewInstanceIndex below min value");
722 
723 	if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth)
724 		TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test");
725 
726 	m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect;
727 
728 	{
729 		vector<const char*>				deviceExtensions;
730 
731 		if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview"))
732 			deviceExtensions.push_back("VK_KHR_multiview");
733 
734 		if ((m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2) &&
735 			!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_create_renderpass2"))
736 			deviceExtensions.push_back("VK_KHR_create_renderpass2");
737 		if ((m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) &&
738 			!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_dynamic_rendering"))
739 			deviceExtensions.push_back("VK_KHR_dynamic_rendering");
740 
741 		if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
742 			deviceExtensions.push_back("VK_EXT_depth_range_unrestricted");
743 
744 		const VkDeviceCreateInfo		deviceInfo			=
745 		{
746 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//VkStructureType					sType;
747 			&enabledFeatures,												//const void*						pNext;
748 			0u,																//VkDeviceCreateFlags				flags;
749 			1u,																//deUint32							queueCreateInfoCount;
750 			&queueInfo,														//const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
751 			0u,																//deUint32							enabledLayerCount;
752 			DE_NULL,														//const char* const*				ppEnabledLayerNames;
753 			static_cast<deUint32>(deviceExtensions.size()),					//deUint32							enabledExtensionCount;
754 			deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],		//const char* const*				pEnabledExtensionNames;
755 			DE_NULL															//const VkPhysicalDeviceFeatures*	pEnabledFeatures;
756 		};
757 
758 		m_logicalDevice					= createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_context.getInstance(), instance, physicalDevice, &deviceInfo);
759 		m_device						= MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), *m_logicalDevice));
760 		m_allocator						= MovePtr<Allocator>(new SimpleAllocator(*m_device, *m_logicalDevice, getPhysicalDeviceMemoryProperties(instance, physicalDevice)));
761 		m_device->getDeviceQueue		(*m_logicalDevice, m_queueFamilyIndex, 0u, &m_queue);
762 	}
763 }
764 
createCommandBuffer(void)765 void MultiViewRenderTestInstance::createCommandBuffer (void)
766 {
767 	// cmdPool
768 	{
769 		const VkCommandPoolCreateInfo cmdPoolParams =
770 		{
771 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType		sType;
772 			DE_NULL,											// const void*			pNext;
773 			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCmdPoolCreateFlags	flags;
774 			m_queueFamilyIndex,									// deUint32				queueFamilyIndex;
775 		};
776 		m_cmdPool = createCommandPool(*m_device, *m_logicalDevice, &cmdPoolParams);
777 	}
778 
779 	// cmdBuffer
780 	{
781 		const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
782 		{
783 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
784 			DE_NULL,											// const void*			pNext;
785 			*m_cmdPool,											// VkCommandPool		commandPool;
786 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
787 			1u,													// deUint32				bufferCount;
788 		};
789 		m_cmdBuffer	= allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo);
790 	}
791 }
792 
madeShaderModule(map<VkShaderStageFlagBits,ShaderModuleSP> & shaderModule,vector<VkPipelineShaderStageCreateInfo> & shaderStageParams)793 void MultiViewRenderTestInstance::madeShaderModule (map<VkShaderStageFlagBits, ShaderModuleSP>& shaderModule, vector<VkPipelineShaderStageCreateInfo>& shaderStageParams)
794 {
795 	// create shaders modules
796 	switch (m_parameters.viewIndex)
797 	{
798 		case TEST_TYPE_VIEW_MASK:
799 		case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
800 		case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
801 		case TEST_TYPE_INSTANCED_RENDERING:
802 		case TEST_TYPE_INPUT_RATE_INSTANCE:
803 		case TEST_TYPE_DRAW_INDIRECT:
804 		case TEST_TYPE_DRAW_INDIRECT_INDEXED:
805 		case TEST_TYPE_DRAW_INDEXED:
806 		case TEST_TYPE_CLEAR_ATTACHMENTS:
807 		case TEST_TYPE_SECONDARY_CMD_BUFFER:
808 		case TEST_TYPE_INPUT_ATTACHMENTS:
809 		case TEST_TYPE_POINT_SIZE:
810 		case TEST_TYPE_MULTISAMPLE:
811 		case TEST_TYPE_QUERIES:
812 		case TEST_TYPE_NON_PRECISE_QUERIES:
813 		case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
814 		case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
815 		case TEST_TYPE_DEPTH:
816 		case TEST_TYPE_DEPTH_DIFFERENT_RANGES:
817 		case TEST_TYPE_STENCIL:
818 			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
819 			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
820 			break;
821 		case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
822 		case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
823 		case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
824 			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
825 			shaderModule[VK_SHADER_STAGE_GEOMETRY_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("geometry"), 0))));
826 			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
827 			break;
828 		case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
829 			shaderModule[VK_SHADER_STAGE_VERTEX_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("vertex"), 0))));
830 			shaderModule[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT]		= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_control"), 0))));
831 			shaderModule[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT]	= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("tessellation_evaluation"), 0))));
832 			shaderModule[VK_SHADER_STAGE_FRAGMENT_BIT]					= (ShaderModuleSP(new Unique<VkShaderModule>(createShaderModule(*m_device, *m_logicalDevice, m_context.getBinaryCollection().get("fragment"), 0))));
833 			break;
834 		default:
835 			DE_ASSERT(0);
836 		break;
837 	}
838 
839 	VkPipelineShaderStageCreateInfo	pipelineShaderStage	=
840 	{
841 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
842 			DE_NULL,												// const void*							pNext;
843 			(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
844 			(VkShaderStageFlagBits)0,								// VkShaderStageFlagBits				stage;
845 			(VkShaderModule)0,										// VkShaderModule						module;
846 			"main",													// const char*							pName;
847 			(const VkSpecializationInfo*)DE_NULL,					// const VkSpecializationInfo*			pSpecializationInfo;
848 	};
849 
850 	for (map<VkShaderStageFlagBits, ShaderModuleSP>::iterator it=shaderModule.begin(); it!=shaderModule.end(); ++it)
851 	{
852 		pipelineShaderStage.stage	= it->first;
853 		pipelineShaderStage.module	= **it->second;
854 		shaderStageParams.push_back(pipelineShaderStage);
855 	}
856 }
857 
makeGraphicsPipeline(const VkRenderPass renderPass,const VkPipelineLayout pipelineLayout,const deUint32 pipelineShaderStageCount,const VkPipelineShaderStageCreateInfo * pipelineShaderStageCreate,const deUint32 subpass,const VkVertexInputRate vertexInputRate,const bool useDepthTest,const bool useStencilTest,const float minDepth,const float maxDepth,const VkFormat dsFormat)858 Move<VkPipeline> MultiViewRenderTestInstance::makeGraphicsPipeline (const VkRenderPass							renderPass,
859 																	const VkPipelineLayout						pipelineLayout,
860 																	const deUint32								pipelineShaderStageCount,
861 																	const VkPipelineShaderStageCreateInfo*		pipelineShaderStageCreate,
862 																	const deUint32								subpass,
863 																	const VkVertexInputRate						vertexInputRate,
864 																	const bool									useDepthTest,
865 																	const bool									useStencilTest,
866 																	const float									minDepth,
867 																	const float									maxDepth,
868 																	const VkFormat								dsFormat)
869 {
870 	const VkVertexInputBindingDescription			vertexInputBindingDescriptions[]	=
871 	{
872 		{
873 			0u,													// binding;
874 			static_cast<deUint32>(sizeof(m_vertexCoord[0])),	// stride;
875 			vertexInputRate										// inputRate
876 		},
877 		{
878 			1u,													// binding;
879 			static_cast<deUint32>(sizeof(m_vertexColor[0])),	// stride;
880 			vertexInputRate										// inputRate
881 		}
882 	};
883 
884 	const VkVertexInputAttributeDescription			vertexInputAttributeDescriptions[]	=
885 	{
886 		{
887 			0u,											// deUint32	location;
888 			0u,											// deUint32	binding;
889 			VK_FORMAT_R32G32B32A32_SFLOAT,				// VkFormat	format;
890 			0u											// deUint32	offset;
891 		},	// VertexElementData::position
892 		{
893 			1u,											// deUint32	location;
894 			1u,											// deUint32	binding;
895 			VK_FORMAT_R32G32B32A32_SFLOAT,				// VkFormat	format;
896 			0u											// deUint32	offset;
897 		},	// VertexElementData::color
898 	};
899 
900 	const VkPipelineVertexInputStateCreateInfo		vertexInputStateParams				=
901 	{
902 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
903 		NULL,															// const void*								pNext;
904 		0u,																// VkPipelineVertexInputStateCreateFlags	flags;
905 		DE_LENGTH_OF_ARRAY(vertexInputBindingDescriptions),				// deUint32									vertexBindingDescriptionCount;
906 		vertexInputBindingDescriptions,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
907 		DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),			// deUint32									vertexAttributeDescriptionCount;
908 		vertexInputAttributeDescriptions								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
909 	};
910 
911 	const VkPrimitiveTopology						topology							= (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST :
912 																						  (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex) ? VK_PRIMITIVE_TOPOLOGY_POINT_LIST :
913 																						  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
914 
915 	const VkPipelineInputAssemblyStateCreateInfo	inputAssemblyStateParams			=
916 	{
917 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType							sType;
918 		DE_NULL,														// const void*								pNext;
919 		0u,																// VkPipelineInputAssemblyStateCreateFlags	flags;
920 		topology,														// VkPrimitiveTopology						topology;
921 		VK_FALSE,														// VkBool32									primitiveRestartEnable;
922 	};
923 
924 	const VkViewport	viewport	= makeViewport(0.0f, 0.0f, (float)m_parameters.extent.width, (float)m_parameters.extent.height, minDepth, maxDepth);
925 	const VkRect2D		scissor		= makeRect2D(m_parameters.extent);
926 
927 	const VkPipelineViewportStateCreateInfo			viewportStateParams					=
928 	{
929 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType						sType;
930 		DE_NULL,												// const void*							pNext;
931 		0u,														// VkPipelineViewportStateCreateFlags	flags;
932 		1u,														// deUint32								viewportCount;
933 		&viewport,												// const VkViewport*					pViewports;
934 		1u,														// deUint32								scissorCount;
935 		&scissor												// const VkRect2D*						pScissors;
936 	};
937 
938 	const VkPipelineRasterizationStateCreateInfo	rasterStateParams					=
939 	{
940 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,	// VkStructureType							sType;
941 		DE_NULL,													// const void*								pNext;
942 		0u,															// VkPipelineRasterizationStateCreateFlags	flags;
943 		VK_FALSE,													// VkBool32									depthClampEnable;
944 		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
945 		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
946 		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
947 		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
948 		VK_FALSE,													// VkBool32									depthBiasEnable;
949 		0.0f,														// float									depthBiasConstantFactor;
950 		0.0f,														// float									depthBiasClamp;
951 		0.0f,														// float									depthBiasSlopeFactor;
952 		1.0f,														// float									lineWidth;
953 	};
954 
955 	const VkSampleCountFlagBits						sampleCountFlagBits					= (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex) ? VK_SAMPLE_COUNT_4_BIT :
956 																						  VK_SAMPLE_COUNT_1_BIT;
957 	const VkPipelineMultisampleStateCreateInfo		multisampleStateParams				=
958 	{
959 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
960 		DE_NULL,													// const void*								pNext;
961 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
962 		sampleCountFlagBits,										// VkSampleCountFlagBits					rasterizationSamples;
963 		VK_FALSE,													// VkBool32									sampleShadingEnable;
964 		0.0f,														// float									minSampleShading;
965 		DE_NULL,													// const VkSampleMask*						pSampleMask;
966 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
967 		VK_FALSE,													// VkBool32									alphaToOneEnable;
968 	};
969 
970 	VkPipelineDepthStencilStateCreateInfo			depthStencilStateParams				=
971 	{
972 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
973 		DE_NULL,													// const void*								pNext;
974 		0u,															// VkPipelineDepthStencilStateCreateFlags	flags;
975 		useDepthTest ? VK_TRUE : VK_FALSE,							// VkBool32									depthTestEnable;
976 		useDepthTest ? VK_TRUE : VK_FALSE,							// VkBool32									depthWriteEnable;
977 		VK_COMPARE_OP_LESS_OR_EQUAL,								// VkCompareOp								depthCompareOp;
978 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
979 		useStencilTest ? VK_TRUE : VK_FALSE,						// VkBool32									stencilTestEnable;
980 		// VkStencilOpState front;
981 		{
982 			VK_STENCIL_OP_KEEP,					// VkStencilOp	failOp;
983 			VK_STENCIL_OP_INCREMENT_AND_CLAMP,	// VkStencilOp	passOp;
984 			VK_STENCIL_OP_KEEP,					// VkStencilOp	depthFailOp;
985 			VK_COMPARE_OP_ALWAYS,				// VkCompareOp	compareOp;
986 			~0u,								// deUint32		compareMask;
987 			~0u,								// deUint32		writeMask;
988 			0u,									// deUint32		reference;
989 		},
990 		// VkStencilOpState back;
991 		{
992 			VK_STENCIL_OP_KEEP,					// VkStencilOp	failOp;
993 			VK_STENCIL_OP_INCREMENT_AND_CLAMP,	// VkStencilOp	passOp;
994 			VK_STENCIL_OP_KEEP,					// VkStencilOp	depthFailOp;
995 			VK_COMPARE_OP_ALWAYS,				// VkCompareOp	compareOp;
996 			~0u,								// deUint32		compareMask;
997 			~0u,								// deUint32		writeMask;
998 			0u,									// deUint32		reference;
999 		},
1000 		0.0f,	// float	minDepthBounds;
1001 		1.0f,	// float	maxDepthBounds;
1002 	};
1003 
1004 	const VkPipelineColorBlendAttachmentState		colorBlendAttachmentState			=
1005 	{
1006 		VK_FALSE,								// VkBool32					blendEnable;
1007 		VK_BLEND_FACTOR_SRC_ALPHA,				// VkBlendFactor			srcColorBlendFactor;
1008 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor;
1009 		VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp;
1010 		VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor;
1011 		VK_BLEND_FACTOR_ONE,					// VkBlendFactor			dstAlphaBlendFactor;
1012 		VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp;
1013 		VK_COLOR_COMPONENT_R_BIT |				// VkColorComponentFlags	colorWriteMask;
1014 		VK_COLOR_COMPONENT_G_BIT |
1015 		VK_COLOR_COMPONENT_B_BIT |
1016 		VK_COLOR_COMPONENT_A_BIT
1017 	};
1018 
1019 	const VkPipelineColorBlendStateCreateInfo		colorBlendStateParams				=
1020 	{
1021 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
1022 		DE_NULL,													// const void*									pNext;
1023 		0u,															// VkPipelineColorBlendStateCreateFlags			flags;
1024 		VK_FALSE,													// VkBool32										logicOpEnable;
1025 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
1026 		1u,															// deUint32										attachmentCount;
1027 		&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments;
1028 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
1029 	};
1030 
1031 	VkPipelineTessellationStateCreateInfo			TessellationState					=
1032 	{
1033 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	// VkStructureType							sType;
1034 		DE_NULL,													// const void*								pNext;
1035 		(VkPipelineTessellationStateCreateFlags)0,					// VkPipelineTessellationStateCreateFlags	flags;
1036 		4u															// deUint32									patchControlPoints;
1037 	};
1038 
1039 	VkPipelineRenderingCreateInfoKHR				renderingCreateInfo
1040 	{
1041 		VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1042 		DE_NULL,
1043 		m_parameters.viewMasks[subpass],
1044 		1u,
1045 		&m_parameters.colorFormat,
1046 		dsFormat,
1047 		dsFormat
1048 	};
1049 
1050 	const VkGraphicsPipelineCreateInfo				graphicsPipelineParams
1051 	{
1052 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,												// VkStructureType									sType;
1053 		(renderPass == 0) ? &renderingCreateInfo : DE_NULL,												// const void*										pNext;
1054 		(VkPipelineCreateFlags)0u,																		// VkPipelineCreateFlags							flags;
1055 		pipelineShaderStageCount,																		// deUint32											stageCount;
1056 		pipelineShaderStageCreate,																		// const VkPipelineShaderStageCreateInfo*			pStages;
1057 		&vertexInputStateParams,																		// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
1058 		&inputAssemblyStateParams,																		// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
1059 		(TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)? &TessellationState : DE_NULL,	// const VkPipelineTessellationStateCreateInfo*		pTessellationState;
1060 		&viewportStateParams,																			// const VkPipelineViewportStateCreateInfo*			pViewportState;
1061 		&rasterStateParams,																				// const VkPipelineRasterizationStateCreateInfo*	pRasterState;
1062 		&multisampleStateParams,																		// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
1063 		&depthStencilStateParams,																		// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
1064 		&colorBlendStateParams,																			// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
1065 		(const VkPipelineDynamicStateCreateInfo*)DE_NULL,												// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
1066 		pipelineLayout,																					// VkPipelineLayout									layout;
1067 		renderPass,																						// VkRenderPass										renderPass;
1068 		subpass,																						// deUint32											subpass;
1069 		0u,																								// VkPipeline										basePipelineHandle;
1070 		0,																								// deInt32											basePipelineIndex;
1071 	};
1072 
1073 	return createGraphicsPipeline(*m_device, *m_logicalDevice, DE_NULL, &graphicsPipelineParams);
1074 }
1075 
readImage(VkImage image,const tcu::PixelBufferAccess & dst)1076 void MultiViewRenderTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
1077 {
1078 	Move<VkBuffer>				buffer;
1079 	MovePtr<Allocation>			bufferAlloc;
1080 	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * mapVkFormat(m_parameters.colorFormat).getPixelSize();
1081 
1082 	// Create destination buffer
1083 	{
1084 		const VkBufferCreateInfo bufferParams	=
1085 		{
1086 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1087 			DE_NULL,								// const void*			pNext;
1088 			0u,										// VkBufferCreateFlags	flags;
1089 			pixelDataSize,							// VkDeviceSize			size;
1090 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
1091 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1092 			1u,										// deUint32				queueFamilyIndexCount;
1093 			&m_queueFamilyIndex,					// const deUint32*		pQueueFamilyIndices;
1094 		};
1095 
1096 		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
1097 		bufferAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
1098 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1099 
1100 		deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
1101 		flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
1102 	}
1103 
1104 	const VkBufferMemoryBarrier	bufferBarrier	=
1105 	{
1106 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
1107 		DE_NULL,									// const void*		pNext;
1108 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
1109 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
1110 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
1111 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
1112 		*buffer,									// VkBuffer			buffer;
1113 		0u,											// VkDeviceSize		offset;
1114 		pixelDataSize								// VkDeviceSize		size;
1115 	};
1116 
1117 	// Copy image to buffer
1118 	const VkImageAspectFlags	aspect			= getAspectFlags(dst.getFormat());
1119 	const VkBufferImageCopy		copyRegion		=
1120 	{
1121 		0u,										// VkDeviceSize				bufferOffset;
1122 		(deUint32)dst.getWidth(),				// deUint32					bufferRowLength;
1123 		(deUint32)dst.getHeight(),				// deUint32					bufferImageHeight;
1124 		{
1125 			aspect,								// VkImageAspectFlags		aspect;
1126 			0u,									// deUint32					mipLevel;
1127 			0u,									// deUint32					baseArrayLayer;
1128 			m_parameters.extent.depth,			// deUint32					layerCount;
1129 		},										// VkImageSubresourceLayers	imageSubresource;
1130 		{ 0, 0, 0 },							// VkOffset3D				imageOffset;
1131 		{ m_parameters.extent.width, m_parameters.extent.height, 1u }	// VkExtent3D				imageExtent;
1132 	};
1133 
1134 	beginCommandBuffer (*m_device, *m_cmdBuffer);
1135 	{
1136 		VkImageSubresourceRange	subresourceRange	=
1137 		{
1138 			aspect,						// VkImageAspectFlags	aspectMask;
1139 			0u,							// deUint32				baseMipLevel;
1140 			1u,							// deUint32				mipLevels;
1141 			0u,							// deUint32				baseArraySlice;
1142 			m_parameters.extent.depth,	// deUint32				arraySize;
1143 		};
1144 
1145 		imageBarrier (*m_device, *m_cmdBuffer, image, subresourceRange,
1146 			VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1147 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1148 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1149 
1150 		m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
1151 		m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
1152 	}
1153 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1154 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1155 
1156 	// Read buffer data
1157 	invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
1158 	tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
1159 }
1160 
checkImage(tcu::ConstPixelBufferAccess & renderedFrame)1161 bool MultiViewRenderTestInstance::checkImage (tcu::ConstPixelBufferAccess& renderedFrame)
1162 {
1163 	const MovePtr<tcu::Texture2DArray>	referenceFrame	= imageData();
1164 	const bool							result			= tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1165 															"Result", "Image comparison result", referenceFrame->getLevel(0), renderedFrame, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR);
1166 
1167 	if (!result)
1168 		for (deUint32 layerNdx = 0u; layerNdx < m_parameters.extent.depth; layerNdx++)
1169 		{
1170 			tcu::ConstPixelBufferAccess ref (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx));
1171 			tcu::ConstPixelBufferAccess dst (mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, 1u, renderedFrame.getPixelPtr(0 ,0, layerNdx));
1172 			tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", ref, dst, tcu::Vec4(0.01f), tcu::COMPARE_LOG_EVERYTHING);
1173 		}
1174 
1175 	return result;
1176 }
1177 
getQuarterRefColor(const deUint32 quarterNdx,const int colorNdx,const int layerNdx,const bool background,const deUint32 subpassNdx) const1178 const tcu::Vec4 MultiViewRenderTestInstance::getQuarterRefColor (const deUint32 quarterNdx, const int colorNdx, const int layerNdx, const bool background, const deUint32 subpassNdx) const
1179 {
1180 	// this function is used for genrating same colors while rendering and while creating reference
1181 
1182 	switch (m_parameters.viewIndex)
1183 	{
1184 		case TEST_TYPE_VIEW_MASK:
1185 			return m_vertexColor[colorNdx];
1186 
1187 		case TEST_TYPE_DRAW_INDEXED:
1188 			return m_vertexColor[m_vertexIndices[colorNdx]];
1189 
1190 		case TEST_TYPE_INSTANCED_RENDERING:
1191 			return m_vertexColor[0] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0);
1192 
1193 		case TEST_TYPE_INPUT_RATE_INSTANCE:
1194 			return m_vertexColor[colorNdx / 4] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, static_cast<float>(quarterNdx + 1u) * 0.10f, 0.0);
1195 
1196 		case TEST_TYPE_DRAW_INDIRECT_INDEXED:
1197 			return m_vertexColor[m_vertexIndices[colorNdx]] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
1198 
1199 		case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
1200 		case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
1201 		case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
1202 		case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
1203 		case TEST_TYPE_INPUT_ATTACHMENTS:
1204 		case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
1205 		case TEST_TYPE_DRAW_INDIRECT:
1206 		case TEST_TYPE_CLEAR_ATTACHMENTS:
1207 		case TEST_TYPE_SECONDARY_CMD_BUFFER:
1208 		case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
1209 			return m_vertexColor[colorNdx] + tcu::Vec4(0.0, static_cast<float>(layerNdx) * 0.10f, 0.0, 0.0);
1210 
1211 		case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
1212 			if (background)
1213 				return m_colorTable[4 + quarterNdx % 4];
1214 			else
1215 				return m_colorTable[layerNdx % 4];
1216 
1217 		case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
1218 			if (background)
1219 				return m_colorTable[4 + quarterNdx % 4];
1220 			else
1221 				return m_colorTable[0];
1222 
1223 		case TEST_TYPE_POINT_SIZE:
1224 		case TEST_TYPE_MULTISAMPLE:
1225 			if (background)
1226 				return tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
1227 			else
1228 				return m_vertexColor[colorNdx];
1229 
1230 		case TEST_TYPE_DEPTH:
1231 			if (background)
1232 				if (subpassNdx < 4)
1233 					return tcu::Vec4(0.66f, 0.0f, 0.0f, 1.0f);
1234 				else
1235 					return tcu::Vec4(0.33f, 0.0f, 0.0f, 1.0f);
1236 			else
1237 				return tcu::Vec4(0.99f, 0.0f, 0.0f, 1.0f);
1238 
1239 		case TEST_TYPE_DEPTH_DIFFERENT_RANGES:
1240 			// for quads from partA generate  1.20, 0.90, 0.60,  0.30
1241 			// for quads from partB generate  0.55, 0.35, 0.15, -0.05
1242 			// depth ranges in views are <0;0.5>, <0;1> or <0.5;1> so
1243 			// at least one quad from partA/partB will always be drawn
1244 			if (subpassNdx < 4)
1245 				return tcu::Vec4(1.2f - 0.3f * static_cast<float>(subpassNdx), 0.0f, 0.0f, 1.0f);
1246 			return tcu::Vec4(0.55f - 0.2f * static_cast<float>(subpassNdx % 4), 0.0f, 0.0f, 1.0f);
1247 
1248 		case TEST_TYPE_STENCIL:
1249 			if (background)
1250 				return tcu::Vec4(0.33f, 0.0f, 0.0f, 0.0f); // Increment value
1251 			else
1252 				return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
1253 
1254 		default:
1255 			TCU_THROW(InternalError, "Impossible");
1256 	}
1257 }
1258 
setPoint(const tcu::PixelBufferAccess & pixelBuffer,const tcu::Vec4 & pointColor,const int pointSize,const int layerNdx,const deUint32 quarter) const1259 void MultiViewRenderTestInstance::setPoint (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& pointColor, const int pointSize, const int layerNdx, const deUint32 quarter) const
1260 {
1261 	DE_ASSERT(TEST_POINT_SIZE_WIDE > TEST_POINT_SIZE_SMALL);
1262 
1263 	const int	pointOffset	= 1 + TEST_POINT_SIZE_WIDE / 2 - (pointSize + 1) / 2;
1264 	const int	offsetX		= pointOffset + static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u);
1265 	const int	offsetY		= pointOffset + static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u);
1266 
1267 	for (int y = 0; y < pointSize; ++y)
1268 	for (int x = 0; x < pointSize; ++x)
1269 		pixelBuffer.setPixel(pointColor, offsetX + x, offsetY + y, layerNdx);
1270 }
1271 
fillTriangle(const tcu::PixelBufferAccess & pixelBuffer,const tcu::Vec4 & color,const int layerNdx,const deUint32 quarter) const1272 void MultiViewRenderTestInstance::fillTriangle (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter) const
1273 {
1274 	const int		offsetX				= static_cast<int>((quarter == 0u || quarter == 1u) ? 0 : m_parameters.extent.width / 2u);
1275 	const int		offsetY				= static_cast<int>((quarter == 0u || quarter == 2u) ? 0 : m_parameters.extent.height / 2u);
1276 	const int		maxY				= static_cast<int>(m_parameters.extent.height / 2u);
1277 	const tcu::Vec4	multisampledColor	= tcu::Vec4(color[0], color[1], color[2], color[3]) * 0.5f;
1278 
1279 	for (int y = 0; y < maxY; ++y)
1280 	{
1281 		for (int x = 0; x < y; ++x)
1282 			pixelBuffer.setPixel(color, offsetX + x, offsetY + (maxY - 1) - y, layerNdx);
1283 
1284 		// Multisampled pixel is on the triangle margin
1285 		pixelBuffer.setPixel(multisampledColor, offsetX + y, offsetY + (maxY - 1) - y, layerNdx);
1286 	}
1287 }
1288 
fillLayer(const tcu::PixelBufferAccess & pixelBuffer,const tcu::Vec4 & color,const int layerNdx) const1289 void MultiViewRenderTestInstance::fillLayer (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx) const
1290 {
1291 	for (deUint32 y = 0u; y < m_parameters.extent.height; ++y)
1292 	for (deUint32 x = 0u; x < m_parameters.extent.width; ++x)
1293 		pixelBuffer.setPixel(color, x, y, layerNdx);
1294 }
1295 
fillQuarter(const tcu::PixelBufferAccess & pixelBuffer,const tcu::Vec4 & color,const int layerNdx,const deUint32 quarter,const deUint32 subpassNdx) const1296 void MultiViewRenderTestInstance::fillQuarter (const tcu::PixelBufferAccess& pixelBuffer, const tcu::Vec4& color, const int layerNdx, const deUint32 quarter, const deUint32 subpassNdx) const
1297 {
1298 	const int h		= m_parameters.extent.height;
1299 	const int h2	= h / 2;
1300 	const int w		= m_parameters.extent.width;
1301 	const int w2	= w / 2;
1302 	int xStart		= 0;
1303 	int xEnd		= 0;
1304 	int yStart		= 0;
1305 	int yEnd		= 0;
1306 
1307 	switch (quarter)
1308 	{
1309 		case 0:	xStart = 0u; xEnd = w2; yStart = 0u; yEnd = h2; break;
1310 		case 1:	xStart = 0u; xEnd = w2; yStart = h2; yEnd = h;  break;
1311 		case 2:	xStart = w2; xEnd = w;  yStart = 0u; yEnd = h2; break;
1312 		case 3:	xStart = w2; xEnd = w;  yStart = h2; yEnd = h;  break;
1313 		default: TCU_THROW(InternalError, "Impossible");
1314 	}
1315 
1316 	if (TEST_TYPE_STENCIL == m_parameters.viewIndex ||
1317 		TEST_TYPE_DEPTH == m_parameters.viewIndex ||
1318 		TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex)
1319 	{
1320 		if (subpassNdx < 4)
1321 		{	// Part A: Horizontal bars near X axis
1322 			yStart	= h2 + (yStart - h2) / 2;
1323 			yEnd	= h2 + (yEnd - h2) / 2;
1324 		}
1325 		else
1326 		{	// Part B: Vertical bars near Y axis (drawn twice)
1327 			xStart	= w2 + (xStart - w2) / 2;
1328 			xEnd	= w2 + (xEnd - w2) / 2;
1329 		}
1330 
1331 		// Update pixels in area
1332 		if (TEST_TYPE_STENCIL == m_parameters.viewIndex)
1333 		{
1334 			for (int y = yStart; y < yEnd; ++y)
1335 			for (int x = xStart; x < xEnd; ++x)
1336 				pixelBuffer.setPixel(pixelBuffer.getPixel(x, y, layerNdx) + color, x, y, layerNdx);
1337 		}
1338 
1339 		if (TEST_TYPE_DEPTH == m_parameters.viewIndex ||
1340 			TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex)
1341 		{
1342 			for (int y = yStart; y < yEnd; ++y)
1343 			for (int x = xStart; x < xEnd; ++x)
1344 			{
1345 				const tcu::Vec4		currentColor	= pixelBuffer.getPixel(x, y, layerNdx);
1346 				const tcu::Vec4&	newColor		= (currentColor[0] < color[0]) ? currentColor : color;
1347 
1348 				pixelBuffer.setPixel(newColor, x, y, layerNdx);
1349 			}
1350 		}
1351 	}
1352 	else
1353 	{
1354 		for (int y = yStart; y < yEnd; ++y)
1355 		for (int x = xStart; x < xEnd; ++x)
1356 			pixelBuffer.setPixel(color , x, y, layerNdx);
1357 	}
1358 }
1359 
imageData(void) const1360 MovePtr<tcu::Texture2DArray> MultiViewRenderTestInstance::imageData (void) const
1361 {
1362 	MovePtr<tcu::Texture2DArray>	referenceFrame	= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth));
1363 	const deUint32					subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
1364 	referenceFrame->allocLevel(0);
1365 
1366 	deMemset (referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize());
1367 
1368 	if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex || TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
1369 	{
1370 		deUint32	clearedViewMask	= 0;
1371 
1372 		// Start from last clear command color, which actually takes effect
1373 		for (int subpassNdx = static_cast<int>(subpassCount) - 1; subpassNdx >= 0; --subpassNdx)
1374 		{
1375 			deUint32	subpassToClearViewMask	= m_parameters.viewMasks[subpassNdx] & ~clearedViewMask;
1376 
1377 			if (subpassToClearViewMask == 0)
1378 				continue;
1379 
1380 			for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
1381 				if ((subpassToClearViewMask & (1 << layerNdx)) != 0 && (clearedViewMask & (1 << layerNdx)) == 0)
1382 					fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, subpassNdx, false), layerNdx);
1383 
1384 			// These has been cleared. Exclude these layers from upcoming attempts to clear
1385 			clearedViewMask |= subpassToClearViewMask;
1386 		}
1387 	}
1388 
1389 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1390 	{
1391 		int			layerNdx	= 0;
1392 		deUint32	mask		= m_parameters.viewMasks[subpassNdx];
1393 
1394 		// iterate over image layers
1395 		while (mask > 0u)
1396 		{
1397 			int colorNdx	= 0;
1398 
1399 			if (mask & 1u)
1400 			{
1401 				if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
1402 				{
1403 					struct ColorDataRGBA
1404 					{
1405 						deUint8	r;
1406 						deUint8	g;
1407 						deUint8	b;
1408 						deUint8	a;
1409 					};
1410 
1411 					ColorDataRGBA	clear		=
1412 					{
1413 						tcu::floatToU8 (1.0f),
1414 						tcu::floatToU8 (0.0f),
1415 						tcu::floatToU8 (0.0f),
1416 						tcu::floatToU8 (1.0f)
1417 					};
1418 
1419 					ColorDataRGBA*	dataSrc		= (ColorDataRGBA*)referenceFrame->getLevel(0).getPixelPtr(0, 0, layerNdx);
1420 					ColorDataRGBA*	dataDes		= dataSrc + 1;
1421 					deUint32		copySize	= 1u;
1422 					deUint32		layerSize	= m_parameters.extent.width * m_parameters.extent.height - copySize;
1423 					deMemcpy(dataSrc, &clear, sizeof(ColorDataRGBA));
1424 
1425 					while (layerSize > 0)
1426 					{
1427 						deMemcpy(dataDes, dataSrc, copySize * sizeof(ColorDataRGBA));
1428 						dataDes = dataDes + copySize;
1429 						layerSize = layerSize - copySize;
1430 						copySize = 2u * copySize;
1431 						if (copySize >= layerSize)
1432 							copySize = layerSize;
1433 					}
1434 				}
1435 
1436 				const deUint32 subpassQuarterNdx = subpassNdx % m_squareCount;
1437 				if (subpassQuarterNdx == 0u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1438 				{
1439 					const tcu::Vec4 color = getQuarterRefColor(0u, colorNdx, layerNdx, true, subpassNdx);
1440 
1441 					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 0u, subpassNdx);
1442 				}
1443 
1444 				colorNdx += 4;
1445 				if (subpassQuarterNdx == 1u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1446 				{
1447 					const tcu::Vec4 color = getQuarterRefColor(1u, colorNdx, layerNdx, true, subpassNdx);
1448 
1449 					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 1u, subpassNdx);
1450 				}
1451 
1452 				colorNdx += 4;
1453 				if (subpassQuarterNdx == 2u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1454 				{
1455 					const tcu::Vec4 color = getQuarterRefColor(2u, colorNdx, layerNdx, true, subpassNdx);
1456 
1457 					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 2u, subpassNdx);
1458 				}
1459 
1460 				colorNdx += 4;
1461 				if (subpassQuarterNdx == 3u || subpassCount == 1u || TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
1462 				{
1463 					const tcu::Vec4 color = getQuarterRefColor(3u, colorNdx, layerNdx, true, subpassNdx);
1464 
1465 					fillQuarter(referenceFrame->getLevel(0), color, layerNdx, 3u, subpassNdx);
1466 				}
1467 
1468 				if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
1469 				{
1470 					const tcu::Vec4	color	(0.0f, 0.0f, 1.0f, 1.0f);
1471 					const int		maxY	= static_cast<int>(static_cast<float>(m_parameters.extent.height) * 0.75f);
1472 					const int		maxX	= static_cast<int>(static_cast<float>(m_parameters.extent.width) * 0.75f);
1473 					for (int y = static_cast<int>(m_parameters.extent.height / 4u); y < maxY; ++y)
1474 					for (int x = static_cast<int>(m_parameters.extent.width / 4u); x < maxX; ++x)
1475 						referenceFrame->getLevel(0).setPixel(color, x, y, layerNdx);
1476 				}
1477 
1478 				if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
1479 				{
1480 					const deUint32	vertexPerPrimitive	= 1u;
1481 					const deUint32	dummyQuarterNdx		= 0u;
1482 					const int		pointSize			= static_cast<int>(layerNdx == 0u ? TEST_POINT_SIZE_WIDE : TEST_POINT_SIZE_SMALL);
1483 
1484 					if (subpassCount == 1)
1485 						for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx)
1486 							setPoint(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), pointSize, layerNdx, drawNdx);
1487 					else
1488 						setPoint(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), pointSize, layerNdx, subpassQuarterNdx);
1489 				}
1490 
1491 				if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
1492 				{
1493 					const deUint32	vertexPerPrimitive	= 3u;
1494 					const deUint32	dummyQuarterNdx		= 0u;
1495 
1496 					if (subpassCount == 1)
1497 						for (deUint32 drawNdx = 0u; drawNdx < m_squareCount; ++drawNdx)
1498 							fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * drawNdx, layerNdx, false), layerNdx, drawNdx);
1499 					else
1500 						fillTriangle(referenceFrame->getLevel(0), getQuarterRefColor(dummyQuarterNdx, vertexPerPrimitive * subpassQuarterNdx, layerNdx, false), layerNdx, subpassQuarterNdx);
1501 				}
1502 			}
1503 
1504 			mask = mask >> 1;
1505 			++layerNdx;
1506 		}
1507 	}
1508 	return referenceFrame;
1509 }
1510 
appendVertex(const tcu::Vec4 & coord,const tcu::Vec4 & color)1511 void MultiViewRenderTestInstance::appendVertex (const tcu::Vec4& coord, const tcu::Vec4& color)
1512 {
1513 	m_vertexCoord.push_back(coord);
1514 	m_vertexColor.push_back(color);
1515 }
1516 
1517 class MultiViewAttachmentsTestInstance : public MultiViewRenderTestInstance
1518 {
1519 public:
1520 						MultiViewAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
1521 protected:
1522 	tcu::TestStatus		iterate								(void);
1523 	void				beforeDraw							(void);
1524 	void				setImageData						(VkImage image);
1525 	de::SharedPtr<ImageAttachment>	m_inputAttachment;
1526 	Move<VkDescriptorPool>			m_descriptorPool;
1527 	Move<VkDescriptorSet>			m_descriptorSet;
1528 	Move<VkDescriptorSetLayout>		m_descriptorSetLayout;
1529 	Move<VkPipelineLayout>			m_pipelineLayout;
1530 
1531 };
1532 
MultiViewAttachmentsTestInstance(Context & context,const TestParameters & parameters)1533 MultiViewAttachmentsTestInstance::MultiViewAttachmentsTestInstance (Context& context, const TestParameters& parameters)
1534 	: MultiViewRenderTestInstance	(context, parameters)
1535 {
1536 }
1537 
iterate(void)1538 tcu::TestStatus MultiViewAttachmentsTestInstance::iterate (void)
1539 {
1540 	const deUint32								subpassCount			= static_cast<deUint32>(m_parameters.viewMasks.size());
1541 	Move<VkRenderPass>							renderPass;
1542 	Move<VkFramebuffer>							frameBuffer;
1543 
1544 	// All color attachment
1545 	m_colorAttachment	= de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat));
1546 	m_inputAttachment	= de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat));
1547 
1548 	// FrameBuffer & renderPass
1549 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
1550 	{
1551 		vector<VkImageView> attachments
1552 		{
1553 			m_colorAttachment->getImageView(),
1554 			m_inputAttachment->getImageView()
1555 		};
1556 		renderPass	= makeRenderPassWithAttachments(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType);
1557 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height);
1558 	}
1559 
1560 	// pipelineLayout
1561 	m_descriptorSetLayout	= makeDescriptorSetLayout(*m_device, *m_logicalDevice);
1562 	m_pipelineLayout		= makePipelineLayout(*m_device, *m_logicalDevice, m_descriptorSetLayout.get());
1563 
1564 	// pipelines
1565 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
1566 	vector<PipelineSp>							pipelines(subpassCount);
1567 
1568 	{
1569 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
1570 		madeShaderModule(shaderModule, shaderStageParams);
1571 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
1572 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *m_pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
1573 	}
1574 
1575 	createVertexData();
1576 	createVertexBuffer();
1577 
1578 	createCommandBuffer();
1579 	setImageData(m_inputAttachment->getImage());
1580 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
1581 
1582 	{
1583 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
1584 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
1585 
1586 		readImage (m_colorAttachment->getImage(), dst);
1587 		if (!checkImage(dst))
1588 			return tcu::TestStatus::fail("Fail");
1589 	}
1590 
1591 	return tcu::TestStatus::pass("Pass");
1592 }
1593 
beforeDraw(void)1594 void MultiViewAttachmentsTestInstance::beforeDraw (void)
1595 {
1596 	const VkDescriptorPoolSize poolSize =
1597 	{
1598 		vk::VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,
1599 		1u
1600 	};
1601 
1602 	const VkDescriptorPoolCreateInfo createInfo =
1603 	{
1604 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1605 		DE_NULL,
1606 		VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1607 		1u,
1608 		1u,
1609 		&poolSize
1610 	};
1611 
1612 	m_descriptorPool = createDescriptorPool(*m_device, *m_logicalDevice, &createInfo);
1613 
1614 	const VkDescriptorSetAllocateInfo	allocateInfo =
1615 	{
1616 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1617 		DE_NULL,
1618 		*m_descriptorPool,
1619 		1u,
1620 		&m_descriptorSetLayout.get()
1621 	};
1622 
1623 	m_descriptorSet	= vk::allocateDescriptorSet(*m_device, *m_logicalDevice, &allocateInfo);
1624 
1625 	const VkDescriptorImageInfo	imageInfo =
1626 	{
1627 		(VkSampler)0,
1628 		m_inputAttachment->getImageView(),
1629 		VK_IMAGE_LAYOUT_GENERAL
1630 	};
1631 
1632 	const VkWriteDescriptorSet	write =
1633 	{
1634 		VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	//VkStructureType				sType;
1635 		DE_NULL,								//const void*					pNext;
1636 		*m_descriptorSet,						//VkDescriptorSet				dstSet;
1637 		0u,										//deUint32						dstBinding;
1638 		0u,										//deUint32						dstArrayElement;
1639 		1u,										//deUint32						descriptorCount;
1640 		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	//VkDescriptorType				descriptorType;
1641 		&imageInfo,								//const VkDescriptorImageInfo*	pImageInfo;
1642 		DE_NULL,								//const VkDescriptorBufferInfo*	pBufferInfo;
1643 		DE_NULL,								//const VkBufferView*			pTexelBufferView;
1644 	};
1645 
1646 	m_device->updateDescriptorSets(*m_logicalDevice, (deUint32)1u, &write, 0u, DE_NULL);
1647 
1648 	const VkImageSubresourceRange	subresourceRange	=
1649 	{
1650 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
1651 		0u,							//deUint32				baseMipLevel;
1652 		1u,							//deUint32				levelCount;
1653 		0u,							//deUint32				baseArrayLayer;
1654 		m_parameters.extent.depth,	//deUint32				layerCount;
1655 	};
1656 	m_device->cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &(*m_descriptorSet), 0u, NULL);
1657 
1658 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
1659 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1660 		0, VK_ACCESS_TRANSFER_WRITE_BIT,
1661 		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1662 
1663 	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
1664 	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
1665 
1666 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
1667 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1668 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1669 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1670 }
1671 
setImageData(VkImage image)1672 void MultiViewAttachmentsTestInstance::setImageData (VkImage image)
1673 {
1674 	const MovePtr<tcu::Texture2DArray>		data		= imageData();
1675 	Move<VkBuffer>					buffer;
1676 	const deUint32					bufferSize	= m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * tcu::getPixelSize(mapVkFormat(m_parameters.colorFormat));
1677 	MovePtr<Allocation>				bufferAlloc;
1678 
1679 	// Create source buffer
1680 	{
1681 		const VkBufferCreateInfo		bufferParams			=
1682 		{
1683 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// VkStructureType		sType;
1684 			DE_NULL,									// const void*			pNext;
1685 			0u,											// VkBufferCreateFlags	flags;
1686 			bufferSize,									// VkDeviceSize			size;
1687 			VK_BUFFER_USAGE_TRANSFER_SRC_BIT,			// VkBufferUsageFlags	usage;
1688 			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode		sharingMode;
1689 			1u,											// deUint32				queueFamilyIndexCount;
1690 			&m_queueFamilyIndex,						// const deUint32*		pQueueFamilyIndices;
1691 		};
1692 
1693 		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
1694 		bufferAlloc = m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
1695 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1696 	}
1697 
1698 	// Barriers for copying buffer to image
1699 	const VkBufferMemoryBarrier				preBufferBarrier		=
1700 	{
1701 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType	sType;
1702 		DE_NULL,										// const void*		pNext;
1703 		VK_ACCESS_HOST_WRITE_BIT,						// VkAccessFlags	srcAccessMask;
1704 		VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags	dstAccessMask;
1705 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			srcQueueFamilyIndex;
1706 		VK_QUEUE_FAMILY_IGNORED,						// deUint32			dstQueueFamilyIndex;
1707 		*buffer,										// VkBuffer			buffer;
1708 		0u,												// VkDeviceSize		offset;
1709 		bufferSize										// VkDeviceSize		size;
1710 	};
1711 
1712 	const VkImageAspectFlags				formatAspect			= getAspectFlags(mapVkFormat(m_parameters.colorFormat));
1713 	VkImageSubresourceRange					subresourceRange		=
1714 	{												// VkImageSubresourceRange	subresourceRange;
1715 		formatAspect,				// VkImageAspectFlags	aspect;
1716 		0u,							// deUint32				baseMipLevel;
1717 		1u,							// deUint32				mipLevels;
1718 		0u,							// deUint32				baseArraySlice;
1719 		m_parameters.extent.depth,	// deUint32				arraySize;
1720 	};
1721 
1722 	const VkBufferImageCopy					copyRegion				=
1723 	{
1724 		0u,															// VkDeviceSize				bufferOffset;
1725 		(deUint32)data->getLevel(0).getWidth(),						// deUint32					bufferRowLength;
1726 		(deUint32)data->getLevel(0).getHeight(),					// deUint32					bufferImageHeight;
1727 		{
1728 			VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags		aspect;
1729 			0u,														// deUint32					mipLevel;
1730 			0u,														// deUint32					baseArrayLayer;
1731 			m_parameters.extent.depth,								// deUint32					layerCount;
1732 		},															// VkImageSubresourceLayers	imageSubresource;
1733 		{ 0, 0, 0 },												// VkOffset3D				imageOffset;
1734 		{m_parameters.extent.width, m_parameters.extent.height, 1u}	// VkExtent3D				imageExtent;
1735 	};
1736 
1737 	// Write buffer data
1738 	deMemcpy(bufferAlloc->getHostPtr(), data->getLevel(0).getDataPtr(), bufferSize);
1739 	flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
1740 
1741 	beginCommandBuffer(*m_device, *m_cmdBuffer);
1742 
1743 	m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1744 	imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
1745 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1746 		0u, VK_ACCESS_TRANSFER_WRITE_BIT,
1747 		VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1748 	m_device->cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
1749 	imageBarrier(*m_device, *m_cmdBuffer, image, subresourceRange,
1750 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1751 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
1752 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1753 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1754 
1755 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1756 }
1757 
1758 class MultiViewInstancedTestInstance : public MultiViewRenderTestInstance
1759 {
1760 public:
1761 						MultiViewInstancedTestInstance	(Context& context, const TestParameters& parameters);
1762 protected:
1763 	void				createVertexData				(void);
1764 	void				draw							(const deUint32			subpassCount,
1765 														 VkRenderPass			renderPass,
1766 														 VkFramebuffer			frameBuffer,
1767 														 vector<PipelineSp>&	pipelines);
1768 };
1769 
MultiViewInstancedTestInstance(Context & context,const TestParameters & parameters)1770 MultiViewInstancedTestInstance::MultiViewInstancedTestInstance (Context& context, const TestParameters& parameters)
1771 	: MultiViewRenderTestInstance	(context, parameters)
1772 {
1773 }
1774 
createVertexData(void)1775 void MultiViewInstancedTestInstance::createVertexData (void)
1776 {
1777 	const tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
1778 
1779 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
1780 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
1781 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
1782 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
1783 }
1784 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)1785 void MultiViewInstancedTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1786 {
1787 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1788 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
1789 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
1790 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
1791 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
1792 
1793 	beginCommandBuffer(*m_device, *m_cmdBuffer);
1794 
1795 	beforeDraw();
1796 
1797 	if (!m_useDynamicRendering)
1798 	{
1799 		const VkRenderPassBeginInfo		renderPassBeginInfo =
1800 		{
1801 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
1802 			DE_NULL,									// const void*			pNext;
1803 			renderPass,									// VkRenderPass			renderPass;
1804 			frameBuffer,								// VkFramebuffer		framebuffer;
1805 			renderArea,									// VkRect2D				renderArea;
1806 			1u,											// uint32_t				clearValueCount;
1807 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
1808 		};
1809 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
1810 	}
1811 
1812 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
1813 
1814 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1815 	{
1816 		if (m_useDynamicRendering)
1817 		{
1818 			beginRendering(
1819 				*m_device,
1820 				*m_cmdBuffer,
1821 				m_colorAttachment->getImageView(),
1822 				renderArea,
1823 				renderPassClearValue,
1824 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1825 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
1826 				0u,
1827 				m_parameters.extent.depth,
1828 				m_parameters.viewMasks[subpassNdx]);
1829 		}
1830 
1831 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
1832 
1833 		m_device->cmdDraw(*m_cmdBuffer, 4u, drawCountPerSubpass, 0u, subpassNdx % m_squareCount);
1834 
1835 		if (m_useDynamicRendering)
1836 			endRendering(*m_device, *m_cmdBuffer);
1837 		else if (subpassNdx < subpassCount - 1u)
1838 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
1839 	}
1840 
1841 	if (!m_useDynamicRendering)
1842 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
1843 
1844 	afterDraw();
1845 
1846 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1847 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1848 }
1849 
1850 class MultiViewInputRateInstanceTestInstance : public MultiViewRenderTestInstance
1851 {
1852 public:
1853 				MultiViewInputRateInstanceTestInstance	(Context& context, const TestParameters& parameters);
1854 protected:
1855 	void		createVertexData						(void);
1856 
1857 	void		draw									(const deUint32			subpassCount,
1858 														 VkRenderPass			renderPass,
1859 														 VkFramebuffer			frameBuffer,
1860 														 vector<PipelineSp>&	pipelines);
1861 };
1862 
MultiViewInputRateInstanceTestInstance(Context & context,const TestParameters & parameters)1863 MultiViewInputRateInstanceTestInstance::MultiViewInputRateInstanceTestInstance (Context& context, const TestParameters& parameters)
1864 	: MultiViewRenderTestInstance	(context, parameters)
1865 {
1866 }
1867 
createVertexData(void)1868 void MultiViewInputRateInstanceTestInstance::createVertexData (void)
1869 {
1870 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f));
1871 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f));
1872 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f));
1873 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f));
1874 }
1875 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)1876 void MultiViewInputRateInstanceTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1877 {
1878 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1879 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
1880 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
1881 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
1882 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
1883 
1884 	beginCommandBuffer(*m_device, *m_cmdBuffer);
1885 
1886 	beforeDraw();
1887 
1888 	if (!m_useDynamicRendering)
1889 	{
1890 		const VkRenderPassBeginInfo		renderPassBeginInfo =
1891 		{
1892 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
1893 			DE_NULL,									// const void*			pNext;
1894 			renderPass,									// VkRenderPass			renderPass;
1895 			frameBuffer,								// VkFramebuffer		framebuffer;
1896 			renderArea,									// VkRect2D				renderArea;
1897 			1u,											// uint32_t				clearValueCount;
1898 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
1899 		};
1900 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
1901 	}
1902 
1903 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
1904 
1905 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1906 	{
1907 		if (m_useDynamicRendering)
1908 		{
1909 			beginRendering(
1910 				*m_device,
1911 				*m_cmdBuffer,
1912 				m_colorAttachment->getImageView(),
1913 				renderArea,
1914 				renderPassClearValue,
1915 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1916 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
1917 				0u,
1918 				m_parameters.extent.depth,
1919 				m_parameters.viewMasks[subpassNdx]);
1920 		}
1921 
1922 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
1923 
1924 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
1925 			m_device->cmdDraw(*m_cmdBuffer, 4u, 4u, 0u, 0u);
1926 
1927 		if (m_useDynamicRendering)
1928 			endRendering(*m_device, *m_cmdBuffer);
1929 		else if (subpassNdx < subpassCount - 1u)
1930 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
1931 	}
1932 
1933 	if (!m_useDynamicRendering)
1934 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
1935 
1936 	afterDraw();
1937 
1938 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
1939 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
1940 }
1941 
1942 class MultiViewDrawIndirectTestInstance : public MultiViewRenderTestInstance
1943 {
1944 public:
1945 				MultiViewDrawIndirectTestInstance	(Context& context, const TestParameters& parameters);
1946 protected:
1947 
1948 	void		draw								(const deUint32			subpassCount,
1949 													 VkRenderPass			renderPass,
1950 													 VkFramebuffer			frameBuffer,
1951 													 vector<PipelineSp>&	pipelines);
1952 };
1953 
MultiViewDrawIndirectTestInstance(Context & context,const TestParameters & parameters)1954 MultiViewDrawIndirectTestInstance::MultiViewDrawIndirectTestInstance (Context& context, const TestParameters& parameters)
1955 	: MultiViewRenderTestInstance	(context, parameters)
1956 {
1957 }
1958 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)1959 void MultiViewDrawIndirectTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
1960 {
1961 	typedef de::SharedPtr<Unique<VkBuffer> >		BufferSP;
1962 	typedef de::SharedPtr<UniquePtr<Allocation> >	AllocationSP;
1963 
1964 	const size_t					nonCoherentAtomSize		= static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);
1965 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
1966 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
1967 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
1968 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
1969 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
1970 	const deUint32					strideInBuffer			= (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1971 															? static_cast<deUint32>(sizeof(vk::VkDrawIndexedIndirectCommand))
1972 															: static_cast<deUint32>(sizeof(vk::VkDrawIndirectCommand));
1973 	vector< BufferSP >				indirectBuffers			(subpassCount);
1974 	vector< AllocationSP >			indirectAllocations		(subpassCount);
1975 
1976 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
1977 	{
1978 		vector<VkDrawIndirectCommand>			drawCommands;
1979 		vector<VkDrawIndexedIndirectCommand>	drawCommandsIndexed;
1980 
1981 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
1982 		{
1983 			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
1984 			{
1985 				const VkDrawIndexedIndirectCommand	drawCommandIndexed	=
1986 				{
1987 					4u,												//  deUint32	indexCount;
1988 					1u,												//  deUint32	instanceCount;
1989 					(drawNdx + subpassNdx % m_squareCount) * 4u,	//  deUint32	firstIndex;
1990 					0u,												//  deInt32		vertexOffset;
1991 					0u,												//  deUint32	firstInstance;
1992 				};
1993 
1994 				drawCommandsIndexed.push_back(drawCommandIndexed);
1995 			}
1996 			else
1997 			{
1998 				const VkDrawIndirectCommand	drawCommand	=
1999 				{
2000 					4u,												//  deUint32	vertexCount;
2001 					1u,												//  deUint32	instanceCount;
2002 					(drawNdx + subpassNdx % m_squareCount) * 4u,	//  deUint32	firstVertex;
2003 					0u												//  deUint32	firstInstance;
2004 				};
2005 
2006 				drawCommands.push_back(drawCommand);
2007 			}
2008 		}
2009 
2010 		const size_t				drawCommandsLength	= (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
2011 														? drawCommandsIndexed.size()
2012 														: drawCommands.size();
2013 		const void*					drawCommandsDataPtr	= (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
2014 														? (void*)&drawCommandsIndexed[0]
2015 														: (void*)&drawCommands[0];
2016 		const size_t				dataSize			= static_cast<size_t>(drawCommandsLength * strideInBuffer);
2017 		const VkDeviceSize			bufferDataSize		= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
2018 		const VkBufferCreateInfo	bufferInfo			= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT);
2019 		Move<VkBuffer>				indirectBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
2020 		MovePtr<Allocation>			allocationBuffer	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *indirectBuffer),  MemoryRequirement::HostVisible);
2021 
2022 		DE_ASSERT(drawCommandsLength != 0);
2023 
2024 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *indirectBuffer, allocationBuffer->getMemory(), allocationBuffer->getOffset()));
2025 
2026 		deMemcpy(allocationBuffer->getHostPtr(), drawCommandsDataPtr, static_cast<size_t>(dataSize));
2027 
2028 		flushAlloc(*m_device, *m_logicalDevice, *allocationBuffer);
2029 		indirectBuffers[subpassNdx] = (BufferSP(new Unique<VkBuffer>(indirectBuffer)));
2030 		indirectAllocations[subpassNdx] = (AllocationSP(new UniquePtr<Allocation>(allocationBuffer)));
2031 	}
2032 
2033 	beginCommandBuffer(*m_device, *m_cmdBuffer);
2034 
2035 	beforeDraw();
2036 
2037 	if (!m_useDynamicRendering)
2038 	{
2039 		const VkRenderPassBeginInfo renderPassBeginInfo
2040 		{
2041 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
2042 			DE_NULL,									// const void*			pNext;
2043 			renderPass,									// VkRenderPass			renderPass;
2044 			frameBuffer,								// VkFramebuffer		framebuffer;
2045 			renderArea,									// VkRect2D				renderArea;
2046 			1u,											// uint32_t				clearValueCount;
2047 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
2048 		};
2049 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2050 	}
2051 
2052 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2053 
2054 	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
2055 		m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);
2056 
2057 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2058 	{
2059 		if (m_useDynamicRendering)
2060 		{
2061 			beginRendering(
2062 				*m_device,
2063 				*m_cmdBuffer,
2064 				m_colorAttachment->getImageView(),
2065 				renderArea,
2066 				renderPassClearValue,
2067 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2068 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
2069 				0u,
2070 				m_parameters.extent.depth,
2071 				m_parameters.viewMasks[subpassNdx]);
2072 		}
2073 
2074 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2075 
2076 		if (m_hasMultiDrawIndirect)
2077 		{
2078 			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
2079 				m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
2080 			else
2081 				m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], 0u, drawCountPerSubpass, strideInBuffer);
2082 		}
2083 		else
2084 		{
2085 			for (deUint32 drawNdx = 0; drawNdx < drawCountPerSubpass; drawNdx++)
2086 			{
2087 				if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
2088 					m_device->cmdDrawIndexedIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
2089 				else
2090 					m_device->cmdDrawIndirect(*m_cmdBuffer, **indirectBuffers[subpassNdx], drawNdx * strideInBuffer, 1, strideInBuffer);
2091 			}
2092 		}
2093 
2094 		if (m_useDynamicRendering)
2095 			endRendering(*m_device, *m_cmdBuffer);
2096 		else if (subpassNdx < subpassCount - 1u)
2097 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2098 	}
2099 
2100 	if (!m_useDynamicRendering)
2101 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
2102 
2103 	afterDraw();
2104 
2105 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2106 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2107 }
2108 
2109 class MultiViewClearAttachmentsTestInstance : public MultiViewRenderTestInstance
2110 {
2111 public:
2112 				MultiViewClearAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
2113 protected:
2114 	void		draw									(const deUint32			subpassCount,
2115 														 VkRenderPass			renderPass,
2116 														 VkFramebuffer			frameBuffer,
2117 														 vector<PipelineSp>&	pipelines);
2118 };
2119 
MultiViewClearAttachmentsTestInstance(Context & context,const TestParameters & parameters)2120 MultiViewClearAttachmentsTestInstance::MultiViewClearAttachmentsTestInstance (Context& context, const TestParameters& parameters)
2121 	: MultiViewRenderTestInstance	(context, parameters)
2122 {
2123 }
2124 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)2125 void MultiViewClearAttachmentsTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2126 {
2127 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2128 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
2129 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2130 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
2131 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
2132 
2133 	beginCommandBuffer(*m_device, *m_cmdBuffer);
2134 
2135 	beforeDraw();
2136 
2137 	if (!m_useDynamicRendering)
2138 	{
2139 		const VkRenderPassBeginInfo renderPassBeginInfo
2140 		{
2141 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
2142 			DE_NULL,									// const void*			pNext;
2143 			renderPass,									// VkRenderPass			renderPass;
2144 			frameBuffer,								// VkFramebuffer		framebuffer;
2145 			renderArea,									// VkRect2D				renderArea;
2146 			1u,											// uint32_t				clearValueCount;
2147 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
2148 		};
2149 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2150 	}
2151 
2152 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2153 
2154 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2155 	{
2156 		VkClearAttachment	clearAttachment	=
2157 		{
2158 			VK_IMAGE_ASPECT_COLOR_BIT,								// VkImageAspectFlags	aspectMask
2159 			0u,														// deUint32				colorAttachment
2160 			makeClearValueColor(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f))	// VkClearValue			clearValue
2161 		};
2162 
2163 		const VkOffset2D	offset[2]		=
2164 		{
2165 			{0, 0},
2166 			{static_cast<deInt32>(static_cast<float>(m_parameters.extent.width) * 0.25f), static_cast<deInt32>(static_cast<float>(m_parameters.extent.height) * 0.25f)}
2167 		};
2168 
2169 		const VkExtent2D	extent[2]		=
2170 		{
2171 			{m_parameters.extent.width, m_parameters.extent.height},
2172 			{static_cast<deUint32>(static_cast<float>(m_parameters.extent.width) * 0.5f), static_cast<deUint32>(static_cast<float>(m_parameters.extent.height) * 0.5f)}
2173 		};
2174 
2175 		const VkRect2D		rect2D[2]		=
2176 		{
2177 			{offset[0], extent[0]},
2178 			{offset[1], extent[1]}
2179 		};
2180 
2181 		VkClearRect			clearRect		=
2182 		{
2183 			rect2D[0],	// VkRect2D	rect
2184 			0u,			// deUint32	baseArrayLayer
2185 			1u,			// deUint32	layerCount
2186 		};
2187 
2188 		if (m_useDynamicRendering)
2189 		{
2190 			beginRendering(
2191 				*m_device,
2192 				*m_cmdBuffer,
2193 				m_colorAttachment->getImageView(),
2194 				renderArea,
2195 				renderPassClearValue,
2196 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2197 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
2198 				0u,
2199 				m_parameters.extent.depth,
2200 				m_parameters.viewMasks[subpassNdx]);
2201 		}
2202 
2203 		m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
2204 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2205 
2206 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2207 			m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
2208 
2209 		clearRect.rect = rect2D[1];
2210 		clearAttachment.clearValue = makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
2211 		m_device->cmdClearAttachments(*m_cmdBuffer, 1u, &clearAttachment, 1u, &clearRect);
2212 
2213 		if (m_useDynamicRendering)
2214 			endRendering(*m_device, *m_cmdBuffer);
2215 		else if (subpassNdx < subpassCount - 1u)
2216 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2217 	}
2218 
2219 	if (!m_useDynamicRendering)
2220 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
2221 
2222 	afterDraw();
2223 
2224 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2225 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2226 }
2227 
2228 class MultiViewSecondaryCommandBufferTestInstance : public MultiViewRenderTestInstance
2229 {
2230 public:
2231 				MultiViewSecondaryCommandBufferTestInstance	(Context& context, const TestParameters& parameters);
2232 protected:
2233 	void		draw										(const deUint32			subpassCount,
2234 															 VkRenderPass			renderPass,
2235 															 VkFramebuffer			frameBuffer,
2236 															 vector<PipelineSp>&	pipelines);
2237 };
2238 
MultiViewSecondaryCommandBufferTestInstance(Context & context,const TestParameters & parameters)2239 MultiViewSecondaryCommandBufferTestInstance::MultiViewSecondaryCommandBufferTestInstance (Context& context, const TestParameters& parameters)
2240 	: MultiViewRenderTestInstance	(context, parameters)
2241 {
2242 }
2243 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)2244 void MultiViewSecondaryCommandBufferTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2245 {
2246 	typedef de::SharedPtr<Unique<VkCommandBuffer> >	VkCommandBufferSp;
2247 
2248 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2249 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
2250 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2251 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
2252 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
2253 
2254 	beginCommandBuffer(*m_device, *m_cmdBuffer);
2255 
2256 	beforeDraw();
2257 
2258 	if (!m_useDynamicRendering)
2259 	{
2260 		const VkRenderPassBeginInfo renderPassBeginInfo
2261 		{
2262 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
2263 			DE_NULL,									// const void*			pNext;
2264 			renderPass,									// VkRenderPass			renderPass;
2265 			frameBuffer,								// VkFramebuffer		framebuffer;
2266 			renderArea,									// VkRect2D				renderArea;
2267 			1u,											// uint32_t				clearValueCount;
2268 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
2269 		};
2270 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderingType);
2271 	}
2272 
2273 	//Create secondary buffer
2274 	const VkCommandBufferAllocateInfo	cmdBufferAllocateInfo	=
2275 	{
2276 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
2277 		DE_NULL,										// const void*				pNext;
2278 		*m_cmdPool,										// VkCommandPool			commandPool;
2279 		VK_COMMAND_BUFFER_LEVEL_SECONDARY,				// VkCommandBufferLevel		level;
2280 		1u,												// deUint32					bufferCount;
2281 	};
2282 	vector<VkCommandBufferSp>	cmdBufferSecondary;
2283 
2284 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2285 	{
2286 		cmdBufferSecondary.push_back(VkCommandBufferSp(new Unique<VkCommandBuffer>(allocateCommandBuffer(*m_device, *m_logicalDevice, &cmdBufferAllocateInfo))));
2287 
2288 		const VkCommandBufferInheritanceRenderingInfoKHR secCmdBufInheritRenderingInfo
2289 		{
2290 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,	// VkStructureType							sType;
2291 			DE_NULL,															// const void*								pNext;
2292 			VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR,			// VkRenderingFlagsKHR						flags;
2293 			m_parameters.viewMasks[subpassNdx],									// uint32_t									viewMask;
2294 			1u,																	// uint32_t									colorAttachmentCount;
2295 			&m_parameters.colorFormat,											// const VkFormat*							pColorAttachmentFormats;
2296 			VK_FORMAT_UNDEFINED,												// VkFormat									depthAttachmentFormat;
2297 			VK_FORMAT_UNDEFINED,												// VkFormat									stencilAttachmentFormat;
2298 			m_parameters.samples												// VkSampleCountFlagBits					rasterizationSamples;
2299 		};
2300 
2301 		const VkCommandBufferInheritanceInfo secCmdBufInheritInfo
2302 		{
2303 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,					// VkStructureType							sType;
2304 			m_useDynamicRendering ? &secCmdBufInheritRenderingInfo : DE_NULL,	// const void*								pNext;
2305 			renderPass,															// VkRenderPass								renderPass;
2306 			subpassNdx,															// deUint32									subpass;
2307 			frameBuffer,														// VkFramebuffer							framebuffer;
2308 			VK_FALSE,															// VkBool32									occlusionQueryEnable;
2309 			(VkQueryControlFlags)0u,											// VkQueryControlFlags						queryFlags;
2310 			(VkQueryPipelineStatisticFlags)0u,									// VkQueryPipelineStatisticFlags			pipelineStatistics;
2311 		};
2312 
2313 		const VkCommandBufferBeginInfo info
2314 		{
2315 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,						// VkStructureType							sType;
2316 			DE_NULL,															// const void*								pNext;
2317 			VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,					// VkCommandBufferUsageFlags				flags;
2318 			&secCmdBufInheritInfo,												// const VkCommandBufferInheritanceInfo*	pInheritanceInfo;
2319 		};
2320 
2321 		VK_CHECK(m_device->beginCommandBuffer(cmdBufferSecondary.back().get()->get(), &info));
2322 
2323 		m_device->cmdBindVertexBuffers(cmdBufferSecondary.back().get()->get(), 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2324 		m_device->cmdBindPipeline(cmdBufferSecondary.back().get()->get(), VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2325 
2326 		if (m_useDynamicRendering)
2327 		{
2328 			beginRendering(
2329 				*m_device,
2330 				*m_cmdBuffer,
2331 				m_colorAttachment->getImageView(),
2332 				renderArea,
2333 				renderPassClearValue,
2334 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2335 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
2336 				VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR,
2337 				m_parameters.extent.depth,
2338 				m_parameters.viewMasks[subpassNdx]);
2339 		}
2340 
2341 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2342 			m_device->cmdDraw(cmdBufferSecondary.back().get()->get(), 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
2343 
2344 		VK_CHECK(m_device->endCommandBuffer(cmdBufferSecondary.back().get()->get()));
2345 
2346 		m_device->cmdExecuteCommands(*m_cmdBuffer, 1u, &cmdBufferSecondary.back().get()->get());
2347 		if (m_useDynamicRendering)
2348 			endRendering(*m_device, *m_cmdBuffer);
2349 		else if (subpassNdx < subpassCount - 1u)
2350 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, m_parameters.renderingType);
2351 	}
2352 
2353 	if (!m_useDynamicRendering)
2354 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
2355 
2356 	afterDraw();
2357 
2358 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2359 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2360 }
2361 
2362 class MultiViewPointSizeTestInstance : public MultiViewRenderTestInstance
2363 {
2364 public:
2365 				MultiViewPointSizeTestInstance	(Context& context, const TestParameters& parameters);
2366 protected:
2367 	void		validatePointSize				(const VkPhysicalDeviceLimits& limits, const deUint32 pointSize);
2368 	void		createVertexData				(void);
2369 	void		draw							(const deUint32			subpassCount,
2370 												 VkRenderPass			renderPass,
2371 												 VkFramebuffer			frameBuffer,
2372 												 vector<PipelineSp>&	pipelines);
2373 };
2374 
MultiViewPointSizeTestInstance(Context & context,const TestParameters & parameters)2375 MultiViewPointSizeTestInstance::MultiViewPointSizeTestInstance (Context& context, const TestParameters& parameters)
2376 	: MultiViewRenderTestInstance	(context, parameters)
2377 {
2378 	const InstanceInterface&		vki					= m_context.getInstanceInterface();
2379 	const VkPhysicalDevice			physDevice			= m_context.getPhysicalDevice();
2380 	const VkPhysicalDeviceLimits	limits				= getPhysicalDeviceProperties(vki, physDevice).limits;
2381 
2382 	validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_WIDE));
2383 	validatePointSize(limits, static_cast<deUint32>(TEST_POINT_SIZE_SMALL));
2384 }
2385 
validatePointSize(const VkPhysicalDeviceLimits & limits,const deUint32 pointSize)2386 void MultiViewPointSizeTestInstance::validatePointSize (const VkPhysicalDeviceLimits& limits, const deUint32 pointSize)
2387 {
2388 	const float	testPointSizeFloat	= static_cast<float>(pointSize);
2389 	float		granuleCount		= 0.0f;
2390 
2391 	if (!de::inRange(testPointSizeFloat, limits.pointSizeRange[0], limits.pointSizeRange[1]))
2392 		TCU_THROW(NotSupportedError, "Required point size is outside of the the limits range");
2393 
2394 	granuleCount = static_cast<float>(deCeilFloatToInt32((testPointSizeFloat - limits.pointSizeRange[0]) / limits.pointSizeGranularity));
2395 
2396 	if (limits.pointSizeRange[0] + granuleCount * limits.pointSizeGranularity != testPointSizeFloat)
2397 		TCU_THROW(NotSupportedError, "Granuliraty does not allow to get required point size");
2398 
2399 	DE_ASSERT(pointSize + 1 <= m_parameters.extent.width / 2);
2400 	DE_ASSERT(pointSize + 1 <= m_parameters.extent.height / 2);
2401 }
2402 
createVertexData(void)2403 void MultiViewPointSizeTestInstance::createVertexData (void)
2404 {
2405 	const float		pixelStepX	= 2.0f / static_cast<float>(m_parameters.extent.width);
2406 	const float		pixelStepY	= 2.0f / static_cast<float>(m_parameters.extent.height);
2407 	const int		pointMargin	= 1 + TEST_POINT_SIZE_WIDE / 2;
2408 
2409 	appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
2410 	appendVertex(tcu::Vec4(-1.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
2411 	appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX,-1.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
2412 	appendVertex(tcu::Vec4( 0.0f + pointMargin * pixelStepX, 0.0f + pointMargin * pixelStepY, 1.0f, 1.0f), tcu::Vec4(1.0f, 0.5f, 0.3f, 1.0f));
2413 }
2414 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)2415 void MultiViewPointSizeTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2416 {
2417 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2418 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
2419 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2420 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
2421 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
2422 
2423 	beginCommandBuffer(*m_device, *m_cmdBuffer);
2424 
2425 	beforeDraw();
2426 
2427 	if (!m_useDynamicRendering)
2428 	{
2429 		const VkRenderPassBeginInfo renderPassBeginInfo
2430 		{
2431 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
2432 			DE_NULL,									// const void*			pNext;
2433 			renderPass,									// VkRenderPass			renderPass;
2434 			frameBuffer,								// VkFramebuffer		framebuffer;
2435 			renderArea,									// VkRect2D				renderArea;
2436 			1u,											// uint32_t				clearValueCount;
2437 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
2438 		};
2439 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2440 	}
2441 
2442 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2443 
2444 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2445 	{
2446 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2447 
2448 		if (m_useDynamicRendering)
2449 		{
2450 			beginRendering(
2451 				*m_device,
2452 				*m_cmdBuffer,
2453 				m_colorAttachment->getImageView(),
2454 				renderArea,
2455 				renderPassClearValue,
2456 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2457 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
2458 				0u,
2459 				m_parameters.extent.depth,
2460 				m_parameters.viewMasks[subpassNdx]);
2461 		}
2462 
2463 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2464 			m_device->cmdDraw(*m_cmdBuffer, 1u, 1u, drawNdx + subpassNdx % m_squareCount, 0u);
2465 
2466 		if (m_useDynamicRendering)
2467 			endRendering(*m_device, *m_cmdBuffer);
2468 		else if (subpassNdx < subpassCount - 1u)
2469 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2470 	}
2471 
2472 	if (!m_useDynamicRendering)
2473 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
2474 
2475 	afterDraw();
2476 
2477 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2478 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2479 }
2480 
2481 class MultiViewMultsampleTestInstance : public MultiViewRenderTestInstance
2482 {
2483 public:
2484 					MultiViewMultsampleTestInstance	(Context& context, const TestParameters& parameters);
2485 protected:
2486 	tcu::TestStatus	iterate							(void);
2487 	void			createVertexData				(void);
2488 
2489 	void			draw							(const deUint32			subpassCount,
2490 													 VkRenderPass			renderPass,
2491 													 VkFramebuffer			frameBuffer,
2492 													 vector<PipelineSp>&	pipelines);
2493 	void			afterDraw						(void);
2494 private:
2495 	de::SharedPtr<ImageAttachment>	m_resolveAttachment;
2496 };
2497 
MultiViewMultsampleTestInstance(Context & context,const TestParameters & parameters)2498 MultiViewMultsampleTestInstance::MultiViewMultsampleTestInstance (Context& context, const TestParameters& parameters)
2499 	: MultiViewRenderTestInstance	(context, parameters)
2500 {
2501 	// Color attachment
2502 	m_resolveAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, VK_SAMPLE_COUNT_1_BIT));
2503 }
2504 
iterate(void)2505 tcu::TestStatus MultiViewMultsampleTestInstance::iterate (void)
2506 {
2507 	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());
2508 	Move<VkRenderPass>							renderPass;
2509 	Move<VkFramebuffer>							frameBuffer;
2510 
2511 	// FrameBuffer & renderPass
2512 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
2513 	{
2514 		renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType, VK_SAMPLE_COUNT_4_BIT);
2515 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
2516 	}
2517 
2518 	// pipelineLayout
2519 	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));
2520 
2521 	// pipelines
2522 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
2523 	vector<PipelineSp>							pipelines(subpassCount);
2524 	const VkVertexInputRate						vertexInputRate				= (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
2525 
2526 	{
2527 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
2528 		madeShaderModule(shaderModule, shaderStageParams);
2529 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
2530 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
2531 	}
2532 
2533 	createCommandBuffer();
2534 	createVertexData();
2535 	createVertexBuffer();
2536 
2537 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
2538 
2539 	{
2540 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
2541 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
2542 
2543 		readImage(m_resolveAttachment->getImage(), dst);
2544 
2545 		if (!checkImage(dst))
2546 			return tcu::TestStatus::fail("Fail");
2547 	}
2548 
2549 	return tcu::TestStatus::pass("Pass");
2550 }
2551 
createVertexData(void)2552 void MultiViewMultsampleTestInstance::createVertexData (void)
2553 {
2554 	tcu::Vec4	color	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
2555 
2556 	color	= tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2557 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
2558 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
2559 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
2560 
2561 	color	= tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2562 	appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
2563 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
2564 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
2565 
2566 	color	= tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2567 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
2568 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
2569 	appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);
2570 
2571 	color	= tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
2572 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
2573 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
2574 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
2575 }
2576 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)2577 void MultiViewMultsampleTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2578 {
2579 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2580 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
2581 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2582 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
2583 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
2584 	const deUint32					vertexPerPrimitive		= 3u;
2585 	const VkImageSubresourceLayers	subresourceLayer		=
2586 	{
2587 		VK_IMAGE_ASPECT_COLOR_BIT,	//  VkImageAspectFlags	aspectMask;
2588 		0u,							//  deUint32			mipLevel;
2589 		0u,							//  deUint32			baseArrayLayer;
2590 		m_parameters.extent.depth,	//  deUint32			layerCount;
2591 	};
2592 	const VkImageResolve			imageResolveRegion		=
2593 	{
2594 		subresourceLayer,															//  VkImageSubresourceLayers	srcSubresource;
2595 		makeOffset3D(0, 0, 0),														//  VkOffset3D					srcOffset;
2596 		subresourceLayer,															//  VkImageSubresourceLayers	dstSubresource;
2597 		makeOffset3D(0, 0, 0),														//  VkOffset3D					dstOffset;
2598 		makeExtent3D(m_parameters.extent.width, m_parameters.extent.height, 1u),	//  VkExtent3D					extent;
2599 	};
2600 
2601 	beginCommandBuffer(*m_device, *m_cmdBuffer);
2602 
2603 	beforeDraw();
2604 
2605 	if (!m_useDynamicRendering)
2606 	{
2607 		const VkRenderPassBeginInfo renderPassBeginInfo
2608 		{
2609 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
2610 			DE_NULL,									// const void*			pNext;
2611 			renderPass,									// VkRenderPass			renderPass;
2612 			frameBuffer,								// VkFramebuffer		framebuffer;
2613 			renderArea,									// VkRect2D				renderArea;
2614 			1u,											// uint32_t				clearValueCount;
2615 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
2616 		};
2617 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2618 	}
2619 
2620 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2621 
2622 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2623 	{
2624 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2625 
2626 		if (m_useDynamicRendering)
2627 		{
2628 			beginRendering(
2629 				*m_device,
2630 				*m_cmdBuffer,
2631 				m_colorAttachment->getImageView(),
2632 				renderArea,
2633 				renderPassClearValue,
2634 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2635 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
2636 				0u,
2637 				m_parameters.extent.depth,
2638 				m_parameters.viewMasks[subpassNdx]);
2639 		}
2640 
2641 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2642 			m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);
2643 
2644 		if (m_useDynamicRendering)
2645 			endRendering(*m_device, *m_cmdBuffer);
2646 		else if (subpassNdx < subpassCount - 1u)
2647 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2648 	}
2649 
2650 	if (!m_useDynamicRendering)
2651 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
2652 
2653 	afterDraw();
2654 
2655 	m_device->cmdResolveImage(*m_cmdBuffer, m_colorAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, m_resolveAttachment->getImage(), VK_IMAGE_LAYOUT_GENERAL, 1u, &imageResolveRegion);
2656 
2657 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2658 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2659 }
2660 
afterDraw(void)2661 void MultiViewMultsampleTestInstance::afterDraw (void)
2662 {
2663 	const VkImageSubresourceRange	subresourceRange		=
2664 	{
2665 		VK_IMAGE_ASPECT_COLOR_BIT,	//  VkImageAspectFlags	aspectMask;
2666 		0u,							//  deUint32			baseMipLevel;
2667 		1u,							//  deUint32			levelCount;
2668 		0u,							//  deUint32			baseArrayLayer;
2669 		m_parameters.extent.depth,	//  deUint32			layerCount;
2670 	};
2671 
2672 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
2673 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
2674 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
2675 		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2676 
2677 	imageBarrier(*m_device, *m_cmdBuffer, m_resolveAttachment->getImage(), subresourceRange,
2678 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
2679 		0u, VK_ACCESS_TRANSFER_WRITE_BIT,
2680 		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
2681 }
2682 
2683 class MultiViewQueriesTestInstance : public MultiViewRenderTestInstance
2684 {
2685 public:
2686 						MultiViewQueriesTestInstance	(Context& context, const TestParameters& parameters);
2687 protected:
2688 	tcu::TestStatus		iterate							(void);
2689 	void				createVertexData				(void);
2690 
2691 	void				draw							(const deUint32			subpassCount,
2692 														 VkRenderPass			renderPass,
2693 														 VkFramebuffer			frameBuffer,
2694 														 vector<PipelineSp>&	pipelines);
2695 	deUint32			getUsedViewsCount				(const deUint32			viewMaskIndex);
2696 	deUint32			getQueryCountersNumber			();
2697 private:
2698 	const deUint32				m_verticesPerPrimitive;
2699 	const VkQueryControlFlags	m_occlusionQueryFlags;
2700 	deUint64					m_timestampMask;
2701 	vector<deUint64>			m_timestampStartValues;
2702 	vector<deUint64>			m_timestampEndValues;
2703 	vector<deBool>				m_counterSeriesStart;
2704 	vector<deBool>				m_counterSeriesEnd;
2705 	vector<deUint64>			m_occlusionValues;
2706 	vector<deUint64>			m_occlusionExpectedValues;
2707 	deUint32					m_occlusionObjectsOffset;
2708 	vector<deUint64>			m_occlusionObjectPixelsCount;
2709 };
2710 
MultiViewQueriesTestInstance(Context & context,const TestParameters & parameters)2711 MultiViewQueriesTestInstance::MultiViewQueriesTestInstance (Context& context, const TestParameters& parameters)
2712 	: MultiViewRenderTestInstance	(context, parameters)
2713 	, m_verticesPerPrimitive		(4u)
2714 	, m_occlusionQueryFlags			((parameters.viewIndex == TEST_TYPE_QUERIES) * VK_QUERY_CONTROL_PRECISE_BIT)
2715 	, m_occlusionObjectsOffset		(0)
2716 {
2717 	// Generate the timestamp mask
2718 	const std::vector<VkQueueFamilyProperties>	queueProperties = vk::getPhysicalDeviceQueueFamilyProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice());
2719 
2720 	if(queueProperties[0].timestampValidBits == 0)
2721 		TCU_THROW(NotSupportedError, "Device does not support timestamp.");
2722 
2723 	m_timestampMask = 0xFFFFFFFFFFFFFFFFull >> (64 - queueProperties[0].timestampValidBits);
2724 }
2725 
iterate(void)2726 tcu::TestStatus MultiViewQueriesTestInstance::iterate (void)
2727 {
2728 	const deUint32								subpassCount			= static_cast<deUint32>(m_parameters.viewMasks.size());
2729 	Move<VkRenderPass>							renderPass;
2730 	Move<VkFramebuffer>							frameBuffer;
2731 	Unique<VkPipelineLayout>					pipelineLayout			(makePipelineLayout(*m_device, *m_logicalDevice));
2732 	vector<PipelineSp>							pipelines				(subpassCount);
2733 	deUint64									occlusionValue			= 0;
2734 	deUint64									occlusionExpectedValue	= 0;
2735 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
2736 
2737 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
2738 	{
2739 		renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType);
2740 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
2741 	}
2742 
2743 	{
2744 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
2745 
2746 		madeShaderModule(shaderModule, shaderStageParams);
2747 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
2748 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
2749 	}
2750 
2751 	createCommandBuffer();
2752 	createVertexData();
2753 	createVertexBuffer();
2754 
2755 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
2756 
2757 	DE_ASSERT(!m_occlusionValues.empty());
2758 	DE_ASSERT(m_occlusionValues.size() == m_occlusionExpectedValues.size());
2759 	DE_ASSERT(m_occlusionValues.size() == m_counterSeriesEnd.size());
2760 	for (size_t ndx = 0; ndx < m_counterSeriesEnd.size(); ++ndx)
2761 	{
2762 		occlusionValue			+= m_occlusionValues[ndx];
2763 		occlusionExpectedValue	+= m_occlusionExpectedValues[ndx];
2764 
2765 		if (m_counterSeriesEnd[ndx])
2766 		{
2767 			if (m_parameters.viewIndex == TEST_TYPE_QUERIES)
2768 			{
2769 				if (occlusionExpectedValue != occlusionValue)
2770 					return tcu::TestStatus::fail("occlusion, result:" + de::toString(occlusionValue) + ", expected:" + de::toString(occlusionExpectedValue));
2771 			}
2772 			else // verify non precise occlusion query
2773 			{
2774 				if (occlusionValue == 0)
2775 					return tcu::TestStatus::fail("occlusion, result: 0, expected non zero value");
2776 			}
2777 		}
2778 	}
2779 
2780 	DE_ASSERT(!m_timestampStartValues.empty());
2781 	DE_ASSERT(m_timestampStartValues.size() == m_timestampEndValues.size());
2782 	DE_ASSERT(m_timestampStartValues.size() == m_counterSeriesStart.size());
2783 	for (size_t ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
2784 	{
2785 		if (m_counterSeriesStart[ndx])
2786 		{
2787 			if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
2788 				continue;
2789 		}
2790 		else
2791 		{
2792 			if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
2793 				continue;
2794 
2795 			if (m_timestampEndValues[ndx] == 0 && m_timestampStartValues[ndx] == 0)
2796 				continue;
2797 		}
2798 
2799 		return tcu::TestStatus::fail("timestamp");
2800 	}
2801 
2802 	return tcu::TestStatus::pass("Pass");
2803 }
2804 
createVertexData(void)2805 void MultiViewQueriesTestInstance::createVertexData (void)
2806 {
2807 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
2808 
2809 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), color);
2810 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
2811 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
2812 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2813 
2814 	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
2815 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
2816 	appendVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), color);
2817 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2818 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
2819 
2820 	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
2821 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
2822 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2823 	appendVertex(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), color);
2824 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
2825 
2826 	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
2827 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
2828 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
2829 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
2830 	appendVertex(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), color);
2831 
2832 	// Create occluded square objects as zoom out of main
2833 	const deUint32	mainObjectsVerticesCount		= static_cast<deUint32>(m_vertexCoord.size());
2834 	const deUint32	mainObjectsCount				= mainObjectsVerticesCount / m_verticesPerPrimitive;
2835 	const deUint32	occlusionObjectMultiplierX[]	= { 1, 2, 2, 1 };
2836 	const deUint32	occlusionObjectMultiplierY[]	= { 1, 1, 3, 3 };
2837 	const deUint32	occlusionObjectDivisor			= 4u;
2838 	const float		occlusionObjectDivisorFloat		= static_cast<float>(occlusionObjectDivisor);
2839 
2840 	DE_ASSERT(0 == m_parameters.extent.width  % (2 * occlusionObjectDivisor));
2841 	DE_ASSERT(0 == m_parameters.extent.height % (2 * occlusionObjectDivisor));
2842 	DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierX) == mainObjectsCount);
2843 	DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierY) == mainObjectsCount);
2844 
2845 	for (size_t objectNdx = 0; objectNdx < mainObjectsCount; ++objectNdx)
2846 	{
2847 		const size_t	objectStart			= objectNdx * m_verticesPerPrimitive;
2848 		const float		xRatio				= static_cast<float>(occlusionObjectMultiplierX[objectNdx]) / occlusionObjectDivisorFloat;
2849 		const float		yRatio				= static_cast<float>(occlusionObjectMultiplierY[objectNdx]) / occlusionObjectDivisorFloat;
2850 		const double	areaRatio			= static_cast<double>(xRatio) * static_cast<double>(yRatio);
2851 		const deUint64	occludedPixelsCount	= static_cast<deUint64>(areaRatio * (m_parameters.extent.width / 2) * (m_parameters.extent.height / 2));
2852 
2853 		m_occlusionObjectPixelsCount.push_back(occludedPixelsCount);
2854 
2855 		for (size_t vertexNdx = 0; vertexNdx < m_verticesPerPrimitive; ++vertexNdx)
2856 		{
2857 			const float		occludedObjectVertexXCoord	= m_vertexCoord[objectStart + vertexNdx][0] * xRatio;
2858 			const float		occludedObjectVertexYCoord	= m_vertexCoord[objectStart + vertexNdx][1] * yRatio;
2859 			const tcu::Vec4	occludedObjectVertexCoord	= tcu::Vec4(occludedObjectVertexXCoord, occludedObjectVertexYCoord, 1.0f, 1.0f);
2860 
2861 			appendVertex(occludedObjectVertexCoord, m_vertexColor[objectStart + vertexNdx]);
2862 		}
2863 	}
2864 
2865 	m_occlusionObjectsOffset = mainObjectsVerticesCount;
2866 }
2867 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)2868 void MultiViewQueriesTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
2869 {
2870 	const VkRect2D				renderArea						= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
2871 	const VkClearValue			renderPassClearValue			= makeClearValueColor(tcu::Vec4(0.0f));
2872 	const VkBuffer				vertexBuffers[]					= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
2873 	const VkDeviceSize			vertexBufferOffsets[]			= {                   0u,                   0u };
2874 	const deUint32				drawCountPerSubpass				= (subpassCount == 1) ? m_squareCount : 1u;
2875 	const deUint32				queryCountersNumber				= (subpassCount == 1) ? m_squareCount * getUsedViewsCount(0) : getQueryCountersNumber();
2876 
2877 	const VkQueryPoolCreateInfo	occlusionQueryPoolCreateInfo	=
2878 	{
2879 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	//  VkStructureType					sType;
2880 		DE_NULL,									//  const void*						pNext;
2881 		(VkQueryPoolCreateFlags)0,					//  VkQueryPoolCreateFlags			flags;
2882 		VK_QUERY_TYPE_OCCLUSION,					//  VkQueryType						queryType;
2883 		queryCountersNumber,						//  deUint32						queryCount;
2884 		0u,											//  VkQueryPipelineStatisticFlags	pipelineStatistics;
2885 	};
2886 	const VkQueryPoolCreateInfo	timestampQueryPoolCreateInfo	=
2887 	{
2888 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	//  VkStructureType					sType;
2889 		DE_NULL,									//  const void*						pNext;
2890 		(VkQueryPoolCreateFlags)0,					//  VkQueryPoolCreateFlags			flags;
2891 		VK_QUERY_TYPE_TIMESTAMP,					//  VkQueryType						queryType;
2892 		queryCountersNumber,						//  deUint32						queryCount;
2893 		0u,											//  VkQueryPipelineStatisticFlags	pipelineStatistics;
2894 	};
2895 	const Unique<VkQueryPool>	occlusionQueryPool				(createQueryPool(*m_device, *m_logicalDevice, &occlusionQueryPoolCreateInfo));
2896 	const Unique<VkQueryPool>	timestampStartQueryPool			(createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
2897 	const Unique<VkQueryPool>	timestampEndQueryPool			(createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
2898 	deUint32					queryStartIndex					= 0;
2899 
2900 	beginCommandBuffer(*m_device, *m_cmdBuffer);
2901 
2902 	beforeDraw();
2903 
2904 	// Query pools must be reset before use
2905 	m_device->cmdResetQueryPool(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, queryCountersNumber);
2906 	m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampStartQueryPool, queryStartIndex, queryCountersNumber);
2907 	m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampEndQueryPool, queryStartIndex, queryCountersNumber);
2908 
2909 	if (!m_useDynamicRendering)
2910 	{
2911 		const VkRenderPassBeginInfo	renderPassBeginInfo
2912 		{
2913 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	//  VkStructureType		sType;
2914 			DE_NULL,									//  const void*			pNext;
2915 			renderPass,									//  VkRenderPass		renderPass;
2916 			frameBuffer,								//  VkFramebuffer		framebuffer;
2917 			renderArea,									//  VkRect2D			renderArea;
2918 			1u,											//  uint32_t			clearValueCount;
2919 			&renderPassClearValue,						//  const VkClearValue*	pClearValues;
2920 		};
2921 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2922 	}
2923 
2924 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
2925 
2926 	m_occlusionExpectedValues.reserve(queryCountersNumber);
2927 	m_counterSeriesStart.reserve(queryCountersNumber);
2928 	m_counterSeriesEnd.reserve(queryCountersNumber);
2929 
2930 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
2931 	{
2932 		deUint32	queryCountersToUse	= getUsedViewsCount(subpassNdx);
2933 
2934 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
2935 
2936 		if (m_useDynamicRendering)
2937 		{
2938 			beginRendering(
2939 				*m_device,
2940 				*m_cmdBuffer,
2941 				m_colorAttachment->getImageView(),
2942 				renderArea,
2943 				renderPassClearValue,
2944 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2945 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
2946 				0u,
2947 				m_parameters.extent.depth,
2948 				m_parameters.viewMasks[subpassNdx]);
2949 		}
2950 
2951 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
2952 		{
2953 			const deUint32 primitiveNumber	= drawNdx + subpassNdx % m_squareCount;
2954 			const deUint32 firstVertex		= primitiveNumber * m_verticesPerPrimitive;
2955 
2956 			m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampStartQueryPool, queryStartIndex);
2957 			{
2958 				m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, firstVertex, 0u);
2959 
2960 				// Render occluded object
2961 				m_device->cmdBeginQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, m_occlusionQueryFlags);
2962 				m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, m_occlusionObjectsOffset + firstVertex, 0u);
2963 				m_device->cmdEndQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex);
2964 
2965 				for (deUint32 viewMaskNdx = 0; viewMaskNdx < queryCountersToUse; ++viewMaskNdx)
2966 				{
2967 					m_occlusionExpectedValues.push_back(m_occlusionObjectPixelsCount[primitiveNumber]);
2968 					m_counterSeriesStart.push_back(viewMaskNdx == 0);
2969 					m_counterSeriesEnd.push_back(viewMaskNdx + 1 == queryCountersToUse);
2970 				}
2971 			}
2972 			m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampEndQueryPool, queryStartIndex);
2973 
2974 			queryStartIndex += queryCountersToUse;
2975 		}
2976 
2977 		if (m_useDynamicRendering)
2978 			endRendering(*m_device, *m_cmdBuffer);
2979 		else if (subpassNdx < subpassCount - 1u)
2980 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
2981 	}
2982 
2983 	DE_ASSERT(queryStartIndex == queryCountersNumber);
2984 
2985 	if (!m_useDynamicRendering)
2986 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
2987 
2988 	afterDraw();
2989 
2990 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
2991 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
2992 
2993 	m_occlusionValues.resize(queryCountersNumber, 0ull);
2994 	m_device->getQueryPoolResults(*m_logicalDevice, *occlusionQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_occlusionValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2995 
2996 	m_timestampStartValues.resize(queryCountersNumber, 0ull);
2997 	m_device->getQueryPoolResults(*m_logicalDevice, *timestampStartQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_timestampStartValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
2998 	for (deUint32 ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
2999 		m_timestampStartValues[ndx] &= m_timestampMask;
3000 
3001 	m_timestampEndValues.resize(queryCountersNumber, 0ull);
3002 	m_device->getQueryPoolResults(*m_logicalDevice, *timestampEndQueryPool, 0u, queryCountersNumber, sizeof(deUint64) * queryCountersNumber, (void*)&m_timestampEndValues[0], sizeof(deUint64), VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WAIT_BIT);
3003 	for (deUint32 ndx = 0; ndx < m_timestampEndValues.size(); ++ndx)
3004 		m_timestampEndValues[ndx] &= m_timestampMask;
3005 }
3006 
getUsedViewsCount(const deUint32 viewMaskIndex)3007 deUint32 MultiViewQueriesTestInstance::getUsedViewsCount (const deUint32 viewMaskIndex)
3008 {
3009 	deUint32 result = 0;
3010 
3011 	for (deUint32 viewMask = m_parameters.viewMasks[viewMaskIndex]; viewMask != 0; viewMask >>= 1)
3012 		if ((viewMask & 1) != 0)
3013 			result++;
3014 
3015 	return result;
3016 }
3017 
getQueryCountersNumber()3018 deUint32 MultiViewQueriesTestInstance::getQueryCountersNumber ()
3019 {
3020 	deUint32 result = 0;
3021 
3022 	for (deUint32 i = 0; i < m_parameters.viewMasks.size(); ++i)
3023 		result += getUsedViewsCount(i);
3024 
3025 	return result;
3026 }
3027 
3028 class MultiViewReadbackTestInstance : public MultiViewRenderTestInstance
3029 {
3030 public:
3031 						MultiViewReadbackTestInstance	(Context& context, const TestParameters& parameters);
3032 protected:
3033 	tcu::TestStatus		iterate							(void);
3034 	void				drawClears						(const deUint32				subpassCount,
3035 														 VkRenderPass				renderPass,
3036 														 VkFramebuffer				frameBuffer,
3037 														 vector<PipelineSp>&		pipelines,
3038 														 const bool					clearPass);
3039 	void				clear							(const VkCommandBuffer		commandBuffer,
3040 														 const VkRect2D&			clearRect2D,
3041 														 const tcu::Vec4&			clearColor);
3042 private:
3043 	vector<VkRect2D>	m_quarters;
3044 };
3045 
MultiViewReadbackTestInstance(Context & context,const TestParameters & parameters)3046 MultiViewReadbackTestInstance::MultiViewReadbackTestInstance (Context& context, const TestParameters& parameters)
3047 	: MultiViewRenderTestInstance	(context, parameters)
3048 {
3049 	const deUint32 halfWidth	= m_parameters.extent.width / 2;
3050 	const deUint32 halfHeight	= m_parameters.extent.height / 2;
3051 
3052 	for (deInt32 x = 0; x < 2; ++x)
3053 	for (deInt32 y = 0; y < 2; ++y)
3054 	{
3055 		const deInt32	offsetX	= static_cast<deInt32>(halfWidth) * x;
3056 		const deInt32	offsetY	= static_cast<deInt32>(halfHeight) * y;
3057 		const VkRect2D	area	= { { offsetX, offsetY}, {halfWidth, halfHeight} };
3058 
3059 		m_quarters.push_back(area);
3060 	}
3061 }
3062 
iterate(void)3063 tcu::TestStatus MultiViewReadbackTestInstance::iterate (void)
3064 {
3065 	const deUint32	subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
3066 
3067 	createCommandBuffer();
3068 
3069 	for (deUint32 pass = 0; pass < 2; ++pass)
3070 	{
3071 		const bool									fullClearPass	= (pass == 0);
3072 		const VkAttachmentLoadOp					loadOp			= (!fullClearPass) ? VK_ATTACHMENT_LOAD_OP_LOAD :
3073 																	  (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_CLEAR :
3074 																	  (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE :
3075 																	  VK_ATTACHMENT_LOAD_OP_DONT_CARE;
3076 		Move<VkRenderPass>							renderPass;
3077 		Move<VkFramebuffer>							frameBuffer;
3078 		Unique<VkPipelineLayout>					pipelineLayout	(makePipelineLayout(*m_device, *m_logicalDevice));
3079 		vector<PipelineSp>							pipelines		(subpassCount);
3080 		map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
3081 
3082 		if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3083 		{
3084 			renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType, VK_SAMPLE_COUNT_1_BIT, loadOp);
3085 			frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
3086 		}
3087 
3088 		{
3089 			vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
3090 			madeShaderModule(shaderModule, shaderStageParams);
3091 			for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
3092 				pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
3093 		}
3094 
3095 		drawClears(subpassCount, *renderPass, *frameBuffer, pipelines, fullClearPass);
3096 	}
3097 
3098 	{
3099 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
3100 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
3101 
3102 		readImage(m_colorAttachment->getImage(), dst);
3103 
3104 		if (!checkImage(dst))
3105 			return tcu::TestStatus::fail("Fail");
3106 	}
3107 
3108 	return tcu::TestStatus::pass("Pass");
3109 }
3110 
drawClears(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines,const bool clearPass)3111 void MultiViewReadbackTestInstance::drawClears (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines, const bool clearPass)
3112 {
3113 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
3114 	const VkClearValue				renderPassClearValue	= makeClearValueColor(m_colorTable[0]);
3115 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
3116 	const bool						withClearColor			= (clearPass && m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR);
3117 
3118 	beginCommandBuffer(*m_device, *m_cmdBuffer);
3119 
3120 	if (clearPass)
3121 		beforeDraw();
3122 
3123 	if (!m_useDynamicRendering)
3124 	{
3125 		const VkRenderPassBeginInfo renderPassBeginInfo
3126 		{
3127 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			//  VkStructureType		sType;
3128 			DE_NULL,											//  const void*			pNext;
3129 			renderPass,											//  VkRenderPass		renderPass;
3130 			frameBuffer,										//  VkFramebuffer		framebuffer;
3131 			renderArea,											//  VkRect2D			renderArea;
3132 			withClearColor ? 1u : 0u,							//  uint32_t			clearValueCount;
3133 			withClearColor ? &renderPassClearValue : DE_NULL,	//  const VkClearValue*	pClearValues;
3134 		};
3135 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3136 	}
3137 
3138 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3139 	{
3140 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
3141 
3142 		if (m_useDynamicRendering)
3143 		{
3144 			VkAttachmentLoadOp loadOperation = VK_ATTACHMENT_LOAD_OP_LOAD;
3145 			if (clearPass)
3146 			{
3147 				if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR)
3148 					loadOperation = VK_ATTACHMENT_LOAD_OP_CLEAR;
3149 				else if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR)
3150 					loadOperation = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
3151 				else
3152 					loadOperation = VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
3153 			}
3154 
3155 			beginRendering(
3156 				*m_device,
3157 				*m_cmdBuffer,
3158 				m_colorAttachment->getImageView(),
3159 				renderArea,
3160 				renderPassClearValue,
3161 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3162 				loadOperation,
3163 				0u,
3164 				m_parameters.extent.depth,
3165 				m_parameters.viewMasks[subpassNdx]);
3166 		}
3167 
3168 		if (clearPass)
3169 		{
3170 			if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR)
3171 				clear(*m_cmdBuffer, renderArea, m_colorTable[subpassNdx % 4]);
3172 		}
3173 		else
3174 		{
3175 			for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
3176 			{
3177 				const deUint32 primitiveNumber	= drawNdx + subpassNdx % m_squareCount;
3178 
3179 				clear(*m_cmdBuffer, m_quarters[primitiveNumber], m_colorTable[4 + primitiveNumber]);
3180 			}
3181 		}
3182 
3183 		if (m_useDynamicRendering)
3184 			endRendering(*m_device, *m_cmdBuffer);
3185 		else if (subpassNdx < subpassCount - 1u)
3186 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3187 	}
3188 
3189 	if (!m_useDynamicRendering)
3190 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
3191 
3192 	if (!clearPass)
3193 		afterDraw();
3194 
3195 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3196 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3197 }
3198 
clear(const VkCommandBuffer commandBuffer,const VkRect2D & clearRect2D,const tcu::Vec4 & clearColor)3199 void MultiViewReadbackTestInstance::clear (const VkCommandBuffer commandBuffer, const VkRect2D& clearRect2D, const tcu::Vec4& clearColor)
3200 {
3201 	const VkClearRect		clearRect		=
3202 	{
3203 		clearRect2D,						//  VkRect2D	rect
3204 		0u,									//  deUint32	baseArrayLayer
3205 		1u,									//  deUint32	layerCount
3206 	};
3207 	const VkClearAttachment	clearAttachment	=
3208 	{
3209 		VK_IMAGE_ASPECT_COLOR_BIT,			//  VkImageAspectFlags	aspectMask
3210 		0u,									//  deUint32			colorAttachment
3211 		makeClearValueColor(clearColor)		//  VkClearValue		clearValue
3212 	};
3213 
3214 	m_device->cmdClearAttachments(commandBuffer, 1u, &clearAttachment, 1u, &clearRect);
3215 }
3216 
3217 class MultiViewDepthStencilTestInstance : public MultiViewRenderTestInstance
3218 {
3219 public:
3220 									MultiViewDepthStencilTestInstance	(Context& context, const TestParameters& parameters);
3221 protected:
3222 	tcu::TestStatus					iterate								(void) override;
3223 	void							createVertexData					(void) override;
3224 
3225 	void							draw								(const deUint32					subpassCount,
3226 																		 VkRenderPass					renderPass,
3227 																		 VkFramebuffer					frameBuffer,
3228 																		 vector<PipelineSp>&			pipelines) override;
3229 	void							beforeDraw							(void) override;
3230 	void							afterDraw							(void) override;
3231 	vector<VkImageView>				makeAttachmentsVector				(void);
3232 	MovePtr<tcu::Texture2DArray>	imageData							(void) const override;
3233 	void							readImage							(VkImage						image,
3234 																		 const tcu::PixelBufferAccess&	dst);
3235 	vector<tcu::Vec2>				getDepthRanges						(void) const;
3236 
3237 private:
3238 	VkFormat						m_dsFormat;
3239 	de::SharedPtr<ImageAttachment>	m_dsAttachment;
3240 	bool							m_depthTest;
3241 	bool							m_stencilTest;
3242 };
3243 
MultiViewDepthStencilTestInstance(Context & context,const TestParameters & parameters)3244 MultiViewDepthStencilTestInstance::MultiViewDepthStencilTestInstance (Context& context, const TestParameters& parameters)
3245 	: MultiViewRenderTestInstance	(context, parameters)
3246 	, m_dsFormat					(VK_FORMAT_UNDEFINED)
3247 	, m_depthTest					(m_parameters.viewIndex == TEST_TYPE_DEPTH ||
3248 									 m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
3249 	, m_stencilTest					(m_parameters.viewIndex == TEST_TYPE_STENCIL)
3250 {
3251 	const VkFormat formats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
3252 
3253 	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(formats); ++ndx)
3254 	{
3255 		const VkFormat				format				= formats[ndx];
3256 		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), format);
3257 
3258 		if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
3259 		{
3260 			m_dsFormat = format;
3261 
3262 			break;
3263 		}
3264 	}
3265 
3266 	if (m_dsFormat == VK_FORMAT_UNDEFINED)
3267 		TCU_FAIL("Supported depth/stencil format not found, that violates specification");
3268 
3269 	// Depth/stencil attachment
3270 	m_dsAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_dsFormat));
3271 }
3272 
makeAttachmentsVector(void)3273 vector<VkImageView>	MultiViewDepthStencilTestInstance::makeAttachmentsVector (void)
3274 {
3275 	vector<VkImageView> attachments;
3276 
3277 	attachments.push_back(m_colorAttachment->getImageView());
3278 	attachments.push_back(m_dsAttachment->getImageView());
3279 
3280 	return attachments;
3281 }
3282 
imageData(void) const3283 MovePtr<tcu::Texture2DArray> MultiViewDepthStencilTestInstance::imageData(void) const
3284 {
3285 	MovePtr<tcu::Texture2DArray>	referenceFrame		= MovePtr<tcu::Texture2DArray>(new tcu::Texture2DArray(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth));
3286 	const deUint32					subpassCount		= static_cast<deUint32>(m_parameters.viewMasks.size());
3287 	const vector<tcu::Vec2>			depthRanges			= getDepthRanges();
3288 
3289 	referenceFrame->allocLevel(0);
3290 	deMemset(referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize());
3291 
3292 	for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
3293 		fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, 0u, false), layerNdx);
3294 
3295 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3296 	{
3297 		int					layerNdx			= 0;
3298 		deUint32			mask				= m_parameters.viewMasks[subpassNdx];
3299 		const tcu::Vec2&	depthRange			= depthRanges[subpassNdx];
3300 		const float			depthMin			= depthRange[0];
3301 		const float			depthMax			= depthRange[1];
3302 
3303 		// iterate over image layers
3304 		while (mask > 0u)
3305 		{
3306 			if (mask & 1u)
3307 			{
3308 				const deUint32	subpassQuarterNdx	= subpassNdx % m_squareCount;
3309 				const int		colorNdx			= subpassQuarterNdx * 4;
3310 				tcu::Vec4		color				= getQuarterRefColor(subpassQuarterNdx, colorNdx, layerNdx, true, subpassNdx);
3311 
3312 				if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
3313 				{
3314 					// quads with depth out of range should be cliiped
3315 					// to simplify code we are drawing them with background color
3316 					if ((color.x() < 0.0f) || (color.x() > 1.0f))
3317 						color.x() = 1.0f;
3318 					else
3319 					{
3320 						const float depthClamped = de::clamp(color.x(), 0.0f, 1.0f);
3321 						color.x() = depthClamped * depthMax + (1.0f - depthClamped) * depthMin;
3322 					}
3323 				}
3324 
3325 				fillQuarter(referenceFrame->getLevel(0), color, layerNdx, subpassQuarterNdx, subpassNdx);
3326 			}
3327 
3328 			mask = mask >> 1;
3329 			++layerNdx;
3330 		}
3331 	}
3332 	return referenceFrame;
3333 }
3334 
readImage(VkImage image,const tcu::PixelBufferAccess & dst)3335 void MultiViewDepthStencilTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
3336 {
3337 	const VkFormat				bufferFormat	= m_depthTest ? getDepthBufferFormat(m_dsFormat) :
3338 												  m_stencilTest ? getStencilBufferFormat(m_dsFormat) :
3339 												  VK_FORMAT_UNDEFINED;
3340 	const deUint32				imagePixelSize	= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(bufferFormat)));
3341 	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * imagePixelSize;
3342 	const tcu::TextureFormat	tcuBufferFormat	= mapVkFormat(bufferFormat);
3343 	Move<VkBuffer>				buffer;
3344 	MovePtr<Allocation>			bufferAlloc;
3345 
3346 	// Create destination buffer
3347 	{
3348 		const VkBufferCreateInfo bufferParams	=
3349 		{
3350 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
3351 			DE_NULL,								// const void*			pNext;
3352 			0u,										// VkBufferCreateFlags	flags;
3353 			pixelDataSize,							// VkDeviceSize			size;
3354 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
3355 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3356 			1u,										// deUint32				queueFamilyIndexCount;
3357 			&m_queueFamilyIndex,					// const deUint32*		pQueueFamilyIndices;
3358 		};
3359 
3360 		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
3361 		bufferAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
3362 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
3363 
3364 		deMemset(bufferAlloc->getHostPtr(), 0xCC, static_cast<size_t>(pixelDataSize));
3365 		flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
3366 	}
3367 
3368 	const VkBufferMemoryBarrier	bufferBarrier	=
3369 	{
3370 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
3371 		DE_NULL,									// const void*		pNext;
3372 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
3373 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
3374 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
3375 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
3376 		*buffer,									// VkBuffer			buffer;
3377 		0u,											// VkDeviceSize		offset;
3378 		pixelDataSize								// VkDeviceSize		size;
3379 	};
3380 
3381 	// Copy image to buffer
3382 	const VkImageAspectFlags	aspect			= m_depthTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
3383 												  m_stencilTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT) :
3384 												  static_cast<VkImageAspectFlags>(0u);
3385 	const VkBufferImageCopy		copyRegion		=
3386 	{
3387 		0u,											// VkDeviceSize				bufferOffset;
3388 		(deUint32)dst.getWidth(),					// deUint32					bufferRowLength;
3389 		(deUint32)dst.getHeight(),					// deUint32					bufferImageHeight;
3390 		{
3391 			aspect,									// VkImageAspectFlags		aspect;
3392 			0u,										// deUint32					mipLevel;
3393 			0u,										// deUint32					baseArrayLayer;
3394 			m_parameters.extent.depth,				// deUint32					layerCount;
3395 		},											// VkImageSubresourceLayers	imageSubresource;
3396 		{ 0, 0, 0 },								// VkOffset3D				imageOffset;
3397 		{											// VkExtent3D				imageExtent;
3398 			m_parameters.extent.width,
3399 			m_parameters.extent.height,
3400 			1u
3401 		}
3402 	};
3403 
3404 	beginCommandBuffer (*m_device, *m_cmdBuffer);
3405 	{
3406 		m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
3407 		m_device->cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0u, DE_NULL);
3408 	}
3409 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3410 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3411 
3412 	// Read buffer data
3413 	invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
3414 
3415 	if (m_depthTest)
3416 	{
3417 		// Translate depth into color space
3418 		tcu::ConstPixelBufferAccess	pixelBuffer	(tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
3419 
3420 		for (int z = 0; z < pixelBuffer.getDepth(); z++)
3421 		for (int y = 0; y < pixelBuffer.getHeight(); y++)
3422 		for (int x = 0; x < pixelBuffer.getWidth(); x++)
3423 		{
3424 			const float		depth	= pixelBuffer.getPixDepth(x, y, z);
3425 			const tcu::Vec4	color	= tcu::Vec4(depth, 0.0f, 0.0f, 1.0f);
3426 
3427 			dst.setPixel(color, x, y, z);
3428 		}
3429 	}
3430 
3431 	if (m_stencilTest)
3432 	{
3433 		// Translate stencil into color space
3434 		tcu::ConstPixelBufferAccess	pixelBuffer	(tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
3435 		const tcu::Vec4				baseColor		= getQuarterRefColor(0u, 0u, 0u, false);
3436 		const tcu::Vec4				colorStep		= getQuarterRefColor(0u, 0u, 0u, true);
3437 		const tcu::Vec4				colorMap[4]		=
3438 		{
3439 			baseColor,
3440 			tcu::Vec4(1.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3441 			tcu::Vec4(2.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3442 			tcu::Vec4(3.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3443 		};
3444 		const tcu::Vec4				invalidColor	= tcu::Vec4(0.0f);
3445 
3446 		for (int z = 0; z < pixelBuffer.getDepth(); z++)
3447 		for (int y = 0; y < pixelBuffer.getHeight(); y++)
3448 		for (int x = 0; x < pixelBuffer.getWidth(); x++)
3449 		{
3450 			const int			stencilInt	= pixelBuffer.getPixStencil(x, y, z);
3451 			const tcu::Vec4&	color		= de::inRange(stencilInt, 0, DE_LENGTH_OF_ARRAY(colorMap)) ? colorMap[stencilInt] : invalidColor;
3452 
3453 			dst.setPixel(color, x, y, z);
3454 		}
3455 	}
3456 }
3457 
iterate(void)3458 tcu::TestStatus MultiViewDepthStencilTestInstance::iterate (void)
3459 {
3460 	const deUint32								subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
3461 	Move<VkRenderPass>						renderPass;
3462 	vector<VkImageView>							attachments		(makeAttachmentsVector());
3463 	Move<VkFramebuffer>						frameBuffer;
3464 	Unique<VkPipelineLayout>					pipelineLayout	(makePipelineLayout(*m_device, *m_logicalDevice));
3465 	vector<PipelineSp>							pipelines		(subpassCount);
3466 	const vector<tcu::Vec2>						depthRanges		(getDepthRanges());
3467 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
3468 
3469 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3470 	{
3471 		renderPass	= makeRenderPassWithDepth(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderingType);
3472 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u);
3473 	}
3474 
3475 	{
3476 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
3477 		madeShaderModule(shaderModule, shaderStageParams);
3478 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
3479 		{
3480 			const tcu::Vec2& depthRange = depthRanges[subpassNdx];
3481 			const float depthMin		= depthRange[0];
3482 			const float depthMax		= depthRange[1];
3483 
3484 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(
3485 				*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(),
3486 				subpassNdx, VK_VERTEX_INPUT_RATE_VERTEX, m_depthTest, m_stencilTest, depthMin, depthMax, m_dsFormat))));
3487 		}
3488 	}
3489 
3490 	createCommandBuffer();
3491 	createVertexData();
3492 	createVertexBuffer();
3493 
3494 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
3495 
3496 	{
3497 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
3498 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
3499 
3500 		readImage(m_dsAttachment->getImage(), dst);
3501 
3502 		if (!checkImage(dst))
3503 			return tcu::TestStatus::fail("Fail");
3504 	}
3505 
3506 	return tcu::TestStatus::pass("Pass");
3507 }
3508 
createVertexData(void)3509 void MultiViewDepthStencilTestInstance::createVertexData (void)
3510 {
3511 /*
3512 	partA - draw vertical quads, marked with 1
3513 
3514 	ViewMasks
3515 	0011
3516 	0110
3517 	1100
3518 	1001
3519 
3520 	Layer3  Layer2  Layer1  Layer0
3521 	  ^       ^       ^       ^
3522 	00|10   00|10   01|00   01|00
3523 	00|10   00|10   01|00   01|00
3524 	--+-->  --+-->  --+-->  --+-->
3525 	00|10   01|00   01|00   00|10
3526 	00|10   01|00   01|00   00|10
3527 
3528 
3529 	partB - draw horizontal quads, marked with 2
3530 
3531 	ViewMasks
3532 	0110
3533 	1100
3534 	1001
3535 	0011
3536 
3537 	Layer3  Layer2  Layer1  Layer0
3538 	  ^       ^       ^       ^
3539 	00|00   00|00   00|00   00|00
3540 	00|22   22|00   22|00   00|22
3541 	--+-->  --+-->  --+-->  --+-->
3542 	22|00   22|00   00|22   00|22
3543 	00|00   00|00   00|00   00|00
3544 
3545 
3546 	Final - after drawing quads from partA and partB (3 marks where quads overlap)
3547 
3548 	Layer3  Layer2  Layer1  Layer0
3549 	  ^       ^       ^       ^
3550 	00|10   00|10   01|00   01|00
3551 	00|32   22|10   23|00   01|22
3552 	--+-->  --+-->  --+-->  --+-->
3553 	22|10   23|00   01|22   00|32
3554 	00|10   01|00   01|00   00|10
3555 */
3556 	tcu::Vec4	color	(0.0f, 0.0f, 0.0f, 1.0f); // is not essential in this test
3557 	float		depth	(getQuarterRefColor(0u, 0u, 0u, true, 0u)[0]);
3558 
3559 	// part A - four horizontal quads
3560 	appendVertex(tcu::Vec4(-1.0f,-0.5f, depth, 1.0f), color);		// when testing TEST_TYPE_DEPTH_DIFFERENT_RANGES
3561 	appendVertex(tcu::Vec4(-1.0f, 0.0f, depth, 1.0f), color);		// this quad will have depth 1.2
3562 	appendVertex(tcu::Vec4( 0.0f,-0.5f, depth, 1.0f), color);		// and will be clipped in all views
3563 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3564 
3565 	depth = getQuarterRefColor(0u, 0u, 0u, true, 1u)[0];
3566 	appendVertex(tcu::Vec4(-1.0f, 0.0f, depth, 1.0f), color);
3567 	appendVertex(tcu::Vec4(-1.0f, 0.5f, depth, 1.0f), color);
3568 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3569 	appendVertex(tcu::Vec4( 0.0f, 0.5f, depth, 1.0f), color);
3570 
3571 	depth = getQuarterRefColor(0u, 0u, 0u, true, 2u)[0];
3572 	appendVertex(tcu::Vec4( 0.0f,-0.5f, depth, 1.0f), color);
3573 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3574 	appendVertex(tcu::Vec4( 1.0f,-0.5f, depth, 1.0f), color);
3575 	appendVertex(tcu::Vec4( 1.0f, 0.0f, depth, 1.0f), color);
3576 
3577 	depth = getQuarterRefColor(0u, 0u, 0u, true, 3u)[0];
3578 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3579 	appendVertex(tcu::Vec4( 0.0f, 0.5f, depth, 1.0f), color);
3580 	appendVertex(tcu::Vec4( 1.0f, 0.0f, depth, 1.0f), color);
3581 	appendVertex(tcu::Vec4( 1.0f, 0.5f, depth, 1.0f), color);
3582 
3583 	// part B - four vertical quads
3584 	depth = getQuarterRefColor(0u, 0u, 0u, true, 4u)[0];
3585 	appendVertex(tcu::Vec4(-0.5f,-1.0f, depth, 1.0f), color);
3586 	appendVertex(tcu::Vec4(-0.5f, 0.0f, depth, 1.0f), color);
3587 	appendVertex(tcu::Vec4( 0.0f,-1.0f, depth, 1.0f), color);
3588 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3589 
3590 	depth = getQuarterRefColor(0u, 0u, 0u, true, 5u)[0];
3591 	appendVertex(tcu::Vec4(-0.5f, 0.0f, depth, 1.0f), color);
3592 	appendVertex(tcu::Vec4(-0.5f, 1.0f, depth, 1.0f), color);
3593 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3594 	appendVertex(tcu::Vec4( 0.0f, 1.0f, depth, 1.0f), color);
3595 
3596 	depth = getQuarterRefColor(0u, 0u, 0u, true, 6u)[0];
3597 	appendVertex(tcu::Vec4( 0.0f,-1.0f, depth, 1.0f), color);
3598 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3599 	appendVertex(tcu::Vec4( 0.5f,-1.0f, depth, 1.0f), color);
3600 	appendVertex(tcu::Vec4( 0.5f, 0.0f, depth, 1.0f), color);
3601 
3602 	depth = getQuarterRefColor(0u, 0u, 0u, true, 7u)[0];			// when testing TEST_TYPE_DEPTH_DIFFERENT_RANGES
3603 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);		// this quad will have depth -0.05
3604 	appendVertex(tcu::Vec4( 0.0f, 1.0f, depth, 1.0f), color);		// and will be clipped in all views
3605 	appendVertex(tcu::Vec4( 0.5f, 0.0f, depth, 1.0f), color);
3606 	appendVertex(tcu::Vec4( 0.5f, 1.0f, depth, 1.0f), color);
3607 }
3608 
getDepthRanges(void) const3609 vector<tcu::Vec2> MultiViewDepthStencilTestInstance::getDepthRanges(void) const
3610 {
3611 	if (TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex)
3612 	{
3613 		DE_ASSERT(m_parameters.viewMasks.size() == 12);
3614 		return
3615 		{
3616 			// ranges used when four quads from part A are drawn
3617 			{0.0f, 1.0f},
3618 			{0.5f, 1.0f},
3619 			{0.0f, 0.5f},
3620 			{0.0f, 1.0f},
3621 
3622 			// ranges used when four quads from part B are drawn
3623 			{0.0f, 0.5f},
3624 			{0.0f, 1.0f},
3625 			{0.5f, 1.0f},
3626 			{0.0f, 0.5f},
3627 
3628 			// ranges used when part B is drawn once again
3629 			{0.5f, 1.0f},
3630 			{0.0f, 0.5f},
3631 			{0.0f, 0.5f},
3632 			{0.0f, 1.0f},
3633 		};
3634 	}
3635 
3636 	// by defaul use <0; 1> range for all subpasses
3637 	return { m_parameters.viewMasks.size(), tcu::Vec2(0.0f, 1.0f) };
3638 }
3639 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)3640 void MultiViewDepthStencilTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
3641 {
3642 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
3643 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
3644 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
3645 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
3646 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
3647 	const deUint32					vertexPerPrimitive		= 4u;
3648 
3649 	beginCommandBuffer(*m_device, *m_cmdBuffer);
3650 
3651 	beforeDraw();
3652 
3653 	if (!m_useDynamicRendering)
3654 	{
3655 		const VkRenderPassBeginInfo renderPassBeginInfo
3656 		{
3657 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
3658 			DE_NULL,									// const void*			pNext;
3659 			renderPass,									// VkRenderPass			renderPass;
3660 			frameBuffer,								// VkFramebuffer		framebuffer;
3661 			renderArea,									// VkRect2D				renderArea;
3662 			1u,											// uint32_t				clearValueCount;
3663 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
3664 		};
3665 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3666 	}
3667 
3668 	m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
3669 
3670 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3671 	{
3672 		deUint32 firstVertexOffset = (subpassNdx < 4) ? 0u : m_squareCount * vertexPerPrimitive;
3673 
3674 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
3675 
3676 		if (m_useDynamicRendering)
3677 		{
3678 			VkRenderingAttachmentInfoKHR colorAttachment
3679 			{
3680 				vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
3681 				DE_NULL,												// const void*							pNext;
3682 				m_colorAttachment->getImageView(),						// VkImageView							imageView;
3683 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout						imageLayout;
3684 				VK_RESOLVE_MODE_NONE,									// VkResolveModeFlagBits				resolveMode;
3685 				DE_NULL,												// VkImageView							resolveImageView;
3686 				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout						resolveImageLayout;
3687 				VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp					loadOp;
3688 				vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
3689 				renderPassClearValue									// VkClearValue							clearValue;
3690 			};
3691 
3692 			VkRenderingAttachmentInfoKHR dsAttachment
3693 			{
3694 				VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,		// VkStructureType						sType;
3695 				DE_NULL,												// const void*							pNext;
3696 				m_dsAttachment->getImageView(),							// VkImageView							imageView;
3697 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,		// VkImageLayout						imageLayout;
3698 				VK_RESOLVE_MODE_NONE,									// VkResolveModeFlagBits				resolveMode;
3699 				DE_NULL,												// VkImageView							resolveImageView;
3700 				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout						resolveImageLayout;
3701 				VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp					loadOp;
3702 				VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp					storeOp;
3703 				makeClearValueDepthStencil(0.0f, 0)						// VkClearValue							clearValue;
3704 			};
3705 
3706 			vk::VkRenderingInfoKHR renderingInfo
3707 			{
3708 				vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
3709 				DE_NULL,
3710 				0u,														// VkRenderingFlagsKHR					flags;
3711 				renderArea,												// VkRect2D								renderArea;
3712 				m_parameters.extent.depth,								// deUint32								layerCount;
3713 				m_parameters.viewMasks[subpassNdx],						// deUint32								viewMask;
3714 				1u,														// deUint32								colorAttachmentCount;
3715 				&colorAttachment,										// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
3716 				(m_depthTest ? &dsAttachment : DE_NULL),				// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
3717 				(m_stencilTest ? &dsAttachment : DE_NULL),				// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
3718 			};
3719 
3720 			m_device->cmdBeginRenderingKHR(*m_cmdBuffer, &renderingInfo);
3721 		}
3722 
3723 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
3724 			m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, firstVertexOffset + (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);
3725 
3726 		if (m_useDynamicRendering)
3727 			endRendering(*m_device, *m_cmdBuffer);
3728 		else if (subpassNdx < subpassCount - 1u)
3729 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3730 	}
3731 
3732 	if (!m_useDynamicRendering)
3733 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
3734 
3735 	afterDraw();
3736 
3737 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3738 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3739 }
3740 
beforeDraw(void)3741 void MultiViewDepthStencilTestInstance::beforeDraw (void)
3742 {
3743 	MultiViewRenderTestInstance::beforeDraw();
3744 
3745 	const VkImageSubresourceRange	subresourceRange		=
3746 	{
3747 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//VkImageAspectFlags	aspectMask;
3748 		0u,															//deUint32				baseMipLevel;
3749 		1u,															//deUint32				levelCount;
3750 		0u,															//deUint32				baseArrayLayer;
3751 		m_parameters.extent.depth,									//deUint32				layerCount;
3752 	};
3753 	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
3754 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3755 		0, VK_ACCESS_TRANSFER_WRITE_BIT,
3756 		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3757 
3758 	const tcu::Vec4		baseColor	= getQuarterRefColor(0u, 0u, 0u, false);
3759 	const float			clearDepth	= baseColor[0];
3760 	const VkClearValue	clearValue	= makeClearValueDepthStencil(clearDepth, 0);
3761 
3762 	m_device->cmdClearDepthStencilImage(*m_cmdBuffer, m_dsAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &subresourceRange);
3763 
3764 	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
3765 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
3766 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
3767 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
3768 }
3769 
afterDraw(void)3770 void MultiViewDepthStencilTestInstance::afterDraw (void)
3771 {
3772 	MultiViewRenderTestInstance::afterDraw();
3773 
3774 	const VkImageSubresourceRange	dsSubresourceRange		=
3775 	{
3776 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//  VkImageAspectFlags	aspectMask;
3777 		0u,															//  deUint32			baseMipLevel;
3778 		1u,															//  deUint32			levelCount;
3779 		0u,															//  deUint32			baseArrayLayer;
3780 		m_parameters.extent.depth,									//  deUint32			layerCount;
3781 	};
3782 
3783 	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), dsSubresourceRange,
3784 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
3785 		VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
3786 		VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3787 }
3788 
3789 class MultiViewRenderTestsCase : public vkt::TestCase
3790 {
3791 public:
MultiViewRenderTestsCase(tcu::TestContext & context,const char * name,const char * description,const TestParameters & parameters)3792 	MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
3793 		: TestCase			(context, name, description)
3794 		, m_parameters		(parameters)
3795 	{
3796 		DE_ASSERT(m_parameters.extent.width == m_parameters.extent.height);
3797 	}
3798 private:
3799 	const TestParameters	m_parameters;
3800 
createInstance(vkt::Context & context) const3801 	vkt::TestInstance*	createInstance		(vkt::Context& context) const
3802 	{
3803 		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex ||
3804 			TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex)
3805 			return new MultiViewAttachmentsTestInstance(context, m_parameters);
3806 
3807 		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
3808 			return new MultiViewInstancedTestInstance(context, m_parameters);
3809 
3810 		if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
3811 			return new MultiViewInputRateInstanceTestInstance(context, m_parameters);
3812 
3813 		if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex ||
3814 			TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
3815 			return new MultiViewDrawIndirectTestInstance(context, m_parameters);
3816 
3817 		if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
3818 			return new MultiViewClearAttachmentsTestInstance(context, m_parameters);
3819 
3820 		if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex ||
3821 			TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex)
3822 			return new MultiViewSecondaryCommandBufferTestInstance(context, m_parameters);
3823 
3824 		if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
3825 			return new MultiViewPointSizeTestInstance(context, m_parameters);
3826 
3827 		if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
3828 			return new MultiViewMultsampleTestInstance(context, m_parameters);
3829 
3830 		if (TEST_TYPE_QUERIES == m_parameters.viewIndex ||
3831 			TEST_TYPE_NON_PRECISE_QUERIES == m_parameters.viewIndex)
3832 			return new MultiViewQueriesTestInstance(context, m_parameters);
3833 
3834 		if (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex ||
3835 			TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex ||
3836 			TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
3837 			TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex ||
3838 			TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex ||
3839 			TEST_TYPE_DRAW_INDEXED == m_parameters.viewIndex)
3840 			return new MultiViewRenderTestInstance(context, m_parameters);
3841 
3842 		if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex ||
3843 			TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
3844 			return new MultiViewReadbackTestInstance(context, m_parameters);
3845 
3846 		if (TEST_TYPE_DEPTH == m_parameters.viewIndex ||
3847 			TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex ||
3848 			TEST_TYPE_STENCIL == m_parameters.viewIndex)
3849 			return new MultiViewDepthStencilTestInstance(context, m_parameters);
3850 
3851 		TCU_THROW(InternalError, "Unknown test type");
3852 	}
3853 
checkSupport(Context & context) const3854 	virtual void		checkSupport		(Context& context) const
3855 	{
3856 		if (m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2)
3857 			context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
3858 
3859 		if (m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
3860 			context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
3861 
3862 		context.requireDeviceFunctionality("VK_KHR_multiview");
3863 		if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
3864 			context.requireDeviceFunctionality("VK_EXT_depth_range_unrestricted");
3865 	}
3866 
initPrograms(SourceCollections & programCollection) const3867 	void				initPrograms		(SourceCollections& programCollection) const
3868 	{
3869 		// Create vertex shader
3870 		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
3871 		{
3872 			std::ostringstream source;
3873 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3874 					<< "#extension GL_EXT_multiview : enable\n"
3875 					<< "layout(location = 0) in highp vec4 in_position;\n"
3876 					<< "layout(location = 1) in vec4 in_color;\n"
3877 					<< "layout(location = 0) out vec4 out_color;\n"
3878 					<< "void main (void)\n"
3879 					<< "{\n"
3880 					<< "	int modInstance = gl_InstanceIndex % 4;\n"
3881 					<< "	int instance    = gl_InstanceIndex + 1;\n"
3882 					<< "	gl_Position = in_position;\n"
3883 					<< "	if (modInstance == 1)\n"
3884 					<< "		gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n"
3885 					<< "	if (modInstance == 2)\n"
3886 					<< "		gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n"
3887 					<< "	if (modInstance == 3)\n"
3888 					<< "		gl_Position =  in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n"
3889 					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
3890 					<< "}\n";
3891 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3892 		}
3893 		else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
3894 		{
3895 			std::ostringstream source;
3896 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3897 					<< "#extension GL_EXT_multiview : enable\n"
3898 					<< "layout(location = 0) in highp vec4 in_position;\n"
3899 					<< "layout(location = 1) in vec4 in_color;\n"
3900 					<< "layout(location = 0) out vec4 out_color;\n"
3901 					<< "void main (void)\n"
3902 					<< "{\n"
3903 					<< "	int instance = gl_InstanceIndex + 1;\n"
3904 					<< "	gl_Position = in_position;\n"
3905 					<< "	if (gl_VertexIndex == 1)\n"
3906 					<< "		gl_Position.y += 1.0f;\n"
3907 					<< "	else if (gl_VertexIndex == 2)\n"
3908 					<< "		gl_Position.x += 1.0f;\n"
3909 					<< "	else if (gl_VertexIndex == 3)\n"
3910 					<< "	{\n"
3911 					<< "		gl_Position.x += 1.0f;\n"
3912 					<< "		gl_Position.y += 1.0f;\n"
3913 					<< "	}\n"
3914 					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
3915 					<< "}\n";
3916 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3917 		}
3918 		else if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
3919 		{
3920 			std::ostringstream source;
3921 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3922 					<< "#extension GL_EXT_multiview : enable\n"
3923 					<< "layout(location = 0) in highp vec4 in_position;\n"
3924 					<< "layout(location = 1) in highp vec4 in_color;\n"
3925 					<< "layout(location = 0) out vec4 out_color;\n"
3926 					<< "void main (void)\n"
3927 					<< "{\n"
3928 					<< "	gl_Position = in_position;\n"
3929 					<< "	if (gl_ViewIndex == 0)\n"
3930 					<< "		gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_WIDE), 1) << "f;\n"
3931 					<< "	else\n"
3932 					<< "		gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_SMALL), 1) << "f;\n"
3933 					<< "	out_color = in_color;\n"
3934 					<< "}\n";
3935 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3936 		}
3937 		else
3938 		{
3939 			const bool generateColor	=  (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex)
3940 										|| (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex)
3941 										|| (TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
3942 										|| (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex);
3943 			std::ostringstream source;
3944 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
3945 					<< "#extension GL_EXT_multiview : enable\n"
3946 					<< "layout(location = 0) in highp vec4 in_position;\n"
3947 					<< "layout(location = 1) in vec4 in_color;\n"
3948 					<< "layout(location = 0) out vec4 out_color;\n"
3949 					<< "void main (void)\n"
3950 					<< "{\n"
3951 					<< "	gl_Position = in_position;\n";
3952 				if (generateColor)
3953 					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
3954 				else
3955 					source << "	out_color = in_color;\n";
3956 			source	<< "}\n";
3957 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
3958 		}
3959 
3960 		if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)
3961 		{// Tessellation control & evaluation
3962 			std::ostringstream source_tc;
3963 			source_tc	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3964 						<< "#extension GL_EXT_multiview : enable\n"
3965 						<< "#extension GL_EXT_tessellation_shader : require\n"
3966 						<< "layout(vertices = 4) out;\n"
3967 						<< "layout(location = 0) in vec4 in_color[];\n"
3968 						<< "layout(location = 0) out vec4 out_color[];\n"
3969 						<< "\n"
3970 						<< "void main (void)\n"
3971 						<< "{\n"
3972 						<< "	if ( gl_InvocationID == 0 )\n"
3973 						<< "	{\n"
3974 						<< "		gl_TessLevelInner[0] = 4.0f;\n"
3975 						<< "		gl_TessLevelInner[1] = 4.0f;\n"
3976 						<< "		gl_TessLevelOuter[0] = 4.0f;\n"
3977 						<< "		gl_TessLevelOuter[1] = 4.0f;\n"
3978 						<< "		gl_TessLevelOuter[2] = 4.0f;\n"
3979 						<< "		gl_TessLevelOuter[3] = 4.0f;\n"
3980 						<< "	}\n"
3981 						<< "	out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
3982 						<< "	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3983 						<< "}\n";
3984 			programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());
3985 
3986 			std::ostringstream source_te;
3987 			source_te	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
3988 						<< "#extension GL_EXT_multiview : enable\n"
3989 						<< "#extension GL_EXT_tessellation_shader : require\n"
3990 						<< "layout( quads, equal_spacing, ccw ) in;\n"
3991 						<< "layout(location = 0) in vec4 in_color[];\n"
3992 						<< "layout(location = 0) out vec4 out_color;\n"
3993 						<< "void main (void)\n"
3994 						<< "{\n"
3995 						<< "	const float u = gl_TessCoord.x;\n"
3996 						<< "	const float v = gl_TessCoord.y;\n"
3997 						<< "	const float w = gl_TessCoord.z;\n"
3998 						<< "	gl_Position = (1 - u) * (1 - v) * gl_in[0].gl_Position +(1 - u) * v * gl_in[1].gl_Position + u * (1 - v) * gl_in[2].gl_Position + u * v * gl_in[3].gl_Position;\n"
3999 						<< "	out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4000 						<< "}\n";
4001 			programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
4002 		}
4003 
4004 		if (TEST_TYPE_VIEW_INDEX_IN_GEOMETRY		== m_parameters.viewIndex ||
4005 			TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY	== m_parameters.viewIndex ||
4006 			TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY	== m_parameters.viewIndex)
4007 		{// Geometry Shader
4008 			std::ostringstream	source;
4009 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4010 					<< "#extension GL_EXT_multiview : enable\n"
4011 					<< "layout(triangles) in;\n"
4012 					<< "layout(triangle_strip, max_vertices = 16) out;\n"
4013 					<< "layout(location = 0) in vec4 in_color[];\n"
4014 					<< "layout(location = 0) out vec4 out_color;\n"
4015 					<< "void main (void)\n"
4016 					<< "{\n"
4017 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4018 					<< "	gl_Position = gl_in[0].gl_Position;\n"
4019 					<< "	EmitVertex();\n"
4020 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4021 					<< "	gl_Position = gl_in[1].gl_Position;\n"
4022 					<< "	EmitVertex();\n"
4023 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4024 					<< "	gl_Position = gl_in[2].gl_Position;\n"
4025 					<< "	EmitVertex();\n"
4026 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4027 					<< "	gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
4028 					<< "	EmitVertex();\n"
4029 					<< "	EndPrimitive();\n"
4030 					<< "}\n";
4031 			programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str());
4032 		}
4033 
4034 		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex)
4035 		{// Create fragment shader read/write attachment
4036 			std::ostringstream source;
4037 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4038 					<< "#extension GL_EXT_multiview : enable\n"
4039 					<< "layout(location = 0) in vec4 in_color;\n"
4040 					<< "layout(location = 0) out vec4 out_color;\n"
4041 					<< "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n"
4042 					<< "void main()\n"
4043 					<<"{\n"
4044 					<< "	out_color = vec4(subpassLoad(in_color_attachment));\n"
4045 					<< "}\n";
4046 			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
4047 		}
4048 		else
4049 		{// Create fragment shader
4050 			std::ostringstream source;
4051 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4052 					<< "#extension GL_EXT_multiview : enable\n"
4053 					<< "layout(location = 0) in vec4 in_color;\n"
4054 					<< "layout(location = 0) out vec4 out_color;\n"
4055 					<< "void main()\n"
4056 					<<"{\n";
4057 				if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
4058 					TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex)
4059 					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
4060 				else
4061 					source << "	out_color = in_color;\n";
4062 			source	<< "}\n";
4063 			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
4064 		}
4065 	}
4066 };
4067 } //anonymous
4068 
createViewMasksName(const std::vector<deUint32> & viewMasks)4069 static std::string createViewMasksName(const std::vector<deUint32>& viewMasks)
4070 {
4071 	std::ostringstream		masks;
4072 
4073 	for (size_t ndx = 0u; ndx < viewMasks.size(); ++ndx)
4074 	{
4075 		masks << viewMasks[ndx];
4076 		if (viewMasks.size() - 1 != ndx)
4077 			masks << "_";
4078 	}
4079 
4080 	return masks.str();
4081 }
4082 
tripleDepthStencilMasks(std::vector<deUint32> & baseMasks)4083 static std::vector<deUint32> tripleDepthStencilMasks(std::vector<deUint32>& baseMasks)
4084 {
4085 	std::vector<deUint32> tripledMasks(baseMasks);
4086 	std::vector<deUint32> partBMasks;
4087 
4088 	// a,b,c,d  =>  b,c,d,a
4089 	partBMasks.insert(partBMasks.end(), baseMasks.begin() + 1, baseMasks.end());
4090 	partBMasks.push_back(baseMasks[0]);
4091 
4092 	tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
4093 	tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
4094 
4095 	return tripledMasks;
4096 }
4097 
multiViewRenderCreateTests(tcu::TestCaseGroup * group)4098 void multiViewRenderCreateTests (tcu::TestCaseGroup* group)
4099 {
4100 	const deUint32				testCaseCount				= 7u;
4101 	const string				shaderName[TEST_TYPE_LAST]	=
4102 	{
4103 		"masks",
4104 		"vertex_shader",
4105 		"fragment_shader",
4106 		"geometry_shader",
4107 		"tessellation_shader",
4108 		"input_attachments",
4109 		"input_attachments_geometry",
4110 		"instanced",
4111 		"input_instance",
4112 		"draw_indirect",
4113 		"draw_indirect_indexed",
4114 		"draw_indexed",
4115 		"clear_attachments",
4116 		"secondary_cmd_buffer",
4117 		"secondary_cmd_buffer_geometry",
4118 		"point_size",
4119 		"multisample",
4120 		"queries",
4121 		"non_precise_queries",
4122 		"readback_implicit_clear",
4123 		"readback_explicit_clear",
4124 		"depth",
4125 		"depth_different_ranges",
4126 		"stencil",
4127 	};
4128 	const VkExtent3D			extent3D[testCaseCount]		=
4129 	{
4130 		{16u,	16u,	4u},
4131 		{64u,	64u,	8u},
4132 		{128u,	128u,	4u},
4133 		{32u,	32u,	5u},
4134 		{64u,	64u,	6u},
4135 		{32u,	32u,	4u},
4136 		{16u,	16u,	10u},
4137 	};
4138 	vector<deUint32>			viewMasks[testCaseCount];
4139 
4140 	viewMasks[0].push_back(15u);	//1111
4141 
4142 	viewMasks[1].push_back(8u);		//1000
4143 
4144 	viewMasks[2].push_back(1u);		//0001
4145 	viewMasks[2].push_back(2u);		//0010
4146 	viewMasks[2].push_back(4u);		//0100
4147 	viewMasks[2].push_back(8u);		//1000
4148 
4149 	viewMasks[3].push_back(15u);	//1111
4150 	viewMasks[3].push_back(15u);	//1111
4151 	viewMasks[3].push_back(15u);	//1111
4152 	viewMasks[3].push_back(15u);	//1111
4153 
4154 	viewMasks[4].push_back(8u);		//1000
4155 	viewMasks[4].push_back(1u);		//0001
4156 	viewMasks[4].push_back(1u);		//0001
4157 	viewMasks[4].push_back(8u);		//1000
4158 
4159 	viewMasks[5].push_back(5u);		//0101
4160 	viewMasks[5].push_back(10u);	//1010
4161 	viewMasks[5].push_back(5u);		//0101
4162 	viewMasks[5].push_back(10u);	//1010
4163 
4164 	const deUint32 minSupportedMultiviewViewCount	= 6u;
4165 	const deUint32 maxViewMask						= (1u << minSupportedMultiviewViewCount) - 1u;
4166 
4167 	for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u)
4168 		viewMasks[testCaseCount - 1].push_back(mask);
4169 
4170 	vector<deUint32>			depthStencilMasks;
4171 
4172 	depthStencilMasks.push_back(3u);	// 0011
4173 	depthStencilMasks.push_back(6u);	// 0110
4174 	depthStencilMasks.push_back(12u);	// 1100
4175 	depthStencilMasks.push_back(9u);	// 1001
4176 
4177 	for (int renderPassTypeNdx = 0; renderPassTypeNdx < 3; ++renderPassTypeNdx)
4178 	{
4179 		RenderingType				renderPassType	(RENDERING_TYPE_RENDERPASS_LEGACY);
4180 		MovePtr<tcu::TestCaseGroup>	targetGroup		(DE_NULL);
4181 		tcu::TestCaseGroup*			targetGroupPtr	(group);
4182 
4183 		if (renderPassTypeNdx == 1)
4184 		{
4185 			renderPassType	= RENDERING_TYPE_RENDERPASS2;
4186 			targetGroup		= MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(group->getTestContext(), "renderpass2", "RenderPass2 index tests"));
4187 			targetGroupPtr	= targetGroup.get();
4188 		}
4189 		else if (renderPassTypeNdx == 2)
4190 		{
4191 			renderPassType	= RENDERING_TYPE_DYNAMIC_RENDERING;
4192 			targetGroup		= MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(group->getTestContext(), "dynamic_rendering", "Dynamic rendering tests"));
4193 			targetGroupPtr	= targetGroup.get();
4194 		}
4195 
4196 		tcu::TestContext&			testCtx				(targetGroupPtr->getTestContext());
4197 		MovePtr<tcu::TestCaseGroup>	groupViewIndex		(new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests."));
4198 
4199 		for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx)
4200 		{
4201 			MovePtr<tcu::TestCaseGroup>	groupShader			(new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str(), ""));
4202 			const TestType				testType			= static_cast<TestType>(testTypeNdx);
4203 			const VkSampleCountFlagBits	sampleCountFlags	= (testType == TEST_TYPE_MULTISAMPLE) ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
4204 			const VkFormat				colorFormat			= (testType == TEST_TYPE_MULTISAMPLE) ? VK_FORMAT_R32G32B32A32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM;
4205 
4206 			// subpassLoad can't be used with dynamic rendering
4207 			if ((testTypeNdx == TEST_TYPE_INPUT_ATTACHMENTS) && (renderPassType == RENDERING_TYPE_DYNAMIC_RENDERING))
4208 				continue;
4209 
4210 			if (testTypeNdx == TEST_TYPE_DEPTH ||
4211                                   testTypeNdx == TEST_TYPE_DEPTH_DIFFERENT_RANGES ||
4212                                   testTypeNdx == TEST_TYPE_STENCIL)
4213 			{
4214 				const VkExtent3D		dsTestExtent3D	= { 64u, 64u, 4u };
4215 				const TestParameters	parameters		= { dsTestExtent3D, tripleDepthStencilMasks(depthStencilMasks), testType, sampleCountFlags, colorFormat, renderPassType };
4216 				const std::string		testName		= createViewMasksName(parameters.viewMasks);
4217 
4218 				groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
4219 			}
4220 			else
4221 			{
4222 				for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx)
4223 				{
4224 					const TestParameters	parameters	=	{ extent3D[testCaseNdx], viewMasks[testCaseNdx], testType, sampleCountFlags, colorFormat, renderPassType };
4225 					const std::string		testName	=	createViewMasksName(parameters.viewMasks);
4226 
4227 					groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
4228 				}
4229 
4230 				// maxMultiviewViewCount case
4231 				{
4232 					const VkExtent3D		incompleteExtent3D	= { 16u, 16u, 0u };
4233 					const vector<deUint32>	dummyMasks;
4234 					const TestParameters	parameters			= { incompleteExtent3D, dummyMasks, testType, sampleCountFlags, colorFormat, renderPassType };
4235 
4236 					groupShader->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", "", parameters));
4237 				}
4238 			}
4239 
4240 			switch (testType)
4241 			{
4242 				case TEST_TYPE_VIEW_MASK:
4243 				case TEST_TYPE_INPUT_ATTACHMENTS:
4244 				case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
4245 				case TEST_TYPE_INSTANCED_RENDERING:
4246 				case TEST_TYPE_INPUT_RATE_INSTANCE:
4247 				case TEST_TYPE_DRAW_INDIRECT:
4248 				case TEST_TYPE_DRAW_INDIRECT_INDEXED:
4249 				case TEST_TYPE_DRAW_INDEXED:
4250 				case TEST_TYPE_CLEAR_ATTACHMENTS:
4251 				case TEST_TYPE_SECONDARY_CMD_BUFFER:
4252 				case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
4253 				case TEST_TYPE_POINT_SIZE:
4254 				case TEST_TYPE_MULTISAMPLE:
4255 				case TEST_TYPE_QUERIES:
4256 				case TEST_TYPE_NON_PRECISE_QUERIES:
4257 				case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
4258 				case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
4259 				case TEST_TYPE_DEPTH:
4260 				case TEST_TYPE_DEPTH_DIFFERENT_RANGES:
4261 				case TEST_TYPE_STENCIL:
4262 					targetGroupPtr->addChild(groupShader.release());
4263 					break;
4264 				case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
4265 				case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
4266 				case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
4267 				case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
4268 					groupViewIndex->addChild(groupShader.release());
4269 					break;
4270 				default:
4271 					DE_ASSERT(0);
4272 					break;
4273 			}
4274 		}
4275 
4276 		targetGroupPtr->addChild(groupViewIndex.release());
4277 
4278 		if (renderPassType != RENDERING_TYPE_RENDERPASS_LEGACY)
4279 			group->addChild(targetGroup.release());
4280 	}
4281 }
4282 
4283 } //MultiView
4284 } //vkt
4285 
4286