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