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