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 "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 
     86 vk::ProgramBinary* compileProgram (const glu::ProgramSources& source, glu::ShaderProgramInfo* buildInfo)
     87 {
     88 	return vk::buildProgram(source, vk::PROGRAM_FORMAT_SPIRV, buildInfo);
     89 }
     90 
     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>
     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 
    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 
    188 static MovePtr<vk::Library> createLibrary (tcu::TestContext& testCtx)
    189 {
    190 	return MovePtr<vk::Library>(testCtx.getPlatform().getVulkanPlatform().createLibrary());
    191 }
    192 
    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 
    206 TestCaseExecutor::~TestCaseExecutor (void)
    207 {
    208 	delete m_instance;
    209 }
    210 
    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 
    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 
    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 
    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 
    361 TestPackage::TestPackage (tcu::TestContext& testCtx)
    362 	: tcu::TestPackage(testCtx, "dEQP-VK", "dEQP Vulkan Tests")
    363 {
    364 }
    365 
    366 TestPackage::~TestPackage (void)
    367 {
    368 }
    369 
    370 tcu::TestCaseExecutor* TestPackage::createExecutor (void) const
    371 {
    372 	return new TestCaseExecutor(m_testCtx);
    373 }
    374 
    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