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