• 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  * Copyright (c) 2023 LunarG, Inc.
8  * Copyright (c) 2023 Nintendo
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Dynamic CB State Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktDynamicStateCBTests.hpp"
28 
29 #include "vktDynamicStateBaseClass.hpp"
30 #include "vktDynamicStateTestCaseUtil.hpp"
31 
32 #include "vkImageUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 
35 #include "tcuImageCompare.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuRGBA.hpp"
38 
39 namespace vkt
40 {
41 namespace DynamicState
42 {
43 
44 using namespace Draw;
45 
46 namespace
47 {
48 
49 class BlendConstantsTestInstance : public DynamicStateBaseClass
50 {
51 public:
BlendConstantsTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,const ShaderMap & shaders)52 	BlendConstantsTestInstance (Context& context, vk::PipelineConstructionType pipelineConstructionType, const ShaderMap& shaders)
53 		: DynamicStateBaseClass	(context, pipelineConstructionType, shaders.at(glu::SHADERTYPE_VERTEX), shaders.at(glu::SHADERTYPE_FRAGMENT), shaders.at(glu::SHADERTYPE_MESH))
54 	{
55 		m_topology = vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
56 
57 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
58 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
59 		m_data.push_back(PositionColorVertex(tcu::Vec4(-1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
60 		m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
61 
62 		DynamicStateBaseClass::initialize();
63 	}
64 
initPipeline(const vk::VkDevice device)65 	virtual void initPipeline (const vk::VkDevice device)
66 	{
67 		const auto&							binaries	= m_context.getBinaryCollection();
68 		const vk::ShaderWrapper				ms			(m_isMesh ? vk::ShaderWrapper(m_vk, device, binaries.get(m_meshShaderName), 0) : vk::ShaderWrapper());
69 		const vk::ShaderWrapper				vs			(m_isMesh ? vk::ShaderWrapper() : vk::ShaderWrapper(m_vk, device, binaries.get(m_vertexShaderName), 0));
70 		const vk::ShaderWrapper				fs			(vk::ShaderWrapper(m_vk, device, binaries.get(m_fragmentShaderName), 0));
71 		std::vector<vk::VkViewport>			viewports	{ { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f } };
72 		std::vector<vk::VkRect2D>			scissors	{ { { 0u, 0u }, { 0u, 0u } } };
73 
74 		const PipelineCreateInfo::ColorBlendState::Attachment	attachmentState(VK_TRUE,
75 																				vk::VK_BLEND_FACTOR_SRC_ALPHA, vk::VK_BLEND_FACTOR_CONSTANT_COLOR, vk::VK_BLEND_OP_ADD,
76 																				vk::VK_BLEND_FACTOR_SRC_ALPHA, vk::VK_BLEND_FACTOR_CONSTANT_ALPHA, vk::VK_BLEND_OP_ADD);
77 		const PipelineCreateInfo::ColorBlendState				colorBlendState(1, static_cast<const vk::VkPipelineColorBlendAttachmentState*>(&attachmentState));
78 		const PipelineCreateInfo::RasterizerState				rasterizerState;
79 		const PipelineCreateInfo::DepthStencilState				depthStencilState;
80 		const PipelineCreateInfo::DynamicState					dynamicState;
81 
82 		m_pipeline.setDefaultTopology(m_topology)
83 				  .setDynamicState(static_cast<const vk::VkPipelineDynamicStateCreateInfo*>(&dynamicState))
84 				  .setDefaultMultisampleState();
85 
86 #ifndef CTS_USES_VULKANSC
87 		if (m_isMesh)
88 		{
89 			m_pipeline
90 				  .setupPreRasterizationMeshShaderState(viewports,
91 														scissors,
92 														m_pipelineLayout,
93 														*m_renderPass,
94 														0u,
95 														vk::ShaderWrapper(),
96 														ms,
97 														static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
98 		}
99 		else
100 #endif // CTS_USES_VULKANSC
101 		{
102 			m_pipeline
103 				  .setupVertexInputState(&m_vertexInputState)
104 				  .setupPreRasterizationShaderState(viewports,
105 													scissors,
106 													m_pipelineLayout,
107 													*m_renderPass,
108 													0u,
109 													vs,
110 													static_cast<const vk::VkPipelineRasterizationStateCreateInfo*>(&rasterizerState));
111 		}
112 
113 		m_pipeline.setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fs, static_cast<const vk::VkPipelineDepthStencilStateCreateInfo*>(&depthStencilState))
114 				  .setupFragmentOutputState(*m_renderPass, 0u, static_cast<const vk::VkPipelineColorBlendStateCreateInfo*>(&colorBlendState))
115 				  .setMonolithicPipelineLayout(m_pipelineLayout)
116 				  .buildPipeline();
117 	}
118 
iterate(void)119 	virtual tcu::TestStatus iterate (void)
120 	{
121 		tcu::TestLog&		log		= m_context.getTestContext().getLog();
122 		const vk::VkQueue	queue	= m_context.getUniversalQueue();
123 		const vk::VkDevice	device	= m_context.getDevice();
124 
125 		const vk::VkClearColorValue clearColor = { { 1.0f, 1.0f, 1.0f, 1.0f } };
126 		beginRenderPassWithClearColor(clearColor);
127 
128 		m_pipeline.bind(*m_cmdBuffer);
129 
130 		// bind states here
131 		setDynamicViewportState(WIDTH, HEIGHT);
132 		setDynamicRasterizationState();
133 		setDynamicDepthStencilState();
134 		setDynamicBlendState(0.33f, 0.1f, 0.66f, 0.5f);
135 
136 #ifndef CTS_USES_VULKANSC
137 		if (m_isMesh)
138 		{
139 			const auto numVert = static_cast<uint32_t>(m_data.size());
140 			DE_ASSERT(numVert >= 2u);
141 
142 			m_vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout.get(), 0u, 1u, &m_descriptorSet.get(), 0u, nullptr);
143 			pushVertexOffset(0u, *m_pipelineLayout);
144 			m_vk.cmdDrawMeshTasksEXT(*m_cmdBuffer, numVert - 2u, 1u, 1u);
145 		}
146 		else
147 #endif // CTS_USES_VULKANSC
148 		{
149 			const vk::VkDeviceSize	vertexBufferOffset	= 0;
150 			const vk::VkBuffer		vertexBuffer		= m_vertexBuffer->object();
151 
152 			m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
153 			m_vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_data.size()), 1, 0, 0);
154 		}
155 
156 		m_renderPass.end(m_vk, *m_cmdBuffer);
157 		endCommandBuffer(m_vk, *m_cmdBuffer);
158 
159 		submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
160 
161 		//validation
162 		{
163 			tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
164 			referenceFrame.allocLevel(0);
165 
166 			const deInt32 frameWidth = referenceFrame.getWidth();
167 			const deInt32 frameHeight = referenceFrame.getHeight();
168 
169 			tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
170 
171 			for (int y = 0; y < frameHeight; y++)
172 			{
173 				const float yCoord = (float)(y / (0.5*frameHeight)) - 1.0f;
174 
175 				for (int x = 0; x < frameWidth; x++)
176 				{
177 					const float xCoord = (float)(x / (0.5*frameWidth)) - 1.0f;
178 
179 					if ((yCoord >= -1.0f && yCoord <= 1.0f && xCoord >= -1.0f && xCoord <= 1.0f))
180 						referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.33f, 1.0f, 0.66f, 1.0f), x, y);
181 				}
182 			}
183 
184 			const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
185 			const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
186 																							  vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
187 
188 			if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
189 				referenceFrame.getLevel(0), renderedFrame, 0.05f,
190 				tcu::COMPARE_LOG_RESULT))
191 			{
192 				return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
193 			}
194 
195 			return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
196 		}
197 	}
198 };
199 
200 #ifndef CTS_USES_VULKANSC
checkMeshShaderSupport(Context & context)201 void checkMeshShaderSupport (Context& context)
202 {
203 	context.requireDeviceFunctionality("VK_EXT_mesh_shader");
204 }
205 #endif // CTS_USES_VULKANSC
206 
207 } //anonymous
208 
DynamicStateCBTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)209 DynamicStateCBTests::DynamicStateCBTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
210 	: TestCaseGroup					(testCtx, "cb_state")
211 	, m_pipelineConstructionType	(pipelineConstructionType)
212 {
213 	/* Left blank on purpose */
214 }
215 
~DynamicStateCBTests(void)216 DynamicStateCBTests::~DynamicStateCBTests (void) {}
217 
init(void)218 void DynamicStateCBTests::init (void)
219 {
220 	ShaderMap pathsBase;
221 	pathsBase[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
222 	pathsBase[glu::SHADERTYPE_VERTEX] = nullptr;
223 	pathsBase[glu::SHADERTYPE_MESH] = nullptr;
224 
225 	{
226 		ShaderMap shaderPaths(pathsBase);
227 		shaderPaths[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
228 		// Check if blend constants are working properly
229 		addChild(new InstanceFactory<BlendConstantsTestInstance>(m_testCtx, "blend_constants", m_pipelineConstructionType, shaderPaths));
230 	}
231 #ifndef CTS_USES_VULKANSC
232 	{
233 		ShaderMap shaderPaths(pathsBase);
234 		shaderPaths[glu::SHADERTYPE_MESH] = "vulkan/dynamic_state/VertexFetch.mesh";
235 		// Check if blend constants are working properly in mesh shaders
236 		addChild(new InstanceFactory<BlendConstantsTestInstance, FunctionSupport0>(m_testCtx, "blend_constants_mesh", m_pipelineConstructionType, shaderPaths, checkMeshShaderSupport));
237 	}
238 #endif // CTS_USES_VULKANSC
239 }
240 
241 } // DynamicState
242 } // vkt
243