• 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::__anon8d3792430111::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 	std::shared_ptr<CustomInstanceWrapper>	m_instanceWrapper;
318 	const TestParameters			m_parameters;
319 	const bool						m_useDynamicRendering;
320 	const int						m_seed;
321 	const deUint32					m_squareCount;
322 
323 	Move<VkDevice>					m_logicalDevice;
324 #ifndef CTS_USES_VULKANSC
325 	de::MovePtr<vk::DeviceDriver>	m_device;
326 #else
327 	de::MovePtr<vk::DeviceDriverSC, vk::DeinitDeviceDeleter> m_device;
328 #endif // CTS_USES_VULKANSC
329 	MovePtr<Allocator>				m_allocator;
330 	deUint32						m_queueFamilyIndex;
331 	VkQueue							m_queue;
332 	vector<tcu::Vec4>				m_vertexCoord;
333 	Move<VkBuffer>					m_vertexCoordBuffer;
334 	MovePtr<Allocation>				m_vertexCoordAlloc;
335 	vector<tcu::Vec4>				m_vertexColor;
336 	Move<VkBuffer>					m_vertexColorBuffer;
337 	MovePtr<Allocation>				m_vertexColorAlloc;
338 	vector<deUint32>				m_vertexIndices;
339 	Move<VkBuffer>					m_vertexIndicesBuffer;
340 	MovePtr<Allocation>				m_vertexIndicesAllocation;
341 	Move<VkCommandPool>				m_cmdPool;
342 	Move<VkCommandBuffer>			m_cmdBuffer;
343 	Move<VkCommandPool>				m_cmdPoolSecondary;
344 	de::SharedPtr<ImageAttachment>	m_colorAttachment;
345 	VkBool32						m_hasMultiDrawIndirect;
346 	vector<tcu::Vec4>				m_colorTable;
347 };
348 
MultiViewRenderTestInstance(Context & context,const TestParameters & parameters)349 MultiViewRenderTestInstance::MultiViewRenderTestInstance (Context& context, const TestParameters& parameters)
350 	: TestInstance			(context)
351 	, m_instanceWrapper		(new CustomInstanceWrapper(context))
352 	, m_parameters			(fillMissingParameters(parameters))
353 	, m_useDynamicRendering	(parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
354 	, m_seed				(context.getTestContext().getCommandLine().getBaseSeed())
355 	, m_squareCount			(4u)
356 	, m_queueFamilyIndex	(0u)
357 {
358 	const float v	= 0.75f;
359 	const float o	= 0.25f;
360 
361 	m_colorTable.push_back(tcu::Vec4(v, o, o, 1.0f));
362 	m_colorTable.push_back(tcu::Vec4(o, v, o, 1.0f));
363 	m_colorTable.push_back(tcu::Vec4(o, o, v, 1.0f));
364 	m_colorTable.push_back(tcu::Vec4(o, v, v, 1.0f));
365 	m_colorTable.push_back(tcu::Vec4(v, o, v, 1.0f));
366 	m_colorTable.push_back(tcu::Vec4(v, v, o, 1.0f));
367 	m_colorTable.push_back(tcu::Vec4(o, o, o, 1.0f));
368 	m_colorTable.push_back(tcu::Vec4(v, v, v, 1.0f));
369 
370 	createMultiViewDevices();
371 
372 	// Color attachment
373 	m_colorAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_parameters.colorFormat, m_parameters.samples));
374 }
375 
~MultiViewRenderTestInstance()376 MultiViewRenderTestInstance::~MultiViewRenderTestInstance()
377 {
378 }
379 
iterate(void)380 tcu::TestStatus MultiViewRenderTestInstance::iterate (void)
381 {
382 	const deUint32								subpassCount				= static_cast<deUint32>(m_parameters.viewMasks.size());
383 	Move<VkRenderPass>							renderPass;
384 	Move<VkFramebuffer>							frameBuffer;
385 
386 	// FrameBuffer & renderPass
387 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
388 	{
389 		renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType);
390 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
391 	}
392 
393 	// pipelineLayout
394 	Unique<VkPipelineLayout>					pipelineLayout				(makePipelineLayout(*m_device, *m_logicalDevice));
395 
396 	// pipelines
397 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
398 	vector<PipelineSp>							pipelines(subpassCount);
399 	const VkVertexInputRate						vertexInputRate				= (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex) ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
400 
401 	{
402 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
403 		madeShaderModule(shaderModule, shaderStageParams);
404 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
405 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx, vertexInputRate))));
406 	}
407 
408 	createCommandBuffer();
409 	createVertexData();
410 	createVertexBuffer();
411 
412 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
413 
414 	{
415 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
416 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
417 
418 		readImage(m_colorAttachment->getImage(), dst);
419 
420 		if (!checkImage(dst))
421 			return tcu::TestStatus::fail("Fail");
422 	}
423 
424 	return tcu::TestStatus::pass("Pass");
425 }
426 
beforeRenderPass(void)427 void MultiViewRenderTestInstance::beforeRenderPass (void)
428 {
429 	const VkImageSubresourceRange	subresourceRange		=
430 	{
431 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
432 		0u,							//deUint32				baseMipLevel;
433 		1u,							//deUint32				levelCount;
434 		0u,							//deUint32				baseArrayLayer;
435 		m_parameters.extent.depth,	//deUint32				layerCount;
436 	};
437 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
438 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
439 		0, VK_ACCESS_TRANSFER_WRITE_BIT,
440 		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
441 
442 	const VkClearValue renderPassClearValue = makeClearValueColor(tcu::Vec4(0.0f));
443 	m_device->cmdClearColorImage(*m_cmdBuffer, m_colorAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &renderPassClearValue.color, 1, &subresourceRange);
444 
445 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
446 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
447 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
448 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
449 }
450 
afterRenderPass(void)451 void MultiViewRenderTestInstance::afterRenderPass (void)
452 {
453 	const VkImageSubresourceRange	subresourceRange		=
454 	{
455 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
456 		0u,							//deUint32				baseMipLevel;
457 		1u,							//deUint32				levelCount;
458 		0u,							//deUint32				baseArrayLayer;
459 		m_parameters.extent.depth,	//deUint32				layerCount;
460 	};
461 
462 	imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
463 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
464 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
465 		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
466 }
467 
468 #ifndef CTS_USES_VULKANSC
addRenderingSubpassDependencyIfRequired(deUint32 currentSubpassNdx)469 void MultiViewRenderTestInstance::addRenderingSubpassDependencyIfRequired (deUint32 currentSubpassNdx)
470 {
471 	// Get the combined view mask since the last pipeline barrier.
472 	deUint32 viewMask = 0;
473 
474 	for (deUint32 subpassNdx = 0; subpassNdx < currentSubpassNdx; ++subpassNdx)
475 	{
476 		if ((viewMask & m_parameters.viewMasks[subpassNdx]) != 0)
477 		{
478 			viewMask = 0; // This subpass should have a pipeline barrier so reset the view mask.
479 		}
480 
481 		viewMask |= m_parameters.viewMasks[subpassNdx];
482 	}
483 
484 	// Add a pipeline barrier if the view mask for this subpass contains bits used in previous subpasses
485 	// since the last pipeline barrier.
486 	if ((viewMask & m_parameters.viewMasks[currentSubpassNdx]) != 0)
487 	{
488 		const VkImageSubresourceRange	subresourceRange		=
489 		{
490 			VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
491 			0u,							//deUint32				baseMipLevel;
492 			1u,							//deUint32				levelCount;
493 			0u,							//deUint32				baseArrayLayer;
494 			m_parameters.extent.depth,	//deUint32				layerCount;
495 		};
496 
497 		imageBarrier(*m_device, *m_cmdBuffer, m_colorAttachment->getImage(), subresourceRange,
498 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
499 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
500 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
501 	}
502 }
503 #endif // CTS_USES_VULKANSC
504 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)505 void MultiViewRenderTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
506 {
507 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
508 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
509 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
510 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
511 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
512 
513 	beginCommandBuffer(*m_device, *m_cmdBuffer);
514 
515 	beforeRenderPass();
516 
517 	if (!m_useDynamicRendering)
518 	{
519 		const VkRenderPassBeginInfo renderPassBeginInfo
520 		{
521 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
522 			DE_NULL,									// const void*			pNext;
523 			renderPass,									// VkRenderPass			renderPass;
524 			frameBuffer,								// VkFramebuffer		framebuffer;
525 			renderArea,									// VkRect2D				renderArea;
526 			1u,											// uint32_t				clearValueCount;
527 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
528 		};
529 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
530 	}
531 
532 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
533 	{
534 		m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
535 
536 		if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
537 			m_device->cmdBindIndexBuffer(*m_cmdBuffer, *m_vertexIndicesBuffer, 0u, VK_INDEX_TYPE_UINT32);
538 
539 		bindResources();
540 
541 #ifndef CTS_USES_VULKANSC
542 		if (m_useDynamicRendering)
543 		{
544 			addRenderingSubpassDependencyIfRequired(subpassNdx);
545 
546 			beginRendering(
547 				*m_device,
548 				*m_cmdBuffer,
549 				m_colorAttachment->getImageView(),
550 				renderArea,
551 				renderPassClearValue,
552 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
553 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
554 				0u,
555 				m_parameters.extent.depth,
556 				m_parameters.viewMasks[subpassNdx]);
557 		}
558 #endif // CTS_USES_VULKANSC
559 
560 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
561 
562 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
563 			if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED)
564 				m_device->cmdDrawIndexed(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u, 0u);
565 			else
566 				m_device->cmdDraw(*m_cmdBuffer, 4u, 1u, (drawNdx + subpassNdx % m_squareCount) * 4u, 0u);
567 
568 #ifndef CTS_USES_VULKANSC
569 		if (m_useDynamicRendering)
570 			endRendering(*m_device, *m_cmdBuffer);
571 		else
572 #endif // CTS_USES_VULKANSC
573 			if (subpassNdx < subpassCount - 1u)
574 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
575 	}
576 
577 	if (!m_useDynamicRendering)
578 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
579 
580 	afterRenderPass();
581 
582 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
583 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
584 }
585 
createVertexData(void)586 void MultiViewRenderTestInstance::createVertexData (void)
587 {
588 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
589 
590 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 1.0f, 1.0f), color);
591 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
592 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
593 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
594 
595 	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
596 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 1.0f, 1.0f), color);
597 	appendVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), color);
598 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
599 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
600 
601 	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
602 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 1.0f, 1.0f), color);
603 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
604 	appendVertex(tcu::Vec4( 1.0f,-1.0f, 1.0f, 1.0f), color);
605 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
606 
607 	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
608 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 1.0f, 1.0f), color);
609 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 1.0f, 1.0f), color);
610 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 1.0f, 1.0f), color);
611 	appendVertex(tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f), color);
612 
613 	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
614 	{
615 		const size_t		verticesCount	= m_vertexCoord.size();
616 		vector<tcu::Vec4>	vertexColor		(verticesCount);
617 		vector<tcu::Vec4>	vertexCoord		(verticesCount);
618 
619 		m_vertexIndices.clear();
620 		m_vertexIndices.reserve(verticesCount);
621 		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
622 			m_vertexIndices.push_back(vertexIdx);
623 
624 		de::Random(m_seed).shuffle(m_vertexIndices.begin(), m_vertexIndices.end());
625 
626 		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
627 			vertexColor[m_vertexIndices[vertexIdx]] = m_vertexColor[vertexIdx];
628 		m_vertexColor.assign(vertexColor.begin(), vertexColor.end());
629 
630 		for (deUint32 vertexIdx = 0; vertexIdx < verticesCount; ++vertexIdx)
631 			vertexCoord[m_vertexIndices[vertexIdx]] = m_vertexCoord[vertexIdx];
632 		m_vertexCoord.assign(vertexCoord.begin(), vertexCoord.end());
633 	}
634 }
635 
fillMissingParameters(const TestParameters & parameters)636 TestParameters MultiViewRenderTestInstance::fillMissingParameters (const TestParameters& parameters)
637 {
638 	if (!parameters.viewMasks.empty())
639 		return parameters;
640 	else
641 	{
642 		const InstanceInterface&			instanceDriver		= m_instanceWrapper->instance.getDriver();
643 		const VkPhysicalDevice				physicalDevice		= chooseDevice(instanceDriver, m_instanceWrapper->instance, m_context.getTestContext().getCommandLine());
644 
645 		VkPhysicalDeviceMultiviewProperties multiviewProperties =
646 		{
647 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,		// VkStructureType	sType;
648 			DE_NULL,													// void*			pNext;
649 			0u,															// deUint32			maxMultiviewViewCount;
650 			0u															// deUint32			maxMultiviewInstanceIndex;
651 		};
652 
653 		VkPhysicalDeviceProperties2 deviceProperties2;
654 		deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
655 		deviceProperties2.pNext = &multiviewProperties;
656 
657 		instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2);
658 
659 		TestParameters newParameters = parameters;
660 		newParameters.extent.depth = multiviewProperties.maxMultiviewViewCount;
661 
662 		vector<deUint32> viewMasks(multiviewProperties.maxMultiviewViewCount);
663 		for (deUint32 i = 0; i < multiviewProperties.maxMultiviewViewCount; i++)
664 			viewMasks[i] = 1 << i;
665 		newParameters.viewMasks = viewMasks;
666 
667 		return newParameters;
668 	}
669 }
670 
createVertexBuffer(void)671 void MultiViewRenderTestInstance::createVertexBuffer (void)
672 {
673 	DE_ASSERT(m_vertexCoord.size() == m_vertexColor.size());
674 	DE_ASSERT(m_vertexCoord.size() != 0);
675 
676 	const size_t	nonCoherentAtomSize	= static_cast<size_t>(m_context.getDeviceProperties().limits.nonCoherentAtomSize);
677 
678 	// Upload vertex coordinates
679 	{
680 		const size_t				dataSize		= static_cast<size_t>(m_vertexCoord.size() * sizeof(m_vertexCoord[0]));
681 		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
682 		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
683 
684 		m_vertexCoordBuffer	= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
685 		m_vertexCoordAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexCoordBuffer), MemoryRequirement::HostVisible);
686 
687 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexCoordBuffer, m_vertexCoordAlloc->getMemory(), m_vertexCoordAlloc->getOffset()));
688 		deMemcpy(m_vertexCoordAlloc->getHostPtr(), m_vertexCoord.data(), static_cast<size_t>(dataSize));
689 		flushAlloc(*m_device, *m_logicalDevice, *m_vertexCoordAlloc);
690 	}
691 
692 	// Upload vertex colors
693 	{
694 		const size_t				dataSize		= static_cast<size_t>(m_vertexColor.size() * sizeof(m_vertexColor[0]));
695 		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
696 		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
697 
698 		m_vertexColorBuffer	= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
699 		m_vertexColorAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexColorBuffer), MemoryRequirement::HostVisible);
700 
701 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexColorBuffer, m_vertexColorAlloc->getMemory(), m_vertexColorAlloc->getOffset()));
702 		deMemcpy(m_vertexColorAlloc->getHostPtr(), m_vertexColor.data(), static_cast<size_t>(dataSize));
703 		flushAlloc(*m_device, *m_logicalDevice, *m_vertexColorAlloc);
704 	}
705 
706 	// Upload vertex indices
707 	if (m_parameters.viewIndex == TEST_TYPE_DRAW_INDEXED || m_parameters.viewIndex == TEST_TYPE_DRAW_INDIRECT_INDEXED)
708 	{
709 		const size_t				dataSize		= static_cast<size_t>(m_vertexIndices.size() * sizeof(m_vertexIndices[0]));
710 		const VkDeviceSize			bufferDataSize	= static_cast<VkDeviceSize>(deAlignSize(dataSize, nonCoherentAtomSize));
711 		const VkBufferCreateInfo	bufferInfo		= makeBufferCreateInfo(bufferDataSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT);
712 
713 		DE_ASSERT(m_vertexIndices.size() == m_vertexCoord.size());
714 
715 		m_vertexIndicesBuffer		= createBuffer(*m_device, *m_logicalDevice, &bufferInfo);
716 		m_vertexIndicesAllocation	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *m_vertexIndicesBuffer), MemoryRequirement::HostVisible);
717 
718 		// Init host buffer data
719 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *m_vertexIndicesBuffer, m_vertexIndicesAllocation->getMemory(), m_vertexIndicesAllocation->getOffset()));
720 		deMemcpy(m_vertexIndicesAllocation->getHostPtr(), m_vertexIndices.data(), static_cast<size_t>(dataSize));
721 		flushAlloc(*m_device, *m_logicalDevice, *m_vertexIndicesAllocation);
722 	}
723 	else
724 		DE_ASSERT(m_vertexIndices.empty());
725 }
726 
createMultiViewDevices(void)727 void MultiViewRenderTestInstance::createMultiViewDevices (void)
728 {
729 	const InstanceDriver&					instanceDriver			( m_instanceWrapper->instance.getDriver() );
730 	const VkPhysicalDevice					physicalDevice			= chooseDevice(instanceDriver, m_instanceWrapper->instance, m_context.getTestContext().getCommandLine());
731 	const vector<VkQueueFamilyProperties>	queueFamilyProperties	= getPhysicalDeviceQueueFamilyProperties(instanceDriver, physicalDevice);
732 
733 	for (; m_queueFamilyIndex < queueFamilyProperties.size(); ++m_queueFamilyIndex)
734 	{
735 		if ((queueFamilyProperties[m_queueFamilyIndex].queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0)
736 			break;
737 	}
738 
739 	const float								queuePriorities			= 1.0f;
740 	const VkDeviceQueueCreateInfo			queueInfo				=
741 	{
742 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,					//VkStructureType			sType;
743 		DE_NULL,													//const void*				pNext;
744 		(VkDeviceQueueCreateFlags)0u,								//VkDeviceQueueCreateFlags	flags;
745 		m_queueFamilyIndex,											//deUint32					queueFamilyIndex;
746 		1u,															//deUint32					queueCount;
747 		&queuePriorities											//const float*				pQueuePriorities;
748 	};
749 
750 #ifndef CTS_USES_VULKANSC
751 	VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures	=
752 	{
753 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,	// VkStructureType			sType;
754 		DE_NULL,														// void*					pNext;
755 		DE_FALSE,														// VkBool32					dynamicRendering
756 	};
757 #endif // CTS_USES_VULKANSC
758 
759 	VkPhysicalDeviceMultiviewFeatures		multiviewFeatures		=
760 	{
761 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,		// VkStructureType			sType;
762 #ifndef CTS_USES_VULKANSC
763 		&dynamicRenderingFeatures,									// void*					pNext;
764 #else
765 		DE_NULL,													// void*					pNext;
766 #endif // CTS_USES_VULKANSC
767 		DE_FALSE,													// VkBool32					multiview;
768 		DE_FALSE,													// VkBool32					multiviewGeometryShader;
769 		DE_FALSE,													// VkBool32					multiviewTessellationShader;
770 	};
771 
772 	VkPhysicalDeviceFeatures2				enabledFeatures;
773 	enabledFeatures.sType					= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
774 	enabledFeatures.pNext					= &multiviewFeatures;
775 
776 	instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &enabledFeatures);
777 
778 	if (!multiviewFeatures.multiview)
779 		TCU_THROW(NotSupportedError, "MultiView not supported");
780 
781 	if (m_parameters.geometryShaderNeeded() && !multiviewFeatures.multiviewGeometryShader)
782 		TCU_THROW(NotSupportedError, "Geometry shader is not supported");
783 
784 	if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex && !multiviewFeatures.multiviewTessellationShader)
785 		TCU_THROW(NotSupportedError, "Tessellation shader is not supported");
786 
787 	VkPhysicalDeviceMultiviewProperties	multiviewProperties			=
788 	{
789 		VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,		//VkStructureType	sType;
790 		DE_NULL,													//void*				pNext;
791 		0u,															//deUint32			maxMultiviewViewCount;
792 		0u															//deUint32			maxMultiviewInstanceIndex;
793 	};
794 
795 	VkPhysicalDeviceProperties2			propertiesDeviceProperties2;
796 	propertiesDeviceProperties2.sType	= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
797 	propertiesDeviceProperties2.pNext	= &multiviewProperties;
798 
799 	instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2);
800 
801 #ifndef CTS_USES_VULKANSC
802 	if (multiviewProperties.maxMultiviewViewCount < 6u)
803 		TCU_FAIL("maxMultiviewViewCount below min value");
804 #endif // CTS_USES_VULKANSC
805 
806 	if (multiviewProperties.maxMultiviewInstanceIndex < 134217727u) //134217727u = 2^27 -1
807 		TCU_FAIL("maxMultiviewInstanceIndex below min value");
808 
809 	if (multiviewProperties.maxMultiviewViewCount <m_parameters.extent.depth)
810 		TCU_THROW(NotSupportedError, "Limit MaxMultiviewViewCount to small to run this test");
811 
812 	m_hasMultiDrawIndirect = enabledFeatures.features.multiDrawIndirect;
813 
814 	{
815 		vector<const char*>				deviceExtensions;
816 
817 		if (!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_multiview"))
818 			deviceExtensions.push_back("VK_KHR_multiview");
819 
820 		if ((m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2) &&
821 			!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_create_renderpass2"))
822 			deviceExtensions.push_back("VK_KHR_create_renderpass2");
823 		if ((m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING) &&
824 			!isCoreDeviceExtension(m_context.getUsedApiVersion(), "VK_KHR_dynamic_rendering"))
825 			deviceExtensions.push_back("VK_KHR_dynamic_rendering");
826 
827 		if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
828 			deviceExtensions.push_back("VK_EXT_depth_range_unrestricted");
829 
830 		void* pNext												= &enabledFeatures;
831 #ifdef CTS_USES_VULKANSC
832 		VkDeviceObjectReservationCreateInfo memReservationInfo	= m_context.getTestContext().getCommandLine().isSubProcess() ? m_context.getResourceInterface()->getStatMax() : resetDeviceObjectReservationCreateInfo();
833 		memReservationInfo.pNext								= pNext;
834 		pNext													= &memReservationInfo;
835 
836 		VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
837 		sc10Features.pNext										= pNext;
838 		pNext													= &sc10Features;
839 
840 		VkPipelineCacheCreateInfo			pcCI;
841 		std::vector<VkPipelinePoolSize>		poolSizes;
842 		if (m_context.getTestContext().getCommandLine().isSubProcess())
843 		{
844 			if (m_context.getResourceInterface()->getCacheDataSize() > 0)
845 			{
846 				pcCI =
847 				{
848 					VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,			// VkStructureType				sType;
849 					DE_NULL,												// const void*					pNext;
850 					VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
851 						VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
852 					m_context.getResourceInterface()->getCacheDataSize(),	// deUintptr					initialDataSize;
853 					m_context.getResourceInterface()->getCacheData()		// const void*					pInitialData;
854 				};
855 				memReservationInfo.pipelineCacheCreateInfoCount		= 1;
856 				memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
857 			}
858 
859 			poolSizes							= m_context.getResourceInterface()->getPipelinePoolSizes();
860 			if (!poolSizes.empty())
861 			{
862 				memReservationInfo.pipelinePoolSizeCount		= deUint32(poolSizes.size());
863 				memReservationInfo.pPipelinePoolSizes			= poolSizes.data();
864 			}
865 		}
866 #endif // CTS_USES_VULKANSC
867 
868 		const VkDeviceCreateInfo		deviceInfo			=
869 		{
870 			VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,							//VkStructureType					sType;
871 			pNext,															//const void*						pNext;
872 			0u,																//VkDeviceCreateFlags				flags;
873 			1u,																//deUint32							queueCreateInfoCount;
874 			&queueInfo,														//const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
875 			0u,																//deUint32							enabledLayerCount;
876 			DE_NULL,														//const char* const*				ppEnabledLayerNames;
877 			static_cast<deUint32>(deviceExtensions.size()),					//deUint32							enabledExtensionCount;
878 			deviceExtensions.empty() ? DE_NULL : &deviceExtensions[0],		//const char* const*				pEnabledExtensionNames;
879 			DE_NULL															//const VkPhysicalDeviceFeatures*	pEnabledFeatures;
880 		};
881 
882 		m_logicalDevice					= createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), m_instanceWrapper->instance, instanceDriver, physicalDevice, &deviceInfo);
883 #ifndef CTS_USES_VULKANSC
884 		m_device						= de::MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_instanceWrapper->instance, *m_logicalDevice));
885 #else
886 		m_device						= de::MovePtr<DeviceDriverSC, DeinitDeviceDeleter>(new DeviceDriverSC(m_context.getPlatformInterface(), m_instanceWrapper->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 InstanceInterface&		vki					= m_instanceWrapper->instance.getDriver();
2575 	const VkPhysicalDevice			physDevice			= chooseDevice(vki, m_instanceWrapper->instance, context.getTestContext().getCommandLine());
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 VkPhysicalDevice						physicalDevice	= chooseDevice(m_instanceWrapper->instance.getDriver(), m_instanceWrapper->instance, context.getTestContext().getCommandLine());
2929 	const std::vector<VkQueueFamilyProperties>	queueProperties	= vk::getPhysicalDeviceQueueFamilyProperties(m_instanceWrapper->instance.getDriver(), physicalDevice);
2930 
2931 	if(queueProperties[0].timestampValidBits == 0)
2932 		TCU_THROW(NotSupportedError, "Device does not support timestamp.");
2933 
2934 	m_timestampMask = 0xFFFFFFFFFFFFFFFFull >> (64 - queueProperties[0].timestampValidBits);
2935 }
2936 
iterate(void)2937 tcu::TestStatus MultiViewQueriesTestInstance::iterate (void)
2938 {
2939 	const deUint32								subpassCount			= static_cast<deUint32>(m_parameters.viewMasks.size());
2940 	Move<VkRenderPass>							renderPass;
2941 	Move<VkFramebuffer>							frameBuffer;
2942 	Unique<VkPipelineLayout>					pipelineLayout			(makePipelineLayout(*m_device, *m_logicalDevice));
2943 	vector<PipelineSp>							pipelines				(subpassCount);
2944 	deUint64									occlusionValue			= 0;
2945 	deUint64									occlusionExpectedValue	= 0;
2946 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
2947 
2948 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
2949 	{
2950 		renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType);
2951 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
2952 	}
2953 
2954 	{
2955 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
2956 
2957 		madeShaderModule(shaderModule, shaderStageParams);
2958 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
2959 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
2960 	}
2961 
2962 	createCommandBuffer();
2963 	createVertexData();
2964 	createVertexBuffer();
2965 
2966 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
2967 
2968 	DE_ASSERT(!m_occlusionValues.empty());
2969 	DE_ASSERT(m_occlusionValues.size() == m_occlusionExpectedValues.size());
2970 	DE_ASSERT(m_occlusionValues.size() == m_counterSeriesEnd.size());
2971 	for (size_t ndx = 0; ndx < m_counterSeriesEnd.size(); ++ndx)
2972 	{
2973 		occlusionValue			+= m_occlusionValues[ndx];
2974 		occlusionExpectedValue	+= m_occlusionExpectedValues[ndx];
2975 
2976 		if (m_counterSeriesEnd[ndx])
2977 		{
2978 			if (m_parameters.viewIndex == TEST_TYPE_QUERIES)
2979 			{
2980 				if (occlusionExpectedValue != occlusionValue)
2981 					return tcu::TestStatus::fail("occlusion, result:" + de::toString(occlusionValue) + ", expected:" + de::toString(occlusionExpectedValue));
2982 			}
2983 			else // verify non precise occlusion query
2984 			{
2985 				if (occlusionValue == 0)
2986 					return tcu::TestStatus::fail("occlusion, result: 0, expected non zero value");
2987 			}
2988 		}
2989 	}
2990 
2991 	DE_ASSERT(!m_timestampStartValues.empty());
2992 	DE_ASSERT(m_timestampStartValues.size() == m_timestampEndValues.size());
2993 	DE_ASSERT(m_timestampStartValues.size() == m_counterSeriesStart.size());
2994 	for (size_t ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
2995 	{
2996 		if (m_counterSeriesStart[ndx])
2997 		{
2998 			if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
2999 				continue;
3000 		}
3001 		else
3002 		{
3003 			if (m_timestampEndValues[ndx] > 0 && m_timestampEndValues[ndx] >= m_timestampStartValues[ndx])
3004 				continue;
3005 
3006 			if (m_timestampEndValues[ndx] == 0 && m_timestampStartValues[ndx] == 0)
3007 				continue;
3008 		}
3009 
3010 		return tcu::TestStatus::fail("timestamp");
3011 	}
3012 
3013 	return tcu::TestStatus::pass("Pass");
3014 }
3015 
createVertexData(void)3016 void MultiViewQueriesTestInstance::createVertexData (void)
3017 {
3018 	tcu::Vec4 color = tcu::Vec4(0.2f, 0.0f, 0.1f, 1.0f);
3019 
3020 	appendVertex(tcu::Vec4(-1.0f,-1.0f, 0.0f, 1.0f), color);
3021 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
3022 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
3023 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
3024 
3025 	color = tcu::Vec4(0.3f, 0.0f, 0.2f, 1.0f);
3026 	appendVertex(tcu::Vec4(-1.0f, 0.0f, 0.0f, 1.0f), color);
3027 	appendVertex(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), color);
3028 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
3029 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
3030 
3031 	color = tcu::Vec4(0.4f, 0.2f, 0.3f, 1.0f);
3032 	appendVertex(tcu::Vec4( 0.0f,-1.0f, 0.0f, 1.0f), color);
3033 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
3034 	appendVertex(tcu::Vec4( 1.0f,-1.0f, 0.0f, 1.0f), color);
3035 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
3036 
3037 	color = tcu::Vec4(0.5f, 0.0f, 0.4f, 1.0f);
3038 	appendVertex(tcu::Vec4( 0.0f, 0.0f, 0.0f, 1.0f), color);
3039 	appendVertex(tcu::Vec4( 0.0f, 1.0f, 0.0f, 1.0f), color);
3040 	appendVertex(tcu::Vec4( 1.0f, 0.0f, 0.0f, 1.0f), color);
3041 	appendVertex(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), color);
3042 
3043 	// Create occluded square objects as zoom out of main
3044 	const deUint32	mainObjectsVerticesCount		= static_cast<deUint32>(m_vertexCoord.size());
3045 	const deUint32	mainObjectsCount				= mainObjectsVerticesCount / m_verticesPerPrimitive;
3046 	const deUint32	occlusionObjectMultiplierX[]	= { 1, 2, 2, 1 };
3047 	const deUint32	occlusionObjectMultiplierY[]	= { 1, 1, 3, 3 };
3048 	const deUint32	occlusionObjectDivisor			= 4u;
3049 	const float		occlusionObjectDivisorFloat		= static_cast<float>(occlusionObjectDivisor);
3050 
3051 	DE_ASSERT(0 == m_parameters.extent.width  % (2 * occlusionObjectDivisor));
3052 	DE_ASSERT(0 == m_parameters.extent.height % (2 * occlusionObjectDivisor));
3053 	DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierX) == mainObjectsCount);
3054 	DE_ASSERT(DE_LENGTH_OF_ARRAY(occlusionObjectMultiplierY) == mainObjectsCount);
3055 
3056 	for (size_t objectNdx = 0; objectNdx < mainObjectsCount; ++objectNdx)
3057 	{
3058 		const size_t	objectStart			= objectNdx * m_verticesPerPrimitive;
3059 		const float		xRatio				= static_cast<float>(occlusionObjectMultiplierX[objectNdx]) / occlusionObjectDivisorFloat;
3060 		const float		yRatio				= static_cast<float>(occlusionObjectMultiplierY[objectNdx]) / occlusionObjectDivisorFloat;
3061 		const double	areaRatio			= static_cast<double>(xRatio) * static_cast<double>(yRatio);
3062 		const deUint64	occludedPixelsCount	= static_cast<deUint64>(areaRatio * (m_parameters.extent.width / 2) * (m_parameters.extent.height / 2));
3063 
3064 		m_occlusionObjectPixelsCount.push_back(occludedPixelsCount);
3065 
3066 		for (size_t vertexNdx = 0; vertexNdx < m_verticesPerPrimitive; ++vertexNdx)
3067 		{
3068 			const float		occludedObjectVertexXCoord	= m_vertexCoord[objectStart + vertexNdx][0] * xRatio;
3069 			const float		occludedObjectVertexYCoord	= m_vertexCoord[objectStart + vertexNdx][1] * yRatio;
3070 			const tcu::Vec4	occludedObjectVertexCoord	= tcu::Vec4(occludedObjectVertexXCoord, occludedObjectVertexYCoord, 1.0f, 1.0f);
3071 
3072 			appendVertex(occludedObjectVertexCoord, m_vertexColor[objectStart + vertexNdx]);
3073 		}
3074 	}
3075 
3076 	m_occlusionObjectsOffset = mainObjectsVerticesCount;
3077 }
3078 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)3079 void MultiViewQueriesTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
3080 {
3081 	const VkRect2D				renderArea						= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
3082 	const VkClearValue			renderPassClearValue			= makeClearValueColor(tcu::Vec4(0.0f));
3083 	const VkBuffer				vertexBuffers[]					= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
3084 	const VkDeviceSize			vertexBufferOffsets[]			= {                   0u,                   0u };
3085 	const deUint32				drawCountPerSubpass				= (subpassCount == 1) ? m_squareCount : 1u;
3086 	const deUint32				queryCountersNumber				= (subpassCount == 1) ? m_squareCount * getUsedViewsCount(0) : getQueryCountersNumber();
3087 
3088 	const VkQueryPoolCreateInfo	occlusionQueryPoolCreateInfo	=
3089 	{
3090 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	//  VkStructureType					sType;
3091 		DE_NULL,									//  const void*						pNext;
3092 		(VkQueryPoolCreateFlags)0,					//  VkQueryPoolCreateFlags			flags;
3093 		VK_QUERY_TYPE_OCCLUSION,					//  VkQueryType						queryType;
3094 		queryCountersNumber,						//  deUint32						queryCount;
3095 		0u,											//  VkQueryPipelineStatisticFlags	pipelineStatistics;
3096 	};
3097 	const VkQueryPoolCreateInfo	timestampQueryPoolCreateInfo	=
3098 	{
3099 		VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO,	//  VkStructureType					sType;
3100 		DE_NULL,									//  const void*						pNext;
3101 		(VkQueryPoolCreateFlags)0,					//  VkQueryPoolCreateFlags			flags;
3102 		VK_QUERY_TYPE_TIMESTAMP,					//  VkQueryType						queryType;
3103 		queryCountersNumber,						//  deUint32						queryCount;
3104 		0u,											//  VkQueryPipelineStatisticFlags	pipelineStatistics;
3105 	};
3106 	const Unique<VkQueryPool>	occlusionQueryPool				(createQueryPool(*m_device, *m_logicalDevice, &occlusionQueryPoolCreateInfo));
3107 	const Unique<VkQueryPool>	timestampStartQueryPool			(createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
3108 	const Unique<VkQueryPool>	timestampEndQueryPool			(createQueryPool(*m_device, *m_logicalDevice, &timestampQueryPoolCreateInfo));
3109 	deUint32					queryStartIndex					= 0;
3110 
3111 	beginCommandBuffer(*m_device, *m_cmdBuffer);
3112 
3113 	beforeRenderPass();
3114 
3115 	// Query pools must be reset before use
3116 	m_device->cmdResetQueryPool(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, queryCountersNumber);
3117 	m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampStartQueryPool, queryStartIndex, queryCountersNumber);
3118 	m_device->cmdResetQueryPool(*m_cmdBuffer, *timestampEndQueryPool, queryStartIndex, queryCountersNumber);
3119 
3120 	if (!m_useDynamicRendering)
3121 	{
3122 		const VkRenderPassBeginInfo	renderPassBeginInfo
3123 		{
3124 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	//  VkStructureType		sType;
3125 			DE_NULL,									//  const void*			pNext;
3126 			renderPass,									//  VkRenderPass		renderPass;
3127 			frameBuffer,								//  VkFramebuffer		framebuffer;
3128 			renderArea,									//  VkRect2D			renderArea;
3129 			1u,											//  uint32_t			clearValueCount;
3130 			&renderPassClearValue,						//  const VkClearValue*	pClearValues;
3131 		};
3132 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3133 	}
3134 
3135 	m_occlusionExpectedValues.reserve(queryCountersNumber);
3136 	m_counterSeriesStart.reserve(queryCountersNumber);
3137 	m_counterSeriesEnd.reserve(queryCountersNumber);
3138 
3139 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3140 	{
3141 		deUint32	queryCountersToUse	= getUsedViewsCount(subpassNdx);
3142 
3143 		m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
3144 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
3145 
3146 #ifndef CTS_USES_VULKANSC
3147 		if (m_useDynamicRendering)
3148 		{
3149 			addRenderingSubpassDependencyIfRequired(subpassNdx);
3150 
3151 			beginRendering(
3152 				*m_device,
3153 				*m_cmdBuffer,
3154 				m_colorAttachment->getImageView(),
3155 				renderArea,
3156 				renderPassClearValue,
3157 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3158 				(subpassNdx ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR),
3159 				0u,
3160 				m_parameters.extent.depth,
3161 				m_parameters.viewMasks[subpassNdx]);
3162 		}
3163 #endif // CTS_USES_VULKANSC
3164 
3165 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
3166 		{
3167 			const deUint32 primitiveNumber	= drawNdx + subpassNdx % m_squareCount;
3168 			const deUint32 firstVertex		= primitiveNumber * m_verticesPerPrimitive;
3169 
3170 			m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampStartQueryPool, queryStartIndex);
3171 			{
3172 				m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, firstVertex, 0u);
3173 
3174 				// Render occluded object
3175 				m_device->cmdBeginQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex, m_occlusionQueryFlags);
3176 				m_device->cmdDraw(*m_cmdBuffer, m_verticesPerPrimitive, 1u, m_occlusionObjectsOffset + firstVertex, 0u);
3177 				m_device->cmdEndQuery(*m_cmdBuffer, *occlusionQueryPool, queryStartIndex);
3178 
3179 				for (deUint32 viewMaskNdx = 0; viewMaskNdx < queryCountersToUse; ++viewMaskNdx)
3180 				{
3181 					m_occlusionExpectedValues.push_back(m_occlusionObjectPixelsCount[primitiveNumber]);
3182 					m_counterSeriesStart.push_back(viewMaskNdx == 0);
3183 					m_counterSeriesEnd.push_back(viewMaskNdx + 1 == queryCountersToUse);
3184 				}
3185 			}
3186 			m_device->cmdWriteTimestamp(*m_cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, *timestampEndQueryPool, queryStartIndex);
3187 
3188 			queryStartIndex += queryCountersToUse;
3189 		}
3190 
3191 #ifndef CTS_USES_VULKANSC
3192 		if (m_useDynamicRendering)
3193 			endRendering(*m_device, *m_cmdBuffer);
3194 		else
3195 #endif // CTS_USES_VULKANSC
3196 			if (subpassNdx < subpassCount - 1u)
3197 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3198 	}
3199 
3200 	DE_ASSERT(queryStartIndex == queryCountersNumber);
3201 
3202 	if (!m_useDynamicRendering)
3203 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
3204 
3205 	afterRenderPass();
3206 
3207 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3208 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3209 
3210 	m_occlusionValues.resize(queryCountersNumber, 0ull);
3211 	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);
3212 
3213 	m_timestampStartValues.resize(queryCountersNumber, 0ull);
3214 	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);
3215 	for (deUint32 ndx = 0; ndx < m_timestampStartValues.size(); ++ndx)
3216 		m_timestampStartValues[ndx] &= m_timestampMask;
3217 
3218 	m_timestampEndValues.resize(queryCountersNumber, 0ull);
3219 	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);
3220 	for (deUint32 ndx = 0; ndx < m_timestampEndValues.size(); ++ndx)
3221 		m_timestampEndValues[ndx] &= m_timestampMask;
3222 }
3223 
getUsedViewsCount(const deUint32 viewMaskIndex)3224 deUint32 MultiViewQueriesTestInstance::getUsedViewsCount (const deUint32 viewMaskIndex)
3225 {
3226 	deUint32 result = 0;
3227 
3228 	for (deUint32 viewMask = m_parameters.viewMasks[viewMaskIndex]; viewMask != 0; viewMask >>= 1)
3229 		if ((viewMask & 1) != 0)
3230 			result++;
3231 
3232 	return result;
3233 }
3234 
getQueryCountersNumber()3235 deUint32 MultiViewQueriesTestInstance::getQueryCountersNumber ()
3236 {
3237 	deUint32 result = 0;
3238 
3239 	for (deUint32 i = 0; i < m_parameters.viewMasks.size(); ++i)
3240 		result += getUsedViewsCount(i);
3241 
3242 	return result;
3243 }
3244 
3245 class MultiViewReadbackTestInstance : public MultiViewRenderTestInstance
3246 {
3247 public:
3248 						MultiViewReadbackTestInstance	(Context& context, const TestParameters& parameters);
3249 protected:
3250 	tcu::TestStatus		iterate							(void);
3251 	void				drawClears						(const deUint32				subpassCount,
3252 														 VkRenderPass				renderPass,
3253 														 VkFramebuffer				frameBuffer,
3254 														 vector<PipelineSp>&		pipelines,
3255 														 const bool					clearPass);
3256 	void				clear							(const VkCommandBuffer		commandBuffer,
3257 														 const VkRect2D&			clearRect2D,
3258 														 const tcu::Vec4&			clearColor);
3259 private:
3260 	vector<VkRect2D>	m_quarters;
3261 };
3262 
MultiViewReadbackTestInstance(Context & context,const TestParameters & parameters)3263 MultiViewReadbackTestInstance::MultiViewReadbackTestInstance (Context& context, const TestParameters& parameters)
3264 	: MultiViewRenderTestInstance	(context, parameters)
3265 {
3266 	const deUint32 halfWidth	= m_parameters.extent.width / 2;
3267 	const deUint32 halfHeight	= m_parameters.extent.height / 2;
3268 
3269 	for (deInt32 x = 0; x < 2; ++x)
3270 	for (deInt32 y = 0; y < 2; ++y)
3271 	{
3272 		const deInt32	offsetX	= static_cast<deInt32>(halfWidth) * x;
3273 		const deInt32	offsetY	= static_cast<deInt32>(halfHeight) * y;
3274 		const VkRect2D	area	= { { offsetX, offsetY}, {halfWidth, halfHeight} };
3275 
3276 		m_quarters.push_back(area);
3277 	}
3278 }
3279 
iterate(void)3280 tcu::TestStatus MultiViewReadbackTestInstance::iterate (void)
3281 {
3282 	const deUint32	subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
3283 
3284 	createCommandBuffer();
3285 
3286 	for (deUint32 pass = 0; pass < 2; ++pass)
3287 	{
3288 		const bool									fullClearPass	= (pass == 0);
3289 		const VkAttachmentLoadOp					loadOp			= (!fullClearPass) ? VK_ATTACHMENT_LOAD_OP_LOAD :
3290 																	  (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_CLEAR :
3291 																	  (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE :
3292 																	  VK_ATTACHMENT_LOAD_OP_DONT_CARE;
3293 		Move<VkRenderPass>							renderPass;
3294 		Move<VkFramebuffer>							frameBuffer;
3295 		Unique<VkPipelineLayout>					pipelineLayout	(makePipelineLayout(*m_device, *m_logicalDevice));
3296 		vector<PipelineSp>							pipelines		(subpassCount);
3297 		map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
3298 
3299 		if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3300 		{
3301 			renderPass	= makeRenderPass (*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_parameters.renderingType, VK_SAMPLE_COUNT_1_BIT, loadOp);
3302 			frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, m_colorAttachment->getImageView(), m_parameters.extent.width, m_parameters.extent.height);
3303 		}
3304 
3305 		{
3306 			vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
3307 			madeShaderModule(shaderModule, shaderStageParams);
3308 			for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
3309 				pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(), subpassNdx))));
3310 		}
3311 
3312 		drawClears(subpassCount, *renderPass, *frameBuffer, pipelines, fullClearPass);
3313 	}
3314 
3315 	{
3316 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
3317 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
3318 
3319 		readImage(m_colorAttachment->getImage(), dst);
3320 
3321 		if (!checkImage(dst))
3322 			return tcu::TestStatus::fail("Fail");
3323 	}
3324 
3325 	return tcu::TestStatus::pass("Pass");
3326 }
3327 
drawClears(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines,const bool clearPass)3328 void MultiViewReadbackTestInstance::drawClears (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines, const bool clearPass)
3329 {
3330 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
3331 	const VkClearValue				renderPassClearValue	= makeClearValueColor(m_colorTable[0]);
3332 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
3333 	const bool						withClearColor			= (clearPass && m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR);
3334 
3335 	beginCommandBuffer(*m_device, *m_cmdBuffer);
3336 
3337 	if (clearPass)
3338 		beforeRenderPass();
3339 
3340 	if (!m_useDynamicRendering)
3341 	{
3342 		const VkRenderPassBeginInfo renderPassBeginInfo
3343 		{
3344 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,			//  VkStructureType		sType;
3345 			DE_NULL,											//  const void*			pNext;
3346 			renderPass,											//  VkRenderPass		renderPass;
3347 			frameBuffer,										//  VkFramebuffer		framebuffer;
3348 			renderArea,											//  VkRect2D			renderArea;
3349 			withClearColor ? 1u : 0u,							//  uint32_t			clearValueCount;
3350 			withClearColor ? &renderPassClearValue : DE_NULL,	//  const VkClearValue*	pClearValues;
3351 		};
3352 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3353 	}
3354 
3355 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3356 	{
3357 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
3358 
3359 #ifndef CTS_USES_VULKANSC
3360 		if (m_useDynamicRendering)
3361 		{
3362 			addRenderingSubpassDependencyIfRequired(subpassNdx);
3363 
3364 			VkAttachmentLoadOp loadOperation = VK_ATTACHMENT_LOAD_OP_LOAD;
3365 			if (clearPass)
3366 			{
3367 				if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR)
3368 					loadOperation = VK_ATTACHMENT_LOAD_OP_CLEAR;
3369 				else if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR)
3370 					loadOperation = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
3371 				else
3372 					loadOperation = VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
3373 			}
3374 
3375 			beginRendering(
3376 				*m_device,
3377 				*m_cmdBuffer,
3378 				m_colorAttachment->getImageView(),
3379 				renderArea,
3380 				renderPassClearValue,
3381 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
3382 				loadOperation,
3383 				0u,
3384 				m_parameters.extent.depth,
3385 				m_parameters.viewMasks[subpassNdx]);
3386 		}
3387 #endif // CTS_USES_VULKANSC
3388 
3389 		if (clearPass)
3390 		{
3391 			if (m_parameters.viewIndex == TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR)
3392 				clear(*m_cmdBuffer, renderArea, m_colorTable[subpassNdx % 4]);
3393 		}
3394 		else
3395 		{
3396 			for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
3397 			{
3398 				const deUint32 primitiveNumber	= drawNdx + subpassNdx % m_squareCount;
3399 
3400 				clear(*m_cmdBuffer, m_quarters[primitiveNumber], m_colorTable[4 + primitiveNumber]);
3401 			}
3402 		}
3403 
3404 #ifndef CTS_USES_VULKANSC
3405 		if (m_useDynamicRendering)
3406 			endRendering(*m_device, *m_cmdBuffer);
3407 		else
3408 #endif // CTS_USES_VULKANSC
3409 			if (subpassNdx < subpassCount - 1u)
3410 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3411 	}
3412 
3413 	if (!m_useDynamicRendering)
3414 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
3415 
3416 	if (!clearPass)
3417 		afterRenderPass();
3418 
3419 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3420 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3421 }
3422 
clear(const VkCommandBuffer commandBuffer,const VkRect2D & clearRect2D,const tcu::Vec4 & clearColor)3423 void MultiViewReadbackTestInstance::clear (const VkCommandBuffer commandBuffer, const VkRect2D& clearRect2D, const tcu::Vec4& clearColor)
3424 {
3425 	const VkClearRect		clearRect		=
3426 	{
3427 		clearRect2D,						//  VkRect2D	rect
3428 		0u,									//  deUint32	baseArrayLayer
3429 		1u,									//  deUint32	layerCount
3430 	};
3431 	const VkClearAttachment	clearAttachment	=
3432 	{
3433 		VK_IMAGE_ASPECT_COLOR_BIT,			//  VkImageAspectFlags	aspectMask
3434 		0u,									//  deUint32			colorAttachment
3435 		makeClearValueColor(clearColor)		//  VkClearValue		clearValue
3436 	};
3437 
3438 	m_device->cmdClearAttachments(commandBuffer, 1u, &clearAttachment, 1u, &clearRect);
3439 }
3440 
3441 class MultiViewDepthStencilTestInstance : public MultiViewRenderTestInstance
3442 {
3443 public:
3444 									MultiViewDepthStencilTestInstance	(Context& context, const TestParameters& parameters);
3445 protected:
3446 	tcu::TestStatus					iterate								(void) override;
3447 	void							createVertexData					(void) override;
3448 
3449 	void							draw								(const deUint32					subpassCount,
3450 																		 VkRenderPass					renderPass,
3451 																		 VkFramebuffer					frameBuffer,
3452 																		 vector<PipelineSp>&			pipelines) override;
3453 	void							beforeRenderPass							(void) override;
3454 	void							afterRenderPass							(void) override;
3455 	vector<VkImageView>				makeAttachmentsVector				(void);
3456 	MovePtr<tcu::Texture2DArray>	imageData							(void) const override;
3457 	void							readImage							(VkImage						image,
3458 																		 const tcu::PixelBufferAccess&	dst);
3459 	vector<tcu::Vec2>				getDepthRanges						(void) const;
3460 
3461 private:
3462 	VkFormat						m_dsFormat;
3463 	de::SharedPtr<ImageAttachment>	m_dsAttachment;
3464 	bool							m_depthTest;
3465 	bool							m_stencilTest;
3466 };
3467 
MultiViewDepthStencilTestInstance(Context & context,const TestParameters & parameters)3468 MultiViewDepthStencilTestInstance::MultiViewDepthStencilTestInstance (Context& context, const TestParameters& parameters)
3469 	: MultiViewRenderTestInstance	(context, parameters)
3470 	, m_dsFormat					(VK_FORMAT_UNDEFINED)
3471 	, m_depthTest					(m_parameters.viewIndex == TEST_TYPE_DEPTH ||
3472 									 m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
3473 	, m_stencilTest					(m_parameters.viewIndex == TEST_TYPE_STENCIL)
3474 {
3475 	const VkFormat formats[] = { VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT };
3476 
3477 	for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(formats); ++ndx)
3478 	{
3479 		const VkFormat				format				= formats[ndx];
3480 		const VkPhysicalDevice		physicalDevice		= chooseDevice(m_instanceWrapper->instance.getDriver(), m_instanceWrapper->instance, context.getTestContext().getCommandLine());
3481 		const VkFormatProperties	formatProperties	= getPhysicalDeviceFormatProperties(m_instanceWrapper->instance.getDriver(), physicalDevice, format);
3482 
3483 		if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0)
3484 		{
3485 			m_dsFormat = format;
3486 
3487 			break;
3488 		}
3489 	}
3490 
3491 	if (m_dsFormat == VK_FORMAT_UNDEFINED)
3492 		TCU_FAIL("Supported depth/stencil format not found, that violates specification");
3493 
3494 	// Depth/stencil attachment
3495 	m_dsAttachment = de::SharedPtr<ImageAttachment>(new ImageAttachment(*m_logicalDevice, *m_device, *m_allocator, m_parameters.extent, m_dsFormat));
3496 }
3497 
makeAttachmentsVector(void)3498 vector<VkImageView>	MultiViewDepthStencilTestInstance::makeAttachmentsVector (void)
3499 {
3500 	vector<VkImageView> attachments;
3501 
3502 	attachments.push_back(m_colorAttachment->getImageView());
3503 	attachments.push_back(m_dsAttachment->getImageView());
3504 
3505 	return attachments;
3506 }
3507 
imageData(void) const3508 MovePtr<tcu::Texture2DArray> MultiViewDepthStencilTestInstance::imageData(void) const
3509 {
3510 	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));
3511 	const deUint32					subpassCount		= static_cast<deUint32>(m_parameters.viewMasks.size());
3512 	const vector<tcu::Vec2>			depthRanges			= getDepthRanges();
3513 
3514 	referenceFrame->allocLevel(0);
3515 	deMemset(referenceFrame->getLevel(0).getDataPtr(), 0, m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth* mapVkFormat(m_parameters.colorFormat).getPixelSize());
3516 
3517 	for (deUint32 layerNdx = 0; layerNdx < m_parameters.extent.depth; ++layerNdx)
3518 		fillLayer(referenceFrame->getLevel(0), getQuarterRefColor(0u, 0u, 0u, false), layerNdx);
3519 
3520 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3521 	{
3522 		int					layerNdx			= 0;
3523 		deUint32			mask				= m_parameters.viewMasks[subpassNdx];
3524 		const tcu::Vec2&	depthRange			= depthRanges[subpassNdx];
3525 		const float			depthMin			= depthRange[0];
3526 		const float			depthMax			= depthRange[1];
3527 
3528 		// iterate over image layers
3529 		while (mask > 0u)
3530 		{
3531 			if (mask & 1u)
3532 			{
3533 				const deUint32	subpassQuarterNdx	= subpassNdx % m_squareCount;
3534 				const int		colorNdx			= subpassQuarterNdx * 4;
3535 				tcu::Vec4		color				= getQuarterRefColor(subpassQuarterNdx, colorNdx, layerNdx, true, subpassNdx);
3536 
3537 				if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
3538 				{
3539 					// quads with depth out of range should be cliiped
3540 					// to simplify code we are drawing them with background color
3541 					if ((color.x() < 0.0f) || (color.x() > 1.0f))
3542 						color.x() = 1.0f;
3543 					else
3544 					{
3545 						const float depthClamped = de::clamp(color.x(), 0.0f, 1.0f);
3546 						color.x() = depthClamped * depthMax + (1.0f - depthClamped) * depthMin;
3547 					}
3548 				}
3549 
3550 				fillQuarter(referenceFrame->getLevel(0), color, layerNdx, subpassQuarterNdx, subpassNdx);
3551 			}
3552 
3553 			mask = mask >> 1;
3554 			++layerNdx;
3555 		}
3556 	}
3557 	return referenceFrame;
3558 }
3559 
readImage(VkImage image,const tcu::PixelBufferAccess & dst)3560 void MultiViewDepthStencilTestInstance::readImage (VkImage image, const tcu::PixelBufferAccess& dst)
3561 {
3562 	const VkFormat				bufferFormat	= m_depthTest ? getDepthBufferFormat(m_dsFormat) :
3563 												  m_stencilTest ? getStencilBufferFormat(m_dsFormat) :
3564 												  VK_FORMAT_UNDEFINED;
3565 	const deUint32				imagePixelSize	= static_cast<deUint32>(tcu::getPixelSize(mapVkFormat(bufferFormat)));
3566 	const VkDeviceSize			pixelDataSize	= dst.getWidth() * dst.getHeight() * dst.getDepth() * imagePixelSize;
3567 	const tcu::TextureFormat	tcuBufferFormat	= mapVkFormat(bufferFormat);
3568 	Move<VkBuffer>				buffer;
3569 	MovePtr<Allocation>			bufferAlloc;
3570 
3571 	// Create destination buffer
3572 	{
3573 		const VkBufferCreateInfo bufferParams	=
3574 		{
3575 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
3576 			DE_NULL,								// const void*			pNext;
3577 			0u,										// VkBufferCreateFlags	flags;
3578 			pixelDataSize,							// VkDeviceSize			size;
3579 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
3580 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
3581 			1u,										// deUint32				queueFamilyIndexCount;
3582 			&m_queueFamilyIndex,					// const deUint32*		pQueueFamilyIndices;
3583 		};
3584 
3585 		buffer		= createBuffer(*m_device, *m_logicalDevice, &bufferParams);
3586 		bufferAlloc	= m_allocator->allocate(getBufferMemoryRequirements(*m_device, *m_logicalDevice, *buffer), MemoryRequirement::HostVisible);
3587 		VK_CHECK(m_device->bindBufferMemory(*m_logicalDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
3588 
3589 		deMemset(bufferAlloc->getHostPtr(), 0xCC, static_cast<size_t>(pixelDataSize));
3590 		flushAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
3591 	}
3592 
3593 	const VkBufferMemoryBarrier	bufferBarrier	=
3594 	{
3595 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
3596 		DE_NULL,									// const void*		pNext;
3597 		VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags	srcAccessMask;
3598 		VK_ACCESS_HOST_READ_BIT,					// VkAccessFlags	dstAccessMask;
3599 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
3600 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			dstQueueFamilyIndex;
3601 		*buffer,									// VkBuffer			buffer;
3602 		0u,											// VkDeviceSize		offset;
3603 		pixelDataSize								// VkDeviceSize		size;
3604 	};
3605 
3606 	// Copy image to buffer
3607 	const VkImageAspectFlags	aspect			= m_depthTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_DEPTH_BIT) :
3608 												  m_stencilTest ? static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_STENCIL_BIT) :
3609 												  static_cast<VkImageAspectFlags>(0u);
3610 	const VkBufferImageCopy		copyRegion		=
3611 	{
3612 		0u,											// VkDeviceSize				bufferOffset;
3613 		(deUint32)dst.getWidth(),					// deUint32					bufferRowLength;
3614 		(deUint32)dst.getHeight(),					// deUint32					bufferImageHeight;
3615 		{
3616 			aspect,									// VkImageAspectFlags		aspect;
3617 			0u,										// deUint32					mipLevel;
3618 			0u,										// deUint32					baseArrayLayer;
3619 			m_parameters.extent.depth,				// deUint32					layerCount;
3620 		},											// VkImageSubresourceLayers	imageSubresource;
3621 		{ 0, 0, 0 },								// VkOffset3D				imageOffset;
3622 		{											// VkExtent3D				imageExtent;
3623 			m_parameters.extent.width,
3624 			m_parameters.extent.height,
3625 			1u
3626 		}
3627 	};
3628 
3629 	beginCommandBuffer (*m_device, *m_cmdBuffer);
3630 	{
3631 		m_device->cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, &copyRegion);
3632 		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);
3633 	}
3634 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3635 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3636 
3637 	// Read buffer data
3638 	invalidateAlloc(*m_device, *m_logicalDevice, *bufferAlloc);
3639 
3640 	if (m_depthTest)
3641 	{
3642 		// Translate depth into color space
3643 		tcu::ConstPixelBufferAccess	pixelBuffer	(tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
3644 
3645 		for (int z = 0; z < pixelBuffer.getDepth(); z++)
3646 		for (int y = 0; y < pixelBuffer.getHeight(); y++)
3647 		for (int x = 0; x < pixelBuffer.getWidth(); x++)
3648 		{
3649 			const float		depth	= pixelBuffer.getPixDepth(x, y, z);
3650 			const tcu::Vec4	color	= tcu::Vec4(depth, 0.0f, 0.0f, 1.0f);
3651 
3652 			dst.setPixel(color, x, y, z);
3653 		}
3654 	}
3655 
3656 	if (m_stencilTest)
3657 	{
3658 		// Translate stencil into color space
3659 		tcu::ConstPixelBufferAccess	pixelBuffer	(tcuBufferFormat, dst.getSize(), bufferAlloc->getHostPtr());
3660 		const tcu::Vec4				baseColor		= getQuarterRefColor(0u, 0u, 0u, false);
3661 		const tcu::Vec4				colorStep		= getQuarterRefColor(0u, 0u, 0u, true);
3662 		const tcu::Vec4				colorMap[4]		=
3663 		{
3664 			baseColor,
3665 			tcu::Vec4(1.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3666 			tcu::Vec4(2.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3667 			tcu::Vec4(3.0f * colorStep[0], 0.0f, 0.0f, 1.0),
3668 		};
3669 		const tcu::Vec4				invalidColor	= tcu::Vec4(0.0f);
3670 
3671 		for (int z = 0; z < pixelBuffer.getDepth(); z++)
3672 		for (int y = 0; y < pixelBuffer.getHeight(); y++)
3673 		for (int x = 0; x < pixelBuffer.getWidth(); x++)
3674 		{
3675 			const int			stencilInt	= pixelBuffer.getPixStencil(x, y, z);
3676 			const tcu::Vec4&	color		= de::inRange(stencilInt, 0, DE_LENGTH_OF_ARRAY(colorMap)) ? colorMap[stencilInt] : invalidColor;
3677 
3678 			dst.setPixel(color, x, y, z);
3679 		}
3680 	}
3681 }
3682 
iterate(void)3683 tcu::TestStatus MultiViewDepthStencilTestInstance::iterate (void)
3684 {
3685 	const deUint32								subpassCount	= static_cast<deUint32>(m_parameters.viewMasks.size());
3686 	Move<VkRenderPass>						renderPass;
3687 	vector<VkImageView>							attachments		(makeAttachmentsVector());
3688 	Move<VkFramebuffer>						frameBuffer;
3689 	Unique<VkPipelineLayout>					pipelineLayout	(makePipelineLayout(*m_device, *m_logicalDevice));
3690 	vector<PipelineSp>							pipelines		(subpassCount);
3691 	const vector<tcu::Vec2>						depthRanges		(getDepthRanges());
3692 	map<VkShaderStageFlagBits, ShaderModuleSP>	shaderModule;
3693 
3694 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3695 	{
3696 		renderPass	= makeRenderPassWithDepth(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderingType);
3697 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u);
3698 	}
3699 
3700 	if (m_parameters.renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
3701 	{
3702 		renderPass	= makeRenderPassWithDepth(*m_device, *m_logicalDevice, m_parameters.colorFormat, m_parameters.viewMasks, m_dsFormat, m_parameters.renderingType);
3703 		frameBuffer	= makeFramebuffer(*m_device, *m_logicalDevice, *renderPass, static_cast<deUint32>(attachments.size()), attachments.data(), m_parameters.extent.width, m_parameters.extent.height, 1u);
3704 	}
3705 
3706 	{
3707 		vector<VkPipelineShaderStageCreateInfo>	shaderStageParams;
3708 		madeShaderModule(shaderModule, shaderStageParams);
3709 		for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; ++subpassNdx)
3710 		{
3711 			const tcu::Vec2& depthRange = depthRanges[subpassNdx];
3712 			const float depthMin		= depthRange[0];
3713 			const float depthMax		= depthRange[1];
3714 
3715 			pipelines[subpassNdx] = (PipelineSp(new Unique<VkPipeline>(makeGraphicsPipeline(
3716 				*renderPass, *pipelineLayout, static_cast<deUint32>(shaderStageParams.size()), shaderStageParams.data(),
3717 				subpassNdx, VK_VERTEX_INPUT_RATE_VERTEX, m_depthTest, m_stencilTest, depthMin, depthMax, m_dsFormat))));
3718 		}
3719 	}
3720 
3721 	createCommandBuffer();
3722 	createVertexData();
3723 	createVertexBuffer();
3724 
3725 	draw(subpassCount, *renderPass, *frameBuffer, pipelines);
3726 
3727 	{
3728 		vector<deUint8>			pixelAccessData	(m_parameters.extent.width * m_parameters.extent.height * m_parameters.extent.depth * mapVkFormat(m_parameters.colorFormat).getPixelSize());
3729 		tcu::PixelBufferAccess	dst				(mapVkFormat(m_parameters.colorFormat), m_parameters.extent.width, m_parameters.extent.height, m_parameters.extent.depth, pixelAccessData.data());
3730 
3731 		readImage(m_dsAttachment->getImage(), dst);
3732 
3733 		if (!checkImage(dst))
3734 			return tcu::TestStatus::fail("Fail");
3735 	}
3736 
3737 	return tcu::TestStatus::pass("Pass");
3738 }
3739 
createVertexData(void)3740 void MultiViewDepthStencilTestInstance::createVertexData (void)
3741 {
3742 /*
3743 	partA - draw vertical quads, marked with 1
3744 
3745 	ViewMasks
3746 	0011
3747 	0110
3748 	1100
3749 	1001
3750 
3751 	Layer3  Layer2  Layer1  Layer0
3752 	  ^       ^       ^       ^
3753 	00|10   00|10   01|00   01|00
3754 	00|10   00|10   01|00   01|00
3755 	--+-->  --+-->  --+-->  --+-->
3756 	00|10   01|00   01|00   00|10
3757 	00|10   01|00   01|00   00|10
3758 
3759 
3760 	partB - draw horizontal quads, marked with 2
3761 
3762 	ViewMasks
3763 	0110
3764 	1100
3765 	1001
3766 	0011
3767 
3768 	Layer3  Layer2  Layer1  Layer0
3769 	  ^       ^       ^       ^
3770 	00|00   00|00   00|00   00|00
3771 	00|22   22|00   22|00   00|22
3772 	--+-->  --+-->  --+-->  --+-->
3773 	22|00   22|00   00|22   00|22
3774 	00|00   00|00   00|00   00|00
3775 
3776 
3777 	Final - after drawing quads from partA and partB (3 marks where quads overlap)
3778 
3779 	Layer3  Layer2  Layer1  Layer0
3780 	  ^       ^       ^       ^
3781 	00|10   00|10   01|00   01|00
3782 	00|32   22|10   23|00   01|22
3783 	--+-->  --+-->  --+-->  --+-->
3784 	22|10   23|00   01|22   00|32
3785 	00|10   01|00   01|00   00|10
3786 */
3787 	tcu::Vec4	color	(0.0f, 0.0f, 0.0f, 1.0f); // is not essential in this test
3788 	float		depth	(getQuarterRefColor(0u, 0u, 0u, true, 0u)[0]);
3789 
3790 	// part A - four horizontal quads
3791 	appendVertex(tcu::Vec4(-1.0f,-0.5f, depth, 1.0f), color);		// when testing TEST_TYPE_DEPTH_DIFFERENT_RANGES
3792 	appendVertex(tcu::Vec4(-1.0f, 0.0f, depth, 1.0f), color);		// this quad will have depth 1.2
3793 	appendVertex(tcu::Vec4( 0.0f,-0.5f, depth, 1.0f), color);		// and will be clipped in all views
3794 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3795 
3796 	depth = getQuarterRefColor(0u, 0u, 0u, true, 1u)[0];
3797 	appendVertex(tcu::Vec4(-1.0f, 0.0f, depth, 1.0f), color);
3798 	appendVertex(tcu::Vec4(-1.0f, 0.5f, depth, 1.0f), color);
3799 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3800 	appendVertex(tcu::Vec4( 0.0f, 0.5f, depth, 1.0f), color);
3801 
3802 	depth = getQuarterRefColor(0u, 0u, 0u, true, 2u)[0];
3803 	appendVertex(tcu::Vec4( 0.0f,-0.5f, depth, 1.0f), color);
3804 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3805 	appendVertex(tcu::Vec4( 1.0f,-0.5f, depth, 1.0f), color);
3806 	appendVertex(tcu::Vec4( 1.0f, 0.0f, depth, 1.0f), color);
3807 
3808 	depth = getQuarterRefColor(0u, 0u, 0u, true, 3u)[0];
3809 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3810 	appendVertex(tcu::Vec4( 0.0f, 0.5f, depth, 1.0f), color);
3811 	appendVertex(tcu::Vec4( 1.0f, 0.0f, depth, 1.0f), color);
3812 	appendVertex(tcu::Vec4( 1.0f, 0.5f, depth, 1.0f), color);
3813 
3814 	// part B - four vertical quads
3815 	depth = getQuarterRefColor(0u, 0u, 0u, true, 4u)[0];
3816 	appendVertex(tcu::Vec4(-0.5f,-1.0f, depth, 1.0f), color);
3817 	appendVertex(tcu::Vec4(-0.5f, 0.0f, depth, 1.0f), color);
3818 	appendVertex(tcu::Vec4( 0.0f,-1.0f, depth, 1.0f), color);
3819 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3820 
3821 	depth = getQuarterRefColor(0u, 0u, 0u, true, 5u)[0];
3822 	appendVertex(tcu::Vec4(-0.5f, 0.0f, depth, 1.0f), color);
3823 	appendVertex(tcu::Vec4(-0.5f, 1.0f, depth, 1.0f), color);
3824 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3825 	appendVertex(tcu::Vec4( 0.0f, 1.0f, depth, 1.0f), color);
3826 
3827 	depth = getQuarterRefColor(0u, 0u, 0u, true, 6u)[0];
3828 	appendVertex(tcu::Vec4( 0.0f,-1.0f, depth, 1.0f), color);
3829 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);
3830 	appendVertex(tcu::Vec4( 0.5f,-1.0f, depth, 1.0f), color);
3831 	appendVertex(tcu::Vec4( 0.5f, 0.0f, depth, 1.0f), color);
3832 
3833 	depth = getQuarterRefColor(0u, 0u, 0u, true, 7u)[0];			// when testing TEST_TYPE_DEPTH_DIFFERENT_RANGES
3834 	appendVertex(tcu::Vec4( 0.0f, 0.0f, depth, 1.0f), color);		// this quad will have depth -0.05
3835 	appendVertex(tcu::Vec4( 0.0f, 1.0f, depth, 1.0f), color);		// and will be clipped in all views
3836 	appendVertex(tcu::Vec4( 0.5f, 0.0f, depth, 1.0f), color);
3837 	appendVertex(tcu::Vec4( 0.5f, 1.0f, depth, 1.0f), color);
3838 }
3839 
getDepthRanges(void) const3840 vector<tcu::Vec2> MultiViewDepthStencilTestInstance::getDepthRanges(void) const
3841 {
3842 	if (TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex)
3843 	{
3844 		DE_ASSERT(m_parameters.viewMasks.size() == 12);
3845 		return
3846 		{
3847 			// ranges used when four quads from part A are drawn
3848 			{0.0f, 1.0f},
3849 			{0.5f, 1.0f},
3850 			{0.0f, 0.5f},
3851 			{0.0f, 1.0f},
3852 
3853 			// ranges used when four quads from part B are drawn
3854 			{0.0f, 0.5f},
3855 			{0.0f, 1.0f},
3856 			{0.5f, 1.0f},
3857 			{0.0f, 0.5f},
3858 
3859 			// ranges used when part B is drawn once again
3860 			{0.5f, 1.0f},
3861 			{0.0f, 0.5f},
3862 			{0.0f, 0.5f},
3863 			{0.0f, 1.0f},
3864 		};
3865 	}
3866 
3867 	// by defaul use <0; 1> range for all subpasses
3868 	return { m_parameters.viewMasks.size(), tcu::Vec2(0.0f, 1.0f) };
3869 }
3870 
draw(const deUint32 subpassCount,VkRenderPass renderPass,VkFramebuffer frameBuffer,vector<PipelineSp> & pipelines)3871 void MultiViewDepthStencilTestInstance::draw (const deUint32 subpassCount, VkRenderPass renderPass, VkFramebuffer frameBuffer, vector<PipelineSp>& pipelines)
3872 {
3873 	const VkRect2D					renderArea				= { { 0, 0 }, { m_parameters.extent.width, m_parameters.extent.height } };
3874 	const VkClearValue				renderPassClearValue	= makeClearValueColor(tcu::Vec4(0.0f));
3875 	const VkBuffer					vertexBuffers[]			= { *m_vertexCoordBuffer, *m_vertexColorBuffer };
3876 	const VkDeviceSize				vertexBufferOffsets[]	= {                   0u,                   0u };
3877 	const deUint32					drawCountPerSubpass		= (subpassCount == 1) ? m_squareCount : 1u;
3878 	const deUint32					vertexPerPrimitive		= 4u;
3879 
3880 	beginCommandBuffer(*m_device, *m_cmdBuffer);
3881 
3882 	beforeRenderPass();
3883 
3884 	if (!m_useDynamicRendering)
3885 	{
3886 		const VkRenderPassBeginInfo renderPassBeginInfo
3887 		{
3888 			VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
3889 			DE_NULL,									// const void*			pNext;
3890 			renderPass,									// VkRenderPass			renderPass;
3891 			frameBuffer,								// VkFramebuffer		framebuffer;
3892 			renderArea,									// VkRect2D				renderArea;
3893 			1u,											// uint32_t				clearValueCount;
3894 			&renderPassClearValue,						// const VkClearValue*	pClearValues;
3895 		};
3896 		cmdBeginRenderPass(*m_device, *m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3897 	}
3898 
3899 	for (deUint32 subpassNdx = 0u; subpassNdx < subpassCount; subpassNdx++)
3900 	{
3901 		deUint32 firstVertexOffset = (subpassNdx < 4) ? 0u : m_squareCount * vertexPerPrimitive;
3902 
3903 		m_device->cmdBindVertexBuffers(*m_cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(vertexBuffers), vertexBuffers, vertexBufferOffsets);
3904 		m_device->cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **pipelines[subpassNdx]);
3905 
3906 #ifndef CTS_USES_VULKANSC
3907 		if (m_useDynamicRendering)
3908 		{
3909 			addRenderingSubpassDependencyIfRequired(subpassNdx);
3910 
3911 			VkRenderingAttachmentInfoKHR colorAttachment
3912 			{
3913 				vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
3914 				DE_NULL,												// const void*							pNext;
3915 				m_colorAttachment->getImageView(),						// VkImageView							imageView;
3916 				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout						imageLayout;
3917 				VK_RESOLVE_MODE_NONE,									// VkResolveModeFlagBits				resolveMode;
3918 				DE_NULL,												// VkImageView							resolveImageView;
3919 				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout						resolveImageLayout;
3920 				VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp					loadOp;
3921 				vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
3922 				renderPassClearValue									// VkClearValue							clearValue;
3923 			};
3924 
3925 			VkRenderingAttachmentInfoKHR dsAttachment
3926 			{
3927 				VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,		// VkStructureType						sType;
3928 				DE_NULL,												// const void*							pNext;
3929 				m_dsAttachment->getImageView(),							// VkImageView							imageView;
3930 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,		// VkImageLayout						imageLayout;
3931 				VK_RESOLVE_MODE_NONE,									// VkResolveModeFlagBits				resolveMode;
3932 				DE_NULL,												// VkImageView							resolveImageView;
3933 				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout						resolveImageLayout;
3934 				VK_ATTACHMENT_LOAD_OP_LOAD,								// VkAttachmentLoadOp					loadOp;
3935 				VK_ATTACHMENT_STORE_OP_STORE,							// VkAttachmentStoreOp					storeOp;
3936 				makeClearValueDepthStencil(0.0f, 0)						// VkClearValue							clearValue;
3937 			};
3938 
3939 			vk::VkRenderingInfoKHR renderingInfo
3940 			{
3941 				vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
3942 				DE_NULL,
3943 				0u,														// VkRenderingFlagsKHR					flags;
3944 				renderArea,												// VkRect2D								renderArea;
3945 				m_parameters.extent.depth,								// deUint32								layerCount;
3946 				m_parameters.viewMasks[subpassNdx],						// deUint32								viewMask;
3947 				1u,														// deUint32								colorAttachmentCount;
3948 				&colorAttachment,										// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
3949 				(m_depthTest ? &dsAttachment : DE_NULL),				// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
3950 				(m_stencilTest ? &dsAttachment : DE_NULL),				// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
3951 			};
3952 
3953 			m_device->cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
3954 		}
3955 #endif // CTS_USES_VULKANSC
3956 
3957 		for (deUint32 drawNdx = 0u; drawNdx < drawCountPerSubpass; ++drawNdx)
3958 			m_device->cmdDraw(*m_cmdBuffer, vertexPerPrimitive, 1u, firstVertexOffset + (drawNdx + subpassNdx % m_squareCount) * vertexPerPrimitive, 0u);
3959 
3960 #ifndef CTS_USES_VULKANSC
3961 		if (m_useDynamicRendering)
3962 			endRendering(*m_device, *m_cmdBuffer);
3963 		else
3964 #endif // CTS_USES_VULKANSC
3965 			if (subpassNdx < subpassCount - 1u)
3966 			cmdNextSubpass(*m_device, *m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE, m_parameters.renderingType);
3967 	}
3968 
3969 	if (!m_useDynamicRendering)
3970 		cmdEndRenderPass(*m_device, *m_cmdBuffer, m_parameters.renderingType);
3971 
3972 	afterRenderPass();
3973 
3974 	VK_CHECK(m_device->endCommandBuffer(*m_cmdBuffer));
3975 	submitCommandsAndWait(*m_device, *m_logicalDevice, m_queue, *m_cmdBuffer);
3976 }
3977 
beforeRenderPass(void)3978 void MultiViewDepthStencilTestInstance::beforeRenderPass (void)
3979 {
3980 	MultiViewRenderTestInstance::beforeRenderPass();
3981 
3982 	const VkImageSubresourceRange	subresourceRange		=
3983 	{
3984 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//VkImageAspectFlags	aspectMask;
3985 		0u,															//deUint32				baseMipLevel;
3986 		1u,															//deUint32				levelCount;
3987 		0u,															//deUint32				baseArrayLayer;
3988 		m_parameters.extent.depth,									//deUint32				layerCount;
3989 	};
3990 	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
3991 		VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
3992 		0, VK_ACCESS_TRANSFER_WRITE_BIT,
3993 		VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
3994 
3995 	const tcu::Vec4		baseColor	= getQuarterRefColor(0u, 0u, 0u, false);
3996 	const float			clearDepth	= baseColor[0];
3997 	const VkClearValue	clearValue	= makeClearValueDepthStencil(clearDepth, 0);
3998 
3999 	m_device->cmdClearDepthStencilImage(*m_cmdBuffer, m_dsAttachment->getImage(),  VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue.depthStencil, 1, &subresourceRange);
4000 
4001 	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), subresourceRange,
4002 		VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
4003 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
4004 		VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
4005 }
4006 
afterRenderPass(void)4007 void MultiViewDepthStencilTestInstance::afterRenderPass (void)
4008 {
4009 	MultiViewRenderTestInstance::afterRenderPass();
4010 
4011 	const VkImageSubresourceRange	dsSubresourceRange		=
4012 	{
4013 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//  VkImageAspectFlags	aspectMask;
4014 		0u,															//  deUint32			baseMipLevel;
4015 		1u,															//  deUint32			levelCount;
4016 		0u,															//  deUint32			baseArrayLayer;
4017 		m_parameters.extent.depth,									//  deUint32			layerCount;
4018 	};
4019 
4020 	imageBarrier(*m_device, *m_cmdBuffer, m_dsAttachment->getImage(), dsSubresourceRange,
4021 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
4022 		VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
4023 		VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
4024 }
4025 
4026 class MultiViewRenderTestsCase : public vkt::TestCase
4027 {
4028 public:
MultiViewRenderTestsCase(tcu::TestContext & context,const char * name,const char * description,const TestParameters & parameters)4029 	MultiViewRenderTestsCase (tcu::TestContext &context, const char *name, const char *description, const TestParameters& parameters)
4030 		: TestCase			(context, name, description)
4031 		, m_parameters		(parameters)
4032 	{
4033 		DE_ASSERT(m_parameters.extent.width == m_parameters.extent.height);
4034 	}
4035 private:
4036 	const TestParameters	m_parameters;
4037 
createInstance(vkt::Context & context) const4038 	vkt::TestInstance*	createInstance		(vkt::Context& context) const
4039 	{
4040 		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex ||
4041 			TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY == m_parameters.viewIndex)
4042 			return new MultiViewAttachmentsTestInstance(context, m_parameters);
4043 
4044 		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
4045 			return new MultiViewInstancedTestInstance(context, m_parameters);
4046 
4047 		if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
4048 			return new MultiViewInputRateInstanceTestInstance(context, m_parameters);
4049 
4050 		if (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex ||
4051 			TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
4052 			return new MultiViewDrawIndirectTestInstance(context, m_parameters);
4053 
4054 		if (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex)
4055 			return new MultiViewClearAttachmentsTestInstance(context, m_parameters);
4056 
4057 		if (TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex ||
4058 			TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY == m_parameters.viewIndex)
4059 			return new MultiViewSecondaryCommandBufferTestInstance(context, m_parameters);
4060 
4061 		if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
4062 			return new MultiViewPointSizeTestInstance(context, m_parameters);
4063 
4064 		if (TEST_TYPE_MULTISAMPLE == m_parameters.viewIndex)
4065 			return new MultiViewMultsampleTestInstance(context, m_parameters);
4066 
4067 		if (TEST_TYPE_QUERIES == m_parameters.viewIndex ||
4068 			TEST_TYPE_NON_PRECISE_QUERIES == m_parameters.viewIndex)
4069 			return new MultiViewQueriesTestInstance(context, m_parameters);
4070 
4071 		if (TEST_TYPE_VIEW_MASK == m_parameters.viewIndex ||
4072 			TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex ||
4073 			TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
4074 			TEST_TYPE_VIEW_INDEX_IN_GEOMETRY == m_parameters.viewIndex ||
4075 			TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex ||
4076 			TEST_TYPE_DRAW_INDEXED == m_parameters.viewIndex)
4077 			return new MultiViewRenderTestInstance(context, m_parameters);
4078 
4079 		if (TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR == m_parameters.viewIndex ||
4080 			TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR == m_parameters.viewIndex)
4081 			return new MultiViewReadbackTestInstance(context, m_parameters);
4082 
4083 		if (TEST_TYPE_DEPTH == m_parameters.viewIndex ||
4084 			TEST_TYPE_DEPTH_DIFFERENT_RANGES == m_parameters.viewIndex ||
4085 			TEST_TYPE_STENCIL == m_parameters.viewIndex)
4086 			return new MultiViewDepthStencilTestInstance(context, m_parameters);
4087 
4088 		TCU_THROW(InternalError, "Unknown test type");
4089 	}
4090 
checkSupport(Context & context) const4091 	virtual void		checkSupport		(Context& context) const
4092 	{
4093 		if (m_parameters.geometryShaderNeeded())
4094 			context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
4095 
4096 		if (m_parameters.renderingType == RENDERING_TYPE_RENDERPASS2)
4097 			context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
4098 
4099 		if (m_parameters.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
4100 			context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
4101 
4102 		context.requireDeviceFunctionality("VK_KHR_multiview");
4103 		if (m_parameters.viewIndex == TEST_TYPE_DEPTH_DIFFERENT_RANGES)
4104 			context.requireDeviceFunctionality("VK_EXT_depth_range_unrestricted");
4105 #ifdef CTS_USES_VULKANSC
4106 		const InstanceInterface&			instance			= context.getInstanceInterface();
4107 		const VkPhysicalDevice				physicalDevice		= context.getPhysicalDevice();
4108 		VkPhysicalDeviceMultiviewProperties	multiviewProperties =
4109 		{
4110 			VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,		//VkStructureType	sType;
4111 			DE_NULL,													//void*				pNext;
4112 			0u,															//deUint32			maxMultiviewViewCount;
4113 			0u															//deUint32			maxMultiviewInstanceIndex;
4114 		};
4115 
4116 		VkPhysicalDeviceProperties2			propertiesDeviceProperties2;
4117 		propertiesDeviceProperties2.sType						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
4118 		propertiesDeviceProperties2.pNext						= &multiviewProperties;
4119 
4120 		instance.getPhysicalDeviceProperties2(physicalDevice, &propertiesDeviceProperties2);
4121 
4122 		if (multiviewProperties.maxMultiviewViewCount < m_parameters.viewMasks.size())
4123 			TCU_THROW(NotSupportedError, "maxMultiviewViewCount is less than required by test");
4124 #endif // CTS_USES_VULKANSC
4125 	}
4126 
initPrograms(SourceCollections & programCollection) const4127 	void				initPrograms		(SourceCollections& programCollection) const
4128 	{
4129 		// Create vertex shader
4130 		if (TEST_TYPE_INSTANCED_RENDERING == m_parameters.viewIndex)
4131 		{
4132 			std::ostringstream source;
4133 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4134 					<< "#extension GL_EXT_multiview : enable\n"
4135 					<< "layout(location = 0) in highp vec4 in_position;\n"
4136 					<< "layout(location = 1) in vec4 in_color;\n"
4137 					<< "layout(location = 0) out vec4 out_color;\n"
4138 					<< "void main (void)\n"
4139 					<< "{\n"
4140 					<< "	int modInstance = gl_InstanceIndex % 4;\n"
4141 					<< "	int instance    = gl_InstanceIndex + 1;\n"
4142 					<< "	gl_Position = in_position;\n"
4143 					<< "	if (modInstance == 1)\n"
4144 					<< "		gl_Position = in_position + vec4(0.0f, 1.0f, 0.0f, 0.0f);\n"
4145 					<< "	if (modInstance == 2)\n"
4146 					<< "		gl_Position = in_position + vec4(1.0f, 0.0f, 0.0f, 0.0f);\n"
4147 					<< "	if (modInstance == 3)\n"
4148 					<< "		gl_Position =  in_position + vec4(1.0f, 1.0f, 0.0f, 0.0f);\n"
4149 					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
4150 					<< "}\n";
4151 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
4152 		}
4153 		else if (TEST_TYPE_INPUT_RATE_INSTANCE == m_parameters.viewIndex)
4154 		{
4155 			std::ostringstream source;
4156 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4157 					<< "#extension GL_EXT_multiview : enable\n"
4158 					<< "layout(location = 0) in highp vec4 in_position;\n"
4159 					<< "layout(location = 1) in vec4 in_color;\n"
4160 					<< "layout(location = 0) out vec4 out_color;\n"
4161 					<< "void main (void)\n"
4162 					<< "{\n"
4163 					<< "	int instance = gl_InstanceIndex + 1;\n"
4164 					<< "	gl_Position = in_position;\n"
4165 					<< "	if (gl_VertexIndex == 1)\n"
4166 					<< "		gl_Position.y += 1.0f;\n"
4167 					<< "	else if (gl_VertexIndex == 2)\n"
4168 					<< "		gl_Position.x += 1.0f;\n"
4169 					<< "	else if (gl_VertexIndex == 3)\n"
4170 					<< "	{\n"
4171 					<< "		gl_Position.x += 1.0f;\n"
4172 					<< "		gl_Position.y += 1.0f;\n"
4173 					<< "	}\n"
4174 					<< "	out_color = in_color + vec4(0.0f, gl_ViewIndex * 0.10f, instance * 0.10f, 0.0f);\n"
4175 					<< "}\n";
4176 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
4177 		}
4178 		else if (TEST_TYPE_POINT_SIZE == m_parameters.viewIndex)
4179 		{
4180 			std::ostringstream source;
4181 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4182 					<< "#extension GL_EXT_multiview : enable\n"
4183 					<< "layout(location = 0) in highp vec4 in_position;\n"
4184 					<< "layout(location = 1) in highp vec4 in_color;\n"
4185 					<< "layout(location = 0) out vec4 out_color;\n"
4186 					<< "void main (void)\n"
4187 					<< "{\n"
4188 					<< "	gl_Position = in_position;\n"
4189 					<< "	if (gl_ViewIndex == 0)\n"
4190 					<< "		gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_WIDE), 1) << "f;\n"
4191 					<< "	else\n"
4192 					<< "		gl_PointSize = " << de::floatToString(static_cast<float>(TEST_POINT_SIZE_SMALL), 1) << "f;\n"
4193 					<< "	out_color = in_color;\n"
4194 					<< "}\n";
4195 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
4196 		}
4197 		else
4198 		{
4199 			const bool generateColor	=  (TEST_TYPE_VIEW_INDEX_IN_VERTEX == m_parameters.viewIndex)
4200 										|| (TEST_TYPE_DRAW_INDIRECT == m_parameters.viewIndex)
4201 										|| (TEST_TYPE_DRAW_INDIRECT_INDEXED == m_parameters.viewIndex)
4202 										|| (TEST_TYPE_CLEAR_ATTACHMENTS == m_parameters.viewIndex);
4203 			std::ostringstream source;
4204 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4205 					<< "#extension GL_EXT_multiview : enable\n"
4206 					<< "layout(location = 0) in highp vec4 in_position;\n"
4207 					<< "layout(location = 1) in vec4 in_color;\n"
4208 					<< "layout(location = 0) out vec4 out_color;\n"
4209 					<< "void main (void)\n"
4210 					<< "{\n"
4211 					<< "	gl_Position = in_position;\n";
4212 				if (generateColor)
4213 					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
4214 				else
4215 					source << "	out_color = in_color;\n";
4216 			source	<< "}\n";
4217 			programCollection.glslSources.add("vertex") << glu::VertexSource(source.str());
4218 		}
4219 
4220 		if (TEST_TYPE_VIEW_INDEX_IN_TESELLATION == m_parameters.viewIndex)
4221 		{// Tessellation control & evaluation
4222 			std::ostringstream source_tc;
4223 			source_tc	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4224 						<< "#extension GL_EXT_multiview : enable\n"
4225 						<< "#extension GL_EXT_tessellation_shader : require\n"
4226 						<< "layout(vertices = 4) out;\n"
4227 						<< "layout(location = 0) in vec4 in_color[];\n"
4228 						<< "layout(location = 0) out vec4 out_color[];\n"
4229 						<< "\n"
4230 						<< "void main (void)\n"
4231 						<< "{\n"
4232 						<< "	if ( gl_InvocationID == 0 )\n"
4233 						<< "	{\n"
4234 						<< "		gl_TessLevelInner[0] = 4.0f;\n"
4235 						<< "		gl_TessLevelInner[1] = 4.0f;\n"
4236 						<< "		gl_TessLevelOuter[0] = 4.0f;\n"
4237 						<< "		gl_TessLevelOuter[1] = 4.0f;\n"
4238 						<< "		gl_TessLevelOuter[2] = 4.0f;\n"
4239 						<< "		gl_TessLevelOuter[3] = 4.0f;\n"
4240 						<< "	}\n"
4241 						<< "	out_color[gl_InvocationID] = in_color[gl_InvocationID];\n"
4242 						<< "	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
4243 						<< "}\n";
4244 			programCollection.glslSources.add("tessellation_control") << glu::TessellationControlSource(source_tc.str());
4245 
4246 			std::ostringstream source_te;
4247 			source_te	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
4248 						<< "#extension GL_EXT_multiview : enable\n"
4249 						<< "#extension GL_EXT_tessellation_shader : require\n"
4250 						<< "layout( quads, equal_spacing, ccw ) in;\n"
4251 						<< "layout(location = 0) in vec4 in_color[];\n"
4252 						<< "layout(location = 0) out vec4 out_color;\n"
4253 						<< "void main (void)\n"
4254 						<< "{\n"
4255 						<< "	const float u = gl_TessCoord.x;\n"
4256 						<< "	const float v = gl_TessCoord.y;\n"
4257 						<< "	const float w = gl_TessCoord.z;\n"
4258 						<< "	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"
4259 						<< "	out_color = in_color[0]+ vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4260 						<< "}\n";
4261 			programCollection.glslSources.add("tessellation_evaluation") << glu::TessellationEvaluationSource(source_te.str());
4262 		}
4263 
4264 		if (m_parameters.geometryShaderNeeded())
4265 		{// Geometry Shader
4266 			std::ostringstream	source;
4267 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4268 					<< "#extension GL_EXT_multiview : enable\n"
4269 					<< "layout(triangles) in;\n"
4270 					<< "layout(triangle_strip, max_vertices = 16) out;\n"
4271 					<< "layout(location = 0) in vec4 in_color[];\n"
4272 					<< "layout(location = 0) out vec4 out_color;\n"
4273 					<< "void main (void)\n"
4274 					<< "{\n"
4275 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4276 					<< "	gl_Position = gl_in[0].gl_Position;\n"
4277 					<< "	EmitVertex();\n"
4278 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4279 					<< "	gl_Position = gl_in[1].gl_Position;\n"
4280 					<< "	EmitVertex();\n"
4281 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4282 					<< "	gl_Position = gl_in[2].gl_Position;\n"
4283 					<< "	EmitVertex();\n"
4284 					<< "	out_color = in_color[0] + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n"
4285 					<< "	gl_Position = vec4(gl_in[2].gl_Position.x, gl_in[1].gl_Position.y, 1.0, 1.0);\n"
4286 					<< "	EmitVertex();\n"
4287 					<< "	EndPrimitive();\n"
4288 					<< "}\n";
4289 			programCollection.glslSources.add("geometry") << glu::GeometrySource(source.str());
4290 		}
4291 
4292 		if (TEST_TYPE_INPUT_ATTACHMENTS == m_parameters.viewIndex)
4293 		{// Create fragment shader read/write attachment
4294 			std::ostringstream source;
4295 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4296 					<< "#extension GL_EXT_multiview : enable\n"
4297 					<< "layout(location = 0) in vec4 in_color;\n"
4298 					<< "layout(location = 0) out vec4 out_color;\n"
4299 					<< "layout(input_attachment_index = 0, set=0, binding=0) uniform highp subpassInput in_color_attachment;\n"
4300 					<< "void main()\n"
4301 					<<"{\n"
4302 					<< "	out_color = vec4(subpassLoad(in_color_attachment));\n"
4303 					<< "}\n";
4304 			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
4305 		}
4306 		else
4307 		{// Create fragment shader
4308 			std::ostringstream source;
4309 			source	<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450)<<"\n"
4310 					<< "#extension GL_EXT_multiview : enable\n"
4311 					<< "layout(location = 0) in vec4 in_color;\n"
4312 					<< "layout(location = 0) out vec4 out_color;\n"
4313 					<< "void main()\n"
4314 					<<"{\n";
4315 				if (TEST_TYPE_VIEW_INDEX_IN_FRAGMENT == m_parameters.viewIndex ||
4316 					TEST_TYPE_SECONDARY_CMD_BUFFER == m_parameters.viewIndex)
4317 					source << "	out_color = in_color + vec4(0.0, gl_ViewIndex * 0.10f, 0.0, 0.0);\n";
4318 				else
4319 					source << "	out_color = in_color;\n";
4320 			source	<< "}\n";
4321 			programCollection.glslSources.add("fragment") << glu::FragmentSource(source.str());
4322 		}
4323 	}
4324 };
4325 } //anonymous
4326 
createViewMasksName(const std::vector<deUint32> & viewMasks)4327 static std::string createViewMasksName(const std::vector<deUint32>& viewMasks)
4328 {
4329 	std::ostringstream		masks;
4330 
4331 	for (size_t ndx = 0u; ndx < viewMasks.size(); ++ndx)
4332 	{
4333 		masks << viewMasks[ndx];
4334 		if (viewMasks.size() - 1 != ndx)
4335 			masks << "_";
4336 	}
4337 
4338 	return masks.str();
4339 }
4340 
tripleDepthStencilMasks(std::vector<deUint32> & baseMasks)4341 static std::vector<deUint32> tripleDepthStencilMasks(std::vector<deUint32>& baseMasks)
4342 {
4343 	std::vector<deUint32> tripledMasks(baseMasks);
4344 	std::vector<deUint32> partBMasks;
4345 
4346 	// a,b,c,d  =>  b,c,d,a
4347 	partBMasks.insert(partBMasks.end(), baseMasks.begin() + 1, baseMasks.end());
4348 	partBMasks.push_back(baseMasks[0]);
4349 
4350 	tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
4351 	tripledMasks.insert(tripledMasks.end(), partBMasks.begin(), partBMasks.end());
4352 
4353 	return tripledMasks;
4354 }
4355 
multiViewRenderCreateTests(tcu::TestCaseGroup * group)4356 void multiViewRenderCreateTests (tcu::TestCaseGroup* group)
4357 {
4358 	const deUint32				testCaseCount				= 7u;
4359 	const string				shaderName[TEST_TYPE_LAST]	=
4360 	{
4361 		"masks",
4362 		"vertex_shader",
4363 		"fragment_shader",
4364 		"geometry_shader",
4365 		"tessellation_shader",
4366 		"input_attachments",
4367 		"input_attachments_geometry",
4368 		"instanced",
4369 		"input_instance",
4370 		"draw_indirect",
4371 		"draw_indirect_indexed",
4372 		"draw_indexed",
4373 		"clear_attachments",
4374 		"secondary_cmd_buffer",
4375 		"secondary_cmd_buffer_geometry",
4376 		"point_size",
4377 		"multisample",
4378 		"queries",
4379 		"non_precise_queries",
4380 		"readback_implicit_clear",
4381 		"readback_explicit_clear",
4382 		"depth",
4383 		"depth_different_ranges",
4384 		"stencil",
4385 	};
4386 	const VkExtent3D			extent3D[testCaseCount]		=
4387 	{
4388 		{16u,	16u,	4u},
4389 		{64u,	64u,	8u},
4390 		{128u,	128u,	4u},
4391 		{32u,	32u,	5u},
4392 		{64u,	64u,	6u},
4393 		{32u,	32u,	4u},
4394 		{16u,	16u,	10u},
4395 	};
4396 	vector<deUint32>			viewMasks[testCaseCount];
4397 
4398 	viewMasks[0].push_back(15u);	//1111
4399 
4400 	viewMasks[1].push_back(8u);		//1000
4401 
4402 	viewMasks[2].push_back(1u);		//0001
4403 	viewMasks[2].push_back(2u);		//0010
4404 	viewMasks[2].push_back(4u);		//0100
4405 	viewMasks[2].push_back(8u);		//1000
4406 
4407 	viewMasks[3].push_back(15u);	//1111
4408 	viewMasks[3].push_back(15u);	//1111
4409 	viewMasks[3].push_back(15u);	//1111
4410 	viewMasks[3].push_back(15u);	//1111
4411 
4412 	viewMasks[4].push_back(8u);		//1000
4413 	viewMasks[4].push_back(1u);		//0001
4414 	viewMasks[4].push_back(1u);		//0001
4415 	viewMasks[4].push_back(8u);		//1000
4416 
4417 	viewMasks[5].push_back(5u);		//0101
4418 	viewMasks[5].push_back(10u);	//1010
4419 	viewMasks[5].push_back(5u);		//0101
4420 	viewMasks[5].push_back(10u);	//1010
4421 
4422 	const deUint32 minSupportedMultiviewViewCount	= 6u;
4423 	const deUint32 maxViewMask						= (1u << minSupportedMultiviewViewCount) - 1u;
4424 
4425 	for (deUint32 mask = 1u; mask <= maxViewMask; mask = mask << 1u)
4426 		viewMasks[testCaseCount - 1].push_back(mask);
4427 
4428 	vector<deUint32>			depthStencilMasks;
4429 
4430 	depthStencilMasks.push_back(3u);	// 0011
4431 	depthStencilMasks.push_back(6u);	// 0110
4432 	depthStencilMasks.push_back(12u);	// 1100
4433 	depthStencilMasks.push_back(9u);	// 1001
4434 
4435 #ifndef CTS_USES_VULKANSC
4436 	int numberOfRenderingTypes = 3;
4437 #else
4438 	int numberOfRenderingTypes = 2;
4439 #endif // CTS_USES_VULKANSC
4440 
4441 	for (int renderPassTypeNdx = 0; renderPassTypeNdx < numberOfRenderingTypes; ++renderPassTypeNdx)
4442 	{
4443 		RenderingType				renderPassType	(RENDERING_TYPE_RENDERPASS_LEGACY);
4444 		MovePtr<tcu::TestCaseGroup>	targetGroup		(DE_NULL);
4445 		tcu::TestCaseGroup*			targetGroupPtr	(group);
4446 
4447 		if (renderPassTypeNdx == 1)
4448 		{
4449 			renderPassType	= RENDERING_TYPE_RENDERPASS2;
4450 			targetGroup		= MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(group->getTestContext(), "renderpass2", "RenderPass2 index tests"));
4451 			targetGroupPtr	= targetGroup.get();
4452 		}
4453 		else if (renderPassTypeNdx == 2)
4454 		{
4455 			renderPassType	= RENDERING_TYPE_DYNAMIC_RENDERING;
4456 			targetGroup		= MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(group->getTestContext(), "dynamic_rendering", "Dynamic rendering tests"));
4457 			targetGroupPtr	= targetGroup.get();
4458 		}
4459 
4460 		tcu::TestContext&			testCtx				(targetGroupPtr->getTestContext());
4461 		MovePtr<tcu::TestCaseGroup>	groupViewIndex		(new tcu::TestCaseGroup(testCtx, "index", "ViewIndex rendering tests."));
4462 
4463 		for (int testTypeNdx = TEST_TYPE_VIEW_MASK; testTypeNdx < TEST_TYPE_LAST; ++testTypeNdx)
4464 		{
4465 			MovePtr<tcu::TestCaseGroup>	groupShader			(new tcu::TestCaseGroup(testCtx, shaderName[testTypeNdx].c_str(), ""));
4466 			const TestType				testType			= static_cast<TestType>(testTypeNdx);
4467 			const VkSampleCountFlagBits	sampleCountFlags	= (testType == TEST_TYPE_MULTISAMPLE) ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
4468 			const VkFormat				colorFormat			= (testType == TEST_TYPE_MULTISAMPLE) ? VK_FORMAT_R32G32B32A32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM;
4469 
4470 			// subpassLoad can't be used with dynamic rendering
4471 			if ((testTypeNdx == TEST_TYPE_INPUT_ATTACHMENTS) && (renderPassType == RENDERING_TYPE_DYNAMIC_RENDERING))
4472 				continue;
4473 
4474 			if (testTypeNdx == TEST_TYPE_DEPTH ||
4475                                   testTypeNdx == TEST_TYPE_DEPTH_DIFFERENT_RANGES ||
4476                                   testTypeNdx == TEST_TYPE_STENCIL)
4477 			{
4478 				const VkExtent3D		dsTestExtent3D	= { 64u, 64u, 4u };
4479 				const TestParameters	parameters		= { dsTestExtent3D, tripleDepthStencilMasks(depthStencilMasks), testType, sampleCountFlags, colorFormat, renderPassType };
4480 				const std::string		testName		= createViewMasksName(parameters.viewMasks);
4481 
4482 				groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
4483 			}
4484 			else
4485 			{
4486 				for (deUint32 testCaseNdx = 0u; testCaseNdx < testCaseCount; ++testCaseNdx)
4487 				{
4488 					const TestParameters	parameters	=	{ extent3D[testCaseNdx], viewMasks[testCaseNdx], testType, sampleCountFlags, colorFormat, renderPassType };
4489 					const std::string		testName	=	createViewMasksName(parameters.viewMasks);
4490 
4491 					groupShader->addChild(new MultiViewRenderTestsCase(testCtx, testName.c_str(), "", parameters));
4492 				}
4493 
4494 				// maxMultiviewViewCount case
4495 				{
4496 					const VkExtent3D		incompleteExtent3D	= { 16u, 16u, 0u };
4497 					const vector<deUint32>	unusedMasks;
4498 					const TestParameters	parameters			= { incompleteExtent3D, unusedMasks, testType, sampleCountFlags, colorFormat, renderPassType };
4499 
4500 					groupShader->addChild(new MultiViewRenderTestsCase(testCtx, "max_multi_view_view_count", "", parameters));
4501 				}
4502 			}
4503 
4504 			switch (testType)
4505 			{
4506 				case TEST_TYPE_VIEW_MASK:
4507 				case TEST_TYPE_INPUT_ATTACHMENTS:
4508 				case TEST_TYPE_INPUT_ATTACHMENTS_GEOMETRY:
4509 				case TEST_TYPE_INSTANCED_RENDERING:
4510 				case TEST_TYPE_INPUT_RATE_INSTANCE:
4511 				case TEST_TYPE_DRAW_INDIRECT:
4512 				case TEST_TYPE_DRAW_INDIRECT_INDEXED:
4513 				case TEST_TYPE_DRAW_INDEXED:
4514 				case TEST_TYPE_CLEAR_ATTACHMENTS:
4515 				case TEST_TYPE_SECONDARY_CMD_BUFFER:
4516 				case TEST_TYPE_SECONDARY_CMD_BUFFER_GEOMETRY:
4517 				case TEST_TYPE_POINT_SIZE:
4518 				case TEST_TYPE_MULTISAMPLE:
4519 				case TEST_TYPE_QUERIES:
4520 				case TEST_TYPE_NON_PRECISE_QUERIES:
4521 				case TEST_TYPE_READBACK_WITH_IMPLICIT_CLEAR:
4522 				case TEST_TYPE_READBACK_WITH_EXPLICIT_CLEAR:
4523 				case TEST_TYPE_DEPTH:
4524 				case TEST_TYPE_DEPTH_DIFFERENT_RANGES:
4525 				case TEST_TYPE_STENCIL:
4526 					targetGroupPtr->addChild(groupShader.release());
4527 					break;
4528 				case TEST_TYPE_VIEW_INDEX_IN_VERTEX:
4529 				case TEST_TYPE_VIEW_INDEX_IN_FRAGMENT:
4530 				case TEST_TYPE_VIEW_INDEX_IN_GEOMETRY:
4531 				case TEST_TYPE_VIEW_INDEX_IN_TESELLATION:
4532 					groupViewIndex->addChild(groupShader.release());
4533 					break;
4534 				default:
4535 					DE_ASSERT(0);
4536 					break;
4537 			}
4538 		}
4539 
4540 		targetGroupPtr->addChild(groupViewIndex.release());
4541 
4542 		if (renderPassType != RENDERING_TYPE_RENDERPASS_LEGACY)
4543 			group->addChild(targetGroup.release());
4544 	}
4545 }
4546 
4547 } //MultiView
4548 } //vkt
4549 
4550