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