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