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
36#include "tcuTestLog.hpp"
37#include "tcuResource.hpp"
38#include "tcuImageCompare.hpp"
39#include "tcuTextureUtil.hpp"
40#include "tcuRGBA.hpp"
41
42#include "vkDefs.hpp"
43
44namespace vkt
45{
46namespace DynamicState
47{
48
49using namespace Draw;
50
51namespace
52{
53
54class StateSwitchTestInstance : public DynamicStateBaseClass
55{
56public:
57	StateSwitchTestInstance (Context &context, ShaderMap shaders)
58		: DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
59	{
60		m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
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
70	virtual tcu::TestStatus iterate (void)
71	{
72		tcu::TestLog& log		= m_context.getTestContext().getLog();
73		const vk::VkQueue queue = m_context.getUniversalQueue();
74
75		beginRenderPass();
76
77		// bind states here
78		vk::VkViewport viewport = { 0, 0, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
79		vk::VkRect2D scissor_1	= { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
80		vk::VkRect2D scissor_2	= { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
81
82		setDynamicRasterizationState();
83		setDynamicBlendState();
84		setDynamicDepthStencilState();
85
86		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
87
88		const vk::VkDeviceSize vertexBufferOffset	= 0;
89		const vk::VkBuffer vertexBuffer				= m_vertexBuffer->object();
90		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
91
92		// bind first state
93		setDynamicViewportState(1, &viewport, &scissor_1);
94		m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
95
96		// bind second state
97		setDynamicViewportState(1, &viewport, &scissor_2);
98		m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
99
100		m_vk.cmdEndRenderPass(*m_cmdBuffer);
101		m_vk.endCommandBuffer(*m_cmdBuffer);
102
103		vk::VkSubmitInfo submitInfo =
104		{
105			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
106			DE_NULL,							// const void*				pNext;
107			0,									// deUint32					waitSemaphoreCount;
108			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
109			(const vk::VkPipelineStageFlags*)DE_NULL,
110			1,									// deUint32					commandBufferCount;
111			&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
112			0,									// deUint32					signalSemaphoreCount;
113			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
114		};
115		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
116
117		//validation
118		VK_CHECK(m_vk.queueWaitIdle(queue));
119
120		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
121		referenceFrame.allocLevel(0);
122
123		const deInt32 frameWidth	= referenceFrame.getWidth();
124		const deInt32 frameHeight	= referenceFrame.getHeight();
125
126		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
127
128		for (int y = 0; y < frameHeight; y++)
129		{
130			const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
131
132			for (int x = 0; x < frameWidth; x++)
133			{
134				const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
135
136				if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
137					(yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
138					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
139			}
140		}
141
142		const vk::VkOffset3D zeroOffset					= { 0, 0, 0 };
143		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
144																						  vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT,
145																						  vk::VK_IMAGE_ASPECT_COLOR_BIT);
146
147		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
148			referenceFrame.getLevel(0), renderedFrame, 0.05f,
149			tcu::COMPARE_LOG_RESULT))
150		{
151
152			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
153		}
154
155		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
156	}
157};
158
159class BindOrderTestInstance : public DynamicStateBaseClass
160{
161public:
162	BindOrderTestInstance (Context& context, ShaderMap shaders)
163		: DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
164	{
165		m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
166
167		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
168		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
169		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
170		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
171
172		DynamicStateBaseClass::initialize();
173	}
174
175	virtual tcu::TestStatus iterate (void)
176	{
177		tcu::TestLog &log		= m_context.getTestContext().getLog();
178		const vk::VkQueue queue = m_context.getUniversalQueue();
179
180		beginRenderPass();
181
182		// bind states here
183		vk::VkViewport viewport = { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
184		vk::VkRect2D scissor_1	= { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
185		vk::VkRect2D scissor_2	= { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
186
187		setDynamicRasterizationState();
188		setDynamicBlendState();
189		setDynamicDepthStencilState();
190		setDynamicViewportState(1, &viewport, &scissor_1);
191
192		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
193
194		const vk::VkDeviceSize vertexBufferOffset = 0;
195		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
196		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
197
198		// rebind in different order
199		setDynamicBlendState();
200		setDynamicRasterizationState();
201		setDynamicDepthStencilState();
202
203		// bind first state
204		setDynamicViewportState(1, &viewport, &scissor_1);
205		m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
206
207		setDynamicViewportState(1, &viewport, &scissor_2);
208		m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
209
210		m_vk.cmdEndRenderPass(*m_cmdBuffer);
211		m_vk.endCommandBuffer(*m_cmdBuffer);
212
213		vk::VkSubmitInfo submitInfo =
214		{
215			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
216			DE_NULL,							// const void*				pNext;
217			0,									// deUint32					waitSemaphoreCount;
218			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
219			(const vk::VkPipelineStageFlags*)DE_NULL,
220			1,									// deUint32					commandBufferCount;
221			&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
222			0,									// deUint32					signalSemaphoreCount;
223			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
224		};
225		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
226
227		//validation
228		VK_CHECK(m_vk.queueWaitIdle(queue));
229
230		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
231		referenceFrame.allocLevel(0);
232
233		const deInt32 frameWidth = referenceFrame.getWidth();
234		const deInt32 frameHeight = referenceFrame.getHeight();
235
236		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
237
238		for (int y = 0; y < frameHeight; y++)
239		{
240			const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
241
242			for (int x = 0; x < frameWidth; x++)
243			{
244				const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
245
246				if ((yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f) ||
247					(yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f))
248					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
249			}
250		}
251
252		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
253		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
254			vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
255
256		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
257			referenceFrame.getLevel(0), renderedFrame, 0.05f,
258			tcu::COMPARE_LOG_RESULT))
259		{
260			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
261		}
262
263		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
264	}
265};
266
267class StatePersistenceTestInstance : public DynamicStateBaseClass
268{
269protected:
270	vk::Move<vk::VkPipeline> m_pipelineAdditional;
271
272public:
273	StatePersistenceTestInstance (Context& context, ShaderMap shaders)
274		: DynamicStateBaseClass (context, shaders[glu::SHADERTYPE_VERTEX], shaders[glu::SHADERTYPE_FRAGMENT])
275	{
276		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
277		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
278		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
279		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
280
281		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
282		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
283		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
284		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
285		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
286		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::blue().toVec()));
287
288		DynamicStateBaseClass::initialize();
289	}
290	virtual void initPipeline (const vk::VkDevice device)
291	{
292		// shaders
293		const vk::Unique<vk::VkShaderModule> vs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_vertexShaderName), 0));
294		const vk::Unique<vk::VkShaderModule> fs (createShaderModule(m_vk, device, m_context.getBinaryCollection().get(m_fragmentShaderName), 0));
295
296		const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
297
298		PipelineCreateInfo pipelineCreateInfo_1(*m_pipelineLayout, *m_renderPass, 0, 0);
299		pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
300		pipelineCreateInfo_1.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
301		pipelineCreateInfo_1.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
302		pipelineCreateInfo_1.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
303		pipelineCreateInfo_1.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
304		pipelineCreateInfo_1.addState(PipelineCreateInfo::ViewportState(1));
305		pipelineCreateInfo_1.addState(PipelineCreateInfo::DepthStencilState());
306		pipelineCreateInfo_1.addState(PipelineCreateInfo::RasterizerState());
307		pipelineCreateInfo_1.addState(PipelineCreateInfo::MultiSampleState());
308		pipelineCreateInfo_1.addState(PipelineCreateInfo::DynamicState());
309
310		PipelineCreateInfo pipelineCreateInfo_2(*m_pipelineLayout, *m_renderPass, 0, 0);
311		pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
312		pipelineCreateInfo_2.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
313		pipelineCreateInfo_2.addState(PipelineCreateInfo::VertexInputState(m_vertexInputState));
314		pipelineCreateInfo_2.addState(PipelineCreateInfo::InputAssemblerState(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
315		pipelineCreateInfo_2.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
316		pipelineCreateInfo_2.addState(PipelineCreateInfo::ViewportState(1));
317		pipelineCreateInfo_2.addState(PipelineCreateInfo::DepthStencilState());
318		pipelineCreateInfo_2.addState(PipelineCreateInfo::RasterizerState());
319		pipelineCreateInfo_2.addState(PipelineCreateInfo::MultiSampleState());
320		pipelineCreateInfo_2.addState(PipelineCreateInfo::DynamicState());
321
322		m_pipeline = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_1);
323		m_pipelineAdditional = vk::createGraphicsPipeline(m_vk, device, DE_NULL, &pipelineCreateInfo_2);
324	}
325
326	virtual tcu::TestStatus iterate(void)
327	{
328		tcu::TestLog &log				= m_context.getTestContext().getLog();
329		const vk::VkQueue queue			= m_context.getUniversalQueue();
330
331		beginRenderPass();
332
333		// bind states here
334		const vk::VkViewport viewport	= { 0.0f, 0.0f, (float)WIDTH, (float)HEIGHT, 0.0f, 0.0f };
335		const vk::VkRect2D scissor_1	= { { 0, 0 }, { WIDTH / 2, HEIGHT / 2 } };
336		const vk::VkRect2D scissor_2	= { { WIDTH / 2, HEIGHT / 2 }, { WIDTH / 2, HEIGHT / 2 } };
337
338		setDynamicRasterizationState();
339		setDynamicBlendState();
340		setDynamicDepthStencilState();
341
342		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
343
344		const vk::VkDeviceSize vertexBufferOffset = 0;
345		const vk::VkBuffer vertexBuffer = m_vertexBuffer->object();
346		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
347
348		// bind first state
349		setDynamicViewportState(1, &viewport, &scissor_1);
350		// draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
351		m_vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
352
353		m_vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineAdditional);
354
355		// bind second state
356		setDynamicViewportState(1, &viewport, &scissor_2);
357		// draw quad using vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
358		m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 4, 0);
359
360		m_vk.cmdEndRenderPass(*m_cmdBuffer);
361		m_vk.endCommandBuffer(*m_cmdBuffer);
362
363		vk::VkSubmitInfo submitInfo =
364		{
365			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
366			DE_NULL,							// const void*				pNext;
367			0,									// deUint32					waitSemaphoreCount;
368			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
369			(const vk::VkPipelineStageFlags*)DE_NULL,
370			1,									// deUint32					commandBufferCount;
371			&m_cmdBuffer.get(),					// const VkCommandBuffer*	pCommandBuffers;
372			0,									// deUint32					signalSemaphoreCount;
373			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
374		};
375		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
376
377		//validation
378		VK_CHECK(m_vk.queueWaitIdle(queue));
379
380		tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
381		referenceFrame.allocLevel(0);
382
383		const deInt32 frameWidth	= referenceFrame.getWidth();
384		const deInt32 frameHeight	= referenceFrame.getHeight();
385
386		tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
387
388		for (int y = 0; y < frameHeight; y++)
389		{
390			const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
391
392			for (int x = 0; x < frameWidth; x++)
393			{
394				const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
395
396				if (yCoord >= -1.0f && yCoord <= 0.0f && xCoord >= -1.0f && xCoord <= 0.0f)
397					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), x, y);
398				else if (yCoord > 0.0f && yCoord <= 1.0f && xCoord > 0.0f && xCoord < 1.0f)
399					referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), x, y);
400			}
401		}
402
403		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
404		const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
405			vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
406
407		if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
408			referenceFrame.getLevel(0), renderedFrame, 0.05f,
409			tcu::COMPARE_LOG_RESULT))
410		{
411			return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
412		}
413
414		return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
415	}
416};
417
418} //anonymous
419
420DynamicStateGeneralTests::DynamicStateGeneralTests (tcu::TestContext& testCtx)
421	: TestCaseGroup (testCtx, "general_state", "General tests for dynamic states")
422{
423	/* Left blank on purpose */
424}
425
426DynamicStateGeneralTests::~DynamicStateGeneralTests (void) {}
427
428void DynamicStateGeneralTests::init (void)
429{
430	ShaderMap shaderPaths;
431	shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
432	shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
433
434	addChild(new InstanceFactory<StateSwitchTestInstance>(m_testCtx, "state_switch", "Perform multiple draws with different VP states (scissor test)", shaderPaths));
435	addChild(new InstanceFactory<BindOrderTestInstance>(m_testCtx, "bind_order", "Check if binding order is not important for pipeline configuration", shaderPaths));
436	addChild(new InstanceFactory<StatePersistenceTestInstance>(m_testCtx, "state_persistence", "Check if bound states are persistent across pipelines", shaderPaths));
437}
438
439} // DynamicState
440} // vkt
441