• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google 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 Test Package
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktTestPackage.hpp"
25 
26 #include "tcuPlatform.hpp"
27 #include "tcuTestCase.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuCommandLine.hpp"
30 
31 #include "vkPlatform.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkBinaryRegistry.hpp"
34 #include "vkGlslToSpirV.hpp"
35 #include "vkDebugReportUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 
38 #include "deUniquePtr.hpp"
39 
40 #include "vktTestGroupUtil.hpp"
41 #include "vktApiTests.hpp"
42 #include "vktPipelineTests.hpp"
43 #include "vktBindingModelTests.hpp"
44 #include "vktSpvAsmTests.hpp"
45 #include "vktShaderLibrary.hpp"
46 #include "vktRenderPassTests.hpp"
47 #include "vktMemoryTests.hpp"
48 #include "vktShaderRenderBuiltinVarTests.hpp"
49 #include "vktShaderRenderDerivateTests.hpp"
50 #include "vktShaderRenderDiscardTests.hpp"
51 #include "vktShaderRenderIndexingTests.hpp"
52 #include "vktShaderRenderLoopTests.hpp"
53 #include "vktShaderRenderMatrixTests.hpp"
54 #include "vktShaderRenderOperatorTests.hpp"
55 #include "vktShaderRenderReturnTests.hpp"
56 #include "vktShaderRenderStructTests.hpp"
57 #include "vktShaderRenderSwitchTests.hpp"
58 #include "vktShaderRenderTextureFunctionTests.hpp"
59 #include "vktShaderRenderTextureGatherTests.hpp"
60 #include "vktShaderBuiltinTests.hpp"
61 #include "vktOpaqueTypeIndexingTests.hpp"
62 #include "vktUniformBlockTests.hpp"
63 #include "vktDynamicStateTests.hpp"
64 #include "vktSSBOLayoutTests.hpp"
65 #include "vktQueryPoolTests.hpp"
66 #include "vktDrawTests.hpp"
67 #include "vktComputeTests.hpp"
68 #include "vktImageTests.hpp"
69 #include "vktInfoTests.hpp"
70 #include "vktWsiTests.hpp"
71 #include "vktSynchronizationTests.hpp"
72 #include "vktSparseResourcesTests.hpp"
73 #include "vktTessellationTests.hpp"
74 #include "vktRasterizationTests.hpp"
75 #include "vktClippingTests.hpp"
76 #include "vktFragmentOperationsTests.hpp"
77 #include "vktTextureTests.hpp"
78 #include "vktGeometryTests.hpp"
79 
80 #include <vector>
81 #include <sstream>
82 
83 namespace // compilation
84 {
85 
compileProgram(const glu::ProgramSources & source,glu::ShaderProgramInfo * buildInfo)86 vk::ProgramBinary* compileProgram (const glu::ProgramSources& source, glu::ShaderProgramInfo* buildInfo)
87 {
88 	return vk::buildProgram(source, vk::PROGRAM_FORMAT_SPIRV, buildInfo);
89 }
90 
compileProgram(const vk::SpirVAsmSource & source,vk::SpirVProgramInfo * buildInfo)91 vk::ProgramBinary* compileProgram (const vk::SpirVAsmSource& source, vk::SpirVProgramInfo* buildInfo)
92 {
93 	return vk::assembleProgram(source, buildInfo);
94 }
95 
96 template <typename InfoType, typename IteratorType>
buildProgram(const std::string & casePath,IteratorType iter,const vk::BinaryRegistryReader & prebuiltBinRegistry,tcu::TestLog & log,vk::BinaryCollection * progCollection)97 vk::ProgramBinary* buildProgram (const std::string&					casePath,
98 								 IteratorType						iter,
99 								 const vk::BinaryRegistryReader&	prebuiltBinRegistry,
100 								 tcu::TestLog&						log,
101 								 vk::BinaryCollection*				progCollection)
102 {
103 	const vk::ProgramIdentifier		progId		(casePath, iter.getName());
104 	const tcu::ScopedLogSection		progSection	(log, iter.getName(), "Program: " + iter.getName());
105 	de::MovePtr<vk::ProgramBinary>	binProg;
106 	InfoType						buildInfo;
107 
108 	try
109 	{
110 		binProg	= de::MovePtr<vk::ProgramBinary>(compileProgram(iter.getProgram(), &buildInfo));
111 		log << buildInfo;
112 	}
113 	catch (const tcu::NotSupportedError& err)
114 	{
115 		// Try to load from cache
116 		log << err << tcu::TestLog::Message << "Building from source not supported, loading stored binary instead" << tcu::TestLog::EndMessage;
117 
118 		binProg = de::MovePtr<vk::ProgramBinary>(prebuiltBinRegistry.loadProgram(progId));
119 
120 		log << iter.getProgram();
121 	}
122 	catch (const tcu::Exception&)
123 	{
124 		// Build failed for other reason
125 		log << buildInfo;
126 		throw;
127 	}
128 
129 	TCU_CHECK_INTERNAL(binProg);
130 
131 	{
132 		vk::ProgramBinary* const	returnBinary	= binProg.get();
133 
134 		progCollection->add(progId.programName, binProg);
135 
136 		return returnBinary;
137 	}
138 }
139 
140 } // anonymous(compilation)
141 
142 namespace vkt
143 {
144 
145 using std::vector;
146 using de::UniquePtr;
147 using de::MovePtr;
148 using tcu::TestLog;
149 
150 namespace
151 {
152 
createDebugReportRecorder(const vk::PlatformInterface & vkp,const vk::InstanceInterface & vki,vk::VkInstance instance)153 MovePtr<vk::DebugReportRecorder> createDebugReportRecorder (const vk::PlatformInterface& vkp, const vk::InstanceInterface& vki, vk::VkInstance instance)
154 {
155 	if (isDebugReportSupported(vkp))
156 		return MovePtr<vk::DebugReportRecorder>(new vk::DebugReportRecorder(vki, instance));
157 	else
158 		TCU_THROW(NotSupportedError, "VK_EXT_debug_report is not supported");
159 }
160 
161 } // anonymous
162 
163 // TestCaseExecutor
164 
165 class TestCaseExecutor : public tcu::TestCaseExecutor
166 {
167 public:
168 												TestCaseExecutor	(tcu::TestContext& testCtx);
169 												~TestCaseExecutor	(void);
170 
171 	virtual void								init				(tcu::TestCase* testCase, const std::string& path);
172 	virtual void								deinit				(tcu::TestCase* testCase);
173 
174 	virtual tcu::TestNode::IterateResult		iterate				(tcu::TestCase* testCase);
175 
176 private:
177 	vk::BinaryCollection						m_progCollection;
178 	vk::BinaryRegistryReader					m_prebuiltBinRegistry;
179 
180 	const UniquePtr<vk::Library>				m_library;
181 	Context										m_context;
182 
183 	const UniquePtr<vk::DebugReportRecorder>	m_debugReportRecorder;
184 
185 	TestInstance*								m_instance;			//!< Current test case instance
186 };
187 
createLibrary(tcu::TestContext & testCtx)188 static MovePtr<vk::Library> createLibrary (tcu::TestContext& testCtx)
189 {
190 	return MovePtr<vk::Library>(testCtx.getPlatform().getVulkanPlatform().createLibrary());
191 }
192 
TestCaseExecutor(tcu::TestContext & testCtx)193 TestCaseExecutor::TestCaseExecutor (tcu::TestContext& testCtx)
194 	: m_prebuiltBinRegistry	(testCtx.getArchive(), "vulkan/prebuilt")
195 	, m_library				(createLibrary(testCtx))
196 	, m_context				(testCtx, m_library->getPlatformInterface(), m_progCollection)
197 	, m_debugReportRecorder	(testCtx.getCommandLine().isValidationEnabled()
198 							 ? createDebugReportRecorder(m_library->getPlatformInterface(),
199 														 m_context.getInstanceInterface(),
200 														 m_context.getInstance())
201 							 : MovePtr<vk::DebugReportRecorder>(DE_NULL))
202 	, m_instance			(DE_NULL)
203 {
204 }
205 
~TestCaseExecutor(void)206 TestCaseExecutor::~TestCaseExecutor (void)
207 {
208 	delete m_instance;
209 }
210 
init(tcu::TestCase * testCase,const std::string & casePath)211 void TestCaseExecutor::init (tcu::TestCase* testCase, const std::string& casePath)
212 {
213 	const TestCase*			vktCase		= dynamic_cast<TestCase*>(testCase);
214 	tcu::TestLog&			log			= m_context.getTestContext().getLog();
215 	vk::SourceCollections	sourceProgs;
216 
217 	DE_UNREF(casePath); // \todo [2015-03-13 pyry] Use this to identify ProgramCollection storage path
218 
219 	if (!vktCase)
220 		TCU_THROW(InternalError, "Test node not an instance of vkt::TestCase");
221 
222 	m_progCollection.clear();
223 	vktCase->initPrograms(sourceProgs);
224 
225 	for (vk::GlslSourceCollection::Iterator progIter = sourceProgs.glslSources.begin(); progIter != sourceProgs.glslSources.end(); ++progIter)
226 	{
227 		vk::ProgramBinary* binProg = buildProgram<glu::ShaderProgramInfo, vk::GlslSourceCollection::Iterator>(casePath, progIter, m_prebuiltBinRegistry, log, &m_progCollection);
228 
229 		try
230 		{
231 			std::ostringstream disasm;
232 
233 			vk::disassembleProgram(*binProg, &disasm);
234 
235 			log << vk::SpirVAsmSource(disasm.str());
236 		}
237 		catch (const tcu::NotSupportedError& err)
238 		{
239 			log << err;
240 		}
241 	}
242 
243 	for (vk::SpirVAsmCollection::Iterator asmIterator = sourceProgs.spirvAsmSources.begin(); asmIterator != sourceProgs.spirvAsmSources.end(); ++asmIterator)
244 	{
245 		buildProgram<vk::SpirVProgramInfo, vk::SpirVAsmCollection::Iterator>(casePath, asmIterator, m_prebuiltBinRegistry, log, &m_progCollection);
246 	}
247 
248 	DE_ASSERT(!m_instance);
249 	m_instance = vktCase->createInstance(m_context);
250 }
251 
deinit(tcu::TestCase *)252 void TestCaseExecutor::deinit (tcu::TestCase*)
253 {
254 	delete m_instance;
255 	m_instance = DE_NULL;
256 
257 	// Collect and report any debug messages
258 	if (m_debugReportRecorder)
259 	{
260 		// \note We are not logging INFORMATION and DEBUG messages
261 		static const vk::VkDebugReportFlagsEXT			errorFlags		= vk::VK_DEBUG_REPORT_ERROR_BIT_EXT;
262 		static const vk::VkDebugReportFlagsEXT			logFlags		= errorFlags
263 																		| vk::VK_DEBUG_REPORT_WARNING_BIT_EXT
264 																		| vk::VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
265 
266 		typedef vk::DebugReportRecorder::MessageList	DebugMessages;
267 
268 		const DebugMessages&	messages	= m_debugReportRecorder->getMessages();
269 		tcu::TestLog&			log			= m_context.getTestContext().getLog();
270 
271 		if (messages.begin() != messages.end())
272 		{
273 			const tcu::ScopedLogSection	section		(log, "DebugMessages", "Debug Messages");
274 			int							numErrors	= 0;
275 
276 			for (DebugMessages::const_iterator curMsg = messages.begin(); curMsg != messages.end(); ++curMsg)
277 			{
278 				if ((curMsg->flags & logFlags) != 0)
279 					log << tcu::TestLog::Message << *curMsg << tcu::TestLog::EndMessage;
280 
281 				if ((curMsg->flags & errorFlags) != 0)
282 					numErrors += 1;
283 			}
284 
285 			m_debugReportRecorder->clearMessages();
286 
287 			if (numErrors > 0)
288 				m_context.getTestContext().setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, (de::toString(numErrors) + " API usage errors found").c_str());
289 		}
290 	}
291 }
292 
iterate(tcu::TestCase *)293 tcu::TestNode::IterateResult TestCaseExecutor::iterate (tcu::TestCase*)
294 {
295 	DE_ASSERT(m_instance);
296 
297 	const tcu::TestStatus	result	= m_instance->iterate();
298 
299 	if (result.isComplete())
300 	{
301 		// Vulkan tests shouldn't set result directly
302 		DE_ASSERT(m_context.getTestContext().getTestResult() == QP_TEST_RESULT_LAST);
303 		m_context.getTestContext().setTestResult(result.getCode(), result.getDescription().c_str());
304 		return tcu::TestNode::STOP;
305 	}
306 	else
307 		return tcu::TestNode::CONTINUE;
308 }
309 
310 // GLSL shader tests
311 
createGlslTests(tcu::TestCaseGroup * glslTests)312 void createGlslTests (tcu::TestCaseGroup* glslTests)
313 {
314 	tcu::TestContext&	testCtx		= glslTests->getTestContext();
315 
316 	// ShaderLibrary-based tests
317 	static const struct
318 	{
319 		const char*		name;
320 		const char*		description;
321 	} s_es310Tests[] =
322 	{
323 		{ "arrays",						"Arrays"					},
324 		{ "conditionals",				"Conditional statements"	},
325 		{ "constant_expressions",		"Constant expressions"		},
326 		{ "constants",					"Constants"					},
327 		{ "conversions",				"Type conversions"			},
328 		{ "functions",					"Functions"					},
329 		{ "linkage",					"Linking"					},
330 		{ "scoping",					"Scoping"					},
331 		{ "swizzles",					"Swizzles"					},
332 	};
333 
334 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_es310Tests); ndx++)
335 		glslTests->addChild(createShaderLibraryGroup(testCtx,
336 													 s_es310Tests[ndx].name,
337 													 s_es310Tests[ndx].description,
338 													 std::string("vulkan/glsl/es310/") + s_es310Tests[ndx].name + ".test").release());
339 
340 	// ShaderRenderCase-based tests
341 	glslTests->addChild(sr::createDerivateTests			(testCtx));
342 	glslTests->addChild(sr::createDiscardTests			(testCtx));
343 	glslTests->addChild(sr::createIndexingTests			(testCtx));
344 	glslTests->addChild(sr::createLoopTests				(testCtx));
345 	glslTests->addChild(sr::createMatrixTests			(testCtx));
346 	glslTests->addChild(sr::createOperatorTests			(testCtx));
347 	glslTests->addChild(sr::createReturnTests			(testCtx));
348 	glslTests->addChild(sr::createStructTests			(testCtx));
349 	glslTests->addChild(sr::createSwitchTests			(testCtx));
350 	glslTests->addChild(sr::createTextureFunctionTests	(testCtx));
351 	glslTests->addChild(sr::createTextureGatherTests	(testCtx));
352 	glslTests->addChild(sr::createBuiltinVarTests		(testCtx));
353 
354 	// ShaderExecutor-based tests
355 	glslTests->addChild(shaderexecutor::createBuiltinTests				(testCtx));
356 	glslTests->addChild(shaderexecutor::createOpaqueTypeIndexingTests	(testCtx));
357 }
358 
359 // TestPackage
360 
TestPackage(tcu::TestContext & testCtx)361 TestPackage::TestPackage (tcu::TestContext& testCtx)
362 	: tcu::TestPackage(testCtx, "dEQP-VK", "dEQP Vulkan Tests")
363 {
364 }
365 
~TestPackage(void)366 TestPackage::~TestPackage (void)
367 {
368 }
369 
createExecutor(void) const370 tcu::TestCaseExecutor* TestPackage::createExecutor (void) const
371 {
372 	return new TestCaseExecutor(m_testCtx);
373 }
374 
init(void)375 void TestPackage::init (void)
376 {
377 	addChild(createTestGroup				(m_testCtx, "info", "Build and Device Info Tests", createInfoTests));
378 	addChild(api::createTests				(m_testCtx));
379 	addChild(memory::createTests			(m_testCtx));
380 	addChild(pipeline::createTests			(m_testCtx));
381 	addChild(BindingModel::createTests		(m_testCtx));
382 	addChild(SpirVAssembly::createTests		(m_testCtx));
383 	addChild(createTestGroup				(m_testCtx, "glsl", "GLSL shader execution tests", createGlslTests));
384 	addChild(createRenderPassTests			(m_testCtx));
385 	addChild(ubo::createTests				(m_testCtx));
386 	addChild(DynamicState::createTests		(m_testCtx));
387 	addChild(ssbo::createTests				(m_testCtx));
388 	addChild(QueryPool::createTests			(m_testCtx));
389 	addChild(Draw::createTests				(m_testCtx));
390 	addChild(compute::createTests			(m_testCtx));
391 	addChild(image::createTests				(m_testCtx));
392 	addChild(wsi::createTests				(m_testCtx));
393 	addChild(synchronization::createTests	(m_testCtx));
394 	addChild(sparse::createTests			(m_testCtx));
395 	addChild(tessellation::createTests		(m_testCtx));
396 	addChild(rasterization::createTests		(m_testCtx));
397 	addChild(clipping::createTests			(m_testCtx));
398 	addChild(FragmentOperations::createTests(m_testCtx));
399 	addChild(texture::createTests			(m_testCtx));
400 	addChild(geometry::createTests			(m_testCtx));
401 }
402 
403 } // vkt
404