• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Dynamic State Tests - General
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDynamicStateGeneralTests.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDynamicStateTestCaseUtil.hpp"
29 #include "vktDynamicStateBaseClass.hpp"
30 #include "vktDrawCreateInfoUtil.hpp"
31 #include "vktDrawImageObjectUtil.hpp"
32 #include "vktDrawBufferObjectUtil.hpp"
33 
34 #include "vkImageUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 
37 #include "tcuTestLog.hpp"
38 #include "tcuResource.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuRGBA.hpp"
42 
43 #include "vkDefs.hpp"
44 #include "vkCmdUtil.hpp"
45 
46 namespace vkt
47 {
48 namespace DynamicState
49 {
50 
51 using namespace Draw;
52 
53 namespace
54 {
55 
56 class StateSwitchTestInstance : public DynamicStateBaseClass
57 {
58 public:
StateSwitchTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)59 	StateSwitchTestInstance (Context &context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
60 		: DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
61 	{
62 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
63 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
64 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
65 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
66 
67 		DynamicStateBaseClass::initialize();
68 	}
69 
iterate(void)70 	virtual tcu::TestStatus iterate (void)
71 	{
72 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
73 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
74 		const vk::VkDevice	device	= m_context.getDevice();
75 
76 		beginRenderPass();
77 
78 		// bind states here
79 		vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
80 		vk::VkRect2D scissor_1	= { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
81 		vk::VkRect2D scissor_2	= { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
82 
83 		setDynamicRasterizationState();
84 		setDynamicBlendState();
85 		setDynamicDepthStencilState();
86 
87 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
88 
89 #ifndef CTS_USES_VULKANSC
90 		if (m_isMesh)
91 		{
92 			const auto numVert = static_cast<uint32_t>(m_data.size());
93 			DE_ASSERT(numVert >= 2u);
94 
95 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
96 			pushVertexOffset(0u, *m_pipelineLayout);
97 
98 			// bind first state
99 			setDynamicViewportState(1, &viewport, &scissor_1);
100 			m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
101 
102 			// bind second state
103 			setDynamicViewportState(1, &viewport, &scissor_2);
104 			m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
105 		}
106 		else
107 #endif // CTS_USES_VULKANSC
108 		{
109 			const vk::VkDeviceSize vertexBufferOffset	= 0;
110 			const vk::VkBuffer vertexBuffer				= m_vertexBuffer->object();
111 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
112 
113 			// bind first state
114 			setDynamicViewportState(1, &viewport, &scissor_1);
115 			m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
116 
117 			// bind second state
118 			setDynamicViewportState(1, &viewport, &scissor_2);
119 			m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
120 		}
121 
122 		endRenderPass(m_vk, *m_cmdBuffer);
123 		endCommandBuffer(m_vk, *m_cmdBuffer);
124 
125 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
126 
127 		//validation
128 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
129 		referenceFrame.allocLevel(0);
130 
131 		const deInt32 frameWidth	= referenceFrame.getWidth();
132 		const deInt32 frameHeight	= referenceFrame.getHeight();
133 
134 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
135 
136 		for (int y = 0; y < frameHeight; y++)
137 		{
138 			const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
139 
140 			for (int x = 0; x < frameWidth; x++)
141 			{
142 				const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
143 
144 				if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
145 					(yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
146 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
147 			}
148 		}
149 
150 		const vk::VkOffset3D zeroOffset					= { 0, 0, 0 };
151 		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
152 																						  vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
153 																						  vk::VK_IMAGE_ASPECT_COLOR_BIT);
154 
155 		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
156 			referenceFrame.getLevel(0), renderedFrame, 0.05f,
157 			tcu::COMPARE_LOG_RESULT))
158 		{
159 
160 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
161 		}
162 
163 		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
164 	}
165 };
166 
167 class BindOrderTestInstance : public DynamicStateBaseClass
168 {
169 public:
BindOrderTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)170 	BindOrderTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
171 		: DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
172 	{
173 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
174 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
175 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
176 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
177 
178 		DynamicStateBaseClass::initialize();
179 	}
180 
iterate(void)181 	virtual tcu::TestStatus iterate (void)
182 	{
183 		tcu::TestLog		&log	= m_context.getTestContext().getLog();
184 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
185 		const vk::VkDevice	device	= m_context.getDevice();
186 
187 		beginRenderPass();
188 
189 		// bind states here
190 		vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
191 		vk::VkRect2D scissor_1	= { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
192 		vk::VkRect2D scissor_2	= { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
193 
194 		setDynamicRasterizationState();
195 		setDynamicBlendState();
196 		setDynamicDepthStencilState();
197 		setDynamicViewportState(1, &viewport, &scissor_1);
198 
199 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
200 
201 #ifndef CTS_USES_VULKANSC
202 		if (m_isMesh)
203 		{
204 			const auto numVert = static_cast<uint32_t>(m_data.size());
205 			DE_ASSERT(numVert >= 2u);
206 
207 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
208 			pushVertexOffset(0u, *m_pipelineLayout);
209 
210 			// rebind in different order
211 			setDynamicBlendState();
212 			setDynamicRasterizationState();
213 			setDynamicDepthStencilState();
214 
215 			// bind first state
216 			setDynamicViewportState(1, &viewport, &scissor_1);
217 			m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
218 
219 			setDynamicViewportState(1, &viewport, &scissor_2);
220 			m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
221 		}
222 		else
223 #endif // CTS_USES_VULKANSC
224 		{
225 			const vk::VkDeviceSize vertexBufferOffset = 0;
226 			const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
227 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
228 
229 			// rebind in different order
230 			setDynamicBlendState();
231 			setDynamicRasterizationState();
232 			setDynamicDepthStencilState();
233 
234 			// bind first state
235 			setDynamicViewportState(1, &viewport, &scissor_1);
236 			m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
237 
238 			setDynamicViewportState(1, &viewport, &scissor_2);
239 			m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
240 		}
241 
242 		endRenderPass(m_vk, *m_cmdBuffer);
243 		endCommandBuffer(m_vk, *m_cmdBuffer);
244 
245 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
246 
247 		//validation
248 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
249 		referenceFrame.allocLevel(0);
250 
251 		const deInt32 frameWidth = referenceFrame.getWidth();
252 		const deInt32 frameHeight = referenceFrame.getHeight();
253 
254 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
255 
256 		for (int y = 0; y < frameHeight; y++)
257 		{
258 			const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
259 
260 			for (int x = 0; x < frameWidth; x++)
261 			{
262 				const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
263 
264 				if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
265 					(yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
266 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
267 			}
268 		}
269 
270 		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
271 		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
272 			vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
273 
274 		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
275 			referenceFrame.getLevel(0), renderedFrame, 0.05f,
276 			tcu::COMPARE_LOG_RESULT))
277 		{
278 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
279 		}
280 
281 		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
282 	}
283 };
284 
285 class StatePersistenceTestInstance : public DynamicStateBaseClass
286 {
287 protected:
288 	vk::GraphicsPipelineWrapper	m_pipelineAdditional;
289 
290 public:
StatePersistenceTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)291 	StatePersistenceTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
292 		: DynamicStateBaseClass (context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
293 		, m_pipelineAdditional	(context.getDeviceInterface(), context.getDevice(), pipelineConstructionType)
294 	{
295 		// This test does not make sense for mesh shader variants.
296 		DE_ASSERT(!m_isMesh);
297 
298 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
299 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
300 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
301 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
302 
303 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
304 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
305 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
306 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
307 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
308 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
309 
310 		DynamicStateBaseClass::initialize();
311 	}
initPipeline(const vk::VkDevice device)312 	virtual void initPipeline (const vk::VkDevice device)
313 	{
314 		const vk::Unique<vk::VkShaderModule>	vs			(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
315 		const vk::Unique<vk::VkShaderModule>	fs			(createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
316 		std::vector<vk::VkViewport>				viewports	{ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
317 		std::vector<vk::VkRect2D>				scissors	{ { { 0u, 0u }, { 0u, 0u } } };
318 
319 		const PipelineCreateInfo::ColorBlendState::Attachment	attachmentState;
320 		const PipelineCreateInfo::ColorBlendState				colorBlendState(1, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
321 		const PipelineCreateInfo::RasterizerState				rasterizerState;
322 		const PipelineCreateInfo::DepthStencilState				depthStencilState;
323 		const PipelineCreateInfo::DynamicState					dynamicState;
324 
325 		m_pipeline.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
326 				  .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
327 				  .setDefaultMultisampleState()
328 				  .setupVertexInputState(&m_vertexInputState)
329 				  .setupPreRasterizationShaderState(viewports,
330 													scissors,
331 													*m_pipelineLayout,
332 													*m_renderPass,
333 													0u,
334 													*vs,
335 													static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState))
336 				  .setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState))
337 				  .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
338 				  .setMonolithicPipelineLayout(*m_pipelineLayout)
339 				  .buildPipeline();
340 
341 		m_pipelineAdditional.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
342 				  .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
343 				  .setDefaultMultisampleState()
344 				  .setupVertexInputState(&m_vertexInputState)
345 				  .setupPreRasterizationShaderState(viewports,
346 													scissors,
347 													*m_pipelineLayout,
348 													*m_renderPass,
349 													0u,
350 													*vs,
351 													static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState))
352 				  .setupFragmentShaderState(*m_pipelineLayout, *m_renderPass, 0u, *fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState))
353 				  .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
354 				  .setMonolithicPipelineLayout(*m_pipelineLayout)
355 				  .buildPipeline();
356 	}
357 
iterate(void)358 	virtual tcu::TestStatus iterate(void)
359 	{
360 		tcu::TestLog&		log			= m_context.getTestContext().getLog();
361 		const vk::VkQueue	queue		= m_context.getUniversalQueue();
362 		const vk::VkDevice	device		= m_context.getDevice();
363 
364 		beginRenderPass();
365 
366 		// bind states here
367 		const vk::VkViewport viewport	= { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
368 		const vk::VkRect2D scissor_1	= { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
369 		const vk::VkRect2D scissor_2	= { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
370 
371 		setDynamicRasterizationState();
372 		setDynamicBlendState();
373 		setDynamicDepthStencilState();
374 
375 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline.getPipeline());
376 
377 		const vk::VkDeviceSize vertexBufferOffset = 0;
378 		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
379 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
380 
381 		// bind first state
382 		setDynamicViewportState(1, &viewport, &scissor_1);
383 		// draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
384 		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
385 
386 		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineAdditional.getPipeline());
387 
388 		// bind second state
389 		setDynamicViewportState(1, &viewport, &scissor_2);
390 		// draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
391 		m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
392 
393 		endRenderPass(m_vk, *m_cmdBuffer);
394 		endCommandBuffer(m_vk, *m_cmdBuffer);
395 
396 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
397 
398 		//validation
399 		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
400 		referenceFrame.allocLevel(0);
401 
402 		const deInt32 frameWidth	= referenceFrame.getWidth();
403 		const deInt32 frameHeight	= referenceFrame.getHeight();
404 
405 		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
406 
407 		for (int y = 0; y < frameHeight; y++)
408 		{
409 			const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
410 
411 			for (int x = 0; x < frameWidth; x++)
412 			{
413 				const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
414 
415 				if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
416 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
417 				else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
418 					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
419 			}
420 		}
421 
422 		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
423 		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
424 			vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
425 
426 		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
427 			referenceFrame.getLevel(0), renderedFrame, 0.05f,
428 			tcu::COMPARE_LOG_RESULT))
429 		{
430 			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
431 		}
432 
433 		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
434 	}
435 };
436 
437 #ifndef CTS_USES_VULKANSC
checkMeshShaderSupport(Context & context)438 void checkMeshShaderSupport (Context& context)
439 {
440 	context.requireDeviceFunctionality("VK_EXT_mesh_shader");
441 }
442 #endif // CTS_USES_VULKANSC
443 
checkNothing(Context &)444 void checkNothing (Context&)
445 {
446 }
447 
448 } //anonymous
449 
DynamicStateGeneralTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)450 DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
451 	: TestCaseGroup					(testCtx, "general_state", "General tests for dynamic states")
452 	, m_pipelineConstructionType	(pipelineConstructionType)
453 {
454 	/* Left blank on purpose */
455 }
456 
~DynamicStateGeneralTests(void)457 DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
458 
init(void)459 void DynamicStateGeneralTests::init (void)
460 {
461 	ShaderMap basePaths;
462 	basePaths[glu::SHADERTYPE_FRAGMENT]	= "vulkan/dynamic_state/VertexFetch.frag";
463 	basePaths[glu::SHADERTYPE_MESH]		= nullptr;
464 	basePaths[glu::SHADERTYPE_VERTEX]	= nullptr;
465 
466 	for (int i = 0; i < 2; ++i)
467 	{
468 		const bool					isMesh				= (i > 0);
469 		ShaderMap					shaderPaths			(basePaths);
470 		std::string					nameSuffix;
471 		std::string					descSuffix;
472 		FunctionSupport0::Function	checkSupportFunc;
473 
474 		if (isMesh)
475 		{
476 #ifndef CTS_USES_VULKANSC
477 			shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
478 			nameSuffix = "_mesh";
479 			descSuffix = " using mesh shaders";
480 			checkSupportFunc = checkMeshShaderSupport;
481 #else
482 			continue;
483 #endif // CTS_USES_VULKANSC
484 		}
485 		else
486 		{
487 			shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
488 			checkSupportFunc = checkNothing;
489 		}
490 
491 		addChild(new InstanceFactory<StateSwitchTestInstance, FunctionSupport0>(m_testCtx, "state_switch" + nameSuffix, "Perform multiple draws with different VP states (scissor test)" + descSuffix, m_pipelineConstructionType, shaderPaths, checkSupportFunc));
492 		addChild(new InstanceFactory<BindOrderTestInstance, FunctionSupport0>(m_testCtx, "bind_order" + nameSuffix, "Check if binding order is not important for pipeline configuration" + descSuffix, m_pipelineConstructionType, shaderPaths, checkSupportFunc));
493 		if (!isMesh)
494 			addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence" + nameSuffix, "Check if bound states are persistent across pipelines" + descSuffix, m_pipelineConstructionType, shaderPaths));
495 	}
496 }
497 
498 } // DynamicState
499 } // vkt
500