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