Beispiel #1
0
ReadPixelsTest::ReadPixelsTest	(Context& context, const char* name, const char* description, bool chooseFormat, int alignment)
	: TestCase			(context, name, description)
	, m_chooseFormat	(chooseFormat)
	, m_alignment		(alignment)
	, m_seed			(deStringHash(name))
{
}
MakeCurrentPerfCase::MakeCurrentPerfCase (EglTestContext& eglTestCtx, const Spec& spec, const char* name, const char* description)
	: TestCase		(eglTestCtx, tcu::NODETYPE_PERFORMANCE, name, description)
	, m_spec		(spec)
	, m_rnd			(deStringHash(name))
	, m_config		(DE_NULL)
{
}
	IterateResult iterate (void)
	{
		de::Random					rnd			(deStringHash(getName()) ^ 0x776002);
		std::vector<tcu::Vec2>		inputs;
		std::vector<deUint32>		outputs;
		const int					maxDiff		= m_precision == glu::PRECISION_HIGHP	? 1		:		// Rounding only.
												  m_precision == glu::PRECISION_MEDIUMP	? 33	:		// (2^-10) * (2^15) + 1
												  m_precision == glu::PRECISION_LOWP	? 129	: 0;	// (2^-8) * (2^15) + 1

		// Special values to check.
		inputs.push_back(tcu::Vec2(0.0f, 0.0f));
		inputs.push_back(tcu::Vec2(-1.0f, 1.0f));
		inputs.push_back(tcu::Vec2(0.5f, -0.5f));
		inputs.push_back(tcu::Vec2(-1.5f, 1.5f));
		inputs.push_back(tcu::Vec2(0.25f, -0.75f));

		// Random values, mostly in range.
		for (int ndx = 0; ndx < 15; ndx++)
		{
			const float x = rnd.getFloat()*2.5f - 1.25f;
			const float y = rnd.getFloat()*2.5f - 1.25f;
			inputs.push_back(tcu::Vec2(x, y));
		}

		// Large random values.
		for (int ndx = 0; ndx < 80; ndx++)
		{
			const float x = rnd.getFloat()*1e6f - 0.5e6f;
			const float y = rnd.getFloat()*1e6f - 0.5e6f;
			inputs.push_back(tcu::Vec2(x, y));
		}

		outputs.resize(inputs.size());

		m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values" << tcu::TestLog::EndMessage;

		{
			const void*	in	= &inputs[0];
			void*		out	= &outputs[0];

			m_executor->useProgram();
			m_executor->execute((int)inputs.size(), &in, &out);
		}

		// Verify
		{
			const int	numValues	= (int)inputs.size();
			const int	maxPrints	= 10;
			int			numFailed	= 0;

			for (int valNdx = 0; valNdx < numValues; valNdx++)
			{
				const deUint16	ref0	= (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 32767.0f), -(1<<15), (1<<15)-1);
				const deUint16	ref1	= (deUint16)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 32767.0f), -(1<<15), (1<<15)-1);
				const deUint32	ref		= (ref1 << 16) | ref0;
				const deUint32	res		= outputs[valNdx];
				const deUint16	res0	= (deUint16)(res & 0xffff);
				const deUint16	res1	= (deUint16)(res >> 16);
				const int		diff0	= de::abs((int)ref0 - (int)res0);
				const int		diff1	= de::abs((int)ref1 - (int)res1);

				if (diff0 > maxDiff || diff1 > maxDiff)
				{
					if (numFailed < maxPrints)
					{
						m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
															   << ", expected packSnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
															   << ", got " << tcu::toHex(res)
															   << "\n  diffs = (" << diff0 << ", " << diff1 << "), max diff = " << maxDiff
										   << TestLog::EndMessage;
					}
					else if (numFailed == maxPrints)
						m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;

					numFailed += 1;
				}
			}

			m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed" << TestLog::EndMessage;

			m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
									numFailed == 0 ? "Pass"					: "Result comparison failed");
		}

		return STOP;
	}
bool DitheringCase::drawAndCheckUnicoloredQuad (const Vec4& quadColor) const
{
	TestLog&					log					= m_testCtx.getLog();
	Random						rnd					(deStringHash(getName()));
	const int					maxViewportWid		= 32;
	const int					maxViewportHei		= 32;
	const int					viewportWid			= de::min(m_renderCtx.getRenderTarget().getWidth(), maxViewportWid);
	const int					viewportHei			= de::min(m_renderCtx.getRenderTarget().getHeight(), maxViewportHei);
	const int					viewportX			= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWid);
	const int					viewportY			= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHei);
	Quad						quad;
	Surface						renderedImg			(viewportWid, viewportHei);

	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportWid, viewportHei));

	log << TestLog::Message << "Dithering is " << (m_ditheringEnabled ? "enabled" : "disabled") << TestLog::EndMessage;

	if (m_ditheringEnabled)
		GLU_CHECK_CALL(glEnable(GL_DITHER));
	else
		GLU_CHECK_CALL(glDisable(GL_DITHER));

	log << TestLog::Message << "Drawing an unicolored quad with color " << quadColor << TestLog::EndMessage;

	quad.color[0] = quadColor;
	quad.color[1] = quadColor;
	quad.color[2] = quadColor;
	quad.color[3] = quadColor;

	m_renderer->render(quad);

	glu::readPixels(m_renderCtx, viewportX, viewportY, renderedImg.getAccess());
	GLU_CHECK_MSG("glReadPixels()");

	log << TestLog::Image(("Quad" + de::toString(m_iteration)).c_str(), ("Quad " + de::toString(m_iteration)).c_str(), renderedImg);

	// Validate, at each pixel, that each color channel is one of its two allowed values.

	{
		Surface		errorMask		(viewportWid, viewportHei);
		bool		colorChoicesOk	= true;

		for (int y = 0; y < renderedImg.getHeight(); y++)
		{
			for (int x = 0; x < renderedImg.getWidth(); x++)
			{
				if (!checkColor(quadColor, renderedImg.getPixel(x, y), colorChoicesOk))
				{
					errorMask.setPixel(x, y, tcu::RGBA::red);

					if (colorChoicesOk)
					{
						log << TestLog::Message << "First failure at pixel (" << x << ", " << y << ") (not printing further errors)" << TestLog::EndMessage;
						colorChoicesOk = false;
					}
				}
				else
					errorMask.setPixel(x, y, tcu::RGBA::green);
			}
		}

		if (!colorChoicesOk)
		{
			log << TestLog::Image("ColorChoiceErrorMask", "Error mask for color choices", errorMask);
			return false;
		}
	}

	// When dithering is disabled, the color selection must be coordinate-independent - i.e. the entire rendered image must be unicolored.

	if (!m_ditheringEnabled)
	{
		const tcu::RGBA renderedClr00 = renderedImg.getPixel(0, 0);

		for (int y = 0; y < renderedImg.getHeight(); y++)
		{
			for (int x = 0; x < renderedImg.getWidth(); x++)
			{
				const tcu::RGBA curClr = renderedImg.getPixel(x, y);

				if (curClr != renderedClr00)
				{
					log << TestLog::Message
						<< "Failure: color at (" << x << ", " << y << ") is " << curClr
						<< " and does not equal the color at (0, 0), which is " << renderedClr00
						<< TestLog::EndMessage;

					return false;
				}
			}
		}
	}

	return true;
}
bool DitheringCase::drawAndCheckGradient (const bool isVerticallyIncreasing, const Vec4& highColor) const
{
	TestLog&					log					= m_testCtx.getLog();
	Random						rnd					(deStringHash(getName()));
	const int					maxViewportWid		= 256;
	const int					maxViewportHei		= 256;
	const int					viewportWid			= de::min(m_renderCtx.getRenderTarget().getWidth(), maxViewportWid);
	const int					viewportHei			= de::min(m_renderCtx.getRenderTarget().getHeight(), maxViewportHei);
	const int					viewportX			= rnd.getInt(0, m_renderCtx.getRenderTarget().getWidth() - viewportWid);
	const int					viewportY			= rnd.getInt(0, m_renderCtx.getRenderTarget().getHeight() - viewportHei);
	const Vec4					quadClr0			(0.0f, 0.0f, 0.0f, 0.0f);
	const Vec4&					quadClr1			= highColor;
	Quad						quad;
	Surface						renderedImg			(viewportWid, viewportHei);

	GLU_CHECK_CALL(glViewport(viewportX, viewportY, viewportWid, viewportHei));

	log << TestLog::Message << "Dithering is " << (m_ditheringEnabled ? "enabled" : "disabled") << TestLog::EndMessage;

	if (m_ditheringEnabled)
		GLU_CHECK_CALL(glEnable(GL_DITHER));
	else
		GLU_CHECK_CALL(glDisable(GL_DITHER));

	log << TestLog::Message << "Drawing a " << (isVerticallyIncreasing ? "vertically" : "horizontally") << " increasing gradient" << TestLog::EndMessage;

	quad.color[0] = quadClr0;
	quad.color[1] = isVerticallyIncreasing ? quadClr1 : quadClr0;
	quad.color[2] = isVerticallyIncreasing ? quadClr0 : quadClr1;
	quad.color[3] = quadClr1;

	m_renderer->render(quad);

	glu::readPixels(m_renderCtx, viewportX, viewportY, renderedImg.getAccess());
	GLU_CHECK_MSG("glReadPixels()");

	log << TestLog::Image(isVerticallyIncreasing ? "VerGradient"		: "HorGradient",
						  isVerticallyIncreasing ? "Vertical gradient"	: "Horizontal gradient",
						  renderedImg);

	// Validate, at each pixel, that each color channel is one of its two allowed values.

	{
		Surface		errorMask		(viewportWid, viewportHei);
		bool		colorChoicesOk	= true;

		for (int y = 0; y < renderedImg.getHeight(); y++)
		{
			for (int x = 0; x < renderedImg.getWidth(); x++)
			{
				const float		inputF		= ((float)(isVerticallyIncreasing ? y : x) + 0.5f) / (float)(isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth());
				const Vec4		inputClr	= (1.0f-inputF)*quadClr0 + inputF*quadClr1;

				if (!checkColor(inputClr, renderedImg.getPixel(x, y), colorChoicesOk))
				{
					errorMask.setPixel(x, y, tcu::RGBA::red);

					if (colorChoicesOk)
					{
						log << TestLog::Message << "First failure at pixel (" << x << ", " << y << ") (not printing further errors)" << TestLog::EndMessage;
						colorChoicesOk = false;
					}
				}
				else
					errorMask.setPixel(x, y, tcu::RGBA::green);
			}
		}

		if (!colorChoicesOk)
		{
			log << TestLog::Image("ColorChoiceErrorMask", "Error mask for color choices", errorMask);
			return false;
		}
	}

	// When dithering is disabled, the color selection must be coordinate-independent - i.e. the colors must be constant in the gradient's constant direction.

	if (!m_ditheringEnabled)
	{
		const int increasingDirectionSize	= isVerticallyIncreasing ? renderedImg.getHeight() : renderedImg.getWidth();
		const int constantDirectionSize		= isVerticallyIncreasing ? renderedImg.getWidth() : renderedImg.getHeight();

		for (int incrPos = 0; incrPos < increasingDirectionSize; incrPos++)
		{
			tcu::RGBA prevConstantDirectionPix;
			for (int constPos = 0; constPos < constantDirectionSize; constPos++)
			{
				const int			x		= isVerticallyIncreasing ? constPos : incrPos;
				const int			y		= isVerticallyIncreasing ? incrPos : constPos;
				const tcu::RGBA		clr		= renderedImg.getPixel(x, y);

				if (constPos > 0 && clr != prevConstantDirectionPix)
				{
					log << TestLog::Message
						<< "Failure: colors should be constant per " << (isVerticallyIncreasing ? "row" : "column")
						<< " (since dithering is disabled), but the color at position (" << x << ", " << y << ") is " << clr
						<< " and does not equal the color at (" << (isVerticallyIncreasing ? x-1 : x) << ", " << (isVerticallyIncreasing ? y : y-1) << "), which is " << prevConstantDirectionPix
						<< TestLog::EndMessage;

					return false;
				}

				prevConstantDirectionPix = clr;
			}
		}
	}

	return true;
}
GLW_APICALL GLint GLW_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name)
{
	DE_UNREF(program);
	return (GLint)(deStringHash(name) & 0x7FFFFFFF);
}